Update MCLinker to work with LLVM 3.4.

This corresponds to merging upstream MCLinker with the following SHA:
6dcbf36cdb146d6f175ba2f18a9004753cafeaff

Change-Id: I1bc8c2ce4accc563450bc71ee295a6e47a0c0469
diff --git a/include/mcld/ADT/BinTree.h b/include/mcld/ADT/BinTree.h
index 76de607..4093b72 100644
--- a/include/mcld/ADT/BinTree.h
+++ b/include/mcld/ADT/BinTree.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_BINARY_TREE_H
-#define MCLD_BINARY_TREE_H
+#ifndef MCLD_ADT_BITREE_H
+#define MCLD_ADT_BITREE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -438,16 +438,16 @@
   //  @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) {
+  template<size_t DIRECT>
+  BinaryTree& join(TreeIteratorBase& pPosition, const DataType& pValue) {
     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));
+    node->data = const_cast<DataType*>(&pValue);
+
+    if (pPosition.isRoot())
+      pPosition.hook<TreeIteratorBase::Leftward>(node);
     else
-      proxy::hook<DIRECT>(position.m_pNode,
-                          const_cast<const node_type*>(node));
+      pPosition.hook<DIRECT>(node);
+
     return *this;
   }
 
@@ -456,14 +456,13 @@
   //  @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) {
+  template<size_t DIRECT>
+  BinaryTree& merge(TreeIteratorBase& pPosition, 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));
+      pPosition.hook<DIRECT>(pTree.m_Root.node.left);
       BinaryTreeBase<DataType>::m_Root.summon(
                                    pTree.BinaryTreeBase<DataType>::m_Root);
       BinaryTreeBase<DataType>::m_Root.delegate(pTree.m_Root);
diff --git a/include/mcld/ADT/Flags.h b/include/mcld/ADT/Flags.h
index d38d941..c6a41e8 100644
--- a/include/mcld/ADT/Flags.h
+++ b/include/mcld/ADT/Flags.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_FLAGS_H
-#define MCLD_FLAGS_H
+#ifndef MCLD_ADT_FLAGS_H
+#define MCLD_ADT_FLAGS_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/ADT/GraphLite/Digraph.h b/include/mcld/ADT/GraphLite/Digraph.h
new file mode 100644
index 0000000..9e1b604
--- /dev/null
+++ b/include/mcld/ADT/GraphLite/Digraph.h
@@ -0,0 +1,85 @@
+//===- Digraph.h ----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ADT_GRAPHLITE_DIGRAPH_H
+#define MCLD_ADT_GRAPHLITE_DIGRAPH_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/ADT/Uncopyable.h>
+#include <mcld/ADT/GraphLite/GraphBasicTypes.h>
+#include <stdint.h>
+
+namespace mcld {
+namespace graph {
+
+/** \class Digraph
+ *  \brief Digraph provides the common interface of all directed graphs.
+ */
+class Digraph : private Uncopyable
+{
+public:
+  typedef DirectedTag direction_tag;
+
+  class Node
+  {
+    friend class Digraph;
+  public:
+    Node() {}
+
+    bool operator==(const Node& pOther) const { return m_ID == pOther.m_ID; }
+    bool operator!=(const Node& pOther) const { return m_ID != pOther.m_ID; }
+
+  protected:
+    intptr_t m_ID;
+  };
+
+  class Arc
+  {
+    friend class Digraph;
+  public:
+    Arc();
+
+    bool operator==(const Node& pOther) const;
+    bool operator!=(const Node& pOther) const;
+
+    Node source() const;
+    Node target() const;
+
+  protected:
+    Arc(Digraph& pParent);
+
+  protected:
+    intptr_t m_ID;
+    Digraph* m_Parent;
+  };
+
+public:
+  Digraph();
+
+  Node addNode();
+
+  Arc addArc(const Node& pSource, const Node& pTarget);
+
+  void erase(const Node& pNode);
+
+  void erase(const Arc& pArc);
+
+  void clear();
+
+  unsigned int numOfNodes() const;
+
+  unsigned int numOfArcs() const;
+
+};
+
+} // namespace of graph
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/GraphLite/GraphBasicTypes.h b/include/mcld/ADT/GraphLite/GraphBasicTypes.h
new file mode 100644
index 0000000..5862bcb
--- /dev/null
+++ b/include/mcld/ADT/GraphLite/GraphBasicTypes.h
@@ -0,0 +1,29 @@
+//===- GraphBasicTypes.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ADT_GRAPHLITE_GRAPHBASICTYPES_H
+#define MCLD_ADT_GRAPHLITE_GRAPHBASICTYPES_H
+
+namespace mcld {
+namespace graph {
+
+/** \class UndirectedTag
+ *  \brief Undirected graph category.
+ */
+struct UndirectedTag {};
+
+/** \class DirectedTag
+ *  \brief Directed graph category.
+ */
+struct DirectedTag {};
+
+} // namespace of graph
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/GraphLite/ListDigraph.h b/include/mcld/ADT/GraphLite/ListDigraph.h
new file mode 100644
index 0000000..4ae2c50
--- /dev/null
+++ b/include/mcld/ADT/GraphLite/ListDigraph.h
@@ -0,0 +1,92 @@
+//===- ListDigraph.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ADT_GRAPHLITE_LISTDIGRAPH_H
+#define MCLD_ADT_GRAPHLITE_LISTDIGRAPH_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Support/GCFactory.h>
+
+namespace mcld {
+namespace graph {
+
+/** \class ListDigraph
+ *  \brief ListDigraph provides an linked-list inplementation of a graph.
+ *
+ *  ListDigraph is designed to get well performance for most algorithms of
+ *  graph theory.
+ *
+ *  Function        | Complexity | Best Complexity
+ *  ----------------|------------|--------------------------
+ *  Storage         | V + E      |
+ *  Add node        | O(1)       |
+ *  Add arc         | O(1)       |
+ *  Remove node     | O(E)       | O(#(fan-in) + #(fan-out))
+ *  Remove edge     | O(1)       |
+ *  Query adjacency | O(E)       | O(#(fan-in) + #(fan-out))
+ *
+ */
+class ListDigraph
+{
+public:
+  struct Node;
+  struct Arc;
+
+  struct Node {
+  public:
+    Node();
+
+  public:
+    Node *prev, *next;
+    Arc *first_in, *first_out;
+  };
+
+  struct Arc {
+  public:
+    Arc();
+
+  public:
+    Node *target, *source;
+    Arc *prev_in, *next_in;
+    Arc *prev_out, *next_out;
+  };
+
+public:
+  ListDigraph();
+
+  Node* addNode();
+
+  Arc* addArc(Node& pU, Node& pV);
+
+  void erase(Node& pNode);
+
+  void erase(Arc& pArc);
+
+  void clear();
+
+  void getHead(Node*& pNode) const { pNode = m_pNodeHead; }
+
+private:
+  typedef GCFactory<Node, 0> NodeList;
+  typedef GCFactory<Arc, 0> ArcList;
+
+private:
+  Node* m_pNodeHead;
+  Node* m_pFreeNodeHead;
+  Arc*  m_pFreeArcHead;
+
+  NodeList m_NodeList;
+  ArcList m_ArcList;
+};
+
+} // namespace of graph
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashBase.h b/include/mcld/ADT/HashBase.h
index 896f5b8..f3332a0 100644
--- a/include/mcld/ADT/HashBase.h
+++ b/include/mcld/ADT/HashBase.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_HASH_BASE_H
-#define MCLD_HASH_BASE_H
+#ifndef MCLD_ADT_HASHBASE_H
+#define MCLD_ADT_HASHBASE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/ADT/HashBase.tcc b/include/mcld/ADT/HashBase.tcc
index 165f4ae..50f6ac4 100644
--- a/include/mcld/ADT/HashBase.tcc
+++ b/include/mcld/ADT/HashBase.tcc
@@ -7,8 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
 // internal non-member functions
+//===----------------------------------------------------------------------===//
 inline static unsigned int compute_bucket_count(unsigned int pNumOfBuckets)
 {
   static const unsigned int bucket_size[] =
@@ -30,8 +31,9 @@
   return (pNumOfBuckets+131101); // rare case. increase constantly
 }
 
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
 // template implementation of HashBucket
+//===----------------------------------------------------------------------===//
 template<typename DataType>
 typename HashBucket<DataType>::entry_type*
 HashBucket<DataType>::getEmptyBucket()
@@ -48,8 +50,9 @@
   return tombstone;
 }
 
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
 // template implementation of HashTableImpl
+//===----------------------------------------------------------------------===//
 template<typename HashEntryTy,
          typename HashFunctionTy>
 HashTableImpl<HashEntryTy, HashFunctionTy>::HashTableImpl()
diff --git a/include/mcld/ADT/HashEntry.h b/include/mcld/ADT/HashEntry.h
index c034783..5c3557f 100644
--- a/include/mcld/ADT/HashEntry.h
+++ b/include/mcld/ADT/HashEntry.h
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef MCLD_HASH_ENTRY_H
-#define MCLD_HASH_ENTRY_H
+#ifndef MCLD_ADT_HASHENTRY_H
+#define MCLD_ADT_HASHENTRY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/ADT/HashEntryFactory.h b/include/mcld/ADT/HashEntryFactory.h
index 42aa5e7..91deab4 100644
--- a/include/mcld/ADT/HashEntryFactory.h
+++ b/include/mcld/ADT/HashEntryFactory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_HASH_ENTRY_FACTORY_H
-#define MCLD_HASH_ENTRY_FACTORY_H
+#ifndef MCLD_ADT_HASHENTRYFACTORY_H
+#define MCLD_ADT_HASHENTRYFACTORY_H
 
 namespace mcld {
 
diff --git a/include/mcld/ADT/HashIterator.h b/include/mcld/ADT/HashIterator.h
index 078b20a..c25870f 100644
--- a/include/mcld/ADT/HashIterator.h
+++ b/include/mcld/ADT/HashIterator.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_HASH_ITERATOR_H
-#define MCLD_HASH_ITERATOR_H
+#ifndef MCLD_ADT_HASHITERATOR_H
+#define MCLD_ADT_HASHITERATOR_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/ADT/HashTable.h b/include/mcld/ADT/HashTable.h
index 0b6757e..522ab48 100644
--- a/include/mcld/ADT/HashTable.h
+++ b/include/mcld/ADT/HashTable.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_HASH_TABLE_H
-#define MCLD_HASH_TABLE_H
+#ifndef MCLD_ADT_HASHTABLE_H
+#define MCLD_ADT_HASHTABLE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/ADT/SizeTraits.h b/include/mcld/ADT/SizeTraits.h
index dbd5d7b..3baf129 100644
--- a/include/mcld/ADT/SizeTraits.h
+++ b/include/mcld/ADT/SizeTraits.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_SIZE_TRAITS_H
-#define MCLD_SIZE_TRAITS_H
+#ifndef MCLD_ADT_SIZETRAITS_H
+#define MCLD_ADT_SIZETRAITS_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -153,6 +153,36 @@
            ((pData & 0x00000000000000FFULL) << 56));
 }
 
+template<size_t SIZE>
+typename SizeTraits<SIZE>::Word bswap(typename SizeTraits<SIZE>::Word pData);
+
+template<>
+inline SizeTraits<32>::Word bswap<32>(SizeTraits<32>::Word pData)
+{
+  return bswap32(pData);
+}
+
+template<>
+inline SizeTraits<64>::Word bswap<64>(SizeTraits<64>::Word pData)
+{
+  return bswap64(pData);
+}
+
+template <size_t WIDTH>
+inline uint64_t signExtend(uint64_t pVal)
+{
+  uint64_t mask = (~((uint64_t)0)) >> (64 - WIDTH);
+  uint64_t sign_bit = 1 << (WIDTH - 1);
+
+  return ((pVal & mask) ^ sign_bit) - sign_bit;
+}
+
+template <>
+inline uint64_t signExtend<64>(uint64_t pVal)
+{
+  return pVal;
+}
+
 template <size_t SizeOfStr, typename FieldType>
 class StringSizerHelper
 {
diff --git a/include/mcld/ADT/StringEntry.h b/include/mcld/ADT/StringEntry.h
index e6d1c20..3588c05 100644
--- a/include/mcld/ADT/StringEntry.h
+++ b/include/mcld/ADT/StringEntry.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_STRING_ENTRY_H
-#define MCLD_STRING_ENTRY_H
+#ifndef MCLD_ADT_STRINGENTRY_H
+#define MCLD_ADT_STRINGENTRY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/ADT/StringHash.h b/include/mcld/ADT/StringHash.h
index a9c0025..048f35f 100644
--- a/include/mcld/ADT/StringHash.h
+++ b/include/mcld/ADT/StringHash.h
@@ -6,15 +6,15 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_STRING_HASH_FUNCTION_H
-#define MCLD_STRING_HASH_FUNCTION_H
+#ifndef MCLD_ADT_STRINGHASH_H
+#define MCLD_ADT_STRINGHASH_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 #include <llvm/ADT/StringRef.h>
 #include <llvm/Support/DataTypes.h>
-#include <llvm/Support/ErrorHandling.h>
 #include <cctype>
+#include <cassert>
 #include <functional>
 
 namespace mcld {
@@ -43,7 +43,8 @@
 {
   uint32_t operator()(const llvm::StringRef& pKey) const
   {
-    llvm::report_fatal_error("Undefined StringHash function.\n");
+    assert(false && "Undefined StringHash function.\n");
+    return 0;
   }
 };
 
diff --git a/include/mcld/ADT/TreeAllocator.h b/include/mcld/ADT/TreeAllocator.h
index 10de761..b2bb39b 100644
--- a/include/mcld/ADT/TreeAllocator.h
+++ b/include/mcld/ADT/TreeAllocator.h
@@ -6,13 +6,13 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TREE_ALLOCATOR_H
-#define MCLD_TREE_ALLOCATOR_H
+#ifndef MCLD_ADT_TREEALLOCATOR_H
+#define MCLD_ADT_TREEALLOCATOR_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 #include <set>
-#include "mcld/Support/GCFactory.h"
+#include <mcld/Support/GCFactory.h>
 
 namespace mcld {
 
diff --git a/include/mcld/ADT/TreeBase.h b/include/mcld/ADT/TreeBase.h
index 13eb474..bca375f 100644
--- a/include/mcld/ADT/TreeBase.h
+++ b/include/mcld/ADT/TreeBase.h
@@ -6,9 +6,9 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TREE_BASE_H
-#define MCLD_TREE_BASE_H
-#include "mcld/ADT/TypeTraits.h"
+#ifndef MCLD_ADT_TREEBASE_H
+#define MCLD_ADT_TREEBASE_H
+#include <mcld/ADT/TypeTraits.h>
 
 #include <cstddef>
 #include <cassert>
@@ -28,18 +28,6 @@
   { }
 };
 
-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
-
 class TreeIteratorBase
 {
 public:
@@ -67,9 +55,10 @@
   virtual ~TreeIteratorBase(){};
 
   template<size_t DIRECT>
-  inline void move() {
-    proxy::move<DIRECT>(m_pNode);
-  }
+  void move() { assert(0 && "not allowed"); }
+
+  template<size_t DIRECT>
+  void hook(NodeBase* pNode) { assert(0 && "not allowed"); }
 
   bool isRoot() const
   { return (m_pNode->right == m_pNode); }
@@ -87,25 +76,29 @@
   { return this->m_pNode != y.m_pNode; }
 };
 
-namespace proxy
+template<> inline
+void TreeIteratorBase::move<TreeIteratorBase::Leftward>()
 {
-  template<>
-  inline void move<TreeIteratorBase::Leftward>(NodeBase *&X)
-  { X = X->left; }
+  this->m_pNode = this->m_pNode->left;
+}
 
-  template<>
-  inline void move<TreeIteratorBase::Rightward>(NodeBase *&X)
-  { X = X->right; }
+template<> inline
+void TreeIteratorBase::move<TreeIteratorBase::Rightward>()
+{
+  this->m_pNode = this->m_pNode->right;
+}
 
-  template<>
-  inline void hook<TreeIteratorBase::Leftward>(NodeBase *X, const NodeBase *Y)
-  { X->left = const_cast<NodeBase*>(Y); }
+template<> inline
+void TreeIteratorBase::hook<TreeIteratorBase::Leftward>(NodeBase* pOther)
+{
+  this->m_pNode->left = pOther;
+}
 
-  template<>
-  inline void hook<TreeIteratorBase::Rightward>(NodeBase* X, const NodeBase* Y)
-  { X->right = const_cast<NodeBase*>(Y); }
-
-} //namespace of template proxy
+template<> inline
+void TreeIteratorBase::hook<TreeIteratorBase::Rightward>(NodeBase* pOther)
+{
+  this->m_pNode->right = pOther;
+}
 
 template<typename DataType>
 class Node : public NodeBase
diff --git a/include/mcld/ADT/TypeTraits.h b/include/mcld/ADT/TypeTraits.h
index 90b2224..7f872da 100644
--- a/include/mcld/ADT/TypeTraits.h
+++ b/include/mcld/ADT/TypeTraits.h
@@ -6,16 +6,16 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TYPE_TRAITS_H
-#define MCLD_TYPE_TRAITS_H
+#ifndef MCLD_ADT_TYPETRAITS_H
+#define MCLD_ADT_TYPETRAITS_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
 #include <cstdlib>
 
-namespace mcld
-{
+namespace mcld {
+
 template<typename DataType>
 struct NonConstTraits;
 
diff --git a/include/mcld/ADT/Uncopyable.h b/include/mcld/ADT/Uncopyable.h
index 7ddfbe3..d899a0a 100644
--- a/include/mcld/ADT/Uncopyable.h
+++ b/include/mcld/ADT/Uncopyable.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_UNCOPYABLE_H
-#define MCLD_UNCOPYABLE_H
+#ifndef MCLD_ADT_UNCOPYABLE_H
+#define MCLD_ADT_UNCOPYABLE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/AttributeOption.h b/include/mcld/AttributeOption.h
index 18d7278..a0130d2 100644
--- a/include/mcld/AttributeOption.h
+++ b/include/mcld/AttributeOption.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ATTRIBUTE_OPTIONS_H
-#define MCLD_ATTRIBUTE_OPTIONS_H
+#ifndef MCLD_ATTRIBUTEOPTION_H
+#define MCLD_ATTRIBUTEOPTION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/BitcodeOption.h b/include/mcld/BitcodeOption.h
index 4e9a5e1..6d2b9b7 100644
--- a/include/mcld/BitcodeOption.h
+++ b/include/mcld/BitcodeOption.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_BITCODE_OPTIONS_H
-#define MCLD_BITCODE_OPTIONS_H
+#ifndef MCLD_BITCODEOPTION_H
+#define MCLD_BITCODEOPTION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/CodeGen/MCLinker.h b/include/mcld/CodeGen/MCLinker.h
index 34ddcb7..10423bb 100644
--- a/include/mcld/CodeGen/MCLinker.h
+++ b/include/mcld/CodeGen/MCLinker.h
@@ -28,10 +28,10 @@
 namespace mcld {
 
 class Module;
-class MemoryArea;
 class IRBuilder;
 class LinkerConfig;
 class Linker;
+class FileHandle;
 
 /** \class MCLinker
 *  \brief MCLinker provides a linking pass for standard compilation flow
@@ -54,7 +54,7 @@
   // - the standard symbols
   MCLinker(LinkerConfig& pConfig,
            mcld::Module& pModule,
-           MemoryArea& pOutput);
+           FileHandle& pFileHandle);
 
 public:
   virtual ~MCLinker();
@@ -71,7 +71,7 @@
 protected:
   LinkerConfig& m_Config;
   mcld::Module& m_Module;
-  MemoryArea& m_Output;
+  FileHandle& m_FileHandle;
   IRBuilder* m_pBuilder;
   Linker* m_pLinker;
 
diff --git a/include/mcld/Target/TargetMachine.h b/include/mcld/CodeGen/TargetMachine.h
similarity index 66%
rename from include/mcld/Target/TargetMachine.h
rename to include/mcld/CodeGen/TargetMachine.h
index 669e860..6454d87 100644
--- a/include/mcld/Target/TargetMachine.h
+++ b/include/mcld/CodeGen/TargetMachine.h
@@ -6,12 +6,9 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TARGET_TARGET_MACHINE_H
-#define MCLD_TARGET_TARGET_MACHINE_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <llvm/Target/TargetMachine.h>
+#ifndef MCLD_CODEGEN_TARGETMACHINE_H
+#define MCLD_CODEGEN_TARGETMACHINE_H
+#include <llvm/Support/CodeGen.h>
 #include <string>
 
 namespace llvm {
@@ -19,20 +16,22 @@
 class Target;
 class TargetData;
 class TargetMachine;
+class MCContext;
+class raw_ostream;
+class formatted_raw_ostream;
+namespace legacy {
 class PassManagerBase;
-
-} // namespace of llvm
+} // namepsace legacy
+} // namespace llvm
 
 namespace mcld {
 
 class Module;
 class Target;
-class MemoryArea;
+class FileHandle;
 class LinkerConfig;
 class ToolOutputFile;
 
-using namespace llvm;
-
 enum CodeGenFileType {
   CGFT_ASMFile,
   CGFT_OBJFile,
@@ -52,9 +51,10 @@
 public:
   /// Adapter of llvm::TargetMachine
   ///
-  MCLDTargetMachine(llvm::TargetMachine &pTM,
-                    const mcld::Target &pTarget,
-                    const std::string &pTriple);
+  MCLDTargetMachine(llvm::TargetMachine& pTM,
+                    const llvm::Target& pLLMVTarget,
+                    const mcld::Target& pMCLDTarget,
+                    const std::string& pTriple);
 
   virtual ~MCLDTargetMachine();
 
@@ -67,48 +67,41 @@
 
   /// appPassesToEmitFile - The target function which we has to modify as
   /// upstreaming.
-  bool addPassesToEmitFile(PassManagerBase &,
+  bool addPassesToEmitFile(llvm::legacy::PassManagerBase &,
                            mcld::ToolOutputFile& pOutput,
                            mcld::CodeGenFileType,
-                           CodeGenOpt::Level,
+                           llvm::CodeGenOpt::Level,
                            mcld::Module& pModule,
                            mcld::LinkerConfig& pConfig,
                            bool DisableVerify = true);
 
-  /// getDataLayout
-  const DataLayout *getDataLayout() const { return m_TM.getDataLayout(); }
-
-  /// 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 &,
+  bool addCommonCodeGenPasses(llvm::legacy::PassManagerBase &,
                               mcld::CodeGenFileType,
-                              CodeGenOpt::Level,
+                              llvm::CodeGenOpt::Level,
                               bool DisableVerify,
                               llvm::MCContext *&OutCtx);
 
-  bool addCompilerPasses(PassManagerBase &pPM,
+  bool addCompilerPasses(llvm::legacy::PassManagerBase &pPM,
                          llvm::formatted_raw_ostream &pOutput,
                          llvm::MCContext *&OutCtx);
 
-  bool addAssemblerPasses(PassManagerBase &pPM,
+  bool addAssemblerPasses(llvm::legacy::PassManagerBase &pPM,
                           llvm::raw_ostream &pOutput,
                           llvm::MCContext *&OutCtx);
 
-  bool addLinkerPasses(PassManagerBase &pPM,
-                       LinkerConfig& pConfig,
-                       Module& pModule,
-                       mcld::MemoryArea& pOutput,
+  bool addLinkerPasses(llvm::legacy::PassManagerBase &pPM,
+                       mcld::LinkerConfig& pConfig,
+                       mcld::Module& pModule,
+                       mcld::FileHandle& pFileHandle,
                        llvm::MCContext *&OutCtx);
 
 private:
   llvm::TargetMachine &m_TM;
-  const mcld::Target *m_pTarget;
+  const llvm::Target *m_pLLVMTarget;
+  const mcld::Target *m_pMCLDTarget;
   const std::string& m_Triple;
 };
 
diff --git a/include/mcld/Config/Config.h b/include/mcld/Config/Config.h
index 94946df..9e52d54 100644
--- a/include/mcld/Config/Config.h
+++ b/include/mcld/Config/Config.h
@@ -40,5 +40,7 @@
 #define MCLD_SYMBOLS_PER_INPUT 128
 #define MCLD_RELOCATIONS_PER_INPUT 1024
 
+#define MCLD_SEGMENTS_PER_OUTPUT 8
+
 #endif
 
diff --git a/include/mcld/Fragment/AlignFragment.h b/include/mcld/Fragment/AlignFragment.h
index 14d0051..1175c07 100644
--- a/include/mcld/Fragment/AlignFragment.h
+++ b/include/mcld/Fragment/AlignFragment.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_ALIGNFRAGMENT_H
-#define MCLD_LD_ALIGNFRAGMENT_H
+#ifndef MCLD_FRAGMENT_ALIGNFRAGMENT_H
+#define MCLD_FRAGMENT_ALIGNFRAGMENT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Fragment/FGNode.h b/include/mcld/Fragment/FGNode.h
deleted file mode 100644
index 0afee0e..0000000
--- a/include/mcld/Fragment/FGNode.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===- FGNode.h -----------------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_FGNODE_H
-#define MCLD_FGNODE_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-
-#include <llvm/Support/DataTypes.h>
-
-#include <vector>
-
-namespace mcld
-{
-
-class Relocation;
-class ResolveInfo;
-class Fragment;
-
-/** \class FGNode
- *  \brief FGNode is a node for FragmentGraph
- */
-class FGNode
-{
-public:
-  typedef ResolveInfo* Slot;
-  typedef Relocation*  Signal;
-
-  typedef std::vector<Fragment*> FragmentListType;
-  typedef FragmentListType::iterator frag_iterator;
-  typedef FragmentListType::const_iterator const_frag_iterator;
-
-  typedef std::vector<Slot> SlotListType;
-  typedef SlotListType::iterator slot_iterator;
-  typedef SlotListType::const_iterator const_slot_iterator;
-
-  typedef std::vector<Signal> SignalListType;
-  typedef SignalListType::iterator signal_iterator;
-  typedef SignalListType::const_iterator const_signal_iterator;
-
-public:
-  FGNode();
-  explicit FGNode(uint32_t pIndex);
-
-  void addFragment(Fragment* pFrag);
-  void addSignal(Signal pSignal);
-  void addSlot(Slot pSlot);
-
-  /// ----- observers ----- ///
-  uint32_t getIndex() const
-  {  return m_Index; }
-
-  slot_iterator         slot_begin   ()       { return m_Slots.begin();     }
-  const_slot_iterator   slot_begin   () const { return m_Slots.begin();     }
-  slot_iterator         slot_end     ()       { return m_Slots.end();       }
-  const_slot_iterator   slot_end     () const { return m_Slots.end();       }
-
-  signal_iterator       signal_begin ()       { return m_Signals.begin();   }
-  const_signal_iterator signal_begin () const { return m_Signals.begin();   }
-  signal_iterator       signal_end   ()       { return m_Signals.end();     }
-  const_signal_iterator signal_end   () const { return m_Signals.end();     }
-
-  frag_iterator         frag_begin   ()       { return m_Fragments.begin(); }
-  const_frag_iterator   frag_begin   () const { return m_Fragments.begin(); }
-  frag_iterator         frag_end     ()       { return m_Fragments.end();   }
-  const_frag_iterator   frag_end     () const { return m_Fragments.end();   }
-
-private:
-  FragmentListType m_Fragments;
-
-  /// m_Signals - a list of relocations describes the possible fan-out of this
-  /// node
-  SignalListType m_Signals;
-
-  /// m_Slots - a list of symbols describes the possible fan-in of this node
-  SlotListType m_Slots;
-
-  /// m_Index - the index in the reachability matrix
-  uint32_t m_Index;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Fragment/FillFragment.h b/include/mcld/Fragment/FillFragment.h
index af78237..aa32ec8 100644
--- a/include/mcld/Fragment/FillFragment.h
+++ b/include/mcld/Fragment/FillFragment.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_FILLFRAGMENT_H
-#define MCLD_LD_FILLFRAGMENT_H
+#ifndef MCLD_FRAGMENT_FILLFRAGMENT_H
+#define MCLD_FRAGMENT_FILLFRAGMENT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Fragment/FragmentGraph.h b/include/mcld/Fragment/FragmentGraph.h
deleted file mode 100644
index 96d438f..0000000
--- a/include/mcld/Fragment/FragmentGraph.h
+++ /dev/null
@@ -1,177 +0,0 @@
-//===- FragmentGraph.h ----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_FRAGMENTGRAPH_H
-#define MCLD_FRAGMENTGRAPH_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-
-#include <vector>
-
-#include <mcld/ADT/HashTable.h>
-#include <mcld/ADT/HashEntry.h>
-#include <mcld/Config/Config.h>
-#include <mcld/Fragment/FGNode.h>
-#include <mcld/Fragment/FGEdge.h>
-#include <mcld/Support/GCFactory.h>
-
-#include <llvm/Support/DataTypes.h>
-
-namespace mcld
-{
-class Module;
-class ResolveInfo;
-class Relocation;
-class LinkerConfig;
-
-/** \class FragmentGraph
- *  \brief FragmentGraph describes the references between fragments.
- */
-class FragmentGraph
-{
-public:
-  typedef FGNode::Slot   Slot;
-  typedef FGNode::Signal Signal;
-
-  typedef GCFactory<FGNode, MCLD_SECTIONS_PER_INPUT> NodeFactoryType;
-  typedef NodeFactoryType::iterator node_iterator;
-  typedef NodeFactoryType::const_iterator const_node_iterator;
-
-  typedef std::vector<FGEdge> EdgeListType;
-  typedef EdgeListType::iterator edge_iterator;
-  typedef EdgeListType::const_iterator const_edge_iterator;
-
-
-public:
-  FragmentGraph();
-  ~FragmentGraph();
-
-  /// construct - construct the whole graph from input Fragments, relocations
-  /// and symbols
-  bool construct(const LinkerConfig& pConfig, Module& pModule);
-
-  /// connect - connect two nodes
-  bool connect(Signal pSignal, Slot pSlot);
-  bool connect(FGNode& pFrom, Slot pSlot);
-
-  /// getEdges - given a node, get the list of edges which are the fan-out of
-  /// this node
-  /// @param pEdges - the edge list which contains the found edges
-  /// @return false - the given node
-  bool getEdges(FGNode& pNode, EdgeListType& pEdges);
-
-  /// ----- observers -----///
-  /// getNode - given a fragment, finde the node which the fragment is belong to
-  FGNode* getNode(const Fragment& pFrag);
-  const FGNode* getNode(const Fragment& pFrag) const;
-
-  FGNode* getNode(const ResolveInfo& pSym);
-  const FGNode* getNode(const ResolveInfo& pSym) const;
-
-private:
-  typedef std::vector<Relocation*> RelocationListType;
-  typedef RelocationListType::iterator reloc_iterator;
-  typedef RelocationListType::const_iterator const_reloc_iterator;
-
-  struct PtrCompare
-  {
-    bool operator()(const void* X, const void* Y) const
-    { return (X==Y); }
-  };
-
-  struct PtrHash
-  {
-    size_t operator()(const void* pKey) const
-    {
-      return (unsigned((uintptr_t)pKey) >> 4) ^
-             (unsigned((uintptr_t)pKey) >> 9);
-    }
-  };
-
-  /// HashTable for Fragment* to Node*
-  typedef HashEntry<const Fragment*, FGNode*, PtrCompare> FragHashEntryType;
-  typedef HashTable<FragHashEntryType,
-                    PtrHash,
-                    EntryFactory<FragHashEntryType> > FragHashTableType;
-
-  /// HashTable for ResolveInfo* to Node*
-  typedef HashEntry<const ResolveInfo*, FGNode*, PtrCompare> SymHashEntryType;
-  typedef HashTable<SymHashEntryType,
-                    PtrHash,
-                    EntryFactory<SymHashEntryType> > SymHashTableType;
-
-  /** \class ReachMatrix
-   *  \brief ReachMatrix is the reachability matrix which describes the relation
-   *   of Nodes in FragmentGraph
-   */
-  class ReachMatrix
-  {
-  public:
-    typedef std::vector<uint32_t> MatrixDataType;
-
-  public:
-    ReachMatrix(size_t pSize);
-    ~ReachMatrix();
-    uint32_t& at(uint32_t pX, uint32_t pY);
-    uint32_t at(uint32_t pX, uint32_t pY) const;
-
-    uint32_t getN() const
-    { return m_N; }
-
-    void print();
-
-  private:
-    // m_Data - the contents of the matrix. Here we use a one dimensional array
-    // to represent the two dimensional matrix
-    MatrixDataType m_Data;
-
-    // m_N - this is an m_N x m_N matrix
-    size_t m_N;
-  };
-
-private:
-  FGNode* producePseudoNode();
-  FGNode* produceRegularNode();
-  void destroyPseudoNode();
-  void destroyRegularNode();
-
-  void initMatrix();
-
-  bool createRegularNodes(Module& pModule);
-  bool setNodeSlots(Module& pModule);
-  bool createPseudoNodes(Module& pModule);
-
-  bool createRegularEdges(Module& pModule);
-  bool createPseudoEdges(Module& pModule);
-
-private:
-  NodeFactoryType* m_pPseudoNodeFactory;
-  NodeFactoryType* m_pRegularNodeFactory;
-
-  /// m_pFragNodeMap - HashTable to map the fragment to the node it belongs to
-  FragHashTableType* m_pFragNodeMap;
-
-  /// m_pSymNodeMap - HashTable to map the ResolveInfo to the node. The node is
-  /// the pseudo node which the contains it's fan-out is to the ResolveInfo
-  SymHashTableType* m_pSymNodeMap;
-
-  ReachMatrix* m_pMatrix;
-
-  /// m_NumOfPNodes - number of pseudo nodes
-  size_t m_NumOfPNodes;
-  /// m_NumOfRNodes - number of regular nodes
-  size_t m_NumOfRNodes;
-  /// m_NumOfEdges - number of edges
-  size_t m_NumOfEdges;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Fragment/FragmentLinker.h b/include/mcld/Fragment/FragmentLinker.h
deleted file mode 100644
index 45ef85d..0000000
--- a/include/mcld/Fragment/FragmentLinker.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//===- FragmentLinker.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_FRAGMENT_FRAGMENT_LINKER_H
-#define MCLD_FRAGMENT_FRAGMENT_LINKER_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-
-#include <string>
-
-#include <mcld/LinkerConfig.h>
-#include <mcld/LD/LDFileFormat.h>
-#include <mcld/LD/LDSymbol.h>
-#include <mcld/Fragment/Relocation.h>
-#include <mcld/MC/MCLDInput.h>
-
-namespace mcld {
-
-class Module;
-class TargetLDBackend;
-class LinkerConfig;
-class MemoryArea;
-
-/** \class FragmentLinker
- *  \brief FragmentLinker provides a pass to link object files.
- */
-class FragmentLinker
-{
-public:
-  FragmentLinker(const LinkerConfig& pConfig,
-                 Module& pModule,
-                 TargetLDBackend& pBackend);
-
-  ~FragmentLinker();
-
-  bool finalizeSymbols();
-
-  /// applyRelocations - apply all relocation enties.
-  bool applyRelocations();
-
-  /// syncRelocationResult - After applying relocation, write back relocation target
-  /// data to output file.
-  void syncRelocationResult(MemoryArea& pOutput);
-
-private:
-  /// normalSyncRelocationResult - sync relocation result when producing shared
-  /// objects or executables
-  void normalSyncRelocationResult(MemoryArea& pOutput);
-
-  /// partialSyncRelocationResult - sync relocation result when doing partial
-  /// link
-  void partialSyncRelocationResult(MemoryArea& pOutput);
-
-  /// writeRelocationResult - helper function of syncRelocationResult, write
-  /// relocation target data to output
-  void writeRelocationResult(Relocation& pReloc, uint8_t* pOutput);
-
-private:
-  const LinkerConfig& m_Config;
-  Module& m_Module;
-  TargetLDBackend& m_Backend;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Fragment/FragmentRef.h b/include/mcld/Fragment/FragmentRef.h
index 3fce7c9..3bfd804 100644
--- a/include/mcld/Fragment/FragmentRef.h
+++ b/include/mcld/Fragment/FragmentRef.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_FRAGMENT_FRAGMENT_REFERENCE_H
-#define MCLD_FRAGMENT_FRAGMENT_REFERENCE_H
+#ifndef MCLD_FRAGMENT_FRAGMENTREF_H
+#define MCLD_FRAGMENT_FRAGMENTREF_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -78,17 +78,6 @@
 
   Offset getOutputOffset() const;
 
-  // -----  dereference  ----- //
-  Address deref();
-
-  ConstAddress deref() const;
-
-  Address operator*()
-  { return deref(); }
-
-  ConstAddress operator*() const
-  { return deref(); }
-
 private:
   friend FragmentRef& NullFragmentRef();
   friend class Chunk<FragmentRef, MCLD_SECTIONS_PER_INPUT>;
diff --git a/include/mcld/Fragment/NullFragment.h b/include/mcld/Fragment/NullFragment.h
index 1c84fae..3440453 100644
--- a/include/mcld/Fragment/NullFragment.h
+++ b/include/mcld/Fragment/NullFragment.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_NULL_FRAGMENT_H
-#define MCLD_LD_NULL_FRAGMENT_H
+#ifndef MCLD_FRAGMENT_NULLFRAGMENT_H
+#define MCLD_FRAGMENT_NULLFRAGMENT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Fragment/RegionFragment.h b/include/mcld/Fragment/RegionFragment.h
index e077264..4f1908a 100644
--- a/include/mcld/Fragment/RegionFragment.h
+++ b/include/mcld/Fragment/RegionFragment.h
@@ -6,30 +6,29 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_REGION_FRAGMENT_H
-#define MCLD_LD_REGION_FRAGMENT_H
+#ifndef MCLD_FRAGMENT_REGIONFRAGMENT_H
+#define MCLD_FRAGMENT_REGIONFRAGMENT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
 #include <mcld/Fragment/Fragment.h>
+#include <llvm/ADT/StringRef.h>
 
 namespace mcld {
 
-class MemoryRegion;
-
 /** \class RegionFragment
- *  \brief RegionFragment is a kind of Fragment containing mcld::MemoryRegion
+ *  \brief RegionFragment is a kind of Fragment containing input memory region
  */
 class RegionFragment : public Fragment
 {
 public:
-  RegionFragment(MemoryRegion& pRegion, SectionData* pSD = NULL);
+  RegionFragment(llvm::StringRef pRegion, SectionData* pSD = NULL);
 
   ~RegionFragment();
 
-  const MemoryRegion& getRegion() const { return m_Region; }
-  MemoryRegion&       getRegion()       { return m_Region; }
+  const llvm::StringRef getRegion() const { return m_Region; }
+  llvm::StringRef       getRegion()       { return m_Region; }
 
   static bool classof(const Fragment *F)
   { return F->getKind() == Fragment::Region; }
@@ -40,7 +39,7 @@
   size_t size() const;
 
 private:
-  MemoryRegion& m_Region;
+  llvm::StringRef m_Region;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/Fragment/Relocation.h b/include/mcld/Fragment/Relocation.h
index e8c57e4..3824dd5 100644
--- a/include/mcld/Fragment/Relocation.h
+++ b/include/mcld/Fragment/Relocation.h
@@ -34,7 +34,7 @@
   typedef uint64_t Address; // FIXME: use SizeTrait<T>::Address instead
   typedef uint64_t DWord;   // FIXME: use SizeTrait<T>::Word instead
   typedef int64_t  SWord;   // FIXME: use SizeTrait<T>::SWord instead
-  typedef uint8_t  Type;
+  typedef uint32_t Type;
   typedef uint32_t Size;
 
 private:
diff --git a/include/mcld/Fragment/TargetFragment.h b/include/mcld/Fragment/TargetFragment.h
index 665fcea..76148ea 100644
--- a/include/mcld/Fragment/TargetFragment.h
+++ b/include/mcld/Fragment/TargetFragment.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_TARGET_FRAGMENT_H
-#define MCLD_LD_TARGET_FRAGMENT_H
+#ifndef MCLD_FRAGMENT_TARGETFRAGMENT_H
+#define MCLD_FRAGMENT_TARGETFRAGMENT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/GeneralOptions.h b/include/mcld/GeneralOptions.h
index 77232ac..8348b6f 100644
--- a/include/mcld/GeneralOptions.h
+++ b/include/mcld/GeneralOptions.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_GENERAL_OPTIONS_H
-#define MCLD_GENERAL_OPTIONS_H
+#ifndef MCLD_GENERALOPTIONS_H
+#define MCLD_GENERALOPTIONS_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -15,11 +15,11 @@
 #include <vector>
 #include <mcld/Support/RealPath.h>
 #include <mcld/Support/FileSystem.h>
-#include <mcld/MC/ZOption.h>
 
 namespace mcld {
 
 class Input;
+class ZOption;
 
 /** \class GeneralOptions
  *  \brief GeneralOptions collects the options that not be one of the
@@ -46,6 +46,10 @@
   typedef RpathList::iterator rpath_iterator;
   typedef RpathList::const_iterator const_rpath_iterator;
 
+  typedef std::vector<std::string> ScriptList;
+  typedef ScriptList::iterator script_iterator;
+  typedef ScriptList::const_iterator const_script_iterator;
+
   typedef std::vector<std::string> AuxiliaryList;
   typedef AuxiliaryList::iterator aux_iterator;
   typedef AuxiliaryList::const_iterator const_aux_iterator;
@@ -54,11 +58,6 @@
   GeneralOptions();
   ~GeneralOptions();
 
-  /// default link script
-  bool hasDefaultLDScript() const;
-  const char* defaultLDScript() const;
-  void setDefaultLDScript(const std::string& pFilename);
-
   /// trace
   void setTrace(bool pEnableTrace = true)
   { m_bTrace = pEnableTrace; }
@@ -84,15 +83,6 @@
   bool Bgroup() const
   { return m_Bgroup; }
 
-  bool hasEntry() const
-  { return !m_Entry.empty(); }
-
-  void setEntry(const std::string& pEntry)
-  { m_Entry = pEntry; }
-
-  const std::string& entry() const
-  { return m_Entry; }
-
   void setDyld(const std::string& pDyld)
   { m_Dyld = pDyld; }
 
@@ -132,10 +122,10 @@
   { return m_bColor; }
 
   void setNoUndefined(bool pEnable = true)
-  { m_bNoUndefined = pEnable; }
+  { m_NoUndefined = (pEnable?YES:NO); }
 
   void setMulDefs(bool pEnable = true)
-  { m_bMulDefs = pEnable; }
+  { m_MulDefs = (pEnable?YES:NO); }
 
   void setEhFrameHdr(bool pEnable = true)
   { m_bCreateEhFrameHdr = pEnable; }
@@ -146,8 +136,11 @@
   bool hasCombReloc() const
   { return m_bCombReloc; }
 
+  bool hasNoUndefined() const
+  { return (Unknown != m_NoUndefined); }
+
   bool isNoUndefined() const
-  { return m_bNoUndefined; }
+  { return (YES == m_NoUndefined); }
 
   bool hasStackSet() const
   { return (Unknown != m_ExecStack); }
@@ -165,7 +158,10 @@
   { return m_bLoadFltr; }
 
   bool hasMulDefs() const
-  { return m_bMulDefs; }
+  { return (Unknown != m_MulDefs); }
+
+  bool isMulDefs() const
+  { return (YES == m_MulDefs); }
 
   bool hasNoCopyReloc() const
   { return m_bNoCopyReloc; }
@@ -278,6 +274,26 @@
   bool printMap() const
   { return m_bPrintMap; }
 
+  void setWarnMismatch(bool pEnable = true)
+  { m_bWarnMismatch = pEnable; }
+
+  bool warnMismatch() const
+  { return m_bWarnMismatch; }
+
+  // --gc-sections
+  void setGCSections(bool pEnable = true)
+  { m_bGCSections = pEnable; }
+
+  bool GCSections() const
+  { return m_bGCSections; }
+
+  // --ld-generated-unwind-info
+  void setGenUnwindInfo(bool pEnable = true)
+  { m_bGenUnwindInfo = pEnable; }
+
+  bool genUnwindInfo() const
+  { return m_bGenUnwindInfo; }
+
   // -G, max GP size option
   void setGPSize(int gpsize)
   { m_GPSize = gpsize; }
@@ -299,6 +315,15 @@
   const_rpath_iterator rpath_end  () const { return m_RpathList.end();   }
   rpath_iterator       rpath_end  ()       { return m_RpathList.end();   }
 
+  // -----  link-in script  ----- //
+  const ScriptList& getScriptList() const { return m_ScriptList; }
+  ScriptList&       getScriptList()       { return m_ScriptList; }
+
+  const_script_iterator script_begin() const { return m_ScriptList.begin(); }
+  script_iterator       script_begin()       { return m_ScriptList.begin(); }
+  const_script_iterator script_end  () const { return m_ScriptList.end();   }
+  script_iterator       script_end  ()       { return m_ScriptList.end();   }
+
   // -----  filter and auxiliary filter  ----- //
   void setFilter(const std::string& pFilter)
   { m_Filter = pFilter; }
@@ -327,21 +352,20 @@
 private:
   Input* m_pDefaultBitcode;
   std::string m_DefaultLDScript;
-  std::string m_Entry;
   std::string m_Dyld;
   std::string m_SOName;
   int8_t m_Verbose;            // --verbose[=0,1,2]
   uint16_t m_MaxErrorNum;      // --error-limit=N
   uint16_t m_MaxWarnNum;       // --warning-limit=N
   status m_ExecStack;          // execstack, noexecstack
+  status m_NoUndefined;        // defs, --no-undefined
+  status m_MulDefs;            // muldefs, --allow-multiple-definition
   uint64_t m_CommPageSize;     // common-page-size=value
   uint64_t m_MaxPageSize;      // max-page-size=value
   bool m_bCombReloc     : 1;   // combreloc, nocombreloc
-  bool m_bNoUndefined   : 1;   // defs, --no-undefined
   bool m_bInitFirst     : 1;   // initfirst
   bool m_bInterPose     : 1;   // interpose
   bool m_bLoadFltr      : 1;   // loadfltr
-  bool m_bMulDefs       : 1;   // muldefs
   bool m_bNoCopyReloc   : 1;   // nocopyreloc
   bool m_bNoDefaultLib  : 1;   // nodefaultlib
   bool m_bNoDelete      : 1;   // nodelete
@@ -367,9 +391,13 @@
   bool m_bNewDTags: 1; // --enable-new-dtags
   bool m_bNoStdlib: 1; // -nostdlib
   bool m_bPrintMap: 1; // --print-map
+  bool m_bWarnMismatch: 1; // --no-warn-mismatch
+  bool m_bGCSections: 1; // --gc-sections
+  bool m_bGenUnwindInfo: 1; // --ld-generated-unwind-info
   uint32_t m_GPSize; // -G, --gpsize
   StripSymbolMode m_StripSymbols;
   RpathList m_RpathList;
+  ScriptList m_ScriptList;
   unsigned int m_HashStyle;
   std::string m_Filter;
   AuxiliaryList m_AuxiliaryList;
diff --git a/include/mcld/IRBuilder.h b/include/mcld/IRBuilder.h
index e9f1d13..7cacb36 100644
--- a/include/mcld/IRBuilder.h
+++ b/include/mcld/IRBuilder.h
@@ -14,7 +14,7 @@
 #ifndef MCLD_IRBUILDER_H
 #define MCLD_IRBUILDER_H
 
-#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/Input.h>
 #include <mcld/MC/InputBuilder.h>
 
 #include <mcld/LD/LDSection.h>
@@ -29,7 +29,6 @@
 
 #include <mcld/Support/Path.h>
 #include <mcld/Support/FileHandle.h>
-#include <mcld/Support/raw_mem_ostream.h>
 
 namespace mcld {
 
@@ -129,19 +128,6 @@
   Input* ReadInput(const std::string& pNameSpec);
 
   /// ReadInput - To read an input file and append it to the input tree.
-  ///
-  /// This function is like to add an input in the command line.
-  ///
-  /// LLVM compiler usually emits outputs by llvm::raw_ostream.
-  /// mcld::raw_mem_ostream inherits llvm::raw_ostream and is suitable to be
-  /// the output of LLVM compier. Users can connect LLVM compiler and MCLinker
-  /// by passing mcld::raw_mem_ostream from LLVM compiler to MCLinker.
-  ///
-  /// @param pMemOStream [in] The input raw_mem_stream
-  /// @param the create mcld::Input.
-  Input* ReadInput(raw_mem_ostream& pMemOStream);
-
-  /// ReadInput - To read an input file and append it to the input tree.
   /// Another way to open file manually. Use MCLinker's mcld::FileHandle.
   Input* ReadInput(FileHandle& pFileHandle);
 
@@ -470,6 +456,10 @@
                                    uint32_t pOffset,
                                    Relocation::Address pAddend = 0);
 
+  /// shouldForceLocal - The helper function for AddSymbol to check if the
+  /// symbols should be force to local symbols
+  bool shouldForceLocal(const ResolveInfo& pInfo, const LinkerConfig& pConfig);
+
 private:
   LDSymbol* addSymbolFromObject(const std::string& pName,
                                 ResolveInfo::Type pType,
diff --git a/include/mcld/InputTree.h b/include/mcld/InputTree.h
index 0c7e060..0213527 100644
--- a/include/mcld/InputTree.h
+++ b/include/mcld/InputTree.h
@@ -6,15 +6,15 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_MC_INPUT_TREE_H
-#define MCLD_MC_INPUT_TREE_H
+#ifndef MCLD_INPUTTREE_H
+#define MCLD_INPUTTREE_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/Input.h>
 #include <mcld/Support/Path.h>
 
 #include <string>
@@ -182,16 +182,16 @@
   //  @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 Input& value) {
+  template<size_t DIRECT>
+  BinaryTree& join(TreeIteratorBase& pPosition, const Input& value) {
     node_type *node = BinaryTreeBase<Input>::createNode();
     node->data = const_cast<Input*>(&value);
-    if (position.isRoot())
-      proxy::hook<TreeIteratorBase::Leftward>(position.m_pNode,
-                          const_cast<const node_type*>(node));
+
+    if (pPosition.isRoot())
+      pPosition.hook<TreeIteratorBase::Leftward>(node);
     else
-      proxy::hook<DIRECT>(position.m_pNode,
-                          const_cast<const node_type*>(node));
+      pPosition.hook<DIRECT>(node);
+
     return *this;
   }
 
@@ -200,14 +200,13 @@
   //  @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) {
+  template<size_t DIRECT>
+  BinaryTree& merge(TreeIteratorBase& pPosition, 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));
+      pPosition.hook<DIRECT>(pTree.m_Root.node.left);
       BinaryTreeBase<Input>::m_Root.summon(
                                    pTree.BinaryTreeBase<Input>::m_Root);
       BinaryTreeBase<Input>::m_Root.delegate(pTree.m_Root);
@@ -248,20 +247,20 @@
    *  connects two nodes of the given iterators togather.
    */
   struct Mover {
-    virtual ~Mover() {}
-    virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const = 0;
+    virtual void connect(TreeIteratorBase& pFrom, NodeBase* pTo) const = 0;
     virtual void move(TreeIteratorBase& pNode) const = 0;
+    virtual ~Mover() { }
   };
 
   /** \class Succeeder
    *  \brief class Succeeder moves the iterator afterward.
    */
   struct Succeeder : public Mover {
-    virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const {
-      proxy::hook<Positional>(pFrom.m_pNode, pTo.m_pNode);
+    void connect(TreeIteratorBase& pFrom, NodeBase* pTo) const {
+      pFrom.hook<Positional>(pTo);
     }
 
-    virtual void move(TreeIteratorBase& pNode) const {
+    void move(TreeIteratorBase& pNode) const {
       pNode.move<Positional>();
     }
   };
@@ -270,11 +269,11 @@
    *  \brief class Includer moves the iterator downward.
    */
   struct Includer : public Mover {
-    virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const {
-      proxy::hook<Inclusive>(pFrom.m_pNode, pTo.m_pNode);
+    void connect(TreeIteratorBase& pFrom, NodeBase* pTo) const {
+      pFrom.hook<Inclusive>(pTo);
     }
 
-    virtual void move(TreeIteratorBase& pNode) const {
+    void move(TreeIteratorBase& pNode) const {
       pNode.move<Inclusive>();
     }
   };
@@ -325,12 +324,12 @@
 mcld::InputTree::enterGroup(mcld::TreeIteratorBase pRoot)
 {
   BinTreeTy::node_type* node = createNode();
+
   if (pRoot.isRoot())
-    proxy::hook<TreeIteratorBase::Leftward>(pRoot.m_pNode,
-        const_cast<const node_type*>(node));
+    pRoot.hook<TreeIteratorBase::Leftward>(node);
   else
-    proxy::hook<DIRECT>(pRoot.m_pNode,
-        const_cast<const node_type*>(node));
+    pRoot.hook<DIRECT>(node);
+
   return *this;
 }
 
@@ -340,12 +339,12 @@
 {
   BinTreeTy::node_type* node = createNode();
   node->data = &pInput;
+
   if (pRoot.isRoot())
-    proxy::hook<TreeIteratorBase::Leftward>(pRoot.m_pNode,
-                                         const_cast<const node_type*>(node));
+    pRoot.hook<TreeIteratorBase::Leftward>(node);
   else
-    proxy::hook<DIRECT>(pRoot.m_pNode,
-                        const_cast<const node_type*>(node));
+    pRoot.hook<DIRECT>(node);
+
   return *this;
 }
 
diff --git a/include/mcld/LD/Archive.h b/include/mcld/LD/Archive.h
index 7dc2205..26de7c3 100644
--- a/include/mcld/LD/Archive.h
+++ b/include/mcld/LD/Archive.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ARCHIVE_H
-#define MCLD_ARCHIVE_H
+#ifndef MCLD_LD_ARCHIVE_H
+#define MCLD_LD_ARCHIVE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -26,9 +26,6 @@
 class Input;
 class InputFactory;
 class InputBuilder;
-class AttributeFactory;
-class ContextFactory;
-class MemoryAreaFactory;
 
 /** \class Archive
  *  \brief This class define the interfacee to Archive files
@@ -40,6 +37,7 @@
   static const char   THIN_MAGIC[];        ///< magic of thin archive
   static const size_t MAGIC_LEN;           ///< length of magic string
   static const char   SVR4_SYMTAB_NAME[];  ///< SVR4 symtab entry name
+  static const char   IRIX6_SYMTAB_NAME[]; ///< Irix6 symtab entry name
   static const char   STRTAB_NAME[];       ///< Name of string table
   static const char   PAD[];               ///< inter-file align padding
   static const char   MEMBER_MAGIC[];      ///< fmag field magic #
@@ -98,7 +96,7 @@
 
 public:
   typedef HashTable<ArchiveMemberEntryType,
-                    hash::StringHash<hash::ELF>,
+                    hash::StringHash<hash::DJB>,
                     EntryFactory<ArchiveMemberEntryType> > ArchiveMemberMapType;
 
   struct Symbol
diff --git a/include/mcld/LD/ArchiveReader.h b/include/mcld/LD/ArchiveReader.h
index 5f24f49..eb6bec5 100644
--- a/include/mcld/LD/ArchiveReader.h
+++ b/include/mcld/LD/ArchiveReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ARCHIVE_READER_INTERFACE_H
-#define MCLD_ARCHIVE_READER_INTERFACE_H
+#ifndef MCLD_LD_ARCHIVEREADER_H
+#define MCLD_LD_ARCHIVEREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -16,6 +16,7 @@
 namespace mcld
 {
 
+class LinkerConfig;
 class Archive;
 
 /** \class ArchiveReader
@@ -34,7 +35,7 @@
   ArchiveReader();
   virtual ~ArchiveReader();
 
-  virtual bool readArchive(Archive& pArchive) = 0;
+  virtual bool readArchive(const LinkerConfig& pConfig, Archive& pArchive) = 0;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/BSDArchiveReader.h b/include/mcld/LD/BSDArchiveReader.h
index 7abeecc..fd49966 100644
--- a/include/mcld/LD/BSDArchiveReader.h
+++ b/include/mcld/LD/BSDArchiveReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_BSD_ARCHIVE_READER_H
-#define MCLD_BSD_ARCHIVE_READER_H
+#ifndef MCLD_LD_BSDARCHIVEREADER_H
+#define MCLD_LD_BSDARCHIVEREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -18,6 +18,7 @@
 
 class Input;
 class Archive;
+class LinkerConfig;
 
 /** \class BSDArchiveReader
  *  \brief BSDArchiveReader reads BSD-variant archive files.
@@ -29,8 +30,8 @@
   BSDArchiveReader();
   ~BSDArchiveReader();
 
-  bool readArchive(Archive& pArchive);
-  bool isMyFormat(Input& pInput) const;
+  bool readArchive(const LinkerConfig& pConfig, Archive& pArchive);
+  bool isMyFormat(Input& pInput, bool &pContinue) const;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/BinaryReader.h b/include/mcld/LD/BinaryReader.h
index e9c47db..6b61dba 100644
--- a/include/mcld/LD/BinaryReader.h
+++ b/include/mcld/LD/BinaryReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_Binary_READER_H
-#define MCLD_Binary_READER_H
+#ifndef MCLD_LD_BINARYREADER_H
+#define MCLD_LD_BINARYREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -25,16 +25,11 @@
  */
 class BinaryReader : public LDReader
 {
-protected:
-  BinaryReader()
-  { }
-
 public:
-  virtual ~BinaryReader()
-  { }
+  virtual ~BinaryReader() = 0;
 
-  virtual bool isMyFormat(Input& pInput) const
-  { return true; }
+  virtual bool isMyFormat(Input& pInput, bool &pContinue) const
+  { pContinue = true; return false; }
 
   virtual bool readBinary(Input& pFile) = 0;
 };
diff --git a/include/mcld/LD/BranchIsland.h b/include/mcld/LD/BranchIsland.h
index f340f0a..ca1543f 100644
--- a/include/mcld/LD/BranchIsland.h
+++ b/include/mcld/LD/BranchIsland.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_BRANCH_ISLAND_H
-#define MCLD_LD_BRANCH_ISLAND_H
+#ifndef MCLD_LD_BRANCHISLAND_H
+#define MCLD_LD_BRANCHISLAND_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -125,7 +125,7 @@
       size_t operator() (const Key& KEY) const
       {
         llvm::StringRef sym_name(KEY.symbol()->name());
-        hash::StringHash<hash::ELF> str_hasher;
+        hash::StringHash<hash::DJB> str_hasher;
         return (size_t((uintptr_t)KEY.prototype())) ^
                str_hasher(sym_name) ^
                KEY.addend();
diff --git a/include/mcld/LD/BranchIslandFactory.h b/include/mcld/LD/BranchIslandFactory.h
index 755cc31..9431fb3 100644
--- a/include/mcld/LD/BranchIslandFactory.h
+++ b/include/mcld/LD/BranchIslandFactory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_BRANCH_ISLAND_FACTORY_H
-#define MCLD_LD_BRANCH_ISLAND_FACTORY_H
+#ifndef MCLD_LD_BRANCHISLANDFACTORY_H
+#define MCLD_LD_BRANCHISLANDFACTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -20,6 +20,7 @@
 {
 
 class Fragment;
+class Module;
 
 /** \class BranchIslandFactory
  *  \brief
@@ -37,6 +38,10 @@
 
   ~BranchIslandFactory();
 
+  /// group - group fragments and create islands when needed
+  /// @param pSectionData - the SectionData holds fragments need to be grouped
+  void group(Module& pModule);
+
   /// produce - produce a island for the given fragment
   /// @param pFragment - the fragment needs a branch island
   BranchIsland* produce(Fragment& pFragment);
diff --git a/include/mcld/LD/DWARFLineInfo.h b/include/mcld/LD/DWARFLineInfo.h
index 004d597..4f19312 100644
--- a/include/mcld/LD/DWARFLineInfo.h
+++ b/include/mcld/LD/DWARFLineInfo.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_DWARF_LINE_INFO_H
-#define MCLD_DWARF_LINE_INFO_H
+#ifndef MCLD_LD_DWARFLINEINFO_H
+#define MCLD_LD_DWARFLINEINFO_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/DiagAttribute.inc b/include/mcld/LD/DiagAttribute.inc
new file mode 100644
index 0000000..453ae65
--- /dev/null
+++ b/include/mcld/LD/DiagAttribute.inc
@@ -0,0 +1,19 @@
+// General
+DIAG(warn_unsupported_attribute_section_format, DiagnosticEngine::Warning, "unsupported format of attribute section in input %0 (version=%1).", "unsupported format of attribute section in input %0 (version=%1).")
+DIAG(warn_unrecognized_vendor_subsection, DiagnosticEngine::Warning, "skip unrecognized private vendor subsection with name '%0' in %1.", "skip unrecognized private vendor subsection with name '%0' in %1.")
+
+// ARM attributes
+DIAG(error_unknown_cpu_arch, DiagnosticEngine::Error, "input %0 has unknown CPU architecture profile.", "input %0 has unknown CPU architecture profile.")
+DIAG(warn_mismatch_cpu_arch_profile, DiagnosticEngine::Warning, "conflicting architecture profiles %0 in %1.", "conflicting architecture profiles %0 in %1.")
+DIAG(error_mismatch_mpextension_use, DiagnosticEngine::Error, "conflicting values from Tag_MPextension_use and Tag_MPextension_use_legacy in %0", "conflicting values from Tag_MPextension_use and Tag_MPextension_use_legacy in %0")
+DIAG(warn_mismatch_enum_size, DiagnosticEngine::Warning, "the size of enumerated data item in input %0 (value=%1) is not compatible with the output (value=%2).", "the size of enumerated data item in input %0 (value=%1) is not compatible with the output (value=%2).")
+DIAG(warn_mismatch_fp16_format, DiagnosticEngine::Warning, "conflicting 16-bit FP number format in %0", "conflicting 16-bit FP number format in %0")
+DIAG(warn_unrecognized_virtualization_use, DiagnosticEngine::Warning, "value of Tag_Virtualization_use cannot be recognized in %0 (value=%1).", "value of Tag_Virtualization_use cannot be recognized in %0 (value=%1).")
+DIAG(warn_mismatch_abi_wmmx_args, DiagnosticEngine::Warning, "%0 uses different way to pass WMMX parameters and results.", "%0 uses different way to pass WMMX parameters and results.")
+DIAG(warn_mismatch_pcs_config, DiagnosticEngine::Warning, "conflicting procedure call standard config in input %0.", "conflicting procedure call standard config in input %0.")
+DIAG(warn_mismatch_r9_use, DiagnosticEngine::Warning, "conflicting way to use R9 in input %0.", "conflicting way to use R9 in input %0.")
+DIAG(warn_conflict_rw_data_and_r9, DiagnosticEngine::Warning, "RW static data addressing (SB-relative) conflicts the use of R9 (Tag_ABI_PCS_R9_use) in input %0.", "RW static data addressing (SB-relative) conflicts the use of R9 (Tag_ABI_PCS_R9_use) in input %0.")
+DIAG(warn_mismatch_wchar_size, DiagnosticEngine::Warning, "incompatible size of wchar_t in input %0 (value=%1) with the output (value=%2).", "incompatible size of wchar_t in input %0 (value=%1) with the output (value=%2).")
+DIAG(warn_unknown_mandatory_attribute, DiagnosticEngine::Warning, "unknown mandatory attribute with tag %0 was ignored in %1.", "unknown mandatory attribute with tag %0 was ignored in %1.")
+DIAG(warn_unknown_attribute, DiagnosticEngine::Warning, "unknown attribute with tag %0 was ignored in %1.", "unknown attribute with tag %0 was ignored in %1.")
+DIAG(warn_mismatch_vfp_args, DiagnosticEngine::Warning, "%0 uses different way to pass the floating point parameter and results.", "%0 uses different way to pass the floating point parameter and results.")
diff --git a/include/mcld/LD/DiagCommonKinds.inc b/include/mcld/LD/DiagCommonKinds.inc
index e7d6328..539eafb 100644
--- a/include/mcld/LD/DiagCommonKinds.inc
+++ b/include/mcld/LD/DiagCommonKinds.inc
@@ -3,7 +3,7 @@
 DIAG(warn_cannot_open_search_dir, DiagnosticEngine::Warning, "can not open search directory `-L%0'", "can not open search directory `-L%0'")
 DIAG(err_no_inputs, DiagnosticEngine::Error, "no inputs", "no inputs")
 DIAG(err_empty_input, DiagnosticEngine::Error, "Empty input file `%0' : %1", "Empty input file `%0' : %1")
-DIAG(err_unrecognized_input_file, DiagnosticEngine::Fatal, "cannot recognize the format of file `%0'.\n  object format or given target machine (%1) is wrong.","cannot recognize the format of file `%0'.\n  object format or given target machine (%1) is wrong.")
+DIAG(warn_unrecognized_input_file, DiagnosticEngine::Warning, "cannot recognize the format of file `%0'.\n  object format or given target machine (%1) is incompatible.","cannot recognize the format of file `%0'.\n  object format or given target machine (%1) is incompatible.")
 DIAG(err_cannot_find_namespec, DiagnosticEngine::Fatal, "cannot recognize namespec -l%0", "cannot recognize namespec -l%0")
 DIAG(err_cannot_identify_option, DiagnosticEngine::Fatal, "unknown command line argument `%0' at %1", "unknown command line argument `%0' at %1")
 DIAG(err_mixed_shared_static_objects, DiagnosticEngine::Error, "cannot link shared objects with -static option.\nShared object `%0': %1", "cannot link shared objects with -static option.\nShared object `%0': %1")
@@ -40,7 +40,7 @@
 DIAG(fatal_cannot_init_target, DiagnosticEngine::Fatal, "Cannot initialize mcld::Target for given triple '%0'.\n(Detail: %1)", "Cannot initialize mcld::Target for given triple '%0'.\n(Detail: %1)")
 DIAG(fatal_cannot_init_lineinfo, DiagnosticEngine::Fatal, "Cannot initialize mcld::DiagnosticLineInfo for given triple '%0'", "Cannot initialize mcld::DiagnosticLineInfo for given triple '%0'")
 DIAG(fatal_cannot_init_backend, DiagnosticEngine::Fatal, "Cannot initialize mcld::TargetLDBackend for given triple '%0'.", "Cannot initialize mcld::TargetLDBackend for given triple '%0'.")
-DIAG(fatal_forbid_nest_group, DiagnosticEngine::Fatal, "May not nest groups", "May not nest groups")
+DIAG(fatal_forbid_nest_group, DiagnosticEngine::Fatal, "not matched --start-group and --end-group", "not matched --start-group and --end-group")
 DIAG(fatal_unwritable_output, DiagnosticEngine::Fatal, "unable to write output file %0", "unable to write output file %0")
 DIAG(warn_unsupported_option, DiagnosticEngine::Warning, "Option `%0' is not implemented yet!", "Option `%0' is not implemented yet!")
 DIAG(warn_shared_textrel, DiagnosticEngine::Warning, "Add DT_TEXTREL in a shared object!", "Add DT_TEXTREL in a shared object.")
@@ -48,3 +48,6 @@
 DIAG(err_nmagic_not_static, DiagnosticEngine::Error, "cannot mix -nmagic option with -shared", "cannot mix -nmagic option with -shared")
 DIAG(err_omagic_not_static, DiagnosticEngine::Error, "cannot mix -omagic option with -shared", "cannot mix -omagic option with -shared")
 DIAG(err_invalid_emulation, DiagnosticEngine::Error, "Invalid target emulation: `%0'.", "Invalid target emulation: `%0'.")
+DIAG(err_cannot_find_scriptfile, DiagnosticEngine::Fatal, "cannot open %0 file %1", "cannot open %0 file %1")
+DIAG(err_unsupported_archive, DiagnosticEngine::Error, "Unsupported archive type.", "Unsupported archive type.")
+DIAG(unexpected_frag_type, DiagnosticEngine::Unreachable, "Unexpected fragment type `%0' when constructing FG", "Unexpected fragment type `%0' when constructing FG")
diff --git a/include/mcld/LD/DiagLDScript.inc b/include/mcld/LD/DiagLDScript.inc
new file mode 100644
index 0000000..c752773
--- /dev/null
+++ b/include/mcld/LD/DiagLDScript.inc
@@ -0,0 +1,3 @@
+DIAG(err_unterminated_comment, DiagnosticEngine::Error, "%0:%1:%2: error: unterminated comment\n", "%0:%1:%2: error: unterminated comment\n")
+DIAG(err_syntax_error, DiagnosticEngine::Error, "%0:%1:%2: error: %3\n", "%0:%1:%2: error: %3\n")
+DIAG(err_assert_failed, DiagnosticEngine::Error,"Assertion failed: %0\n", "Assertion failed: %0\n")
diff --git a/include/mcld/LD/DiagRelocations.inc b/include/mcld/LD/DiagRelocations.inc
index 7ada05f..bacae6e 100644
--- a/include/mcld/LD/DiagRelocations.inc
+++ b/include/mcld/LD/DiagRelocations.inc
@@ -1,6 +1,7 @@
 DIAG(reloc_factory_has_not_config, DiagnosticEngine::Fatal, "Please call mcld::Linker::config before creating relocations", "Please call mcld::Linker::config before creating relocations")
 DIAG(unsupported_bitclass, DiagnosticEngine::Fatal, "Only supports 32 and 64 bits targets. (Target: %0, bitclass:%1)", "Only supports 32 and 64 bits targets. (Target: %0, bitclass:%1)")
-DIAG(undefined_reference, DiagnosticEngine::Fatal, "undefined reference to `%0'", "In %1:%2, variable %0 must be defined")
+DIAG(undefined_reference, DiagnosticEngine::Fatal, "%1(%2+%3): undefined reference to `%0'", "%1(%2+%3): undefined reference to `%0'")
+DIAG(undefined_reference_text, DiagnosticEngine::Fatal, "%1:%2:function %3: undefined reference to `%0'", "%1:%2: undefined reference to `%0'")
 DIAG(non_pic_relocation, DiagnosticEngine::Error, "attempt to generate unsupported relocation type `%0' for symbol `%1', recompile with -fPIC", "attempt to generate unsupported relocation type `%0' for symbol `%1, recompile with -fPIC")
 DIAG(base_relocation, DiagnosticEngine::Fatal, "relocation type `%0' is not supported for symbol `%1'\nPlease report to %2", "relocation type `%0' is not supported for symbol `%1'\nPlease report to %2")
 DIAG(dynamic_relocation, DiagnosticEngine::Fatal, "unexpected relocation type `%0' in object file", "unexpected relocation type `%0' in object file")
@@ -11,3 +12,4 @@
 DIAG(result_badreloc, DiagnosticEngine::Error, "applying relocation `%0' encounters unexpected opcode on symbol `%1'","applying relocation `%0' encounters unexpected opcode on symbol `%1'")
 DIAG(invalid_tls, DiagnosticEngine::Error, "TLS relocation against invalid symbol `%0' in section `%1'", "TLS relocation against invalid symbol `%0' in section `%1'")
 DIAG(unknown_reloc_section_type, DiagnosticEngine::Unreachable, "unknown relocation section type: `%0' in section `%1'", "unknown relocation section type: `%0' in section `%1'")
+DIAG(unsupport_cond_branch_reloc, DiagnosticEngine::Error, "applying relocation `%0', conditional branch to PLT in THUMB-2 not supported yet", "applying relocation `%0', conditional branch to PLT in THUMB-2 not supported yet")
diff --git a/include/mcld/LD/DiagSymbolResolutions.inc b/include/mcld/LD/DiagSymbolResolutions.inc
index 786eb4b..04113dc 100644
--- a/include/mcld/LD/DiagSymbolResolutions.inc
+++ b/include/mcld/LD/DiagSymbolResolutions.inc
@@ -8,3 +8,4 @@
 DIAG(indirect_refer_to_inexist, DiagnosticEngine::Fatal, "indirect symbol %0 points to a undefined symbol", "variable %0 is undefined")
 DIAG(multiple_definitions, DiagnosticEngine::Error, "multiple definition of symbol `%0'", "you define variable %0 twice")
 DIAG(undefined_situation, DiagnosticEngine::Unreachable, "reach undefined situation, action: %0, old(%1) -> new(%2)", "reach undefined situation, action: %0, old(%1) -> new(%2)")
+DIAG(multiple_absolute_definitions, DiagnosticEngine::Error, "inconsistent definitions of absolute symbol `%0': old(%1) -> new(%2)", "you defined an absolute symbol with different values")
diff --git a/include/mcld/LD/Diagnostic.h b/include/mcld/LD/Diagnostic.h
index 2e4db11..1982ef0 100644
--- a/include/mcld/LD/Diagnostic.h
+++ b/include/mcld/LD/Diagnostic.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_DIAGNOSTIC_H
-#define MCLD_DIAGNOSTIC_H
+#ifndef MCLD_LD_DIAGNOSTIC_H
+#define MCLD_LD_DIAGNOSTIC_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/DiagnosticEngine.h b/include/mcld/LD/DiagnosticEngine.h
index 1c825a2..b003955 100644
--- a/include/mcld/LD/DiagnosticEngine.h
+++ b/include/mcld/LD/DiagnosticEngine.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_DIAGNOSTIC_ENGINE_H
-#define MCLD_DIAGNOSTIC_ENGINE_H
+#ifndef MCLD_LD_DIAGNOSTICENGINE_H
+#define MCLD_LD_DIAGNOSTICENGINE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/DiagnosticInfos.h b/include/mcld/LD/DiagnosticInfos.h
index cb9bdbd..16ebbab 100644
--- a/include/mcld/LD/DiagnosticInfos.h
+++ b/include/mcld/LD/DiagnosticInfos.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_DIAGNOSTIC_INFORMATION_H
-#define MCLD_DIAGNOSTIC_INFORMATION_H
+#ifndef MCLD_LD_DIAGNOSTICINFORMATION_H
+#define MCLD_LD_DIAGNOSTICINFORMATION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -18,12 +18,14 @@
 namespace diag {
   enum ID {
 #define DIAG(ENUM, CLASS, ADDRMSG, LINEMSG) ENUM,
+#include "mcld/LD/DiagAttribute.inc"
 #include "mcld/LD/DiagCommonKinds.inc"
 #include "mcld/LD/DiagReaders.inc"
 #include "mcld/LD/DiagSymbolResolutions.inc"
 #include "mcld/LD/DiagRelocations.inc"
 #include "mcld/LD/DiagLayouts.inc"
 #include "mcld/LD/DiagGOTPLT.inc"
+#include "mcld/LD/DiagLDScript.inc"
 #undef DIAG
     NUM_OF_BUILDIN_DIAGNOSTIC_INFO
   };
diff --git a/include/mcld/LD/DiagnosticLineInfo.h b/include/mcld/LD/DiagnosticLineInfo.h
index 30f0546..db35287 100644
--- a/include/mcld/LD/DiagnosticLineInfo.h
+++ b/include/mcld/LD/DiagnosticLineInfo.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_DIAGNOSTICLINEINFO_H
-#define MCLD_DIAGNOSTICLINEINFO_H
+#ifndef MCLD_LD_DIAGNOSTICLINEINFO_H
+#define MCLD_LD_DIAGNOSTICLINEINFO_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/DiagnosticPrinter.h b/include/mcld/LD/DiagnosticPrinter.h
index b3617a7..7cf5c8e 100644
--- a/include/mcld/LD/DiagnosticPrinter.h
+++ b/include/mcld/LD/DiagnosticPrinter.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_DIAGNOSTIC_PRINTER_H
-#define MCLD_DIAGNOSTIC_PRINTER_H
+#ifndef MCLD_LD_DIAGNOSTICPRINTER_H
+#define MCLD_LD_DIAGNOSTICPRINTER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/DynObjFileFormat.h b/include/mcld/LD/DynObjFileFormat.h
index 7b1626d..e0972c3 100644
--- a/include/mcld/LD/DynObjFileFormat.h
+++ b/include/mcld/LD/DynObjFileFormat.h
@@ -1,4 +1,4 @@
-//===- header.h -----------------------------------------------------------===//
+//===- DynObjFileFormat.h -------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef DYNOBJFORMAT_H
-#define DYNOBJFORMAT_H
+#ifndef MCLD_LD_DYNOBJFILEFORMAT_H
+#define MCLD_LD_DYNOBJFILEFORMAT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/DynObjReader.h b/include/mcld/LD/DynObjReader.h
index ddc9500..8a7a6be 100644
--- a/include/mcld/LD/DynObjReader.h
+++ b/include/mcld/LD/DynObjReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_DYNAMIC_SHARED_OBJECT_READER_H
-#define MCLD_DYNAMIC_SHARED_OBJECT_READER_H
+#ifndef MCLD_LD_DYNOBJREADER_H
+#define MCLD_LD_DYNOBJREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/ELFBinaryReader.h b/include/mcld/LD/ELFBinaryReader.h
index fc3a067..9da4535 100644
--- a/include/mcld/LD/ELFBinaryReader.h
+++ b/include/mcld/LD/ELFBinaryReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_Binary_READER_H
-#define MCLD_ELF_Binary_READER_H
+#ifndef MCLD_LD_ELFBINARYREADER_H
+#define MCLD_LD_ELFBINARYREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -19,7 +19,6 @@
 class Module;
 class Input;
 class IRBuilder;
-class GNULDBackend;
 class LinkerConfig;
 
 /** \lclass ELFBinaryReader
@@ -28,16 +27,15 @@
 class ELFBinaryReader : public BinaryReader
 {
 public:
-  ELFBinaryReader(GNULDBackend& pBackend,
-                  IRBuilder& pBuilder,
-                  const LinkerConfig& pConfig);
+  ELFBinaryReader(IRBuilder& pBuilder, const LinkerConfig& pConfig);
 
   ~ELFBinaryReader();
 
-  virtual bool readBinary(Input& pInput);
+  bool isMyFormat(Input& pInput, bool &pContinue) const;
+
+  bool readBinary(Input& pInput);
 
 private:
-  GNULDBackend& m_Backend;
   IRBuilder& m_Builder;
   const LinkerConfig& m_Config;
 };
diff --git a/include/mcld/LD/ELFDynObjFileFormat.h b/include/mcld/LD/ELFDynObjFileFormat.h
index 2ee97a6..dd9cbb9 100644
--- a/include/mcld/LD/ELFDynObjFileFormat.h
+++ b/include/mcld/LD/ELFDynObjFileFormat.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_DYNAMIC_OBJECT_FILE_FROMAT_H
-#define MCLD_ELF_DYNAMIC_OBJECT_FILE_FROMAT_H
+#ifndef MCLD_LD_ELFDYNOBJFILEFROMAT_H
+#define MCLD_LD_ELFDYNOBJFILEFROMAT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/ELFDynObjReader.h b/include/mcld/LD/ELFDynObjReader.h
index f6d2067..23b96ad 100644
--- a/include/mcld/LD/ELFDynObjReader.h
+++ b/include/mcld/LD/ELFDynObjReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_DYNAMIC_SHARED_OBJECT_READER_H
-#define MCLD_ELF_DYNAMIC_SHARED_OBJECT_READER_H
+#ifndef MCLD_LD_ELFDYNOBJREADER_H
+#define MCLD_LD_ELFDYNOBJREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -35,7 +35,7 @@
   ~ELFDynObjReader();
 
   // -----  observers  ----- //
-  bool isMyFormat(Input &pFile) const;
+  bool isMyFormat(Input &pFile, bool &pContinue) const;
 
   // -----  readers  ----- //
   bool readHeader(Input& pFile);
diff --git a/include/mcld/LD/ELFObjectReader.h b/include/mcld/LD/ELFObjectReader.h
index 27e4489..a124676 100644
--- a/include/mcld/LD/ELFObjectReader.h
+++ b/include/mcld/LD/ELFObjectReader.h
@@ -46,7 +46,7 @@
   ~ELFObjectReader();
 
   // -----  observers  ----- //
-  bool isMyFormat(Input &pFile) const;
+  bool isMyFormat(Input &pFile, bool &pContinue) const;
 
   // -----  readers  ----- //
   bool readHeader(Input& pFile);
diff --git a/include/mcld/LD/ELFObjectWriter.h b/include/mcld/LD/ELFObjectWriter.h
index 12a5842..9caa76a 100644
--- a/include/mcld/LD/ELFObjectWriter.h
+++ b/include/mcld/LD/ELFObjectWriter.h
@@ -6,18 +6,20 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_OBJECT_WRITER_H
-#define MCLD_ELF_OBJECT_WRITER_H
+#ifndef MCLD_LD_ELFOBJWRITER_H
+#define MCLD_LD_ELFOBJWRITER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 #include <mcld/LD/ObjectWriter.h>
 #include <cassert>
 
+#include <mcld/Support/FileOutputBuffer.h>
 #include <llvm/Support/system_error.h>
 
 namespace mcld {
 
+class EhFrame;
 class Module;
 class LinkerConfig;
 class GNULDBackend;
@@ -27,8 +29,6 @@
 class SectionData;
 class RelocData;
 class Output;
-class MemoryRegion;
-class MemoryArea;
 
 /** \class ELFObjectWriter
  *  \brief ELFObjectWriter writes the target-independent parts of object files.
@@ -42,10 +42,13 @@
 
   ~ELFObjectWriter();
 
-  llvm::error_code writeObject(Module& pModule, MemoryArea& pOutput);
+  llvm::error_code writeObject(Module& pModule, FileOutputBuffer& pOutput);
+
+  size_t getOutputSize(const Module& pModule) const;
 
 private:
-  void writeSection(MemoryArea& pOutput, LDSection *section);
+  void writeSection(Module& pModule,
+                    FileOutputBuffer& pOutput, LDSection *section);
 
   GNULDBackend&       target()        { return m_Backend; }
 
@@ -55,7 +58,7 @@
   template<size_t SIZE>
   void writeELFHeader(const LinkerConfig& pConfig,
                       const Module& pModule,
-                      MemoryArea& pOutput) const;
+                      FileOutputBuffer& pOutput) const;
 
   uint64_t getEntryPoint(const LinkerConfig& pConfig,
                          const Module& pModule) const;
@@ -64,19 +67,21 @@
   template<size_t SIZE>
   void emitSectionHeader(const Module& pModule,
                          const LinkerConfig& pConfig,
-                         MemoryArea& pOutput) const;
+                         FileOutputBuffer& pOutput) const;
 
   // emitProgramHeader - emit ElfXX_Phdr
   template<size_t SIZE>
-  void emitProgramHeader(MemoryArea& pOutput) const;
+  void emitProgramHeader(FileOutputBuffer& pOutput) const;
 
   // emitShStrTab - emit .shstrtab
   void emitShStrTab(const LDSection& pShStrTab,
                     const Module& pModule,
-                    MemoryArea& pOutput);
+                    FileOutputBuffer& pOutput);
 
-  void emitSectionData(const LDSection& pSection,
-                       MemoryRegion& pRegion) const;
+  void emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const;
+
+  void emitEhFrame(Module& pModule,
+                   EhFrame& pFrame, MemoryRegion& pRegion) const;
 
   void emitRelocation(const LinkerConfig& pConfig,
                       const LDSection& pSection,
diff --git a/include/mcld/LD/ELFReader.h b/include/mcld/LD/ELFReader.h
index 9df21d3..6750ebd 100644
--- a/include/mcld/LD/ELFReader.h
+++ b/include/mcld/LD/ELFReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_READER_H
-#define MCLD_ELF_READER_H
+#ifndef MCLD_LD_ELFREADER_H
+#define MCLD_LD_ELFREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -20,8 +20,6 @@
 #include <mcld/LD/ResolveInfo.h>
 #include <mcld/LD/LDSymbol.h>
 #include <mcld/Target/GNULDBackend.h>
-#include <mcld/Support/MemoryRegion.h>
-#include <mcld/Support/MemoryArea.h>
 
 namespace mcld {
 
@@ -60,19 +58,19 @@
   { return sizeof(ELFHeader); }
 
   /// isELF - is this a ELF file
-  bool isELF(void* pELFHeader) const;
+  bool isELF(const void* pELFHeader) const;
 
   /// isMyEndian - is this ELF file in the same endian to me?
-  bool isMyEndian(void* pELFHeader) const;
+  bool isMyEndian(const void* pELFHeader) const;
 
   /// isMyMachine - is this ELF file generated for the same machine.
-  bool isMyMachine(void* pELFHeader) const;
+  bool isMyMachine(const void* pELFHeader) const;
 
   /// fileType - the file type of this file
-  Input::Type fileType(void* pELFHeader) const;
+  Input::Type fileType(const void* pELFHeader) const;
 
   /// readSectionHeaders - read ELF section header table and create LDSections
-  bool readSectionHeaders(Input& pInput, void* pELFHeader) const;
+  bool readSectionHeaders(Input& pInput, const void* pELFHeader) const;
 
   /// readRegularSection - read a regular section and create fragments.
   bool readRegularSection(Input& pInput, SectionData& pSD) const;
@@ -80,24 +78,24 @@
   /// readSymbols - read ELF symbols and create LDSymbol
   bool readSymbols(Input& pInput,
                    IRBuilder& pBuilder,
-                   const MemoryRegion& pRegion,
+                   llvm::StringRef pRegion,
                    const char* StrTab) const;
 
   /// readSignature - read a symbol from the given Input and index in symtab
   /// This is used to get the signature of a group section.
   ResolveInfo* readSignature(Input& pInput,
-                                    LDSection& pSymTab,
-                                    uint32_t pSymIdx) const;
+                             LDSection& pSymTab,
+                             uint32_t pSymIdx) const;
 
   /// readRela - read ELF rela and create Relocation
   bool readRela(Input& pInput,
                 LDSection& pSection,
-                const MemoryRegion& pRegion) const;
+                llvm::StringRef pRegion) const;
 
   /// readRel - read ELF rel and create Relocation
   bool readRel(Input& pInput,
                LDSection& pSection,
-               const MemoryRegion& pRegion) const;
+               llvm::StringRef pRegion) const;
 
   /// readDynamic - read ELF .dynamic in input dynobj
   bool readDynamic(Input& pInput) const;
@@ -150,19 +148,19 @@
   { return sizeof(ELFHeader); }
 
   /// isELF - is this a ELF file
-  bool isELF(void* pELFHeader) const;
+  bool isELF(const void* pELFHeader) const;
 
   /// isMyEndian - is this ELF file in the same endian to me?
-  bool isMyEndian(void* pELFHeader) const;
+  bool isMyEndian(const void* pELFHeader) const;
 
   /// isMyMachine - is this ELF file generated for the same machine.
-  bool isMyMachine(void* pELFHeader) const;
+  bool isMyMachine(const void* pELFHeader) const;
 
   /// fileType - the file type of this file
-  Input::Type fileType(void* pELFHeader) const;
+  Input::Type fileType(const void* pELFHeader) const;
 
   /// readSectionHeaders - read ELF section header table and create LDSections
-  bool readSectionHeaders(Input& pInput, void* pELFHeader) const;
+  bool readSectionHeaders(Input& pInput, const void* pELFHeader) const;
 
   /// readRegularSection - read a regular section and create fragments.
   bool readRegularSection(Input& pInput, SectionData& pSD) const;
@@ -170,24 +168,24 @@
   /// readSymbols - read ELF symbols and create LDSymbol
   bool readSymbols(Input& pInput,
                    IRBuilder& pBuilder,
-                   const MemoryRegion& pRegion,
+                   llvm::StringRef pRegion,
                    const char* StrTab) const;
 
   /// readSignature - read a symbol from the given Input and index in symtab
   /// This is used to get the signature of a group section.
   ResolveInfo* readSignature(Input& pInput,
-                                    LDSection& pSymTab,
-                                    uint32_t pSymIdx) const;
+                             LDSection& pSymTab,
+                             uint32_t pSymIdx) const;
 
   /// readRela - read ELF rela and create Relocation
   bool readRela(Input& pInput,
                 LDSection& pSection,
-                const MemoryRegion& pRegion) const;
+                llvm::StringRef pRegion) const;
 
   /// readRel - read ELF rel and create Relocation
   bool readRel(Input& pInput,
                LDSection& pSection,
-               const MemoryRegion& pRegion) const;
+               llvm::StringRef pRegion) const;
 
   /// readDynamic - read ELF .dynamic in input dynobj
   bool readDynamic(Input& pInput) const;
diff --git a/include/mcld/LD/ELFReaderIf.h b/include/mcld/LD/ELFReaderIf.h
index 245b542..0ce5992 100644
--- a/include/mcld/LD/ELFReaderIf.h
+++ b/include/mcld/LD/ELFReaderIf.h
@@ -1,4 +1,4 @@
-//===- ELFReader.h --------------------------------------------------------===//
+//===- ELFReaderIf.h ------------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_READER_INTERFACE_H
-#define MCLD_ELF_READER_INTERFACE_H
+#ifndef MCLD_LD_ELFREADERIF_H
+#define MCLD_LD_ELFREADERIF_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -46,16 +46,16 @@
   virtual size_t getELFHeaderSize() const = 0;
 
   /// isELF - is this a ELF file
-  virtual bool isELF(void* pELFHeader) const = 0;
+  virtual bool isELF(const void* pELFHeader) const = 0;
 
   /// isMyEndian - is this ELF file in the same endian to me?
-  virtual bool isMyEndian(void* pELFHeader) const = 0;
+  virtual bool isMyEndian(const void* pELFHeader) const = 0;
 
   /// isMyMachine - is this ELF file generated for the same machine.
-  virtual bool isMyMachine(void* pELFHeader) const = 0;
+  virtual bool isMyMachine(const void* pELFHeader) const = 0;
 
   /// fileType - the file type of this file
-  virtual Input::Type fileType(void* pELFHeader) const = 0;
+  virtual Input::Type fileType(const void* pELFHeader) const = 0;
 
   /// target - the target backend
   const GNULDBackend& target() const { return m_Backend; }
@@ -63,7 +63,8 @@
 
 
   /// readSectionHeaders - read ELF section header table and create LDSections
-  virtual bool readSectionHeaders(Input& pInput, void* pELFHeader) const = 0;
+  virtual bool readSectionHeaders(Input& pInput,
+                                  const void* pELFHeader) const = 0;
 
   /// readRegularSection - read a regular section and create fragments.
   virtual bool readRegularSection(Input& pInput, SectionData& pSD) const = 0;
@@ -71,7 +72,7 @@
   /// readSymbols - read ELF symbols and create LDSymbol
   virtual bool readSymbols(Input& pInput,
                            IRBuilder& pBuilder,
-                           const MemoryRegion& pRegion,
+                           llvm::StringRef pRegion,
                            const char* StrTab) const = 0;
 
   /// readSignature - read a symbol from the given Input and index in symtab
@@ -83,12 +84,12 @@
   /// readRela - read ELF rela and create Relocation
   virtual bool readRela(Input& pInput,
                         LDSection& pSection,
-                        const MemoryRegion& pRegion) const = 0;
+                        llvm::StringRef pRegion) const = 0;
 
   /// readRel - read ELF rel and create Relocation
   virtual bool readRel(Input& pInput,
                        LDSection& pSection,
-                       const MemoryRegion& pRegion) const = 0;
+                       llvm::StringRef pRegion) const = 0;
 
   /// readDynamic - read ELF .dynamic in input dynobj
   virtual bool readDynamic(Input& pInput) const = 0;
diff --git a/include/mcld/LD/ELFSegment.h b/include/mcld/LD/ELFSegment.h
index d7f769e..5079b54 100644
--- a/include/mcld/LD/ELFSegment.h
+++ b/include/mcld/LD/ELFSegment.h
@@ -6,45 +6,52 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_SEGMENT_H
-#define MCLD_ELF_SEGMENT_H
+#ifndef MCLD_LD_ELFSEGMENT_H
+#define MCLD_LD_ELFSEGMENT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
+#include <mcld/Support/Allocators.h>
+#include <mcld/Config/Config.h>
 #include <llvm/Support/ELF.h>
 #include <llvm/Support/DataTypes.h>
-#include <mcld/LD/LDSection.h>
-#include <cassert>
 #include <vector>
 
 namespace mcld
 {
 
+class LDSection;
+
 /** \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;
+  typedef std::vector<LDSection*> SectionList;
+  typedef SectionList::iterator iterator;
+  typedef SectionList::const_iterator const_iterator;
+  typedef SectionList::reverse_iterator reverse_iterator;
+  typedef SectionList::const_reverse_iterator const_reverse_iterator;
+
+private:
+  friend class Chunk<ELFSegment, MCLD_SEGMENTS_PER_OUTPUT>;
+  ELFSegment();
+  ELFSegment(uint32_t pType, uint32_t pFlag = llvm::ELF::PF_R);
+
 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,
-             uint64_t pMaxSectAlign = 0);
   ~ELFSegment();
 
   ///  -----  iterators  -----  ///
-  sect_iterator       begin()       { return m_SectionList.begin(); }
-  const_sect_iterator begin() const { return m_SectionList.begin(); }
-  sect_iterator       end()         { return m_SectionList.end(); }
-  const_sect_iterator end()   const { return m_SectionList.end(); }
+  iterator       begin()       { return m_SectionList.begin(); }
+  const_iterator begin() const { return m_SectionList.begin(); }
+  iterator       end()         { return m_SectionList.end(); }
+  const_iterator end()   const { return m_SectionList.end(); }
+
+  reverse_iterator       rbegin()       { return m_SectionList.rbegin(); }
+  const_reverse_iterator rbegin() const { return m_SectionList.rbegin(); }
+  reverse_iterator       rend()         { return m_SectionList.rend(); }
+  const_reverse_iterator rend()   const { return m_SectionList.rend(); }
 
   LDSection*       front()       { return m_SectionList.front(); }
   const LDSection* front() const { return m_SectionList.front(); }
@@ -52,35 +59,20 @@
   const LDSection* back()  const { return m_SectionList.back(); }
 
   ///  -----  observers  -----  ///
-  uint32_t type() const
-  { return m_Type; }
+  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 std::max(m_Align, m_MaxSectionAlign); }
 
-  uint64_t offset() const
-  { return m_Offset; }
+  size_t size() const { return m_SectionList.size(); }
+  bool  empty() const { return m_SectionList.empty(); }
 
-  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 std::max(m_Align, m_MaxSectionAlign); }
-
-  size_t numOfSections() const
-  { return m_SectionList.size(); }
-
+  bool isLoadSegment() const;
   bool isDataSegment() const;
-
   bool isBssSegment() const;
 
   ///  -----  modifiers  -----  ///
@@ -112,13 +104,14 @@
   void setAlign(uint64_t pAlign)
   { m_Align = pAlign; }
 
-  void addSection(LDSection* pSection)
-  {
-    assert(NULL != pSection);
-    if (pSection->align() > m_MaxSectionAlign)
-      m_MaxSectionAlign = pSection->align();
-    m_SectionList.push_back(pSection);
-  }
+  iterator insert(iterator pPos, LDSection* pSection);
+
+  void append(LDSection* pSection);
+
+  /* factory methods */
+  static ELFSegment* Create(uint32_t pType, uint32_t pFlag = llvm::ELF::PF_R);
+  static void Destroy(ELFSegment*& pSegment);
+  static void Clear();
 
 private:
   uint32_t m_Type;            // Type of segment
@@ -130,7 +123,7 @@
   uint64_t m_Memsz;           // # of bytes in mem image of segment (may be 0)
   uint64_t m_Align;           // alignment constraint
   uint64_t m_MaxSectionAlign; // max alignment of the sections in this segment
-  std::vector<LDSection*> m_SectionList;
+  SectionList m_SectionList;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/ELFSegmentFactory.h b/include/mcld/LD/ELFSegmentFactory.h
index 5085a18..6df0389 100644
--- a/include/mcld/LD/ELFSegmentFactory.h
+++ b/include/mcld/LD/ELFSegmentFactory.h
@@ -6,38 +6,64 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELFSEGMENT_FACTORY_H
-#define MCLD_ELFSEGMENT_FACTORY_H
+#ifndef MCLD_LD_ELFSEGMENTFACTORY_H
+#define MCLD_LD_ELFSEGMENTFACTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
-#include <mcld/Support/GCFactory.h>
-#include <mcld/LD/ELFSegment.h>
+
+#include <llvm/Support/DataTypes.h>
+#include <llvm/Support/ELF.h>
+#include <vector>
 
 namespace mcld
 {
 
+class ELFSegment;
+class LDSection;
+
 /** \class ELFSegmentFactory
  *  \brief provide the interface to create and delete an ELFSegment
  */
-class ELFSegmentFactory : public GCFactory<ELFSegment, 0>
+class ELFSegmentFactory
 {
 public:
-  /// ELFSegmentFactory - the factory of ELFSegment
-  /// pNum is the magic number of the ELF segments in the output
-  ELFSegmentFactory(size_t pNum);
-  ~ELFSegmentFactory();
+  typedef std::vector<ELFSegment*> Segments;
+  typedef Segments::const_iterator const_iterator;
+  typedef Segments::iterator iterator;
+
+  const_iterator begin() const { return m_Segments.begin(); }
+  iterator       begin()       { return m_Segments.begin(); }
+  const_iterator end()   const { return m_Segments.end(); }
+  iterator       end()         { return m_Segments.end(); }
+
+  const ELFSegment* front() const { return m_Segments.front(); }
+  ELFSegment*       front()       { return m_Segments.front(); }
+  const ELFSegment* back()  const { return m_Segments.back(); }
+  ELFSegment*       back()        { return m_Segments.back(); }
+
+  size_t size() const { return m_Segments.size(); }
+
+  bool empty() const { return m_Segments.empty(); }
+
+  iterator find(uint32_t pType, uint32_t pFlagSet, uint32_t pFlagClear);
+
+  const_iterator
+  find(uint32_t pType, uint32_t pFlagSet, uint32_t pFlagClear) const;
+
+  iterator       find(uint32_t pType, const LDSection* pSection);
+
+  const_iterator find(uint32_t pType, const LDSection* pSection) const;
 
   /// 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, uint32_t pFlag = llvm::ELF::PF_R);
 
-  ELFSegment*
-  find(uint32_t pType, uint32_t pFlagSet, uint32_t pFlagClear);
+  void erase(iterator pSegment);
 
-  const ELFSegment*
-  find(uint32_t pType, uint32_t pFlagSet, uint32_t pFlagClear) const;
+private:
+  Segments m_Segments;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/EhFrame.h b/include/mcld/LD/EhFrame.h
index c067746..6663d0f 100644
--- a/include/mcld/LD/EhFrame.h
+++ b/include/mcld/LD/EhFrame.h
@@ -6,23 +6,30 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_EH_FRAME_H
-#define MCLD_LD_EH_FRAME_H
+#ifndef MCLD_LD_EHFRAME_H
+#define MCLD_LD_EHFRAME_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
 #include <mcld/Config/Config.h>
 #include <mcld/Fragment/RegionFragment.h>
-#include <mcld/Fragment/NullFragment.h>
+#include <mcld/LD/SectionData.h>
 #include <mcld/Support/Allocators.h>
 
+#include <llvm/ADT/StringRef.h>
+#include <list>
+#include <map>
+#include <set>
 #include <vector>
 
 namespace mcld {
 
+class Input;
+class Module;
 class LDSection;
-class SectionData;
+class ObjectLinker;
+class Relocation;
 
 /** \class EhFrame
  *  \brief EhFrame represents .eh_frame section
@@ -41,53 +48,128 @@
   EhFrame& operator=(const EhFrame&); // DO NOT IMPLEMENT
 
 public:
+  enum RecordType {
+    RECORD_UNKNOWN,
+    RECORD_INPUT,
+    RECORD_GENERATED
+  };
+
+  class CIE;
+  class FDE;
+
+  typedef std::vector<CIE*> CIEList;
+  typedef CIEList::iterator cie_iterator;
+  typedef CIEList::const_iterator const_cie_iterator;
+
+  typedef std::list<FDE*> FDEList;
+  typedef FDEList::iterator fde_iterator;
+  typedef FDEList::const_iterator const_fde_iterator;
+
+  typedef std::map</*offset*/size_t, CIE*> CIEMap;
+
+  // A super class of CIE and FDE, containing the same part
+  class Record : public RegionFragment
+  {
+  public:
+    Record(llvm::StringRef pRegion);
+    virtual ~Record();
+
+    const llvm::StringRef getRegion() const { return RegionFragment::getRegion(); }
+          llvm::StringRef getRegion()       { return RegionFragment::getRegion(); }
+    virtual RecordType getRecordType() const { return RECORD_UNKNOWN; }
+
+  private:
+    Record(const Record&);            // DO NOT IMPLEMENT
+    Record& operator=(const Record&); // DO NOT IMPLEMENT
+  };
+
   /** \class CIE
    *  \brief Common Information Entry.
    *  The CIE structure refers to LSB Core Spec 4.1, chap.10.6. Exception Frames.
    */
-  class CIE : public RegionFragment
+  class CIE : public Record
   {
   public:
-    CIE(MemoryRegion& pRegion);
+    CIE(llvm::StringRef pRegion);
+    ~CIE();
+
+    virtual RecordType getRecordType() const { return RECORD_INPUT; }
 
     void setFDEEncode(uint8_t pEncode) { m_FDEEncode = pEncode; }
     uint8_t getFDEEncode() const { return m_FDEEncode; }
 
+    void setMergeable(bool pVal = true) { m_Mergeable = pVal; }
+    virtual bool getMergeable() const { return m_Mergeable; }
+
+    void setRelocation(const Relocation& pReloc) { m_pReloc = &pReloc; }
+    const Relocation* getRelocation() const { return m_pReloc; }
+
+    void setPersonalityOffset(uint64_t pOffset) { m_PersonalityOffset = pOffset; }
+    uint64_t getPersonalityOffset() const { return m_PersonalityOffset; }
+
+    void setPersonalityName(const std::string& pStr) { m_PersonalityName = pStr; }
+    const std::string& getPersonalityName() const { return m_PersonalityName; }
+
+    void setAugmentationData(const std::string& pStr) { m_AugmentationData = pStr; }
+    const std::string& getAugmentationData() const { return m_AugmentationData; }
+
+    void add(FDE& pFDE) { m_FDEs.push_back(&pFDE); }
+    void remove(FDE& pFDE) { m_FDEs.remove(&pFDE); }
+    void clearFDEs() { m_FDEs.clear(); }
+    size_t numOfFDEs() const { return m_FDEs.size(); }
+
+    const_fde_iterator begin() const { return m_FDEs.begin(); }
+    fde_iterator       begin()       { return m_FDEs.begin(); }
+    const_fde_iterator end() const { return m_FDEs.end(); }
+    fde_iterator       end()       { return m_FDEs.end(); }
+
   private:
     uint8_t m_FDEEncode;
+    bool m_Mergeable;
+    const Relocation* m_pReloc;
+    uint64_t m_PersonalityOffset;
+    std::string m_PersonalityName;
+    std::string m_AugmentationData;
+    FDEList m_FDEs;
   };
 
   /** \class FDE
    *  \brief Frame Description Entry
    *  The FDE structure refers to LSB Core Spec 4.1, chap.10.6. Exception Frames.
    */
-  class FDE : public RegionFragment
+  class FDE : public Record
   {
   public:
-    FDE(MemoryRegion& pRegion,
-        const CIE& pCIE,
-        uint32_t pDataStart);
+    FDE(llvm::StringRef pRegion, CIE& pCIE);
+    ~FDE();
 
-    const CIE& getCIE() const { return m_CIE; }
-
-    uint32_t getDataStart() const { return m_DataStart; }
+    void setCIE(CIE& pCIE);
+    const CIE& getCIE() const { return *m_pCIE; }
+    CIE&       getCIE()       { return *m_pCIE; }
 
   private:
-    const CIE& m_CIE;
-    uint32_t m_DataStart;
+    CIE* m_pCIE;  // Referenced CIE may change when merging.
   };
 
-  typedef std::vector<CIE*> CIEList;
+  // These are created for PLT
+  class GeneratedCIE : public CIE
+  {
+  public:
+    GeneratedCIE(llvm::StringRef pRegion);
+    ~GeneratedCIE();
 
-  // cie_iterator and const_cie_iterator must be a kind of random access iterator
-  typedef CIEList::iterator cie_iterator;
-  typedef CIEList::const_iterator const_cie_iterator;
+    virtual RecordType getRecordType() const { return RECORD_GENERATED; }
+    virtual bool getMergeable() const { return true; }
+  };
 
-  typedef std::vector<FDE*> FDEList;
+  class GeneratedFDE : public FDE
+  {
+  public:
+    GeneratedFDE(llvm::StringRef pRegion, CIE& pCIE);
+    ~GeneratedFDE();
 
-  // fde_iterator and const_fde_iterator must be a kind of random access iterator
-  typedef FDEList::iterator fde_iterator;
-  typedef FDEList::const_iterator const_fde_iterator;
+    virtual RecordType getRecordType() const { return RECORD_GENERATED; }
+  };
 
 public:
   static EhFrame* Create(LDSection& pSection);
@@ -97,7 +179,7 @@
   static void Clear();
 
   /// merge - move all data from pOther to this object.
-  EhFrame& merge(EhFrame& pOther);
+  EhFrame& merge(const Input& pInput, EhFrame& pInFrame);
 
   const LDSection& getSection() const;
   LDSection&       getSection();
@@ -106,17 +188,13 @@
   SectionData*       getSectionData()       { return m_pSectionData; }
 
   // -----  fragment  ----- //
-  /// addFragment - when we start treating CIEs and FDEs as regular fragments,
-  /// we call this function instead of addCIE() and addFDE().
-  void addFragment(RegionFragment& pFrag);
-
-  void addFragment(NullFragment& pFrag);
+  void addFragment(Fragment& pFrag);
 
   /// addCIE - add a CIE entry in EhFrame
-  void addCIE(CIE& pCIE);
+  void addCIE(CIE& pCIE, bool pAlsoAddFragment = true);
 
   /// addFDE - add a FDE entry in EhFrame
-  void addFDE(FDE& pFDE);
+  void addFDE(FDE& pFDE, bool pAlsoAddFragment = true);
 
   // -----  CIE  ----- //
   const_cie_iterator cie_begin() const { return m_CIEs.begin(); }
@@ -129,29 +207,54 @@
   const CIE& cie_back () const { return *m_CIEs.back(); }
   CIE&       cie_back ()       { return *m_CIEs.back(); }
 
+  bool emptyCIEs() const { return m_CIEs.empty(); }
   size_t numOfCIEs() const { return m_CIEs.size(); }
+  size_t numOfFDEs() const;
 
-  // -----  FDE  ----- //
-  const_fde_iterator fde_begin() const { return m_FDEs.begin(); }
-  fde_iterator       fde_begin()       { return m_FDEs.begin(); }
-  const_fde_iterator fde_end  () const { return m_FDEs.end(); }
-  fde_iterator       fde_end  ()       { return m_FDEs.end(); }
+  const CIEMap& getCIEMap() const { return m_FoundCIEs; }
+  CIEMap&       getCIEMap()       { return m_FoundCIEs; }
 
-  const FDE& fde_front() const { return *m_FDEs.front(); }
-  FDE&       fde_front()       { return *m_FDEs.front(); }
-  const FDE& fde_back () const { return *m_FDEs.back(); }
-  FDE&       fde_back ()       { return *m_FDEs.back(); }
+public:
+  size_t computeOffsetSize();
 
-  size_t numOfFDEs() const { return m_FDEs.size(); }
+  /// getDataStartOffset - Get the offset after length and ID field.
+  /// The offset is 8byte for 32b, and 16byte for 64b.
+  /// We can just use "BITCLASS/4" to represent offset.
+  template <size_t BITCLASS>
+  static size_t getDataStartOffset() { return BITCLASS / 4; }
+
+private:
+  // We needs to check if it is mergeable and check personality name
+  // before merging them. The important note is we must do this after
+  // ALL readSections done, that is the reason why we don't check this
+  // immediately when reading.
+  void setupAttributes(const LDSection* reloc_sect);
+  void removeDiscardedFDE(CIE& pCIE, const LDSection* pRelocEhFrameSect);
+
+private:
+  void removeAndUpdateCIEForFDE(EhFrame& pInFrame, CIE& pInCIE, CIE& pOutCIE,
+                                const LDSection* reloc_sect);
+  void moveInputFragments(EhFrame& pInFrame);
+  void moveInputFragments(EhFrame& pInFrame, CIE& pInCIE, CIE* pOutCIE = 0);
 
 private:
   LDSection* m_pSection;
   SectionData* m_pSectionData;
 
+  // Each eh_frame has a list of CIE, and each CIE has a list of FDE
+  // pointing to the CIE itself. This is used by management when we are
+  // processing eh_frame merge.
+  // However, don't forget we need to handle the Fragments inside SectionData
+  // correctly since they are truly used when output emission.
   CIEList m_CIEs;
-  FDEList m_FDEs;
+
+  // We need this map to find the corresponding CIE for FDE. Not all FDE point
+  // to the nearest CIE.
+  CIEMap m_FoundCIEs;
 };
 
+bool operator==(const EhFrame::CIE&, const EhFrame::CIE&);
+
 } // namespace of mcld
 
 #endif
diff --git a/include/mcld/LD/EhFrameHdr.h b/include/mcld/LD/EhFrameHdr.h
index 3a5971d..2d7b0e9 100644
--- a/include/mcld/LD/EhFrameHdr.h
+++ b/include/mcld/LD/EhFrameHdr.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_EHFRAMEHDR_H
-#define MCLD_EHFRAMEHDR_H
+#ifndef MCLD_LD_EHFRAMEHDR_H
+#define MCLD_LD_EHFRAMEHDR_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -15,11 +15,11 @@
 #include <cassert>
 
 #include <mcld/LD/EhFrame.h>
+#include <mcld/Support/FileOutputBuffer.h>
 namespace mcld {
 
 class LDSection;
-class MemoryArea;
-class MemoryRegion;
+class FileOutputBuffer;
 
 /** \class EhFrameHdr
  *  \brief EhFrameHdr represents .eh_frame_hdr section.
@@ -47,13 +47,14 @@
 
   /// emitOutput - write out eh_frame_hdr
   template<size_t size>
-  void emitOutput(MemoryArea& pOutput)
+  void emitOutput(FileOutputBuffer& pOutput)
   { assert(false && "Call invalid EhFrameHdr::emitOutput"); }
 
 private:
   /// computePCBegin - return the address of FDE's pc
   /// @ref binutils gold: ehframe.cc:222
-  uint32_t computePCBegin(const EhFrame::FDE& pFDE, const MemoryRegion& pEhFrameRegion);
+  uint32_t computePCBegin(const EhFrame::FDE& pFDE,
+                          const MemoryRegion& pEhFrameRegion);
 
 private:
   /// .eh_frame_hdr section
@@ -68,7 +69,7 @@
 //===----------------------------------------------------------------------===//
 /// emitOutput - write out eh_frame_hdr
 template<>
-void EhFrameHdr::emitOutput<32>(MemoryArea& pOutput);
+void EhFrameHdr::emitOutput<32>(FileOutputBuffer& pOutput);
 
 } // namespace of mcld
 
diff --git a/include/mcld/LD/EhFrameReader.h b/include/mcld/LD/EhFrameReader.h
index 1ac0351..509debf 100644
--- a/include/mcld/LD/EhFrameReader.h
+++ b/include/mcld/LD/EhFrameReader.h
@@ -6,17 +6,18 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_EH_FRAME_READER_H
-#define MCLD_EH_FRAME_READER_H
+#ifndef MCLD_LD_EHFRAMEREADER_H
+#define MCLD_LD_EHFRAMEREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
-#include <mcld/Support/MemoryRegion.h>
+#include <mcld/LD/EhFrame.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/DataTypes.h>
 
 namespace mcld {
 
 class Input;
-class EhFrame;
 class LDSection;
 
 /** \class EhFrameReader
@@ -28,8 +29,8 @@
 class EhFrameReader
 {
 public:
-  typedef const uint8_t* ConstAddress;
-  typedef       uint8_t* Address;
+  typedef const char* ConstAddress;
+  typedef       char* Address;
 
 public:
   /// read - read an .eh_frame section and create the corresponding
@@ -70,29 +71,29 @@
   /// @param pSection - the input .eh_frame section
   /// @param pRegion - the memory region that needs to handle with.
   typedef bool (*Action)(EhFrame& pEhFrame,
-                         MemoryRegion& pRegion,
+                         llvm::StringRef pRegion,
                          const Token& pToken);
 private:
   /// scan - scan pData from pHandler for a token.
-  template<bool SAME_ENDIAN> Token
-  scan(ConstAddress pHandler, uint64_t pOffset, const MemoryRegion& pData) const;
+  template<bool SAME_ENDIAN> Token scan(ConstAddress pHandler,
+                                        uint64_t pOffset,
+                                        llvm::StringRef pData) const;
 
   static bool addCIE(EhFrame& pEhFrame,
-                     MemoryRegion& pRegion,
+                     llvm::StringRef pRegion,
                      const Token& pToken);
 
   static bool addFDE(EhFrame& pEhFrame,
-                     MemoryRegion& pRegion,
+                     llvm::StringRef pRegion,
                      const Token& pToken);
 
   static bool addTerm(EhFrame& pEhFrame,
-                      MemoryRegion& pRegion,
+                      llvm::StringRef pRegion,
                       const Token& pToken);
 
   static bool reject(EhFrame& pEhFrame,
-                     MemoryRegion& pRegion,
+                     llvm::StringRef pRegion,
                      const Token& pToken);
-
 };
 
 template<> bool
@@ -101,7 +102,7 @@
 template<> EhFrameReader::Token
 EhFrameReader::scan<true>(ConstAddress pHandler,
                           uint64_t pOffset,
-                          const MemoryRegion& pData) const;
+                          llvm::StringRef pData) const;
 
 } // namespace of mcld
 
diff --git a/include/mcld/LD/GNUArchiveReader.h b/include/mcld/LD/GNUArchiveReader.h
index 7a33ff4..1c2e10a 100644
--- a/include/mcld/LD/GNUArchiveReader.h
+++ b/include/mcld/LD/GNUArchiveReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_GNU_ARCHIVE_READER_H
-#define MCLD_GNU_ARCHIVE_READER_H
+#ifndef MCLD_LD_GNUARCHIVEREADER_H
+#define MCLD_LD_GNUARCHIVEREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -20,8 +20,8 @@
 class Module;
 class Input;
 class ELFObjectReader;
-class MemoryAreaFactory;
 class Archive;
+class LinkerConfig;
 
 /** \class GNUArchiveReader
  *  \brief GNUArchiveReader reads GNU archive files.
@@ -35,10 +35,10 @@
 
   /// readArchive - read an archive, include the needed members, and build up
   /// the subtree
-  bool readArchive(Archive& pArchive);
+  bool readArchive(const LinkerConfig& pConfig, Archive& pArchive);
 
   /// isMyFormat
-  bool isMyFormat(Input& input) const;
+  bool isMyFormat(Input& input, bool &pContinue) const;
 
 private:
   /// isArchive
@@ -78,13 +78,16 @@
 
   /// includeMember - include the object member in the given file offset, and
   /// return the size of the object
+  /// @param pConfig - LinkerConfig
   /// @param pArchiveRoot - the archive root
   /// @param pFileOffset  - file offset of the member header in the archive
-  size_t includeMember(Archive& pArchiveRoot, uint32_t pFileOffset);
+  size_t includeMember(const LinkerConfig& pConfig,
+                       Archive& pArchiveRoot,
+                       uint32_t pFileOffset);
 
   /// includeAllMembers - include all object members. This is called if
   /// --whole-archive is the attribute for this archive file.
-  bool includeAllMembers(Archive& pArchive);
+  bool includeAllMembers(const LinkerConfig& pConfig, Archive& pArchive);
 
 private:
   Module& m_Module;
diff --git a/include/mcld/LD/GarbageCollection.h b/include/mcld/LD/GarbageCollection.h
new file mode 100644
index 0000000..3476cd1
--- /dev/null
+++ b/include/mcld/LD/GarbageCollection.h
@@ -0,0 +1,94 @@
+//===- GarbageCollection.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LD_GARBAGECOLLECTION_H
+#define MCLD_LD_GARBAGECOLLECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <map>
+#include <set>
+#include <vector>
+
+namespace mcld {
+
+class LDSection;
+class LinkerConfig;
+class Module;
+class TargetLDBackend;
+
+/** \class GarbageCollection
+ *  \brief Implementation of garbage collection for --gc-section.
+ *  @ref GNU gold, gc.
+ */
+class GarbageCollection
+{
+public:
+  typedef std::set<const LDSection*> SectionListTy;
+  typedef std::vector<const LDSection*> SectionVecTy;
+
+  /** \class SectionReachedListMap
+   *  \brief Map the section to the list of sections which it can reach directly
+   */
+  class SectionReachedListMap
+  {
+  public:
+    SectionReachedListMap() {}
+
+    /// addReference - add a reference from pFrom to pTo
+    void addReference(const LDSection& pFrom, const LDSection& pTo);
+
+    /// getReachedList - get the list of sections which can be reached by
+    /// pSection, create one if the list has not existed
+    SectionListTy& getReachedList(const LDSection& pSection);
+
+    /// findReachedList - find the list of sections which can be reached by
+    /// pSection, return NULL if the list not exists
+    SectionListTy* findReachedList(const LDSection& pSection);
+
+  private:
+    typedef std::map<const LDSection*, SectionListTy> ReachedSectionsTy;
+
+  private:
+    /// m_ReachedSections - map a section to the reachable sections list
+    ReachedSectionsTy m_ReachedSections;
+  };
+
+public:
+  GarbageCollection(const LinkerConfig& pConfig,
+                    const TargetLDBackend& pBackend,
+                    Module& pModule);
+  ~GarbageCollection();
+
+  /// run - do garbage collection
+  bool run();
+
+private:
+  void setUpReachedSections();
+  void findReferencedSections(SectionVecTy& pEntry);
+  void getEntrySections(SectionVecTy& pEntry);
+  void stripSections();
+
+private:
+  /// m_SectionReachedListMap - map the section to the list of sections which it
+  /// can reach directly
+  SectionReachedListMap m_SectionReachedListMap;
+
+  /// m_ReferencedSections - a list of sections which can be reached from entry
+  SectionListTy m_ReferencedSections;
+
+  const LinkerConfig& m_Config;
+  const TargetLDBackend& m_Backend;
+  Module& m_Module;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Group.h b/include/mcld/LD/Group.h
index 31c4a68..30e8f63 100644
--- a/include/mcld/LD/Group.h
+++ b/include/mcld/LD/Group.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef LD_GROUP_H
-#define LD_GROUP_H
+#ifndef MCLD_LD_GROUP_H
+#define MCLD_LD_GROUP_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/GroupReader.h b/include/mcld/LD/GroupReader.h
index 01178a0..fa1e182 100644
--- a/include/mcld/LD/GroupReader.h
+++ b/include/mcld/LD/GroupReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_GROUPREADER_H
-#define MCLD_GROUPREADER_H
+#ifndef MCLD_LD_GROUPREADER_H
+#define MCLD_LD_GROUPREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -43,6 +43,7 @@
   /// readGroup - handle the input sub-tree wich its root is pRoot
   /// @param pRoot - the root Group node of the sub-tree
   bool readGroup(Module::input_iterator pRoot,
+                 Module::input_iterator pEnd,
                  InputBuilder& pBuilder,
                  const LinkerConfig& pConfig);
 
diff --git a/include/mcld/LD/LDContext.h b/include/mcld/LD/LDContext.h
index 3ab6ce1..c9f30ae 100644
--- a/include/mcld/LD/LDContext.h
+++ b/include/mcld/LD/LDContext.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LDCONTEXT_H
-#define MCLD_LDCONTEXT_H
+#ifndef MCLD_LD_LDCONTEXT_H
+#define MCLD_LD_LDCONTEXT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -72,6 +72,12 @@
   void addSymbol(LDSymbol* pSym)
   { m_SymTab.push_back(pSym); }
 
+  const_sym_iterator symTabBegin() const { return m_SymTab.begin(); }
+  sym_iterator       symTabBegin()       { return m_SymTab.begin(); }
+
+  const_sym_iterator symTabEnd() const { return m_SymTab.end(); }
+  sym_iterator       symTabEnd()       { return m_SymTab.end(); }
+
   // -----  relocations  ----- //
   const_sect_iterator relocSectBegin() const { return m_RelocSections.begin(); }
   sect_iterator       relocSectBegin()       { return m_RelocSections.begin(); }
diff --git a/include/mcld/LD/LDFileFormat.h b/include/mcld/LD/LDFileFormat.h
index 4fa58ce..fb5ab63 100644
--- a/include/mcld/LD/LDFileFormat.h
+++ b/include/mcld/LD/LDFileFormat.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LDFILE_FORMAT_H
-#define MCLD_LDFILE_FORMAT_H
+#ifndef MCLD_LD_LDFILEFORMAT_H
+#define MCLD_LD_LDFILEFORMAT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/LDReader.h b/include/mcld/LD/LDReader.h
index 4fde9f0..38bf24d 100644
--- a/include/mcld/LD/LDReader.h
+++ b/include/mcld/LD/LDReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_READER_INTERFACE_H
-#define MCLD_READER_INTERFACE_H
+#ifndef MCLD_LD_LDREADER_H
+#define MCLD_LD_LDREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -37,7 +37,7 @@
 public:
   virtual ~LDReader() { }
 
-  virtual bool isMyFormat(Input& pInput) const = 0;
+  virtual bool isMyFormat(Input& pInput, bool &pContinue) const = 0;
 
 };
 
diff --git a/include/mcld/LD/LDSymbol.h b/include/mcld/LD/LDSymbol.h
index b40213c..bebdd18 100644
--- a/include/mcld/LD/LDSymbol.h
+++ b/include/mcld/LD/LDSymbol.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_SYMBOL_H
-#define MCLD_LD_SYMBOL_H
+#ifndef MCLD_LD_LDSYMBOL_H
+#define MCLD_LD_LDSYMBOL_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -19,7 +19,12 @@
 #include <mcld/LD/ResolveInfo.h>
 #include <mcld/Support/Allocators.h>
 
-#include <llvm/Support/ManagedStatic.h>
+namespace llvm {
+
+// forware declaration
+template<class T> void* object_creator();
+
+} // namespace of llvm
 
 namespace mcld {
 
diff --git a/include/mcld/LD/MsgHandler.h b/include/mcld/LD/MsgHandler.h
index 9b1ed80..62def8e 100644
--- a/include/mcld/LD/MsgHandler.h
+++ b/include/mcld/LD/MsgHandler.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_MESSAGE_HANDLER_H
-#define MCLD_MESSAGE_HANDLER_H
+#ifndef MCLD_LD_MSGHANDLER_H
+#define MCLD_LD_MSGHANDLER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/NamePool.h b/include/mcld/LD/NamePool.h
index 32354ea..7a8f816 100644
--- a/include/mcld/LD/NamePool.h
+++ b/include/mcld/LD/NamePool.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_NAME_POOL_H
-#define MCLD_NAME_POOL_H
+#ifndef MCLD_LD_NAMEPOOL_H
+#define MCLD_LD_NAMEPOOL_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -38,7 +38,14 @@
 class NamePool : private Uncopyable
 {
 public:
-  typedef HashTable<ResolveInfo, hash::StringHash<hash::ELF> > Table;
+  typedef HashTable<ResolveInfo, hash::StringHash<hash::DJB> > Table;
+  typedef Table::iterator syminfo_iterator;
+  typedef Table::const_iterator const_syminfo_iterator;
+
+  typedef GCFactory<ResolveInfo*, 128> FreeInfoSet;
+  typedef FreeInfoSet::iterator freeinfo_iterator;
+  typedef FreeInfoSet::const_iterator const_freeinfo_iterator;
+
   typedef size_t size_type;
 
 public:
@@ -56,7 +63,7 @@
                             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.
@@ -69,6 +76,7 @@
                     ResolveInfo::Desc pDesc,
                     ResolveInfo::Binding pBinding,
                     ResolveInfo::SizeType pSize,
+                    LDSymbol::ValueType pValue,
                     ResolveInfo::Visibility pVisibility,
                     ResolveInfo* pOldInfo,
                     Resolver::Result& pResult);
@@ -93,15 +101,39 @@
   bool empty() const
   { return m_Table.empty(); }
 
+  // syminfo_iterator - traverse the ResolveInfo in the resolved HashTable
+  syminfo_iterator syminfo_begin()
+  { return m_Table.begin(); }
+
+  syminfo_iterator syminfo_end()
+  { return m_Table.end(); }
+
+  const_syminfo_iterator syminfo_begin() const
+  { return m_Table.begin(); }
+
+  const_syminfo_iterator syminfo_end() const
+  { return m_Table.end(); }
+
+  // freeinfo_iterator - traverse the ResolveInfo those do not need to be
+  // resolved, for example, local symbols
+  freeinfo_iterator freeinfo_begin()
+  { return m_FreeInfoSet.begin(); }
+
+  freeinfo_iterator freeinfo_end()
+  { return m_FreeInfoSet.end(); }
+
+  const_freeinfo_iterator freeinfo_begin() const
+  { return m_FreeInfoSet.begin(); }
+
+  const_freeinfo_iterator freeinfo_end() const
+  { return m_FreeInfoSet.end(); }
+
   // -----  capacity  ----- //
   void reserve(size_type pN);
 
   size_type capacity() const;
 
 private:
-  typedef GCFactory<ResolveInfo*, 128> FreeInfoSet;
-
-private:
   Resolver* m_pResolver;
   Table m_Table;
   FreeInfoSet m_FreeInfoSet;
diff --git a/include/mcld/LD/ObjectReader.h b/include/mcld/LD/ObjectReader.h
index 2ca3173..34427f8 100644
--- a/include/mcld/LD/ObjectReader.h
+++ b/include/mcld/LD/ObjectReader.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_OBJECT_READER_H
-#define MCLD_OBJECT_READER_H
+#ifndef MCLD_LD_OBJECTREADER_H
+#define MCLD_LD_OBJECTREADER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -29,7 +29,7 @@
 class ObjectReader : public LDReader
 {
 protected:
-  typedef HashTable<ResolveInfo, hash::StringHash<hash::ELF> > GroupSignatureMap;
+  typedef HashTable<ResolveInfo, hash::StringHash<hash::DJB> > GroupSignatureMap;
 
 protected:
   ObjectReader()
diff --git a/include/mcld/LD/ObjectWriter.h b/include/mcld/LD/ObjectWriter.h
index c1dcac6..2a42aed 100644
--- a/include/mcld/LD/ObjectWriter.h
+++ b/include/mcld/LD/ObjectWriter.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_OBJECT_WRITER_INTERFACE_H
-#define MCLD_OBJECT_WRITER_INTERFACE_H
+#ifndef MCLD_LD_OBJECTWRITER_H
+#define MCLD_LD_OBJECTWRITER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -16,7 +16,7 @@
 namespace mcld {
 
 class Module;
-class MemoryArea;
+class FileOutputBuffer;
 
 /** \class ObjectWriter
  *  \brief ObjectWriter provides a common interface for object file writers.
@@ -29,7 +29,10 @@
 public:
   virtual ~ObjectWriter();
 
-  virtual llvm::error_code writeObject(Module& pModule, MemoryArea& pOutput) = 0;
+  virtual llvm::error_code writeObject(Module& pModule,
+                                       FileOutputBuffer& pOutput) = 0;
+
+  virtual size_t getOutputSize(const Module& pModule) const = 0;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/RelocData.h b/include/mcld/LD/RelocData.h
index b53151a..68bc7e1 100644
--- a/include/mcld/LD/RelocData.h
+++ b/include/mcld/LD/RelocData.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_RELOCATION_DATA_H
-#define MCLD_RELOCATION_DATA_H
+#ifndef MCLD_LD_RELOCDATA_H
+#define MCLD_LD_RELOCDATA_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -21,6 +21,8 @@
 #include <llvm/ADT/ilist_node.h>
 #include <llvm/Support/DataTypes.h>
 
+#include <list>
+
 namespace mcld {
 
 class LDSection;
@@ -73,6 +75,7 @@
   bool empty() const { return m_Relocations.empty(); }
 
   RelocData& append(Relocation& pRelocation);
+  Relocation& remove(Relocation& pRelocation);
 
   reference              front ()       { return m_Relocations.front();  }
   const_reference        front () const { return m_Relocations.front();  }
@@ -88,6 +91,18 @@
   const_reverse_iterator rend  () const { return m_Relocations.rend();   }
   reverse_iterator       rend  ()       { return m_Relocations.rend();   }
 
+  template<class Comparator> void sort(Comparator pComparator) {
+    /* FIXME: use llvm::iplist::sort */
+    std::list<Relocation*> relocs;
+    for (iterator it = begin(), ie = end(); it != ie; ++it)
+      relocs.push_back(it);
+    relocs.sort(pComparator);
+    m_Relocations.clear();
+    for (std::list<Relocation*>::iterator it = relocs.begin(),
+      ie = relocs.end(); it != ie; ++it)
+      m_Relocations.push_back(*it);
+  }
+
 private:
   RelocationListType m_Relocations;
   LDSection* m_pSection;
diff --git a/include/mcld/LD/Relocator.h b/include/mcld/LD/Relocator.h
index 54ea7e8..2828a5b 100644
--- a/include/mcld/LD/Relocator.h
+++ b/include/mcld/LD/Relocator.h
@@ -61,10 +61,21 @@
   /// @param pReloc - a read in relocation entry
   /// @param pInputSym - the input LDSymbol of relocation target symbol
   /// @param pSection - the section of relocation applying target
+  /// @param pInput - the input file of relocation
   virtual void scanRelocation(Relocation& pReloc,
                               IRBuilder& pBuilder,
                               Module& pModule,
-                              LDSection& pSection) = 0;
+                              LDSection& pSection,
+                              Input& pInput) = 0;
+
+  /// issueUndefRefError - Provides a basic version for undefined reference dump.
+  /// It will handle the filename and function name automatically.
+  /// @param pReloc - a read in relocation entry
+  /// @param pSection - the section of relocation applying target
+  /// @ param pInput - the input file of relocation
+  virtual void issueUndefRef(Relocation& pReloc,
+                             LDSection& pSection,
+                             Input& pInput);
 
   /// initializeScan - do initialization before scan relocations in pInput
   /// @return - return true for initialization success
diff --git a/include/mcld/LD/ResolveInfo.h b/include/mcld/LD/ResolveInfo.h
index 6f28169..9616719 100644
--- a/include/mcld/LD/ResolveInfo.h
+++ b/include/mcld/LD/ResolveInfo.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_RESOLVE_INFO_H
-#define MCLD_RESOLVE_INFO_H
+#ifndef MCLD_LD_RESOLVEINFO_H
+#define MCLD_LD_RESOLVEINFO_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -18,6 +18,7 @@
 namespace mcld {
 
 class LDSymbol;
+class LinkerConfig;
 
 /** \class ResolveInfo
  *  \brief ResolveInfo records the information about how to resolve a symbol.
@@ -142,6 +143,10 @@
     m_BitField |= indirect_flag;
   }
 
+  /// setInDyn - set if the symbol has been seen in the dynamic objects. Once
+  /// InDyn set, then it won't be set back to false
+  void setInDyn();
+
   // -----  observers  ----- //
   bool isNull() const;
 
@@ -167,6 +172,8 @@
 
   bool isIndirect() const;
 
+  bool isInDyn() const;
+
   uint32_t type() const;
 
   uint32_t desc() const;
@@ -207,6 +214,9 @@
   uint32_t bitfield() const
   { return m_BitField; }
 
+  // shouldForceLocal - check if this symbol should be forced to local
+  bool shouldForceLocal(const LinkerConfig& pConfig);
+
   // -----  For HashTable  ----- //
   bool compare(const key_type& pKey);
 
@@ -236,7 +246,11 @@
 
   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 IN_DYN_OFFSET      = 16;
+  static const uint32_t IN_DYN_MASK        = 1   << IN_DYN_OFFSET;
+
+  static const uint32_t NAME_LENGTH_OFFSET = 17;
   static const uint32_t INFO_MASK          = 0xF;
   static const uint32_t RESOLVE_MASK       = 0xFFFF;
 
@@ -262,6 +276,7 @@
   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;
+  static const uint32_t indyn_flag     = 1        << IN_DYN_OFFSET;
 
 private:
   ResolveInfo();
@@ -274,8 +289,8 @@
   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|
+   *  31     ...    17 16    15    12 11     10..7 6      ..    5 4     3   2   1   0
+   * |length of m_Name|InDyn|reserved|Symbol|Type |ELF visibility|Local|Com|Def|Dyn|Weak|
    */
   uint32_t m_BitField;
   char m_Name[];
diff --git a/include/mcld/LD/Resolver.h b/include/mcld/LD/Resolver.h
index d506a2d..069a167 100644
--- a/include/mcld/LD/Resolver.h
+++ b/include/mcld/LD/Resolver.h
@@ -6,13 +6,14 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_SYMBOL_RESOLVER_H
-#define MCLD_SYMBOL_RESOLVER_H
+#ifndef MCLD_LD_RESOLVER_H
+#define MCLD_LD_RESOLVER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 #include <string>
 #include <utility>
+#include <mcld/LD/LDSymbol.h>
 
 namespace mcld
 {
@@ -59,7 +60,7 @@
   /// @param pNew the symbol which is used to replace pOld
   virtual bool resolve(ResolveInfo & __restrict__ pOld,
                        const ResolveInfo & __restrict__ pNew,
-                       bool &pOverride) const = 0;
+                       bool &pOverride, LDSymbol::ValueType pValue) const = 0;
 
   /// resolveAgain - Can override by derived classes.
   /// @return the pointer to resolved ResolveInfo
diff --git a/include/mcld/LD/SectionData.h b/include/mcld/LD/SectionData.h
index 4f58afa..0a74961 100644
--- a/include/mcld/LD/SectionData.h
+++ b/include/mcld/LD/SectionData.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_SECTION_DATA_H
-#define MCLD_LD_SECTION_DATA_H
+#ifndef MCLD_LD_SECTIONDATA_H
+#define MCLD_LD_SECTIONDATA_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/SectionSymbolSet.h b/include/mcld/LD/SectionSymbolSet.h
index 801fe37..fe814a7 100644
--- a/include/mcld/LD/SectionSymbolSet.h
+++ b/include/mcld/LD/SectionSymbolSet.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_SECTIONSYMBOLSET_H
-#define MCLD_SECTIONSYMBOLSET_H
+#ifndef MCLD_LD_SECTIONSYMBOLSET_H
+#define MCLD_LD_SECTIONSYMBOLSET_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/StaticResolver.h b/include/mcld/LD/StaticResolver.h
index 9fc6104..586e44d 100644
--- a/include/mcld/LD/StaticResolver.h
+++ b/include/mcld/LD/StaticResolver.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_STATIC_SYMBOL_RESOLVER_H
-#define MCLD_STATIC_SYMBOL_RESOLVER_H
+#ifndef MCLD_LD_STATICRESOLVER_H
+#define MCLD_LD_STATICRESOLVER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -111,7 +111,7 @@
   /// @param pNew the symbol which is used to replace pOld
   virtual bool resolve(ResolveInfo & __restrict__ pOld,
                        const ResolveInfo & __restrict__ pNew,
-                       bool &pOverride) const;
+                       bool &pOverride, LDSymbol::ValueType pValue) const;
 
 private:
   inline unsigned int getOrdinate(const ResolveInfo& pInfo) const {
diff --git a/include/mcld/LD/StubFactory.h b/include/mcld/LD/StubFactory.h
index 8548e5a..4298c16 100644
--- a/include/mcld/LD/StubFactory.h
+++ b/include/mcld/LD/StubFactory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_STUB_FACTORY_H
-#define MCLD_LD_STUB_FACTORY_H
+#ifndef MCLD_LD_STUBFACTORY_H
+#define MCLD_LD_STUBFACTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LD/TextDiagnosticPrinter.h b/include/mcld/LD/TextDiagnosticPrinter.h
index 3e7d4c4..6400fa2 100644
--- a/include/mcld/LD/TextDiagnosticPrinter.h
+++ b/include/mcld/LD/TextDiagnosticPrinter.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TEXT_DIAGNOSTIC_PRINTER_H
-#define MCLD_TEXT_DIAGNOSTIC_PRINTER_H
+#ifndef MCLD_LD_TEXTDIAGNOSTICPRINTER_H
+#define MCLD_LD_TEXTDIAGNOSTICPRINTER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Linker.h b/include/mcld/Linker.h
index 83eb295..80f6586 100644
--- a/include/mcld/Linker.h
+++ b/include/mcld/Linker.h
@@ -27,7 +27,7 @@
 class ObjectLinker;
 
 class FileHandle;
-class MemoryArea;
+class FileOutputBuffer;
 
 /** \class Linker
 *  \brief Linker is a modular linker.
@@ -46,7 +46,7 @@
   bool normalize(Module& pModule, IRBuilder& pBuilder);
 
   /// resolve - To build up the topology of mcld::Module.
-  bool resolve();
+  bool resolve(Module& pModule);
 
   /// layout - To serialize the final result of the output mcld::Module.
   bool layout();
@@ -54,15 +54,15 @@
   /// link - A convenient way to resolve and to layout the output mcld::Module.
   bool link(Module& pModule, IRBuilder& pBuilder);
 
-  /// emit - To emit output mcld::Module to a output MemoryArea
-  bool emit(MemoryArea& pOutput);
+  /// emit - To emit output mcld::Module to a FileOutputBuffer.
+  bool emit(FileOutputBuffer& pOutput);
 
   /// emit - To open a file for output in pPath and to emit output mcld::Module
   /// to the file.
-  bool emit(const std::string& pPath);
+  bool emit(const Module& pModule, const std::string& pPath);
 
   /// emit - To emit output mcld::Module in the pFileDescriptor.
-  bool emit(int pFileDescriptor);
+  bool emit(const Module& pModule, int pFileDescriptor);
 
   bool reset();
 
diff --git a/include/mcld/LinkerConfig.h b/include/mcld/LinkerConfig.h
index 96dd5dc..a41be39 100644
--- a/include/mcld/LinkerConfig.h
+++ b/include/mcld/LinkerConfig.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LINKER_CONFIG_H
-#define MCLD_LINKER_CONFIG_H
+#ifndef MCLD_LINKERCONFIG_H
+#define MCLD_LINKERCONFIG_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/LinkerScript.h b/include/mcld/LinkerScript.h
index 91e4bdb..bdd0917 100644
--- a/include/mcld/LinkerScript.h
+++ b/include/mcld/LinkerScript.h
@@ -6,21 +6,26 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LINKER_SCRIPT_H
-#define MCLD_LINKER_SCRIPT_H
+#ifndef MCLD_LINKERSCRIPT_H
+#define MCLD_LINKERSCRIPT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 #include <string>
+#include <vector>
 #include <llvm/ADT/StringRef.h>
 #include <mcld/ADT/StringEntry.h>
 #include <mcld/ADT/StringHash.h>
 #include <mcld/ADT/HashTable.h>
 #include <mcld/Object/SectionMap.h>
 #include <mcld/MC/SearchDirs.h>
+#include <mcld/Script/Assignment.h>
+#include <mcld/Script/AssertCmd.h>
 
 namespace mcld {
 
+class LDSymbol;
+
 /** \class LinkerScript
  *
  */
@@ -28,16 +33,16 @@
 {
 public:
   typedef HashTable<StringEntry<llvm::StringRef>,
-                    hash::StringHash<hash::ELF>,
+                    hash::StringHash<hash::DJB>,
                     StringEntryFactory<llvm::StringRef> > SymbolRenameMap;
 
   typedef HashTable<StringEntry<uint64_t>,
-                    hash::StringHash<hash::ELF>,
+                    hash::StringHash<hash::DJB>,
                     StringEntryFactory<uint64_t> > AddressMap;
 
-  typedef HashTable<StringEntry<llvm::StringRef>,
-                    hash::StringHash<hash::ELF>,
-                    StringEntryFactory<llvm::StringRef> > DefSymMap;
+  typedef std::vector<std::pair<LDSymbol*, Assignment> > Assignments;
+
+  typedef std::vector<AssertCmd> Assertions;
 
 public:
   LinkerScript();
@@ -53,8 +58,11 @@
   const SectionMap& sectionMap() const { return m_SectionMap; }
   SectionMap&       sectionMap()       { return m_SectionMap; }
 
-  const DefSymMap& defSymMap() const { return m_DefSymMap; }
-  DefSymMap&       defSymMap()       { return m_DefSymMap; }
+  const Assignments& assignments() const { return m_Assignments; }
+  Assignments&       assignments()       { return m_Assignments; }
+
+  const Assertions& assertions() const { return m_Assertions; }
+  Assertions&       assertions()       { return m_Assertions; }
 
   /// search directory
   const SearchDirs& directories() const { return m_SearchDirs; }
@@ -67,12 +75,29 @@
 
   bool hasSysroot() const;
 
+  /// entry point
+  const std::string& entry() const;
+
+  void setEntry(const std::string& pEntry);
+
+  bool hasEntry() const;
+
+  /// output filename
+  const std::string& outputFile() const;
+
+  void setOutputFile(const std::string& pOutputFile);
+
+  bool hasOutputFile() const;
+
 private:
   SymbolRenameMap m_SymbolRenames;
   AddressMap m_AddressMap;
   SectionMap m_SectionMap;
-  DefSymMap m_DefSymMap;
+  Assignments m_Assignments;
+  Assertions m_Assertions;
   SearchDirs m_SearchDirs;
+  std::string m_Entry;
+  std::string m_OutputFile;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/MC/Attribute.h b/include/mcld/MC/Attribute.h
index 11f6d26..a7c7176 100644
--- a/include/mcld/MC/Attribute.h
+++ b/include/mcld/MC/Attribute.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ATTRIBUTE_H
-#define MCLD_ATTRIBUTE_H
+#ifndef MCLD_MC_ATTRIBUTE_H
+#define MCLD_MC_ATTRIBUTE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/MC/AttributeSet.h b/include/mcld/MC/AttributeSet.h
index e50384d..97b20a9 100644
--- a/include/mcld/MC/AttributeSet.h
+++ b/include/mcld/MC/AttributeSet.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ATTRIBUTE_SET_H
-#define MCLD_ATTRIBUTE_SET_H
+#ifndef MCLD_MC_ATTRIBUTESET_H
+#define MCLD_MC_ATTRIBUTESET_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/MC/CommandAction.h b/include/mcld/MC/CommandAction.h
index a0ff909..19f74fd 100644
--- a/include/mcld/MC/CommandAction.h
+++ b/include/mcld/MC/CommandAction.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_MC_COMMAND_ACTION_H
-#define MCLD_MC_COMMAND_ACTION_H
+#ifndef MCLD_MC_COMMANDACTION_H
+#define MCLD_MC_COMMANDACTION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -15,11 +15,13 @@
 #include <string>
 #include <mcld/Support/Path.h>
 #include <mcld/MC/InputAction.h>
+#include <mcld/Script/ScriptFile.h>
 
 namespace mcld {
 
 class SearchDirs;
 class InputBuilder;
+class LinkerConfig;
 
 //===----------------------------------------------------------------------===//
 // Derived InputAction
@@ -44,7 +46,7 @@
 public:
   NamespecAction(unsigned int pPosition,
                  const std::string &pNamespec,
-                 SearchDirs& pSearchDirs);
+                 const SearchDirs& pSearchDirs);
 
   const std::string &namespec() const { return m_Namespec; }
 
@@ -52,7 +54,7 @@
 
 private:
   std::string m_Namespec;
-  SearchDirs& m_SearchDirs;
+  const SearchDirs& m_SearchDirs;
 };
 
 /// BitcodeAction
@@ -159,6 +161,41 @@
   bool activate(InputBuilder&) const;
 };
 
+/// DefSymAction
+class DefSymAction : public InputAction
+{
+public:
+  explicit DefSymAction(unsigned int pPosition, std::string& pAssignment);
+
+  bool activate(InputBuilder&) const;
+
+  const std::string& assignment() const { return m_Assignment; }
+
+private:
+  std::string& m_Assignment;
+};
+
+/// ScriptAction
+class ScriptAction : public InputAction
+{
+public:
+  ScriptAction(unsigned int pPosition,
+               const std::string& pFileName,
+               ScriptFile::Kind pKind,
+               const SearchDirs& pSearchDirs);
+
+  bool activate(InputBuilder&) const;
+
+  const std::string& filename() const { return m_FileName; }
+
+  ScriptFile::Kind kind() const { return m_Kind; }
+
+private:
+  std::string m_FileName;
+  ScriptFile::Kind m_Kind;
+  const SearchDirs& m_SearchDirs;
+};
+
 } // end of namespace mcld
 
 #endif
diff --git a/include/mcld/MC/ContextFactory.h b/include/mcld/MC/ContextFactory.h
index dde2627..169dbfa 100644
--- a/include/mcld/MC/ContextFactory.h
+++ b/include/mcld/MC/ContextFactory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_CONTEXT_FACTORY_H
-#define MCLD_CONTEXT_FACTORY_H
+#ifndef MCLD_MC_CONTEXTFACTORY_H
+#define MCLD_MC_CONTEXTFACTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/MC/FileAction.h b/include/mcld/MC/FileAction.h
index 4644405..269c700 100644
--- a/include/mcld/MC/FileAction.h
+++ b/include/mcld/MC/FileAction.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_MC_FILE_ACTION_H
-#define MCLD_MC_FILE_ACTION_H
+#ifndef MCLD_MC_FILEACTION_H
+#define MCLD_MC_FILEACTION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -17,7 +17,6 @@
 namespace mcld {
 
 class ContextFactory;
-class MemoryAreaFactory;
 
 /** \class ContextAction
  *  \brief ContextAction is a command object to create input's LDContext.
diff --git a/include/mcld/MC/MCLDInput.h b/include/mcld/MC/Input.h
similarity index 95%
rename from include/mcld/MC/MCLDInput.h
rename to include/mcld/MC/Input.h
index 94b9479..a8e9c35 100644
--- a/include/mcld/MC/MCLDInput.h
+++ b/include/mcld/MC/Input.h
@@ -1,4 +1,4 @@
-//===- MCLDInput.h --------------------------------------------------------===//
+//===- Input.h ------------------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -10,8 +10,8 @@
 //  Input class inherits MCLDFile, which is used to represent a input file
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_INPUT_H
-#define MCLD_INPUT_H
+#ifndef MCLD_MC_INPUT_H
+#define MCLD_MC_INPUT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -35,6 +35,7 @@
 public:
   enum Type {
     Unknown,
+    Binary,
     Object,
     Exec,
     DynObj,
diff --git a/include/mcld/MC/InputAction.h b/include/mcld/MC/InputAction.h
index fb7d660..4b94378 100644
--- a/include/mcld/MC/InputAction.h
+++ b/include/mcld/MC/InputAction.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_MC_INPUT_ACTION_H
-#define MCLD_MC_INPUT_ACTION_H
+#ifndef MCLD_MC_INPUTACTION_H
+#define MCLD_MC_INPUTACTION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/MC/InputBuilder.h b/include/mcld/MC/InputBuilder.h
index 0301c15..1b2e8b9 100644
--- a/include/mcld/MC/InputBuilder.h
+++ b/include/mcld/MC/InputBuilder.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_MC_INPUT_BUILDER_H
-#define MCLD_MC_INPUT_BUILDER_H
+#ifndef MCLD_MC_INPUTBUILDER_H
+#define MCLD_MC_INPUTBUILDER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -16,7 +16,7 @@
 #include <stack>
 
 #include <mcld/InputTree.h>
-#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/Input.h>
 #include <mcld/Support/FileHandle.h>
 
 namespace mcld {
@@ -26,7 +26,6 @@
 class ContextFactory;
 class MemoryAreaFactory;
 class AttrConstraint;
-class raw_mem_ostream;
 
 /** \class InputBuilder
  *  \brief InputBuilder recieves InputActions and build the InputTree.
diff --git a/include/mcld/MC/InputFactory.h b/include/mcld/MC/InputFactory.h
index d644222..8c73d0b 100644
--- a/include/mcld/MC/InputFactory.h
+++ b/include/mcld/MC/InputFactory.h
@@ -6,13 +6,13 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_INPUT_FACTORY_H
-#define MCLD_INPUT_FACTORY_H
+#ifndef MCLD_MC_INPUTFACTORY_H
+#define MCLD_MC_INPUTFACTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 #include <mcld/Support/GCFactory.h>
-#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/Input.h>
 
 namespace mcld {
 
diff --git a/include/mcld/MC/MCLDDirectory.h b/include/mcld/MC/MCLDDirectory.h
index 988f9d3..77692c0 100644
--- a/include/mcld/MC/MCLDDirectory.h
+++ b/include/mcld/MC/MCLDDirectory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_MCLDDIRECTORY_H
-#define MCLD_MCLDDIRECTORY_H
+#ifndef MCLD_MC_MCLDDIRECTORY_H
+#define MCLD_MC_MCLDDIRECTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/MC/SearchDirs.h b/include/mcld/MC/SearchDirs.h
index 0c0c657..a3bcf39 100644
--- a/include/mcld/MC/SearchDirs.h
+++ b/include/mcld/MC/SearchDirs.h
@@ -12,7 +12,7 @@
 #include <gtest.h>
 #endif
 #include <mcld/ADT/Uncopyable.h>
-#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/Input.h>
 #include <mcld/Support/Path.h>
 
 #include <llvm/ADT/StringRef.h>
diff --git a/include/mcld/MC/SymbolCategory.h b/include/mcld/MC/SymbolCategory.h
index 61c015e..9ecc5b9 100644
--- a/include/mcld/MC/SymbolCategory.h
+++ b/include/mcld/MC/SymbolCategory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_SYMBOL_CATEGORY_H
-#define MCLD_SYMBOL_CATEGORY_H
+#ifndef MCLD_MC_SYMBOLCATEGORY_H
+#define MCLD_MC_SYMBOLCATEGORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/MC/ZOption.h b/include/mcld/MC/ZOption.h
index e451734..d9cd635 100644
--- a/include/mcld/MC/ZOption.h
+++ b/include/mcld/MC/ZOption.h
@@ -6,15 +6,15 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ZOPTION_H
-#define MCLD_ZOPTION_H
+#ifndef MCLD_MC_ZOPTION_H
+#define MCLD_MC_ZOPTION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
+
 #include <llvm/Support/DataTypes.h>
 
-namespace mcld
-{
+namespace mcld {
 
 /** \class ZOption
  *  \brief The -z options for GNU ld compatibility.
@@ -50,19 +50,13 @@
 public:
   ZOption();
 
-  ~ZOption();
+  Kind kind() const { return m_Kind; }
 
-  Kind kind() const
-  { return m_Kind; }
+  void setKind(Kind pKind) { m_Kind = pKind; }
 
-  uint64_t pageSize() const
-  { return m_PageSize; }
+  uint64_t pageSize() const { return m_PageSize; }
 
-  void setKind(Kind pKind)
-  { m_Kind = pKind; }
-
-  void setPageSize(uint64_t pPageSize)
-  { m_PageSize = pPageSize; }
+  void setPageSize(uint64_t pPageSize) { m_PageSize = pPageSize; }
 
 private:
   Kind m_Kind;
diff --git a/include/mcld/Module.h b/include/mcld/Module.h
index 9ea9812..9dfb59e 100644
--- a/include/mcld/Module.h
+++ b/include/mcld/Module.h
@@ -16,25 +16,18 @@
 #include <gtest.h>
 #endif
 
-#include <vector>
-#include <string>
-#include <map>
-
-#include <mcld/LinkerScript.h>
 #include <mcld/InputTree.h>
-#include <mcld/ADT/HashTable.h>
-#include <mcld/ADT/HashEntry.h>
-#include <mcld/Support/GCFactoryListTraits.h>
-#include <mcld/Fragment/Fragment.h>
 #include <mcld/LD/NamePool.h>
 #include <mcld/LD/SectionSymbolSet.h>
 #include <mcld/MC/SymbolCategory.h>
-#include <mcld/MC/MCLDInput.h>
 
-#include <llvm/ADT/ilist.h>
+#include <vector>
+#include <string>
 
 namespace mcld {
 
+class Input;
+class LinkerScript;
 class LDSection;
 class LDSymbol;
 
diff --git a/include/mcld/Object/ObjectBuilder.h b/include/mcld/Object/ObjectBuilder.h
index 79f81a5..ec80528 100644
--- a/include/mcld/Object/ObjectBuilder.h
+++ b/include/mcld/Object/ObjectBuilder.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_OBJECT_OBJECT_BUILDER_H
-#define MCLD_OBJECT_OBJECT_BUILDER_H
+#ifndef MCLD_OBJECT_OBJECTBUILDER_H
+#define MCLD_OBJECT_OBJECTBUILDER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -27,6 +27,7 @@
 class RelocData;
 class Fragment;
 class Relocation;
+class Input;
 
 /** \class ObjectBuilder
  *  \brief ObjectBuilder recieve ObjectAction and build the mcld::Module.
@@ -67,7 +68,7 @@
   /// @param [in] pInputSection The merged input section.
   /// @return The merged output section. If the corresponding output sections
   /// is not defined, return NULL.
-  LDSection* MergeSection(LDSection& pInputSection);
+  LDSection* MergeSection(const Input& pInputFile, LDSection& pInputSection);
 
   /// MoveSectionData - move the fragment of pFrom to pTo section data.
   static bool MoveSectionData(SectionData& pFrom, SectionData& pTo);
diff --git a/include/mcld/Object/ObjectLinker.h b/include/mcld/Object/ObjectLinker.h
index 128cf64..5c8c5cc 100644
--- a/include/mcld/Object/ObjectLinker.h
+++ b/include/mcld/Object/ObjectLinker.h
@@ -6,39 +6,34 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-// ObjectLinker plays the same role as GNU collect2 to prepare all implicit
-// parameters for FragmentLinker.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_OBJECT_OBJECT_LINKER_H
-#define MCLD_OBJECT_OBJECT_LINKER_H
+#ifndef MCLD_OBJECT_OBJECTLINKER_H
+#define MCLD_OBJECT_OBJECTLINKER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
-#include <stddef.h>
+#include <llvm/Support/DataTypes.h>
 
 namespace mcld {
 
 class Module;
 class LinkerConfig;
 class IRBuilder;
-class FragmentLinker;
 class TargetLDBackend;
-class MemoryArea;
-class MemoryAreaFactory;
+class FileOutputBuffer;
 class ObjectReader;
 class DynObjReader;
 class ArchiveReader;
 class GroupReader;
 class BinaryReader;
+class ScriptReader;
 class ObjectWriter;
 class DynObjWriter;
 class ExecWriter;
 class BinaryWriter;
+class Relocation;
+class ResolveInfo;
 
 /** \class ObjectLinker
- *  \brief ObjectLinker prepares parameters for FragmentLinker.
  */
 class ObjectLinker
 {
@@ -48,11 +43,7 @@
 
   ~ObjectLinker();
 
-  void setup(Module& pModule, IRBuilder& pBuilder);
-
-  /// initFragmentLinker - initialize FragmentLinker
-  ///  Connect all components in FragmentLinker
-  bool initFragmentLinker();
+  bool initialize(Module& pModule, IRBuilder& pBuilder);
 
   /// initStdSections - initialize standard sections of the output file.
   bool initStdSections();
@@ -69,9 +60,16 @@
   /// readRelocations - read all relocation entries
   bool readRelocations();
 
+  /// dataStrippingOpt - optimizations for reducing code size
+  void dataStrippingOpt();
+
   /// mergeSections - put allinput sections into output sections
   bool mergeSections();
 
+  /// addSymbolsToOutput - after all symbols has been resolved, add the symbol
+  /// to output
+  void addSymbolsToOutput(Module& pModule);
+
   /// allocateCommonSymobols - allocate fragments for common symbols to the
   /// corresponding sections
   bool allocateCommonSymbols();
@@ -122,18 +120,10 @@
   bool finalizeSymbolValue();
 
   /// emitOutput - emit the output file.
-  bool emitOutput(MemoryArea& pOutput);
+  bool emitOutput(FileOutputBuffer& pOutput);
 
   /// postProcessing - do modificatiion after all processes
-  bool postProcessing(MemoryArea& pOutput);
-
-  /// getLinker - get internal FragmentLinker object
-  const FragmentLinker* getLinker() const { return m_pLinker; }
-  FragmentLinker*       getLinker()       { return m_pLinker; }
-
-  /// hasInitLinker - has Linker been initialized?
-  bool hasInitLinker() const
-  { return (NULL != m_pLinker); }
+  bool postProcessing(FileOutputBuffer& pOutput);
 
   // -----  readers and writers  ----- //
   const ObjectReader*  getObjectReader () const { return m_pObjectReader;  }
@@ -151,12 +141,31 @@
   const BinaryReader*  getBinaryReader () const { return m_pBinaryReader;  }
   BinaryReader*        getBinaryReader ()       { return m_pBinaryReader;  }
 
+  const ScriptReader*  getScriptReader () const { return m_pScriptReader;  }
+  ScriptReader*        getScriptReader ()       { return m_pScriptReader;  }
+
   const ObjectWriter*  getWriter () const { return m_pWriter;  }
   ObjectWriter*        getWriter ()       { return m_pWriter;  }
 
 private:
+  /// normalSyncRelocationResult - sync relocation result when producing shared
+  /// objects or executables
+  void normalSyncRelocationResult(FileOutputBuffer& pOutput);
+
+  /// partialSyncRelocationResult - sync relocation result when doing partial
+  /// link
+  void partialSyncRelocationResult(FileOutputBuffer& pOutput);
+
+  /// writeRelocationResult - helper function of syncRelocationResult, write
+  /// relocation target data to output
+  void writeRelocationResult(Relocation& pReloc, uint8_t* pOutput);
+
+  /// addSymbolToOutput - add a symbol to output symbol table if it's not a
+  /// section symbol and not defined in the discarded section
+  void addSymbolToOutput(ResolveInfo& pInfo, Module& pModule);
+
+private:
   const LinkerConfig& m_Config;
-  FragmentLinker* m_pLinker;
   Module* m_pModule;
   IRBuilder* m_pBuilder;
 
@@ -168,6 +177,7 @@
   ArchiveReader* m_pArchiveReader;
   GroupReader*   m_pGroupReader;
   BinaryReader*  m_pBinaryReader;
+  ScriptReader*  m_pScriptReader;
   ObjectWriter*  m_pWriter;
 };
 
diff --git a/include/mcld/Object/SectionMap.h b/include/mcld/Object/SectionMap.h
index 37df4a3..e6e779d 100644
--- a/include/mcld/Object/SectionMap.h
+++ b/include/mcld/Object/SectionMap.h
@@ -6,82 +6,206 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_SECTION_MAP_H
-#define MCLD_SECTION_MAP_H
+#ifndef MCLD_OBJECT_SECTIONMAP_H
+#define MCLD_OBJECT_SECTIONMAP_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
+#include <mcld/Script/OutputSectDesc.h>
+#include <mcld/Script/InputSectDesc.h>
+#include <mcld/Script/Assignment.h>
+#include <llvm/Support/DataTypes.h>
 #include <vector>
 #include <string>
 
-#include <llvm/Support/DataTypes.h>
-
 namespace mcld {
 
+class Fragment;
+class LDSection;
+
 /** \class SectionMap
- *  \brief descirbe the mappings of input section's name (or prefix) to
- *         its associated output section's name and offset
+ *  \brief descirbe how to map input sections into output sections
  */
 class SectionMap
 {
 public:
-  // a mapping in SectionMap is the triple of
-  // {input substr, output section's name, output section's offset}
-  struct NamePair
-  {
+  class Input {
   public:
-    NamePair();
-    NamePair(const std::string& pFrom, const std::string& pTo);
+    typedef std::vector<std::pair<Fragment*, Assignment> > DotAssignments;
+    typedef DotAssignments::const_iterator const_dot_iterator;
+    typedef DotAssignments::iterator dot_iterator;
 
-    bool isNull() const;
+    Input(const std::string& pName, InputSectDesc::KeepPolicy pPolicy);
+    Input(const InputSectDesc& pInputDesc);
 
-  public:
-    unsigned int hash;
-    std::string from;
-    std::string to;
+    InputSectDesc::KeepPolicy policy() const { return m_Policy; }
+
+    const InputSectDesc::Spec& spec() const { return m_Spec; }
+
+    const LDSection* getSection() const { return m_pSection; }
+    LDSection*       getSection()       { return m_pSection; }
+
+    const_dot_iterator dot_begin() const { return m_DotAssignments.begin(); }
+    dot_iterator       dot_begin()       { return m_DotAssignments.begin(); }
+    const_dot_iterator dot_end  () const { return m_DotAssignments.end(); }
+    dot_iterator       dot_end  ()       { return m_DotAssignments.end(); }
+
+    const DotAssignments& dotAssignments() const { return m_DotAssignments; }
+    DotAssignments&       dotAssignments()       { return m_DotAssignments; }
+
+  private:
+    InputSectDesc::KeepPolicy m_Policy;
+    InputSectDesc::Spec m_Spec;
+    LDSection* m_pSection;
+    DotAssignments m_DotAssignments;
   };
 
-  typedef std::vector<NamePair> NamePairList;
-  typedef NamePairList::iterator iterator;
-  typedef NamePairList::const_iterator const_iterator;
+  class Output {
+  public:
+    typedef std::vector<Input*> InputList;
+    typedef InputList::const_iterator const_iterator;
+    typedef InputList::iterator iterator;
+    typedef InputList::const_reference const_reference;
+    typedef InputList::reference reference;
 
-  /// NullName - the null object of NamePair
-  static NamePair NullName;
+    typedef std::vector<Assignment> DotAssignments;
+    typedef DotAssignments::const_iterator const_dot_iterator;
+    typedef DotAssignments::iterator dot_iterator;
+
+    Output(const std::string& pName);
+    Output(const OutputSectDesc& pOutputDesc);
+
+    const std::string& name() const { return m_Name; }
+
+    const OutputSectDesc::Prolog& prolog() const { return m_Prolog; }
+    OutputSectDesc::Prolog&       prolog()       { return m_Prolog; }
+
+    const OutputSectDesc::Epilog& epilog() const { return m_Epilog; }
+    OutputSectDesc::Epilog&       epilog()       { return m_Epilog; }
+
+    size_t order() const { return m_Order; }
+
+    void setOrder(size_t pOrder) { m_Order = pOrder; }
+
+    bool hasContent() const;
+
+    const LDSection* getSection() const { return m_pSection; }
+    LDSection*       getSection()       { return m_pSection; }
+
+    void setSection(LDSection* pSection) { m_pSection = pSection; }
+
+    const_iterator begin() const { return m_InputList.begin(); }
+    iterator       begin()       { return m_InputList.begin(); }
+    const_iterator end  () const { return m_InputList.end(); }
+    iterator       end  ()       { return m_InputList.end(); }
+
+    const_reference front() const { return m_InputList.front(); }
+    reference       front()       { return m_InputList.front(); }
+    const_reference back () const { return m_InputList.back(); }
+    reference       back ()       { return m_InputList.back(); }
+
+    size_t size() const { return m_InputList.size(); }
+
+    bool empty() const { return m_InputList.empty(); }
+
+    bool isDiscard() const { return m_bIsDiscard; }
+
+    void append(Input* pInput) { m_InputList.push_back(pInput); }
+
+    const_dot_iterator dot_begin() const { return m_DotAssignments.begin(); }
+    dot_iterator       dot_begin()       { return m_DotAssignments.begin(); }
+    const_dot_iterator dot_end  () const { return m_DotAssignments.end(); }
+    dot_iterator       dot_end  ()       { return m_DotAssignments.end(); }
+
+    const_dot_iterator find_first_explicit_dot() const;
+    dot_iterator       find_first_explicit_dot();
+
+    const_dot_iterator find_last_explicit_dot() const;
+    dot_iterator       find_last_explicit_dot();
+
+    const DotAssignments& dotAssignments() const { return m_DotAssignments; }
+    DotAssignments&       dotAssignments()       { return m_DotAssignments; }
+
+  private:
+    std::string m_Name;
+    OutputSectDesc::Prolog m_Prolog;
+    OutputSectDesc::Epilog m_Epilog;
+    LDSection* m_pSection;
+    size_t m_Order;
+    bool m_bIsDiscard;
+    InputList m_InputList;
+    DotAssignments m_DotAssignments;
+  };
+
+  struct SHOCompare
+  {
+    bool operator()(const Output* LHS, const Output* RHS) const
+    { return LHS->order() < RHS->order(); }
+  };
+
+  typedef std::pair<const Output*, const Input*> const_mapping;
+  typedef std::pair<Output*, Input*> mapping;
+
+  typedef std::vector<Output*> OutputDescList;
+  typedef OutputDescList::const_iterator const_iterator;
+  typedef OutputDescList::iterator iterator;
+  typedef OutputDescList::const_reference const_reference;
+  typedef OutputDescList::reference reference;
+
+  typedef OutputDescList::const_reverse_iterator const_reverse_iterator;
+  typedef OutputDescList::reverse_iterator reverse_iterator;
 
 public:
-  // get the possible output section name based on the mapping table
-  // return NullPair if not found
-  const NamePair& find(const std::string& pFrom) const;
-  NamePair&       find(const std::string& pFrom);
+  ~SectionMap();
 
-  const NamePair& find(const std::string& pFrom, unsigned int pHash) const;
-  NamePair&       find(const std::string& pFrom, unsigned int pHash);
+  const_mapping find(const std::string& pInputFile,
+                     const std::string& pInputSection) const;
+  mapping       find(const std::string& pInputFile,
+                     const std::string& pInputSection);
 
-  // add a mapping from input sub-string to output name.
-  // @param [in]  pFrom  the given input sub-string
-  // @param [in]  pTo    the mapped output string
-  // @param [out] pExist does pFrom exist?
-  NamePair& append(const std::string& pFrom,
-                   const std::string& pTo,
-                   bool& pExist);
+  const_iterator find(const std::string& pOutputSection) const;
+  iterator       find(const std::string& pOutputSection);
 
-  const_iterator begin() const { return m_NamePairList.begin(); }
-  iterator       begin()       { return m_NamePairList.begin(); }
-  const_iterator end  () const { return m_NamePairList.end(); }
-  iterator       end  ()       { return m_NamePairList.end(); }
+  std::pair<mapping, bool>
+  insert(const std::string& pInputSection,
+         const std::string& pOutputSection,
+         InputSectDesc::KeepPolicy pPolicy = InputSectDesc::NoKeep);
+  std::pair<mapping, bool>
+  insert(const InputSectDesc& pInputDesc, const OutputSectDesc& pOutputDesc);
 
-  bool           empty() const { return m_NamePairList.empty(); }
-  size_t         size () const { return m_NamePairList.size(); }
+  bool   empty() const { return m_OutputDescList.empty(); }
+  size_t size () const { return m_OutputDescList.size(); }
 
-  static unsigned int hash(const std::string& pString);
+  const_iterator begin() const { return m_OutputDescList.begin(); }
+  iterator       begin()       { return m_OutputDescList.begin(); }
+  const_iterator end  () const { return m_OutputDescList.end(); }
+  iterator       end  ()       { return m_OutputDescList.end(); }
+
+  const_reference front() const { return m_OutputDescList.front(); }
+  reference       front()       { return m_OutputDescList.front(); }
+  const_reference back () const { return m_OutputDescList.back(); }
+  reference       back ()       { return m_OutputDescList.back(); }
+
+  const_reverse_iterator rbegin() const { return m_OutputDescList.rbegin(); }
+  reverse_iterator       rbegin()       { return m_OutputDescList.rbegin(); }
+  const_reverse_iterator rend  () const { return m_OutputDescList.rend(); }
+  reverse_iterator       rend  ()       { return m_OutputDescList.rend(); }
+
+  iterator insert(iterator pPosition, LDSection* pSection);
+
+  // fixupDotSymbols - ensure the dot assignments are valid
+  void fixupDotSymbols();
 
 private:
-  bool matched(const NamePair& pNamePair,
-               const std::string& pInput,
-               unsigned int pHash) const;
+  bool matched(const Input& pInput,
+               const std::string& pInputFile,
+               const std::string& pInputSection) const;
+
+  bool matched(const WildcardPattern& pPattern, const std::string& pName) const;
+
 private:
-  NamePairList m_NamePairList;
+  OutputDescList m_OutputDescList;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/Script/AssertCmd.h b/include/mcld/Script/AssertCmd.h
new file mode 100644
index 0000000..1e57375
--- /dev/null
+++ b/include/mcld/Script/AssertCmd.h
@@ -0,0 +1,58 @@
+//===- AssertCmd.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_ASSERTCMD_H
+#define MCLD_SCRIPT_ASSERTCMD_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+#include <string>
+
+namespace mcld
+{
+
+class RpnExpr;
+class Module;
+
+/** \class AssertCmd
+ *  \brief This class defines the interfaces to assert command.
+ */
+
+class AssertCmd : public ScriptCommand
+{
+public:
+  AssertCmd(RpnExpr& pRpnExpr, const std::string& pMessage);
+
+  ~AssertCmd();
+
+  AssertCmd& operator=(const AssertCmd& pAssertCmd);
+
+  const RpnExpr& getRpnExpr() const { return m_RpnExpr; }
+  RpnExpr&       getRpnExpr()       { return m_RpnExpr; }
+
+  const std::string& message() const { return m_Message; }
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::ASSERT;
+  }
+
+  void activate(Module& pModule);
+
+private:
+  RpnExpr& m_RpnExpr;
+  std::string m_Message;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Script/Assignment.h b/include/mcld/Script/Assignment.h
new file mode 100644
index 0000000..068735d
--- /dev/null
+++ b/include/mcld/Script/Assignment.h
@@ -0,0 +1,87 @@
+//===- Assignment.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_ASSIGNMENT_H
+#define MCLD_SCRIPT_ASSIGNMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+
+namespace mcld
+{
+
+class Module;
+class RpnExpr;
+class SymOperand;
+class RpnEvaluator;
+
+/** \class Assignment
+ *  \brief This class defines the interfaces to assignment command.
+ */
+
+class Assignment : public ScriptCommand
+{
+public:
+  enum Level {
+    OUTSIDE_SECTIONS, // outside SECTIONS command
+    OUTPUT_SECTION,   // related to an output section
+    INPUT_SECTION     // related to an input section
+  };
+
+  enum Type {
+    DEFAULT,
+    HIDDEN,
+    PROVIDE,
+    PROVIDE_HIDDEN
+  };
+
+public:
+  Assignment(Level pLevel,
+             Type pType,
+             SymOperand& pSymbol,
+             RpnExpr& pRpnExpr);
+
+  ~Assignment();
+
+  Assignment& operator=(const Assignment& pAssignment);
+
+  Level level() const { return m_Level; }
+
+  Type type() const { return m_Type; }
+
+  const SymOperand& symbol() const { return m_Symbol; }
+  SymOperand&       symbol()       { return m_Symbol; }
+
+  const RpnExpr& getRpnExpr() const { return m_RpnExpr; }
+  RpnExpr&       getRpnExpr()       { return m_RpnExpr; }
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::ASSIGNMENT;
+  }
+
+  void activate(Module& pModule);
+
+  /// assign - evaluate the rhs and assign the result to lhs.
+  bool assign(RpnEvaluator& pEvaluator);
+
+private:
+  Level m_Level;
+  Type m_Type;
+  SymOperand& m_Symbol;
+  RpnExpr& m_RpnExpr;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/BinaryOp.h b/include/mcld/Script/BinaryOp.h
new file mode 100644
index 0000000..884c0c1
--- /dev/null
+++ b/include/mcld/Script/BinaryOp.h
@@ -0,0 +1,135 @@
+//===- BinaryOp.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_BINARYOP_H
+#define MCLD_SCRIPT_BINARYOP_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/Operator.h>
+#include <cstddef>
+
+namespace mcld
+{
+
+class Operand;
+class IntOperand;
+class Module;
+class TargetLDBackend;
+
+/** \class BinaryOP
+ *  \brief This class defines the interfaces to an binary operator token.
+ */
+
+template<Operator::Type TYPE>
+class BinaryOp : public Operator
+{
+private:
+  friend class Operator;
+
+  BinaryOp()
+    : Operator(Operator::BINARY, TYPE), m_Size(0)
+  {
+    m_pOperand[0] = m_pOperand[1] = NULL;
+  }
+
+public:
+  ~BinaryOp()
+  {}
+
+  IntOperand* eval(const Module& pModule, const TargetLDBackend& pBackend);
+
+  void appendOperand(Operand* pOperand)
+  {
+    m_pOperand[m_Size++] = pOperand;
+    if (m_Size == 2)
+      m_Size = 0;
+  }
+
+private:
+  size_t m_Size;
+  Operand* m_pOperand[2];
+};
+
+template<>
+IntOperand* BinaryOp<Operator::MUL>::eval(const Module&,
+                                          const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::DIV>::eval(const Module&,
+                                          const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::MOD>::eval(const Module&,
+                                          const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::ADD>::eval(const Module&,
+                                          const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::SUB>::eval(const Module&,
+                                          const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::LSHIFT>::eval(const Module&,
+                                             const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::RSHIFT>::eval(const Module&,
+                                             const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::LT>::eval(const Module&,
+                                         const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::LE>::eval(const Module&,
+                                         const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::GT>::eval(const Module&,
+                                         const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::GE>::eval(const Module&,
+                                         const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::EQ>::eval(const Module&,
+                                         const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::NE>::eval(const Module&,
+                                         const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::BITWISE_AND>::eval(const Module&,
+                                                  const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::BITWISE_XOR>::eval(const Module&,
+                                                  const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::BITWISE_OR>::eval(const Module&,
+                                                 const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::LOGICAL_AND>::eval(const Module&,
+                                                  const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::LOGICAL_OR>::eval(const Module&,
+                                                 const TargetLDBackend&);
+
+template<>
+IntOperand* BinaryOp<Operator::ALIGN>::eval(const Module&,
+                                            const TargetLDBackend&);
+template<>
+IntOperand*
+BinaryOp<Operator::DATA_SEGMENT_RELRO_END>::eval(const Module&,
+                                                 const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::MAX>::eval(const Module&,
+                                          const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::MIN>::eval(const Module&,
+                                          const TargetLDBackend&);
+template<>
+IntOperand* BinaryOp<Operator::SEGMENT_START>::eval(const Module&,
+                                                    const TargetLDBackend&);
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/EntryCmd.h b/include/mcld/Script/EntryCmd.h
new file mode 100644
index 0000000..acbdd10
--- /dev/null
+++ b/include/mcld/Script/EntryCmd.h
@@ -0,0 +1,49 @@
+//===- EntryCmd.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_ENTRYCMD_H
+#define MCLD_SCRIPT_ENTRYCMD_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+#include <string>
+
+namespace mcld
+{
+
+class Module;
+
+/** \class EntryCmd
+ *  \brief This class defines the interfaces to Entry command.
+ */
+
+class EntryCmd : public ScriptCommand
+{
+public:
+  EntryCmd(const std::string& pEntry);
+  ~EntryCmd();
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::ENTRY;
+  }
+
+  void activate(Module& pModule);
+
+private:
+  std::string m_Entry;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/ExprToken.h b/include/mcld/Script/ExprToken.h
new file mode 100644
index 0000000..be248d5
--- /dev/null
+++ b/include/mcld/Script/ExprToken.h
@@ -0,0 +1,50 @@
+//===- ExprToken.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_EXPRTOKEN_H
+#define MCLD_SCRIPT_EXPRTOKEN_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class ExprToken
+ *  \brief This class defines the interfaces to an expression token.
+ */
+
+class ExprToken
+{
+public:
+  enum Kind {
+    OPERATOR,
+    OPERAND
+  };
+
+protected:
+  ExprToken(Kind pKind)
+    : m_Kind(pKind)
+  {}
+
+public:
+  virtual ~ExprToken()
+  {}
+
+  virtual void dump() const = 0;
+
+  Kind kind() const { return m_Kind; }
+
+private:
+  Kind m_Kind;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/FileToken.h b/include/mcld/Script/FileToken.h
new file mode 100644
index 0000000..92faab4
--- /dev/null
+++ b/include/mcld/Script/FileToken.h
@@ -0,0 +1,50 @@
+//===- FileToken.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_FILETOKEN_H
+#define MCLD_SCRIPT_FILETOKEN_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/InputToken.h>
+#include <mcld/Support/Allocators.h>
+#include <mcld/Config/Config.h>
+
+namespace mcld
+{
+
+/** \class FileToken
+ *  \brief This class defines the interfaces to a filename in INPUT/GROUP
+ *         command.
+ */
+
+class FileToken : public InputToken
+{
+private:
+  friend class Chunk<FileToken, MCLD_SYMBOLS_PER_INPUT>;
+  FileToken();
+  FileToken(const std::string& pName, bool pAsNeeded);
+
+public:
+  ~FileToken();
+
+  static bool classof(const InputToken* pToken)
+  {
+    return pToken->type() == InputToken::File;
+  }
+
+  /* factory method */
+  static FileToken* create(const std::string& pName, bool pAsNeeded);
+  static void destroy(FileToken*& pToken);
+  static void clear();
+};
+
+} // namepsace of mcld
+
+#endif
diff --git a/include/mcld/Script/FlexLexer.h b/include/mcld/Script/FlexLexer.h
new file mode 100644
index 0000000..f09ab20
--- /dev/null
+++ b/include/mcld/Script/FlexLexer.h
@@ -0,0 +1,215 @@
+//===- FlexLexer.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// -*-C++-*-
+// FlexLexer.h -- define interfaces for lexical analyzer classes generated
+// by flex
+
+// Copyright (c) 1993 The Regents of the University of California.
+// All rights reserved.
+//
+// This code is derived from software contributed to Berkeley by
+// Kent Williams and Tom Epperly.
+//
+//  Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions
+//  are met:
+
+//  1. Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//  2. Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+
+//  Neither the name of the University nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+//  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+//  PURPOSE.
+
+// This file defines FlexLexer, an abstract class which specifies the
+// external interface provided to flex C++ lexer objects, and yyFlexLexer,
+// which defines a particular lexer class.
+//
+// If you want to create multiple lexer classes, you use the -P flag
+// to rename each yyFlexLexer to some other xxFlexLexer.  You then
+// include <FlexLexer.h> in your other sources once per lexer class:
+//
+//	#undef yyFlexLexer
+//	#define yyFlexLexer xxFlexLexer
+//	#include <FlexLexer.h>
+//
+//	#undef yyFlexLexer
+//	#define yyFlexLexer zzFlexLexer
+//	#include <FlexLexer.h>
+//	...
+
+#ifndef __FLEX_LEXER_H
+// Never included before - need to define base class.
+#define __FLEX_LEXER_H
+
+#include <iostream>
+#  ifndef FLEX_STD
+#    define FLEX_STD std::
+#  endif
+
+extern "C++" {
+
+struct yy_buffer_state;
+typedef int yy_state_type;
+
+class FlexLexer {
+public:
+	virtual ~FlexLexer()	{ }
+
+	const char* YYText() const	{ return yytext; }
+	int YYLeng()	const	{ return yyleng; }
+
+	virtual void
+		yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
+	virtual struct yy_buffer_state*
+		yy_create_buffer( FLEX_STD istream* s, int size ) = 0;
+	virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
+	virtual void yyrestart( FLEX_STD istream* s ) = 0;
+
+	virtual int yylex() = 0;
+
+	// Call yylex with new input/output sources.
+	int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 )
+		{
+		switch_streams( new_in, new_out );
+		return yylex();
+		}
+
+	// Switch to new input/output streams.  A nil stream pointer
+	// indicates "keep the current one".
+	virtual void switch_streams( FLEX_STD istream* new_in = 0,
+					FLEX_STD ostream* new_out = 0 ) = 0;
+
+	int lineno() const		{ return yylineno; }
+
+	int debug() const		{ return yy_flex_debug; }
+	void set_debug( int flag )	{ yy_flex_debug = flag; }
+
+protected:
+	char* yytext;
+	int yyleng;
+	int yylineno;		// only maintained if you use %option yylineno
+	int yy_flex_debug;	// only has effect with -d or "%option debug"
+};
+
+}
+#endif // FLEXLEXER_H
+
+#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
+// Either this is the first time through (yyFlexLexerOnce not defined),
+// or this is a repeated include to define a different flavor of
+// yyFlexLexer, as discussed in the flex manual.
+#define yyFlexLexerOnce
+
+extern "C++" {
+
+class yyFlexLexer : public FlexLexer {
+public:
+	// arg_yyin and arg_yyout default to the cin and cout, but we
+	// only make that assignment when initializing in yylex().
+	yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 );
+
+	virtual ~yyFlexLexer();
+
+	void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
+	struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size );
+	void yy_delete_buffer( struct yy_buffer_state* b );
+	void yyrestart( FLEX_STD istream* s );
+
+	void yypush_buffer_state( struct yy_buffer_state* new_buffer );
+	void yypop_buffer_state();
+
+	virtual int yylex();
+	virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 );
+	virtual int yywrap();
+
+protected:
+	virtual int LexerInput( char* buf, int max_size );
+	virtual void LexerOutput( const char* buf, int size );
+	virtual void LexerError( const char* msg );
+
+	void yyunput( int c, char* buf_ptr );
+	int yyinput();
+
+	void yy_load_buffer_state();
+	void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s );
+	void yy_flush_buffer( struct yy_buffer_state* b );
+
+	int yy_start_stack_ptr;
+	int yy_start_stack_depth;
+	int* yy_start_stack;
+
+	void yy_push_state( int new_state );
+	void yy_pop_state();
+	int yy_top_state();
+
+	yy_state_type yy_get_previous_state();
+	yy_state_type yy_try_NUL_trans( yy_state_type current_state );
+	int yy_get_next_buffer();
+
+	FLEX_STD istream* yyin;	// input source for default LexerInput
+	FLEX_STD ostream* yyout;	// output sink for default LexerOutput
+
+	// yy_hold_char holds the character lost when yytext is formed.
+	char yy_hold_char;
+
+	// Number of characters read into yy_ch_buf.
+	int yy_n_chars;
+
+	// Points to current character in buffer.
+	char* yy_c_buf_p;
+
+	int yy_init;		// whether we need to initialize
+	int yy_start;		// start state number
+
+	// Flag which is used to allow yywrap()'s to do buffer switches
+	// instead of setting up a fresh yyin.  A bit of a hack ...
+	int yy_did_buffer_switch_on_eof;
+
+
+	size_t yy_buffer_stack_top; /**< index of top of stack. */
+	size_t yy_buffer_stack_max; /**< capacity of stack. */
+	struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */
+	void yyensure_buffer_stack(void);
+
+	// The following are not always needed, but may be depending
+	// on use of certain flex features (like REJECT or yymore()).
+
+	yy_state_type yy_last_accepting_state;
+	char* yy_last_accepting_cpos;
+
+	yy_state_type* yy_state_buf;
+	yy_state_type* yy_state_ptr;
+
+	char* yy_full_match;
+	int* yy_full_state;
+	int yy_full_lp;
+
+	int yy_lp;
+	int yy_looking_for_trail_begin;
+
+	int yy_more_flag;
+	int yy_more_len;
+	int yy_more_offset;
+	int yy_prev_more_offset;
+};
+
+}
+
+#endif // yyFlexLexer || ! yyFlexLexerOnce
+
diff --git a/include/mcld/Script/GroupCmd.h b/include/mcld/Script/GroupCmd.h
new file mode 100644
index 0000000..3006c79
--- /dev/null
+++ b/include/mcld/Script/GroupCmd.h
@@ -0,0 +1,60 @@
+//===- GroupCmd.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_GROUPCMD_H
+#define MCLD_SCRIPT_GROUPCMD_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+
+namespace mcld
+{
+
+class StringList;
+class InputTree;
+class InputBuilder;
+class GroupReader;
+class LinkerConfig;
+
+/** \class GroupCmd
+ *  \brief This class defines the interfaces to Group command.
+ */
+
+class GroupCmd : public ScriptCommand
+{
+public:
+  GroupCmd(StringList& pStringList,
+           InputTree& pInputTree,
+           InputBuilder& pBuilder,
+           GroupReader& m_GroupReader,
+           const LinkerConfig& pConfig);
+  ~GroupCmd();
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::GROUP;
+  }
+
+  void activate(Module& pModule);
+
+private:
+  StringList& m_StringList;
+  InputTree& m_InputTree;
+  InputBuilder& m_Builder;
+  GroupReader& m_GroupReader;
+  const LinkerConfig& m_Config;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/InputSectDesc.h b/include/mcld/Script/InputSectDesc.h
new file mode 100644
index 0000000..e2bbf8d
--- /dev/null
+++ b/include/mcld/Script/InputSectDesc.h
@@ -0,0 +1,105 @@
+//===- InputSectDesc.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_INPUTSECTDESC_H
+#define MCLD_SCRIPT_INPUTSECTDESC_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+#include <mcld/Script/StringList.h>
+#include <cassert>
+
+namespace mcld
+{
+
+class WildcardPattern;
+class OutputSectDesc;
+
+/** \class InputSectDesc
+ *  \brief This class defines the interfaces to input section description.
+ */
+
+class InputSectDesc : public ScriptCommand
+{
+public:
+  enum KeepPolicy {
+    Keep,
+    NoKeep
+  };
+
+  struct Spec {
+    bool hasFile() const { return m_pWildcardFile != NULL; }
+    const WildcardPattern& file() const {
+      assert(hasFile());
+      return *m_pWildcardFile;
+    }
+
+    bool hasExcludeFiles() const {
+      return m_pExcludeFiles != NULL && !m_pExcludeFiles->empty();
+    }
+    const StringList& excludeFiles() const {
+      assert(hasExcludeFiles());
+      return *m_pExcludeFiles;
+    }
+
+    bool hasSections() const {
+      return m_pWildcardSections != NULL && !m_pWildcardSections->empty();
+    }
+    const StringList& sections() const {
+      assert(hasSections());
+      return *m_pWildcardSections;
+    }
+
+    bool operator==(const Spec& pRHS) const {
+      /* FIXME: currently I don't check the real content */
+      if (this == &pRHS)
+        return true;
+      if (m_pWildcardFile != pRHS.m_pWildcardFile)
+        return false;
+      if (m_pExcludeFiles != pRHS.m_pExcludeFiles)
+        return false;
+      if (m_pWildcardSections != pRHS.m_pWildcardSections)
+        return false;
+      return true;
+    }
+
+    WildcardPattern* m_pWildcardFile;
+    StringList* m_pExcludeFiles;
+    StringList* m_pWildcardSections;
+  };
+
+public:
+  InputSectDesc(KeepPolicy pPolicy,
+                const Spec& pSpec,
+                const OutputSectDesc& pOutputDesc);
+  ~InputSectDesc();
+
+  KeepPolicy policy() const { return m_KeepPolicy; }
+
+  const Spec& spec() const { return m_Spec; }
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::INPUT_SECT_DESC;
+  }
+
+  void activate(Module& pModule);
+
+private:
+  KeepPolicy m_KeepPolicy;
+  Spec m_Spec;
+  const OutputSectDesc& m_OutputSectDesc;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Script/InputToken.h b/include/mcld/Script/InputToken.h
new file mode 100644
index 0000000..8d89022
--- /dev/null
+++ b/include/mcld/Script/InputToken.h
@@ -0,0 +1,56 @@
+//===- InputToken.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_INPUTTOKEN_H
+#define MCLD_SCRIPT_INPUTTOKEN_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/StrToken.h>
+
+namespace mcld
+{
+
+/** \class InputToken
+ *  \brief This class defines the interfaces to a file/namespec token.
+ */
+
+class InputToken : public StrToken
+{
+public:
+  enum Type {
+    Unknown,
+    File,
+    NameSpec
+  };
+
+protected:
+  InputToken();
+  InputToken(Type pType, const std::string& pName, bool pAsNeeded);
+
+public:
+  virtual ~InputToken();
+
+  Type type() const { return m_Type; }
+
+  bool asNeeded() const { return m_bAsNeeded; }
+
+  static bool classof(const StrToken* pToken)
+  {
+    return pToken->kind() == StrToken::Input;
+  }
+
+private:
+  Type m_Type;
+  bool m_bAsNeeded;
+};
+
+} // namepsace of mcld
+
+#endif
diff --git a/include/mcld/Script/NameSpec.h b/include/mcld/Script/NameSpec.h
new file mode 100644
index 0000000..96cf95c
--- /dev/null
+++ b/include/mcld/Script/NameSpec.h
@@ -0,0 +1,50 @@
+//===- NameSpec.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_NAMESPEC_H
+#define MCLD_SCRIPT_NAMESPEC_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/InputToken.h>
+#include <mcld/Support/Allocators.h>
+#include <mcld/Config/Config.h>
+
+namespace mcld
+{
+
+/** \class NameSpec
+ *  \brief This class defines the interfaces to a namespec in INPUT/GROUP
+ *         command.
+ */
+
+class NameSpec : public InputToken
+{
+private:
+  friend class Chunk<NameSpec, MCLD_SYMBOLS_PER_INPUT>;
+  NameSpec();
+  NameSpec(const std::string& pName, bool pAsNeeded);
+
+public:
+  ~NameSpec();
+
+  static bool classof(const InputToken* pToken)
+  {
+    return pToken->type() == InputToken::NameSpec;
+  }
+
+  /* factory method */
+  static NameSpec* create(const std::string& pName, bool pAsNeeded);
+  static void destroy(NameSpec*& pToken);
+  static void clear();
+};
+
+} // namepsace of mcld
+
+#endif
diff --git a/include/mcld/Script/NullaryOp.h b/include/mcld/Script/NullaryOp.h
new file mode 100644
index 0000000..95fdc18
--- /dev/null
+++ b/include/mcld/Script/NullaryOp.h
@@ -0,0 +1,65 @@
+//===- NullaryOp.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_NULLOP_H
+#define MCLD_SCRIPT_NULLOP_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/Operator.h>
+#include <cassert>
+
+namespace mcld
+{
+
+class Operand;
+class IntOperand;
+class Module;
+class TargetLDBackend;
+
+/** \class NullaryOp
+ *  \brief This class defines the interfaces to an nullary operator token.
+ */
+
+template<Operator::Type TYPE>
+class NullaryOp : public Operator
+{
+private:
+  friend class Operator;
+
+  NullaryOp()
+    : Operator(Operator::NULLARY, TYPE)
+  {}
+
+public:
+  ~NullaryOp()
+  {}
+
+  IntOperand* eval(const Module& pModule, const TargetLDBackend& pBackend);
+
+  void appendOperand(Operand* pOperand)
+  {
+    assert(0);
+  }
+};
+
+template<>
+IntOperand* NullaryOp<Operator::SIZEOF_HEADERS>::eval(const Module&,
+                                                      const TargetLDBackend&);
+template<>
+IntOperand* NullaryOp<Operator::MAXPAGESIZE>::eval(const Module&,
+                                                   const TargetLDBackend&);
+
+template<>
+IntOperand* NullaryOp<Operator::COMMONPAGESIZE>::eval(const Module&,
+                                                      const TargetLDBackend&);
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Script/Operand.h b/include/mcld/Script/Operand.h
new file mode 100644
index 0000000..403701c
--- /dev/null
+++ b/include/mcld/Script/Operand.h
@@ -0,0 +1,241 @@
+//===- Operand.h ----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_OPERAND_H
+#define MCLD_SCRIPT_OPERAND_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ExprToken.h>
+#include <mcld/Object/SectionMap.h>
+#include <mcld/Support/Allocators.h>
+#include <mcld/Config/Config.h>
+#include <llvm/Support/DataTypes.h>
+#include <string>
+#include <cassert>
+
+namespace mcld
+{
+
+/** \class Operand
+ *  \brief This class defines the interfaces to an operand token.
+ */
+
+class Operand : public ExprToken
+{
+public:
+  enum Type {
+    SYMBOL,
+    INTEGER,
+    SECTION,
+    SECTION_DESC,
+    FRAGMENT
+  };
+
+protected:
+  Operand(Type pType);
+  virtual ~Operand();
+
+public:
+  Type type() const { return m_Type; }
+
+  virtual bool isDot() const { return false; }
+
+  virtual uint64_t value() const = 0;
+
+  static bool classof(const ExprToken* pToken)
+  {
+    return pToken->kind() == ExprToken::OPERAND;
+  }
+
+private:
+  Type m_Type;
+};
+
+/** \class SymOperand
+ *  \brief This class defines the interfaces to a symbol operand.
+ */
+
+class SymOperand : public Operand
+{
+private:
+  friend class Chunk<SymOperand, MCLD_SYMBOLS_PER_INPUT>;
+  SymOperand();
+  SymOperand(const std::string& pName);
+
+public:
+  void dump() const;
+
+  const std::string& name() const { return m_Name; }
+
+  bool isDot() const;
+
+  uint64_t value() const { return m_Value; }
+
+  void setValue(uint64_t pValue) { m_Value = pValue; }
+
+  static bool classof(const Operand* pOperand)
+  {
+    return pOperand->type() == Operand::SYMBOL;
+  }
+
+  /* factory method */
+  static SymOperand* create(const std::string& pName);
+  static void destroy(SymOperand*& pOperand);
+  static void clear();
+
+private:
+  std::string m_Name;
+  uint64_t m_Value;
+};
+
+/** \class IntOperand
+ *  \brief This class defines the interfaces to an integer operand.
+ */
+
+class IntOperand : public Operand
+{
+private:
+  friend class Chunk<IntOperand, MCLD_SYMBOLS_PER_INPUT>;
+  IntOperand();
+  IntOperand(uint64_t pValue);
+
+public:
+  void dump() const;
+
+  uint64_t value() const { return m_Value; }
+
+  void setValue(uint64_t pValue) { m_Value = pValue; }
+
+  static bool classof(const Operand* pOperand)
+  {
+    return pOperand->type() == Operand::INTEGER;
+  }
+
+  /* factory method */
+  static IntOperand* create(uint64_t pValue);
+  static void destroy(IntOperand*& pOperand);
+  static void clear();
+
+private:
+  uint64_t m_Value;
+};
+
+/** \class SectOperand
+ *  \brief This class defines the interfaces to an section name operand.
+ */
+class LDSection;
+
+class SectOperand : public Operand
+{
+private:
+  friend class Chunk<SectOperand, MCLD_SECTIONS_PER_INPUT>;
+  SectOperand();
+  SectOperand(const std::string& pName);
+
+public:
+  void dump() const;
+
+  const std::string& name() const { return m_Name; }
+
+  uint64_t value() const
+  {
+    assert(0);
+    return 0;
+  }
+
+  static bool classof(const Operand* pOperand)
+  {
+    return pOperand->type() == Operand::SECTION;
+  }
+
+  /* factory method */
+  static SectOperand* create(const std::string& pName);
+  static void destroy(SectOperand*& pOperand);
+  static void clear();
+
+private:
+  std::string m_Name;
+};
+
+/** \class SectDescOperand
+ *  \brief This class defines the interfaces to an section name operand.
+ */
+
+class SectDescOperand : public Operand
+{
+private:
+  friend class Chunk<SectDescOperand, MCLD_SECTIONS_PER_INPUT>;
+  SectDescOperand();
+  SectDescOperand(const SectionMap::Output* pOutputDesc);
+
+public:
+  void dump() const;
+
+  const SectionMap::Output* outputDesc() const { return m_pOutputDesc; }
+
+  uint64_t value() const
+  {
+    assert(0);
+    return 0;
+  }
+
+  static bool classof(const Operand* pOperand)
+  {
+    return pOperand->type() == Operand::SECTION_DESC;
+  }
+
+  /* factory method */
+  static SectDescOperand* create(const SectionMap::Output* pOutputDesc);
+  static void destroy(SectDescOperand*& pOperand);
+  static void clear();
+
+private:
+  const SectionMap::Output* m_pOutputDesc;
+};
+
+/** \class FragOperand
+ *  \brief This class defines the interfaces to a fragment operand.
+ */
+
+class Fragment;
+
+class FragOperand : public Operand
+{
+private:
+  friend class Chunk<FragOperand, MCLD_SYMBOLS_PER_INPUT>;
+  FragOperand();
+  FragOperand(Fragment& pFragment);
+
+public:
+  void dump() const;
+
+  const Fragment* frag() const { return m_pFragment; }
+  Fragment*       frag()       { return m_pFragment; }
+
+  uint64_t value() const;
+
+  static bool classof(const Operand* pOperand)
+  {
+    return pOperand->type() == Operand::FRAGMENT;
+  }
+
+  /* factory method */
+  static FragOperand* create(Fragment& pFragment);
+  static void destroy(FragOperand*& pOperand);
+  static void clear();
+
+private:
+  Fragment* m_pFragment;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/Operator.h b/include/mcld/Script/Operator.h
new file mode 100644
index 0000000..1fe8118
--- /dev/null
+++ b/include/mcld/Script/Operator.h
@@ -0,0 +1,231 @@
+//===- Operator.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_OPERATOR_INTERFACE_H
+#define MCLD_SCRIPT_OPERATOR_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ExprToken.h>
+#include <llvm/Support/DataTypes.h>
+
+namespace mcld
+{
+
+class Operand;
+class IntOperand;
+class Module;
+class TargetLDBackend;
+
+/** \class Operator
+ *  \brief This class defines the interfaces to an operator token.
+ */
+
+class Operator : public ExprToken
+{
+public:
+  enum Arity {
+    NULLARY,
+    UNARY,
+    BINARY,
+    TERNARY
+  };
+
+  enum Type {
+    /* arithmetic operator */
+    UNARY_PLUS  = 0,
+    UNARY_MINUS = 1,
+    LOGICAL_NOT = 2,
+    BITWISE_NOT = 3,
+    MUL         = 4,
+    DIV         = 5,
+    MOD         = 6,
+    ADD         = 7,
+    SUB         = 8,
+    LSHIFT      = 9,
+    RSHIFT      = 10,
+    LT          = 11,
+    LE          = 12,
+    GT          = 13,
+    GE          = 14,
+    EQ          = 15,
+    NE          = 16,
+    BITWISE_AND = 17,
+    BITWISE_XOR = 18,
+    BITWISE_OR  = 19,
+    LOGICAL_AND = 20,
+    LOGICAL_OR  = 21,
+    TERNARY_IF  = 22,
+    ASSIGN      = 23,
+    ADD_ASSIGN  = 24,
+    SUB_ASSIGN  = 25,
+    MUL_ASSIGN  = 26,
+    DIV_ASSIGN  = 27,
+    AND_ASSIGN  = 28,
+    OR_ASSIGN   = 29,
+    LS_ASSIGN   = 30,
+    RS_ASSIGN   = 31,
+    /* function */
+    ABSOLUTE               = 32,
+    ADDR                   = 33,
+    ALIGN                  = 34,
+    ALIGNOF                = 35,
+    BLOCK                  = 36,
+    DATA_SEGMENT_ALIGN     = 37,
+    DATA_SEGMENT_END       = 38,
+    DATA_SEGMENT_RELRO_END = 39,
+    DEFINED                = 40,
+    LENGTH                 = 41,
+    LOADADDR               = 42,
+    MAX                    = 43,
+    MIN                    = 44,
+    NEXT                   = 45,
+    ORIGIN                 = 46,
+    SEGMENT_START          = 47,
+    SIZEOF                 = 48,
+    SIZEOF_HEADERS         = 49,
+    MAXPAGESIZE            = 50,
+    COMMONPAGESIZE         = 51
+  };
+
+  static const char* OpNames[];
+
+protected:
+  Operator(Arity pArity, Type pType);
+
+  const IntOperand* result() const { return m_pIntOperand; }
+  IntOperand*       result()       { return m_pIntOperand; }
+
+public:
+  virtual ~Operator();
+
+  Arity arity() const { return m_Arity; }
+
+  Type type() const { return m_Type; }
+
+  virtual void dump() const;
+
+  virtual IntOperand* eval(const Module& pModule,
+                           const TargetLDBackend& pBackend) = 0;
+
+  virtual void appendOperand(Operand* pOperand) = 0;
+
+  static bool classof(const ExprToken* pToken)
+  {
+    return pToken->kind() == ExprToken::OPERATOR;
+  }
+
+  template<Operator::Type TYPE>
+  static Operator& create();
+
+private:
+  Arity m_Arity;
+  Type m_Type;
+  IntOperand* m_pIntOperand;
+};
+
+/* Nullary operator */
+template<>
+Operator& Operator::create<Operator::SIZEOF_HEADERS>();
+template<>
+Operator& Operator::create<Operator::MAXPAGESIZE>();
+template<>
+Operator& Operator::create<Operator::COMMONPAGESIZE>();
+
+/* Unary operator */
+template<>
+Operator& Operator::create<Operator::UNARY_PLUS>();
+template<>
+Operator& Operator::create<Operator::UNARY_MINUS>();
+template<>
+Operator& Operator::create<Operator::LOGICAL_NOT>();
+template<>
+Operator& Operator::create<Operator::BITWISE_NOT>();
+
+template<>
+Operator& Operator::create<Operator::ABSOLUTE>();
+template<>
+Operator& Operator::create<Operator::ADDR>();
+template<>
+Operator& Operator::create<Operator::ALIGNOF>();
+template<>
+Operator& Operator::create<Operator::DATA_SEGMENT_END>();
+template<>
+Operator& Operator::create<Operator::DEFINED>();
+template<>
+Operator& Operator::create<Operator::LENGTH>();
+template<>
+Operator& Operator::create<Operator::LOADADDR>();
+template<>
+Operator& Operator::create<Operator::NEXT>();
+template<>
+Operator& Operator::create<Operator::ORIGIN>();
+template<>
+Operator& Operator::create<Operator::SIZEOF>();
+
+/* Binary operator */
+template<>
+Operator& Operator::create<Operator::MUL>();
+template<>
+Operator& Operator::create<Operator::DIV>();
+template<>
+Operator& Operator::create<Operator::MOD>();
+template<>
+Operator& Operator::create<Operator::ADD>();
+template<>
+Operator& Operator::create<Operator::SUB>();
+template<>
+Operator& Operator::create<Operator::LSHIFT>();
+template<>
+Operator& Operator::create<Operator::RSHIFT>();
+template<>
+Operator& Operator::create<Operator::LT>();
+template<>
+Operator& Operator::create<Operator::LE>();
+template<>
+Operator& Operator::create<Operator::GT>();
+template<>
+Operator& Operator::create<Operator::GE>();
+template<>
+Operator& Operator::create<Operator::EQ>();
+template<>
+Operator& Operator::create<Operator::NE>();
+template<>
+Operator& Operator::create<Operator::BITWISE_AND>();
+template<>
+Operator& Operator::create<Operator::BITWISE_XOR>();
+template<>
+Operator& Operator::create<Operator::BITWISE_OR>();
+template<>
+Operator& Operator::create<Operator::LOGICAL_AND>();
+template<>
+Operator& Operator::create<Operator::LOGICAL_OR>();
+
+template<>
+Operator& Operator::create<Operator::ALIGN>();
+template<>
+Operator& Operator::create<Operator::DATA_SEGMENT_RELRO_END>();
+template<>
+Operator& Operator::create<Operator::MAX>();
+template<>
+Operator& Operator::create<Operator::MIN>();
+template<>
+Operator& Operator::create<Operator::SEGMENT_START>();
+
+/* Ternary operator */
+template<>
+Operator& Operator::create<Operator::TERNARY_IF>();
+
+template<>
+Operator&
+Operator::create<Operator::DATA_SEGMENT_ALIGN>();
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/OutputArchCmd.h b/include/mcld/Script/OutputArchCmd.h
new file mode 100644
index 0000000..51b75cc
--- /dev/null
+++ b/include/mcld/Script/OutputArchCmd.h
@@ -0,0 +1,49 @@
+//===- OutputArchCmd.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_OUTPUTARCHCMD_H
+#define MCLD_SCRIPT_OUTPUTARCHCMD_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+#include <string>
+
+namespace mcld
+{
+
+class Module;
+
+/** \class OutputArchCmd
+ *  \brief This class defines the interfaces to OutputArch command.
+ */
+
+class OutputArchCmd : public ScriptCommand
+{
+public:
+  OutputArchCmd(const std::string& pArch);
+  ~OutputArchCmd();
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::OUTPUT_ARCH;
+  }
+
+  void activate(Module& pModule);
+
+private:
+  std::string m_Arch;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/OutputCmd.h b/include/mcld/Script/OutputCmd.h
new file mode 100644
index 0000000..0a63891
--- /dev/null
+++ b/include/mcld/Script/OutputCmd.h
@@ -0,0 +1,50 @@
+//===- OutputCmd.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_OUTPUTCMD_H
+#define MCLD_SCRIPT_OUTPUTCMD_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+#include <string>
+
+namespace mcld
+{
+
+class Module;
+
+/** \class OutputCmd
+ *  \brief This class defines the interfaces to Output command.
+ */
+
+class OutputCmd : public ScriptCommand
+{
+public:
+  OutputCmd(const std::string& pOutputFile);
+
+  ~OutputCmd();
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::OUTPUT;
+  }
+
+  void activate(Module& pModule);
+
+private:
+  std::string m_OutputFile;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/OutputFormatCmd.h b/include/mcld/Script/OutputFormatCmd.h
new file mode 100644
index 0000000..b716e81
--- /dev/null
+++ b/include/mcld/Script/OutputFormatCmd.h
@@ -0,0 +1,63 @@
+//===- OutputFormatCmd.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_OUTPUTFORMATCMD_H
+#define MCLD_SCRIPT_OUTPUTFORMATCMD_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+#include <string>
+#include <vector>
+
+namespace mcld
+{
+
+class Module;
+
+/** \class OutputFormatCmd
+ *  \brief This class defines the interfaces to OutputFormat command.
+ */
+
+class OutputFormatCmd : public ScriptCommand
+{
+public:
+  typedef std::vector<std::string> FormatList;
+  typedef FormatList::const_iterator const_iterator;
+  typedef FormatList::iterator iterator;
+
+public:
+  OutputFormatCmd(const std::string& pFormat);
+  OutputFormatCmd(const std::string& pDefault,
+                  const std::string& pBig,
+                  const std::string& pLittle);
+  ~OutputFormatCmd();
+
+  const_iterator begin() const { return m_FormatList.begin(); }
+  iterator       begin()       { return m_FormatList.begin(); }
+  const_iterator end()   const { return m_FormatList.end(); }
+  iterator       end()         { return m_FormatList.end(); }
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::OUTPUT_FORMAT;
+  }
+
+  void activate(Module& pModule);
+
+private:
+  FormatList m_FormatList;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/OutputSectDesc.h b/include/mcld/Script/OutputSectDesc.h
new file mode 100644
index 0000000..3c5187b
--- /dev/null
+++ b/include/mcld/Script/OutputSectDesc.h
@@ -0,0 +1,214 @@
+//===- OutputSectDesc.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_OUTPUTSECTDESC_H
+#define MCLD_SCRIPT_OUTPUTSECTDESC_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+#include <vector>
+#include <string>
+#include <cassert>
+
+namespace mcld
+{
+
+class RpnExpr;
+class StringList;
+
+/** \class OutputSectDesc
+ *  \brief This class defines the interfaces to output section description.
+ */
+
+class OutputSectDesc : public ScriptCommand
+{
+public:
+  enum Type {
+    LOAD, // ALLOC
+    NOLOAD,
+    DSECT,
+    COPY,
+    INFO,
+    OVERLAY
+  };
+
+  enum Constraint {
+    NO_CONSTRAINT,
+    ONLY_IF_RO,
+    ONLY_IF_RW
+  };
+
+  struct Prolog {
+    bool hasVMA() const { return m_pVMA != NULL; }
+    const RpnExpr& vma() const {
+      assert(hasVMA());
+      return *m_pVMA;
+    }
+    RpnExpr& vma() {
+      assert(hasVMA());
+      return *m_pVMA;
+    }
+
+    void setType(Type pType) {
+      m_Type = pType;
+    }
+
+    Type type() const { return m_Type; }
+
+    bool hasLMA() const { return m_pLMA != NULL; }
+    const RpnExpr& lma() const {
+      assert(hasLMA());
+      return *m_pLMA;
+    }
+    RpnExpr& lma() {
+      assert(hasLMA());
+      return *m_pLMA;
+    }
+
+    bool hasAlign() const { return m_pAlign != NULL; }
+    const RpnExpr& align() const {
+      assert(hasAlign());
+      return *m_pAlign;
+    }
+
+    bool hasSubAlign() const { return m_pSubAlign != NULL; }
+    const RpnExpr& subAlign() const {
+      assert(hasSubAlign());
+      return *m_pSubAlign;
+    }
+
+    Constraint constraint() const { return m_Constraint; }
+
+    bool operator==(const Prolog& pRHS) const {
+      /* FIXME: currently I don't check the real content */
+      if (this == &pRHS)
+        return true;
+      if (m_pVMA != pRHS.m_pVMA)
+        return false;
+      if (m_Type != pRHS.m_Type)
+        return false;
+      if (m_pLMA!= pRHS.m_pLMA)
+        return false;
+      if (m_pAlign != pRHS.m_pAlign)
+        return false;
+      if (m_pSubAlign != pRHS.m_pSubAlign)
+        return false;
+      if (m_Constraint != pRHS.m_Constraint)
+        return false;
+      return true;
+    }
+
+    RpnExpr* m_pVMA;
+    Type m_Type;
+    RpnExpr* m_pLMA;
+    RpnExpr* m_pAlign;
+    RpnExpr* m_pSubAlign;
+    Constraint m_Constraint;
+  };
+
+  struct Epilog {
+    bool hasRegion() const { return m_pRegion != NULL; }
+    const std::string& region() const {
+      assert(hasRegion());
+      return *m_pRegion;
+    }
+
+    bool hasLMARegion() const { return m_pLMARegion != NULL; }
+    const std::string& lmaRegion() const {
+      assert(hasLMARegion());
+      return *m_pLMARegion;
+    }
+
+    bool hasPhdrs() const { return m_pPhdrs != NULL; }
+    const StringList& phdrs() const {
+      assert(hasPhdrs());
+      return *m_pPhdrs;
+    }
+
+    bool hasFillExp() const { return m_pFillExp != NULL; }
+    const RpnExpr& fillExp() const {
+      assert(hasFillExp());
+      return *m_pFillExp;
+    }
+
+    bool operator==(const Epilog& pRHS) const {
+      /* FIXME: currently I don't check the real content */
+      if (this == &pRHS)
+        return true;
+      if (m_pRegion != pRHS.m_pRegion)
+        return false;
+      if (m_pLMARegion != pRHS.m_pLMARegion)
+        return false;
+      if (m_pPhdrs != pRHS.m_pPhdrs)
+        return false;
+      if (m_pFillExp != pRHS.m_pFillExp)
+        return false;
+      return true;
+    }
+
+    const std::string* m_pRegion;
+    const std::string* m_pLMARegion;
+    StringList* m_pPhdrs;
+    RpnExpr* m_pFillExp;
+  };
+
+  typedef std::vector<ScriptCommand*> OutputSectCmds;
+  typedef OutputSectCmds::const_iterator const_iterator;
+  typedef OutputSectCmds::iterator iterator;
+  typedef OutputSectCmds::const_reference const_reference;
+  typedef OutputSectCmds::reference reference;
+
+public:
+  OutputSectDesc(const std::string& pName, const Prolog& pProlog);
+  ~OutputSectDesc();
+
+  const_iterator  begin() const { return m_OutputSectCmds.begin(); }
+  iterator        begin()       { return m_OutputSectCmds.begin(); }
+  const_iterator  end()   const { return m_OutputSectCmds.end(); }
+  iterator        end()         { return m_OutputSectCmds.end(); }
+
+  const_reference front() const { return m_OutputSectCmds.front(); }
+  reference       front()       { return m_OutputSectCmds.front(); }
+  const_reference back()  const { return m_OutputSectCmds.back(); }
+  reference       back()        { return m_OutputSectCmds.back(); }
+
+  const std::string& name() const { return m_Name; }
+
+  size_t size() const { return m_OutputSectCmds.size(); }
+
+  bool empty() const { return m_OutputSectCmds.empty(); }
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::OUTPUT_SECT_DESC;
+  }
+
+  void activate(Module& pModule);
+
+  void push_back(ScriptCommand* pCommand);
+
+  void setEpilog(const Epilog& pEpilog);
+
+  const Prolog& prolog() const { return m_Prolog; }
+
+  const Epilog& epilog() const { return m_Epilog; }
+
+private:
+  OutputSectCmds m_OutputSectCmds;
+  std::string m_Name;
+  Prolog m_Prolog;
+  Epilog m_Epilog;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Script/RpnEvaluator.h b/include/mcld/Script/RpnEvaluator.h
new file mode 100644
index 0000000..7e35e86
--- /dev/null
+++ b/include/mcld/Script/RpnEvaluator.h
@@ -0,0 +1,36 @@
+//===- RpnEvaluator.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_RPNEVALUATOR_H
+#define MCLD_SCRIPT_RPNEVALUATOR_H
+
+namespace mcld {
+
+class RpnExpr;
+class Module;
+class TargetLDBackend;
+
+/** \class RpnEvaluator
+ *  \brief RpnEvaluator evaluate a rpn expression
+ */
+class RpnEvaluator
+{
+public:
+  RpnEvaluator(const Module& pModule, const TargetLDBackend& pBackend);
+
+  // evaluate a valid expression and set the value in the second parameter
+  bool eval(const RpnExpr& pExpr, uint64_t& pResult);
+
+private:
+  const Module& m_Module;
+  const TargetLDBackend& m_Backend;
+};
+
+} // mcld
+
+#endif
diff --git a/include/mcld/Script/RpnExpr.h b/include/mcld/Script/RpnExpr.h
new file mode 100644
index 0000000..96b11e9
--- /dev/null
+++ b/include/mcld/Script/RpnExpr.h
@@ -0,0 +1,81 @@
+//===- RPNExpr.h ----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_RPNEXPR_H
+#define MCLD_SCRIPT_RPNEXPR_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Support/Allocators.h>
+#include <mcld/Config/Config.h>
+#include <mcld/Object/SectionMap.h>
+#include <vector>
+
+namespace mcld
+{
+
+class ExprToken;
+class Fragment;
+
+/** \class RpnExpr
+ *  \brief This class defines the interfaces to a rpn expression.
+ */
+
+class RpnExpr
+{
+public:
+  typedef std::vector<ExprToken*> TokenQueue;
+  typedef TokenQueue::const_iterator const_iterator;
+  typedef TokenQueue::iterator iterator;
+
+private:
+  friend class Chunk<RpnExpr, MCLD_SYMBOLS_PER_INPUT>;
+  RpnExpr();
+
+public:
+  ~RpnExpr();
+
+  const_iterator begin() const { return m_TokenQueue.begin(); }
+  iterator       begin()       { return m_TokenQueue.begin(); }
+  const_iterator end()   const { return m_TokenQueue.end(); }
+  iterator       end()         { return m_TokenQueue.end(); }
+
+  size_t size() const { return m_TokenQueue.size(); }
+
+  bool empty() const { return m_TokenQueue.empty(); }
+
+  bool hasDot() const;
+
+  void dump() const;
+
+  void push_back(ExprToken* pToken);
+
+  iterator insert(iterator pPosition, ExprToken* pToken);
+
+  void erase(iterator pPosition);
+
+  /* factory methods */
+  static RpnExpr* create();
+  static void destroy(RpnExpr*& pRpnExpr);
+  static void clear();
+
+  // buildHelperExpr - build the helper expr:
+  //                   ADDR ( `output_sect' ) + SIZEOF ( `output_sect' )
+  static RpnExpr* buildHelperExpr(SectionMap::iterator pIter);
+  // buildHelperExpr - build the helper expr: `fragment'
+  static RpnExpr* buildHelperExpr(Fragment& pFrag);
+
+private:
+  TokenQueue m_TokenQueue;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/ScriptCommand.h b/include/mcld/Script/ScriptCommand.h
new file mode 100644
index 0000000..06e07eb
--- /dev/null
+++ b/include/mcld/Script/ScriptCommand.h
@@ -0,0 +1,60 @@
+//===- ScriptCommand.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_COMMAND_H
+#define MCLD_SCRIPT_COMMAND_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld {
+
+class Module;
+
+/** \class ScriptCommand
+ *  \brief This class defines the interfaces to a script command.
+ */
+class ScriptCommand
+{
+public:
+  enum Kind {
+    ENTRY,
+    OUTPUT_FORMAT,
+    GROUP,
+    OUTPUT,
+    SEARCH_DIR,
+    OUTPUT_ARCH,
+    ASSERT,
+    ASSIGNMENT,
+    SECTIONS,
+    OUTPUT_SECT_DESC,
+    INPUT_SECT_DESC
+  };
+
+protected:
+  ScriptCommand(Kind pKind)
+    : m_Kind(pKind)
+  {}
+
+public:
+  virtual ~ScriptCommand() = 0;
+
+  virtual void dump() const = 0;
+
+  virtual void activate(Module&) = 0;
+
+  Kind getKind() const { return m_Kind; }
+
+private:
+  Kind m_Kind;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/ScriptFile.h b/include/mcld/Script/ScriptFile.h
new file mode 100644
index 0000000..03662e3
--- /dev/null
+++ b/include/mcld/Script/ScriptFile.h
@@ -0,0 +1,165 @@
+//===- ScriptFile.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_SCRIPTFILE_H
+#define MCLD_SCRIPT_SCRIPTFILE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/Assignment.h>
+#include <mcld/Script/OutputSectDesc.h>
+#include <mcld/Script/InputSectDesc.h>
+#include <vector>
+#include <string>
+
+namespace mcld
+{
+
+class ScriptCommand;
+class Input;
+class InputTree;
+class InputBuilder;
+class GroupReader;
+class LinkerConfig;
+class RpnExpr;
+class StringList;
+class Module;
+
+/** \class ScriptFile
+ *  \brief This class defines the interfaces to a linker script file.
+ */
+
+class ScriptFile
+{
+public:
+  enum Kind {
+    LDScript,      // -T
+    Expression,    // --defsym
+    VersionScript, // --version-script
+    DynamicList,   // --dynamic-list
+    Unknown
+  };
+
+  typedef std::vector<ScriptCommand*> CommandQueue;
+  typedef CommandQueue::const_iterator const_iterator;
+  typedef CommandQueue::iterator iterator;
+  typedef CommandQueue::const_reference const_reference;
+  typedef CommandQueue::reference reference;
+
+public:
+  ScriptFile(Kind pKind, Input& pInput, InputBuilder& pBuilder);
+  ~ScriptFile();
+
+  const_iterator  begin() const { return m_CommandQueue.begin(); }
+  iterator        begin()       { return m_CommandQueue.begin(); }
+  const_iterator  end()   const { return m_CommandQueue.end(); }
+  iterator        end()         { return m_CommandQueue.end(); }
+
+  const_reference front() const { return m_CommandQueue.front(); }
+  reference       front()       { return m_CommandQueue.front(); }
+  const_reference back()  const { return m_CommandQueue.back(); }
+  reference       back()        { return m_CommandQueue.back(); }
+
+  const Input& input() const { return m_Input; }
+  Input&       input()       { return m_Input; }
+
+  size_t size() const { return m_CommandQueue.size(); }
+
+  Kind getKind() const { return m_Kind; }
+
+  const InputTree& inputs() const { return *m_pInputTree; }
+  InputTree&       inputs()       { return *m_pInputTree; }
+
+  const std::string& name() const { return m_Name; }
+  std::string&       name()       { return m_Name; }
+
+  void dump() const;
+  void activate(Module& pModule);
+
+  /// ENTRY(symbol)
+  void addEntryPoint(const std::string& pSymbol);
+
+  /// OUTPUT_FORMAT(bfdname)
+  /// OUTPUT_FORMAT(default, big, little)
+  void addOutputFormatCmd(const std::string& pFormat);
+  void addOutputFormatCmd(const std::string& pDefault,
+                          const std::string& pBig,
+                          const std::string& pLittle);
+
+  /// GROUP(file, file, ...)
+  /// GROUP(file file ...)
+  void addGroupCmd(StringList& pStringList,
+                   GroupReader& pGroupReader,
+                   const LinkerConfig& pConfig);
+
+  /// OUTPUT(filename)
+  void addOutputCmd(const std::string& pFileName);
+
+  /// SEARCH_DIR(path)
+  void addSearchDirCmd(const std::string& pPath);
+
+  /// OUTPUT_ARCH(bfdarch)
+  void addOutputArchCmd(const std::string& pArch);
+
+  /// ASSERT(exp, message)
+  void addAssertCmd(RpnExpr& pRpnExpr, const std::string& pMessage);
+
+  /// assignment
+  void addAssignment(const std::string& pSymbol,
+                     RpnExpr& pRpnExpr,
+                     Assignment::Type pType = Assignment::DEFAULT);
+
+  bool hasSectionsCmd() const;
+
+  void enterSectionsCmd();
+
+  void leaveSectionsCmd();
+
+  void enterOutputSectDesc(const std::string& pName,
+                           const OutputSectDesc::Prolog& pProlog);
+
+  void leaveOutputSectDesc(const OutputSectDesc::Epilog& pEpilog);
+
+  void addInputSectDesc(InputSectDesc::KeepPolicy pPolicy,
+                        const InputSectDesc::Spec& pSpec);
+
+  RpnExpr* createRpnExpr();
+  const RpnExpr* getCurrentRpnExpr() const { return m_pRpnExpr; }
+  RpnExpr*       getCurrentRpnExpr()       { return m_pRpnExpr; }
+
+  StringList* createStringList();
+  const StringList* getCurrentStringList() const { return m_pStringList; }
+  StringList*       getCurrentStringList()       { return m_pStringList; }
+
+  void setAsNeeded(bool pEnable = true);
+  bool asNeeded() const { return m_bAsNeeded; }
+
+  static const std::string& createParserStr(const char* pText, size_t pLength);
+
+  static void clearParserStrPool();
+
+private:
+  Kind m_Kind;
+  Input& m_Input;
+  std::string m_Name;
+  InputTree* m_pInputTree;
+  InputBuilder& m_Builder;
+  CommandQueue m_CommandQueue;
+  bool m_bHasSectionsCmd;
+  bool m_bInSectionsCmd;
+  bool m_bInOutputSectDesc;
+  RpnExpr* m_pRpnExpr;
+  StringList* m_pStringList;
+  bool m_bAsNeeded;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/ScriptReader.h b/include/mcld/Script/ScriptReader.h
new file mode 100644
index 0000000..14a667f
--- /dev/null
+++ b/include/mcld/Script/ScriptReader.h
@@ -0,0 +1,49 @@
+//===- ScriptReader.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_SCRIPTREADER_H
+#define MCLD_SCRIPT_SCRIPTREADER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/LDReader.h>
+
+namespace mcld {
+
+class Module;
+class ScriptFile;
+class Input;
+class GroupReader;
+class LinkerConfig;
+class LinkerScript;
+class TargetLDBackend;
+
+class ScriptReader : public LDReader
+{
+public:
+  ScriptReader(GroupReader& pGroupReader);
+
+  ~ScriptReader();
+
+  /// readScript
+  bool readScript(const LinkerConfig& pConfig, ScriptFile& pScriptFile);
+
+  /// isMyFormat
+  bool isMyFormat(Input& pInput, bool &pContinue) const;
+
+  GroupReader& getGroupReader() { return m_GroupReader; }
+
+private:
+  GroupReader& m_GroupReader;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/ScriptScanner.h b/include/mcld/Script/ScriptScanner.h
new file mode 100644
index 0000000..43897e5
--- /dev/null
+++ b/include/mcld/Script/ScriptScanner.h
@@ -0,0 +1,62 @@
+//===- ScriptScanner.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_SCRIPTSCANNER_H
+#define MCLD_SCRIPT_SCRIPTSCANNER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#ifndef __FLEX_LEXER_H
+#include "FlexLexer.h"
+#endif
+
+#ifndef YY_DECL
+#define YY_DECL                                                       \
+  mcld::ScriptParser::token_type                                      \
+  mcld::ScriptScanner::lex(mcld::ScriptParser::semantic_type* yylval, \
+                           mcld::ScriptParser::location_type* yylloc, \
+                           const mcld::ScriptFile& pScriptFile)
+#endif
+
+#include <mcld/Script/ScriptFile.h>
+#include "ScriptParser.h"
+#include <stack>
+
+namespace mcld {
+
+/** \class ScriptScanner
+ *
+ */
+class ScriptScanner : public yyFlexLexer
+{
+public:
+  ScriptScanner(std::istream* yyin = NULL, std::ostream* yyout = NULL);
+
+  virtual ~ScriptScanner();
+
+  virtual ScriptParser::token_type lex(ScriptParser::semantic_type* yylval,
+                                       ScriptParser::location_type* yylloc,
+                                       const ScriptFile& pScriptFile);
+
+  void setLexState(ScriptFile::Kind pKind);
+
+  void popLexState();
+
+private:
+  void enterComments(ScriptParser::location_type& pLocation);
+
+private:
+  ScriptFile::Kind m_Kind;
+  std::stack<ScriptFile::Kind> m_StateStack;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/SearchDirCmd.h b/include/mcld/Script/SearchDirCmd.h
new file mode 100644
index 0000000..f695a76
--- /dev/null
+++ b/include/mcld/Script/SearchDirCmd.h
@@ -0,0 +1,49 @@
+//===- SearchDirCmd.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_SEARCHDIRCMD_H
+#define MCLD_SCRIPT_SEARCHDIRCMD_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+#include <string>
+
+namespace mcld
+{
+
+class Module;
+
+/** \class SearchDirCmd
+ *  \brief This class defines the interfaces to SEARCH_DIR command.
+ */
+
+class SearchDirCmd : public ScriptCommand
+{
+public:
+  SearchDirCmd(const std::string& pPath);
+  ~SearchDirCmd();
+
+  void dump() const;
+
+  void activate(Module& pModule);
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::SEARCH_DIR;
+  }
+
+private:
+  std::string m_Path;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/SectionsCmd.h b/include/mcld/Script/SectionsCmd.h
new file mode 100644
index 0000000..afff1b1
--- /dev/null
+++ b/include/mcld/Script/SectionsCmd.h
@@ -0,0 +1,72 @@
+//===- SectionsCmd.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_SECTIONSCMD_H
+#define MCLD_SCRIPT_SECTIONSCMD_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/ScriptCommand.h>
+#include <llvm/Support/DataTypes.h>
+#include <vector>
+
+namespace mcld
+{
+
+class Module;
+
+/** \class SectionsCmd
+ *  \brief This class defines the interfaces to SECTIONS command.
+ */
+
+class SectionsCmd : public ScriptCommand
+{
+public:
+  typedef std::vector<ScriptCommand*> SectionCommands;
+  typedef SectionCommands::const_iterator const_iterator;
+  typedef SectionCommands::iterator iterator;
+  typedef SectionCommands::const_reference const_reference;
+  typedef SectionCommands::reference reference;
+
+public:
+  SectionsCmd();
+  ~SectionsCmd();
+
+  const_iterator  begin() const { return m_SectionCommands.begin(); }
+  iterator        begin()       { return m_SectionCommands.begin(); }
+  const_iterator  end()   const { return m_SectionCommands.end(); }
+  iterator        end()         { return m_SectionCommands.end(); }
+
+  const_reference front() const { return m_SectionCommands.front(); }
+  reference       front()       { return m_SectionCommands.front(); }
+  const_reference back()  const { return m_SectionCommands.back(); }
+  reference       back()        { return m_SectionCommands.back(); }
+
+  size_t size() const { return m_SectionCommands.size(); }
+
+  bool empty() const { return m_SectionCommands.empty(); }
+
+  void dump() const;
+
+  static bool classof(const ScriptCommand* pCmd)
+  {
+    return pCmd->getKind() == ScriptCommand::SECTIONS;
+  }
+
+  void activate(Module& pModule);
+
+  void push_back(ScriptCommand* pCommand);
+
+private:
+  SectionCommands m_SectionCommands;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Script/StrToken.h b/include/mcld/Script/StrToken.h
new file mode 100644
index 0000000..359b0be
--- /dev/null
+++ b/include/mcld/Script/StrToken.h
@@ -0,0 +1,67 @@
+//===- StrToken.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_STRTOKEN_H
+#define MCLD_SCRIPT_STRTOKEN_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Support/Allocators.h>
+#include <mcld/Config/Config.h>
+#include <string>
+
+namespace mcld
+{
+
+/** \class StrToken
+ *  \brief This class defines the interfaces to a element in EXCLUDE_FILE list
+ *         or in Output Section Phdr, or be a base class of other str token.
+ */
+
+class StrToken
+{
+public:
+  enum Kind {
+    Unknown,
+    String,
+    Input,
+    Wildcard
+  };
+
+private:
+  friend class Chunk<StrToken, MCLD_SYMBOLS_PER_INPUT>;
+protected:
+  StrToken();
+  StrToken(Kind pKind, const std::string& pString);
+
+public:
+  virtual ~StrToken();
+
+  Kind kind() const { return m_Kind; }
+
+  const std::string& name() const { return m_Name; }
+
+  static bool classof(const StrToken* pToken)
+  {
+    return pToken->kind() == StrToken::String;
+  }
+
+  /* factory method */
+  static StrToken* create(const std::string& pString);
+  static void destroy(StrToken*& pToken);
+  static void clear();
+
+private:
+  Kind m_Kind;
+  std::string m_Name;
+};
+
+} // namepsace of mcld
+
+#endif
diff --git a/include/mcld/Script/StringList.h b/include/mcld/Script/StringList.h
new file mode 100644
index 0000000..da27e41
--- /dev/null
+++ b/include/mcld/Script/StringList.h
@@ -0,0 +1,72 @@
+//===- StringList.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_STRINGLIST_H
+#define MCLD_SCRIPT_STRINGLIST_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Config/Config.h>
+#include <mcld/Support/Allocators.h>
+#include <vector>
+
+namespace mcld
+{
+
+class StrToken;
+
+/** \class StringList
+ *  \brief This class defines the interfaces to StringList.
+ */
+
+class StringList
+{
+public:
+  typedef std::vector<StrToken*> Tokens;
+  typedef Tokens::const_iterator const_iterator;
+  typedef Tokens::iterator iterator;
+  typedef Tokens::const_reference const_reference;
+  typedef Tokens::reference reference;
+
+private:
+  friend class Chunk<StringList, MCLD_SYMBOLS_PER_INPUT>;
+  StringList();
+
+public:
+  ~StringList();
+
+  const_iterator  begin() const { return m_Tokens.begin(); }
+  iterator        begin()       { return m_Tokens.begin(); }
+  const_iterator  end()   const { return m_Tokens.end(); }
+  iterator        end()         { return m_Tokens.end(); }
+
+  const_reference front() const { return m_Tokens.front(); }
+  reference       front()       { return m_Tokens.front(); }
+  const_reference back()  const { return m_Tokens.back(); }
+  reference       back()        { return m_Tokens.back(); }
+
+  bool empty() const { return m_Tokens.empty(); }
+
+  void push_back(StrToken* pToken);
+
+  void dump() const;
+
+  /* factory methods */
+  static StringList* create();
+  static void destroy(StringList*& pStringList);
+  static void clear();
+
+private:
+  Tokens m_Tokens;
+};
+
+} // namepsace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/TernaryOp.h b/include/mcld/Script/TernaryOp.h
new file mode 100644
index 0000000..0517b4a
--- /dev/null
+++ b/include/mcld/Script/TernaryOp.h
@@ -0,0 +1,71 @@
+//===- TernaryOp.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_TERNARYOP_H
+#define MCLD_SCRIPT_TERNARYOP_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/Operator.h>
+#include <cstddef>
+
+namespace mcld
+{
+
+class Operand;
+class IntOperand;
+class Module;
+class TargetLDBackend;
+
+/** \class TernaryOP
+ *  \brief This class defines the interfaces to an binary operator token.
+ */
+
+template<Operator::Type TYPE>
+class TernaryOp : public Operator
+{
+private:
+  friend class Operator;
+
+  TernaryOp()
+    : Operator(Operator::TERNARY, TYPE)
+  {
+    m_pOperand[0] = m_pOperand[1] = m_pOperand[2] = NULL;
+  }
+
+public:
+  ~TernaryOp()
+  {}
+
+  IntOperand* eval(const Module& pModule, const TargetLDBackend& pBackend);
+
+  void appendOperand(Operand* pOperand)
+  {
+    m_pOperand[m_Size++] = pOperand;
+    if (m_Size == 3)
+      m_Size = 0;
+  }
+
+private:
+  size_t m_Size;
+  Operand* m_pOperand[3];
+};
+
+template<>
+IntOperand* TernaryOp<Operator::TERNARY_IF>::eval(const Module&,
+                                                  const TargetLDBackend&);
+
+template<>
+IntOperand*
+TernaryOp<Operator::DATA_SEGMENT_ALIGN>::eval(const Module&,
+                                              const TargetLDBackend&);
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Script/UnaryOp.h b/include/mcld/Script/UnaryOp.h
new file mode 100644
index 0000000..6b79b3c
--- /dev/null
+++ b/include/mcld/Script/UnaryOp.h
@@ -0,0 +1,102 @@
+//===- UnaryOp.h ----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_UNARYOP_H
+#define MCLD_SCRIPT_UNARYOP_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/Operator.h>
+#include <cstddef>
+
+namespace mcld
+{
+
+class Operand;
+class IntOperand;
+class Module;
+class TargetLDBackend;
+
+/** \class UnaryOp
+ *  \brief This class defines the interfaces to an unary operator token.
+ */
+
+template<Operator::Type TYPE>
+class UnaryOp : public Operator
+{
+private:
+  friend class Operator;
+
+  UnaryOp()
+    : Operator(Operator::UNARY, TYPE), m_pOperand(NULL)
+  {}
+
+public:
+  ~UnaryOp()
+  {}
+
+  IntOperand* eval(const Module& pModule, const TargetLDBackend& pBackend);
+
+  void appendOperand(Operand* pOperand)
+  {
+    m_pOperand = pOperand;
+  }
+
+private:
+  Operand* m_pOperand;
+};
+
+template<>
+IntOperand* UnaryOp<Operator::UNARY_PLUS>::eval(const Module&,
+                                                const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::UNARY_MINUS>::eval(const Module&,
+                                                 const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::LOGICAL_NOT>::eval(const Module&,
+                                                 const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::BITWISE_NOT>::eval(const Module&,
+                                                 const TargetLDBackend&);
+
+template<>
+IntOperand* UnaryOp<Operator::ABSOLUTE>::eval(const Module&,
+                                              const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::ADDR>::eval(const Module&,
+                                          const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::ALIGNOF>::eval(const Module&,
+                                             const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::DATA_SEGMENT_END>::eval(const Module&,
+                                                      const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::DEFINED>::eval(const Module&,
+                                             const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::LENGTH>::eval(const Module&,
+                                            const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::LOADADDR>::eval(const Module&,
+                                              const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::NEXT>::eval(const Module&,
+                                          const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::ORIGIN>::eval(const Module&,
+                                            const TargetLDBackend&);
+template<>
+IntOperand* UnaryOp<Operator::SIZEOF>::eval(const Module&,
+                                            const TargetLDBackend&);
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Script/WildcardPattern.h b/include/mcld/Script/WildcardPattern.h
new file mode 100644
index 0000000..0c91435
--- /dev/null
+++ b/include/mcld/Script/WildcardPattern.h
@@ -0,0 +1,71 @@
+//===- WildcardPattern.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SCRIPT_WILDCARDPATTERN_H
+#define MCLD_SCRIPT_WILDCARDPATTERN_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Script/StrToken.h>
+#include <mcld/Support/Allocators.h>
+#include <mcld/Config/Config.h>
+#include <llvm/ADT/StringRef.h>
+
+namespace mcld
+{
+
+/** \class WildcardPattern
+ *  \brief This class defines the interfaces to Input Section Wildcard Patterns
+ */
+
+class WildcardPattern : public StrToken
+{
+public:
+  enum SortPolicy {
+    SORT_NONE,
+    SORT_BY_NAME,
+    SORT_BY_ALIGNMENT,
+    SORT_BY_NAME_ALIGNMENT,
+    SORT_BY_ALIGNMENT_NAME,
+    SORT_BY_INIT_PRIORITY
+  };
+
+private:
+  friend class Chunk<WildcardPattern, MCLD_SYMBOLS_PER_INPUT>;
+  WildcardPattern();
+  WildcardPattern(const std::string& pPattern, SortPolicy pPolicy);
+
+public:
+  ~WildcardPattern();
+
+  SortPolicy sortPolicy() const { return m_SortPolicy; }
+
+  bool isPrefix() const { return m_bIsPrefix; }
+
+  llvm::StringRef prefix() const;
+
+  static bool classof(const StrToken* pToken)
+  {
+    return pToken->kind() == StrToken::Wildcard;
+  }
+
+  /* factory method */
+  static WildcardPattern* create(const std::string& pPattern,
+                                 SortPolicy pPolicy);
+  static void destroy(WildcardPattern*& pToken);
+  static void clear();
+
+private:
+  SortPolicy m_SortPolicy;
+  bool m_bIsPrefix;
+};
+
+} // namepsace of mcld
+
+#endif
diff --git a/include/mcld/Support/CommandLine.h b/include/mcld/Support/CommandLine.h
index 00907fe..6cb0fae 100644
--- a/include/mcld/Support/CommandLine.h
+++ b/include/mcld/Support/CommandLine.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_COMMANDLINE_H
-#define MCLD_COMMANDLINE_H
+#ifndef MCLD_SUPPORT_COMMANDLINE_H
+#define MCLD_SUPPORT_COMMANDLINE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/DefSymParser.h b/include/mcld/Support/DefSymParser.h
deleted file mode 100644
index a721b48..0000000
--- a/include/mcld/Support/DefSymParser.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- DefSymParser.h -----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_DEFSYM_PARSER_H
-#define MCLD_DEFSYM_PARSER_H
-
-#include <mcld/Module.h>
-#include <llvm/ADT/StringRef.h>
-
-namespace mcld {
-
-/** \class DefSymParser
- *  \brief DefSymParser parses --defsym option.
- */
-class DefSymParser
-{
-public:
-  DefSymParser(const Module& pModule);
-
-  // parse a valid expression and set the value in the second parameter
-  bool parse(llvm::StringRef, uint64_t&);
-
-private:
-  const Module& m_Module;
-};
-
-} // mcld
-
-#endif
diff --git a/include/mcld/Support/Directory.h b/include/mcld/Support/Directory.h
index 66ba118..2bf8f06 100644
--- a/include/mcld/Support/Directory.h
+++ b/include/mcld/Support/Directory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_DIRECTORY_H
-#define MCLD_DIRECTORY_H
+#ifndef MCLD_SUPPORT_DIRECTORY_H
+#define MCLD_SUPPORT_DIRECTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/FileHandle.h b/include/mcld/Support/FileHandle.h
index f9fe73a..9f551b9 100644
--- a/include/mcld/Support/FileHandle.h
+++ b/include/mcld/Support/FileHandle.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_FILE_HANDLE_H
-#define MCLD_FILE_HANDLE_H
+#ifndef MCLD_SUPPORT_FILEHANDLE_H
+#define MCLD_SUPPORT_FILEHANDLE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/FileOutputBuffer.h b/include/mcld/Support/FileOutputBuffer.h
new file mode 100644
index 0000000..a49ffb7
--- /dev/null
+++ b/include/mcld/Support/FileOutputBuffer.h
@@ -0,0 +1,72 @@
+//===- FileOutputBuffer.h -------------------------------------------------===//
+//
+//                     the mclinker project
+//
+// this file is distributed under the university of illinois open source
+// license. see license.txt for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SUPPORT_FILEOUTPUTBUFFER_H
+#define MCLD_SUPPORT_FILEOUTPUTBUFFER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Support/MemoryRegion.h>
+#include <llvm/ADT/OwningPtr.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/DataTypes.h>
+#include <llvm/Support/FileSystem.h>
+#include <llvm/Support/system_error.h>
+
+namespace mcld {
+
+class FileHandle;
+
+/// FileOutputBuffer - This interface is borrowed from llvm bassically, and we
+/// may use ostream to emit output later.
+class FileOutputBuffer {
+public:
+  /// Factory method to create an OutputBuffer object which manages a read/write
+  /// buffer of the specified size. When committed, the buffer will be written
+  /// to the file at the specified path.
+  static llvm::error_code create(FileHandle& pFileHandle,
+                                 size_t pSize,
+                                 llvm::OwningPtr<FileOutputBuffer>& pResult);
+
+  /// Returns a pointer to the start of the buffer.
+  uint8_t* getBufferStart() {
+    return (uint8_t*)m_pRegion->data();
+  }
+
+  /// Returns a pointer to the end of the buffer.
+  uint8_t* getBufferEnd() {
+    return (uint8_t*)m_pRegion->data() + m_pRegion->size();
+  }
+
+  /// Returns size of the buffer.
+  size_t getBufferSize() const {
+    return m_pRegion->size();
+  }
+
+  MemoryRegion request(size_t pOffset, size_t pLength);
+
+  /// Returns path where file will show up if buffer is committed.
+  llvm::StringRef getPath() const;
+
+  ~FileOutputBuffer();
+
+private:
+  FileOutputBuffer(const FileOutputBuffer &);
+  FileOutputBuffer &operator=(const FileOutputBuffer &);
+
+  FileOutputBuffer(llvm::sys::fs::mapped_file_region* pRegion,
+                   FileHandle& pFileHandle);
+
+  llvm::OwningPtr<llvm::sys::fs::mapped_file_region> m_pRegion;
+  FileHandle& m_FileHandle;
+};
+
+} // namespace mcld
+
+#endif
diff --git a/include/mcld/Support/FileSystem.h b/include/mcld/Support/FileSystem.h
index 927346e..e0dddd7 100644
--- a/include/mcld/Support/FileSystem.h
+++ b/include/mcld/Support/FileSystem.h
@@ -11,8 +11,8 @@
 // path class.
 //===----------------------------------------------------------------------===//
 
-#ifndef MCLD_FILE_SYSTEM_H
-#define MCLD_FILE_SYSTEM_H
+#ifndef MCLD_SUPPORT_FILESYSTEM_H
+#define MCLD_SUPPORT_FILESYSTEM_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/GCFactory.h b/include/mcld/Support/GCFactory.h
index 6679f41..9ae8650 100644
--- a/include/mcld/Support/GCFactory.h
+++ b/include/mcld/Support/GCFactory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_GC_FACTORY_H
-#define MCLD_GC_FACTORY_H
+#ifndef MCLD_SUPPORT_GCFACTORY_H
+#define MCLD_SUPPORT_GCFACTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/GCFactoryListTraits.h b/include/mcld/Support/GCFactoryListTraits.h
index 986f6f6..b7d44d3 100644
--- a/include/mcld/Support/GCFactoryListTraits.h
+++ b/include/mcld/Support/GCFactoryListTraits.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_GC_FACTORY_LIST_TRAITS_H
-#define MCLD_GC_FACTORY_LIST_TRAITS_H
+#ifndef MCLD_SUPPORT_GCFACTORYLISTTRAITS_H
+#define MCLD_SUPPORT_GCFACTORYLISTTRAITS_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/HandleToArea.h b/include/mcld/Support/HandleToArea.h
deleted file mode 100644
index 8c24db7..0000000
--- a/include/mcld/Support/HandleToArea.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//===- HandleToArea.h -----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_FILE_HANDLE_TO_MEMORY_AREA_H
-#define MCLD_FILE_HANDLE_TO_MEMORY_AREA_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <mcld/ADT/Uncopyable.h>
-#include <mcld/ADT/TypeTraits.h>
-#include <mcld/ADT/StringHash.h>
-#include <mcld/Support/Path.h>
-#include <mcld/Support/FileHandle.h>
-#include <vector>
-
-namespace mcld {
-
-class MemoryArea;
-
-/** \class HandleToArea
- *
- *  Special double-key associative container. Keys are Path and file handler,
- *  associative value is MemoryArea.
- *
- *  For high performance, HandleToArea is not designed to contain unique
- *  <key, value> pair. The key and value may be duplicated.
- *
- *  Like FileHandle, HandleToArea should neither throw exception nor call
- *  expressive diagnostic.
- */
-class HandleToArea : private Uncopyable
-{
-private:
-  struct Bucket {
-    unsigned int hash_value;
-    FileHandle* handle;
-    MemoryArea* area;
-  };
-
-  // the best data structure is a binary search tree.
-  // However, by the shrinking time-to-market constraint, I used
-  // vector and sequential search here.
-  typedef std::vector<Bucket> HandleToAreaMap;
-
-  typedef hash::StringHash<hash::BKDR> HashFunction;
-
-public:
-  typedef HandleToAreaMap::iterator iterator;
-  typedef HandleToAreaMap::const_iterator const_iterator;
-
-public:
-  struct Result {
-  public:
-    Result(FileHandle* pHandle, MemoryArea* pArea)
-      : handle(pHandle), area(pArea) { }
-
-  public:
-    FileHandle* handle;
-    MemoryArea* area;
-  };
-
-  struct ConstResult {
-  public:
-    ConstResult(const FileHandle* pHandle, const MemoryArea* pArea)
-      : handle(pHandle), area(pArea) { }
-
-  public:
-    const FileHandle* handle;
-    const MemoryArea* area;
-  };
-
-public:
-  bool push_back(FileHandle* pHandle, MemoryArea* pArea);
-
-  bool erase(MemoryArea* pArea);
-
-  bool erase(const sys::fs::Path& pPath);
-
-  Result findFirst(const sys::fs::Path& pPath);
-
-  ConstResult findFirst(const sys::fs::Path& pPath) const;
-
-  iterator begin()
-  { return m_AreaMap.begin(); }
-
-  iterator end()
-  { return m_AreaMap.end(); }
-
-  const_iterator begin() const
-  { return m_AreaMap.begin(); }
-
-  const_iterator end() const
-  { return m_AreaMap.end(); }
-
-  // -----  capacity  ----- //
-  bool empty() const
-  { return m_AreaMap.empty(); }
-
-  size_t size() const
-  { return m_AreaMap.size(); }
-
-  HandleToArea() : m_AreaMap() { }
-
-  ~HandleToArea() { }
-
-private:
-  HandleToAreaMap m_AreaMap;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Support/LEB128.h b/include/mcld/Support/LEB128.h
index 816ed72..e44966a 100644
--- a/include/mcld/Support/LEB128.h
+++ b/include/mcld/Support/LEB128.h
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef MCLD_LEB128_H
-#define MCLD_LEB128_H
+#ifndef MCLD_SUPPORT_LEB128_H
+#define MCLD_SUPPORT_LEB128_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/MemoryArea.h b/include/mcld/Support/MemoryArea.h
index d3ae9b7..18ea985 100644
--- a/include/mcld/Support/MemoryArea.h
+++ b/include/mcld/Support/MemoryArea.h
@@ -6,43 +6,22 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_MEMORY_AREA_H
-#define MCLD_SUPPORT_MEMORY_AREA_H
+#ifndef MCLD_SUPPORT_MEMORYAREA_H
+#define MCLD_SUPPORT_MEMORYAREA_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
 #include <mcld/ADT/Uncopyable.h>
-#include <cstddef>
-#include <map>
 
-#if defined(ENABLE_UNITTEST)
-namespace mcldtest {
-  class MemoryAreaTest;
-} // namespace of mcldtest
-#endif
+#include <llvm/ADT/OwningPtr.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/MemoryBuffer.h>
 
 namespace mcld {
 
-class Space;
-class FileHandle;
-class MemoryRegion;
-
 /** \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.
+ *  \brief MemoryArea is used to manage input read-only memory space.
  */
 class MemoryArea : private Uncopyable
 {
@@ -52,72 +31,22 @@
   // If the given file handler is read-only, client can not request a region
   // that out of the file size.
   // @param pFileHandle - file handler
-  explicit MemoryArea(FileHandle& pFileHandle);
+  explicit MemoryArea(llvm::StringRef pFilename);
 
-  // constructor by set universal space.
-  // Client can not request a region that out of the universal space.
-  // @param pUniverse - file handler
-  explicit MemoryArea(Space& pUniverse);
-
-  // destructor
-  ~MemoryArea();
+  explicit MemoryArea(const char* pMemBuffer, size_t pSize);
 
   // 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);
+  llvm::StringRef request(size_t pOffset, size_t pLength);
 
-  // release - release a MemoryRegion.
-  // release a MemoryRegion does not cause
-  void release(MemoryRegion* pRegion);
-
-  // clear - release all memory regions.
-  void clear();
-
-  const FileHandle* handler() const { return m_pFileHandle; }
-  FileHandle*       handler()       { return m_pFileHandle; }
-
-  bool hasHandler() const { return (NULL != m_pFileHandle); }
-
-  // -----  space list methods  ----- //
-  Space* find(size_t pOffset, size_t pLength);
-
-  const Space* find(size_t pOffset, size_t pLength) const;
+  size_t size() const;
 
 private:
-  class Key {
-  public:
-    Key(size_t pOffset, size_t pLength)
-    : m_Offset(pOffset), m_Length(pLength)
-    { }
-
-    size_t offset() const { return m_Offset; }
-
-    size_t length() const { return m_Length; }
-
-    struct Compare {
-      bool operator()(const Key& KEY1, const Key& KEY2) const
-      {
-        return KEY1.offset() + KEY1.length() < KEY2.offset() ||
-               (KEY1.offset() < KEY2.offset() &&
-                (KEY1.offset() + KEY1.length() < KEY2.offset() + KEY2.length()));
-      }
-    };
-
-  private:
-    size_t m_Offset;
-    size_t m_Length;
-  };
-
-  typedef std::multimap<Key, Space*, Key::Compare> SpaceMapType;
-
-private:
-  SpaceMapType m_SpaceMap;
-  FileHandle* m_pFileHandle;
+  llvm::OwningPtr<llvm::MemoryBuffer> m_pMemoryBuffer;
 };
 
 } // namespace of mcld
 
 #endif
-
diff --git a/include/mcld/Support/MemoryAreaFactory.h b/include/mcld/Support/MemoryAreaFactory.h
index b28f096..302fbd1 100644
--- a/include/mcld/Support/MemoryAreaFactory.h
+++ b/include/mcld/Support/MemoryAreaFactory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_MEMORY_AREA_FACTORY_H
-#define MCLD_SUPPORT_MEMORY_AREA_FACTORY_H
+#ifndef MCLD_SUPPORT_MEMORYAREAFACTORY_H
+#define MCLD_SUPPORT_MEMORYAREAFACTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -15,7 +15,7 @@
 #include <mcld/Support/MemoryArea.h>
 #include <mcld/Support/Path.h>
 #include <mcld/Support/FileHandle.h>
-#include <mcld/Support/HandleToArea.h>
+#include <llvm/ADT/StringMap.h>
 
 namespace mcld
 {
@@ -63,12 +63,10 @@
   MemoryArea* produce(int pFD, FileHandle::OpenMode pMode);
 
   void destruct(MemoryArea* pArea);
-
 private:
-  HandleToArea m_HandleToArea;
+  llvm::StringMap<MemoryArea*> m_AreaMap;
 };
 
 } // namespace of mcld
 
 #endif
-
diff --git a/include/mcld/Support/MemoryRegion.h b/include/mcld/Support/MemoryRegion.h
index 0984873..0d18f59 100644
--- a/include/mcld/Support/MemoryRegion.h
+++ b/include/mcld/Support/MemoryRegion.h
@@ -6,112 +6,24 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef LD_MEMORY_REGION_H
-#define LD_MEMORY_REGION_H
+#ifndef MCLD_SUPPORT_MEMORYREGION_H
+#define MCLD_SUPPORT_MEMORYREGION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
-#include <mcld/Config/Config.h>
-#include <mcld/ADT/Uncopyable.h>
-#include <mcld/Support/Allocators.h>
-#include <mcld/Support/Space.h>
+#include <mcld/ADT/TypeTraits.h>
+#include <llvm/ADT/ArrayRef.h>
+#include <llvm/Support/DataTypes.h>
 
 namespace mcld {
 
-class MemoryArea;
+typedef NonConstTraits<uint8_t>::pointer Address;
+typedef ConstTraits<uint8_t>::pointer ConstAddress;
 
-/** \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 Chunk<MemoryRegion, MCLD_REGION_CHUNK_SIZE>;
-friend class RegionFactory;
-friend class MemoryArea;
+typedef llvm::ArrayRef<uint8_t> ConstMemoryRegion;
+typedef llvm::MutableArrayRef<uint8_t> MemoryRegion;
 
-public:
-  typedef Space::Address Address;
-  typedef Space::ConstAddress ConstAddress;
-
-private:
-  MemoryRegion();
-
-  MemoryRegion(const Address pVMAStart, size_t pSize);
-
-  ~MemoryRegion();
-
-  void setParent(Space& pSpace) { m_pParent = &pSpace; }
-
-public:
-  /// Create - To wrap a piece of memory and to create a new region.
-  /// This function wraps a piece of memory and to create a new region. Region
-  /// is just a wraper, it is not responsible for deallocate the given memory.
-  ///
-  /// @param pStart [in] The start address of a piece of memory
-  /// @param pSize  [in] The size of the given memory
-  static MemoryRegion* Create(void* pStart, size_t pSize);
-
-  /// Create - To wrap a piece of memory and to create a new region.
-  /// This function wraps a piece of memory and to create a new region. Region
-  /// is just a wraper, it is not responsible for deallocate the given memory.
-  ///
-  /// If a wrapped memory comes from a Space, then we say the space is the
-  /// parent of the region. pSpace is a memory counting container. It remembers
-  /// the number of regions in it. A space which has no region will be removed
-  /// quickly.
-  ///
-  /// The wrapped memory will be deallocated by Space when the space has no
-  /// region used it.
-  ///
-  /// @param pStart [in] The start address of a piece of memory
-  /// @param pSize  [in] The size of the given memory
-  /// @param pSpace [in] The parent space.
-  static MemoryRegion* Create(void* pStart, size_t pSize, Space& pSpace);
-
-  /// Destroy - To destroy the region
-  /// If the region has a parent space, it will be also remove from the space.
-  ///
-  /// @param pRegion [in, out] pRegion is set to NULL if the destruction is
-  /// success.
-  static void Destroy(MemoryRegion*& pRegion);
-
-  const Space* parent() const { return m_pParent; }
-  Space*       parent()       { return m_pParent; }
-
-  bool hasParent() const { return (NULL != m_pParent); }
-
-  ConstAddress start() const { return m_VMAStart; }
-  Address      start()       { return m_VMAStart; }
-
-  ConstAddress end() const { return m_VMAStart+m_Length; }
-  Address      end()       { return m_VMAStart+m_Length; }
-
-  size_t size() const { return m_Length; }
-
-  ConstAddress getBuffer(size_t pOffset = 0) const
-  { return m_VMAStart+pOffset; }
- 
-  Address getBuffer(size_t pOffset = 0)
-  { return m_VMAStart+pOffset; }
-
-private:
-  Space* m_pParent;
-  Address m_VMAStart;
-  size_t m_Length;
-};
-
-} // namespace of mcld
+} // namespace mcld
 
 #endif
-
diff --git a/include/mcld/Support/MsgHandling.h b/include/mcld/Support/MsgHandling.h
index d00132c..778ec68 100644
--- a/include/mcld/Support/MsgHandling.h
+++ b/include/mcld/Support/MsgHandling.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_MESSAGE_HANDLING_H
-#define MCLD_MESSAGE_HANDLING_H
+#ifndef MCLD_SUPPORT_MSGHANDLING_H
+#define MCLD_SUPPORT_MSGHANDLING_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/Path.h b/include/mcld/Support/Path.h
index 13e8ddb..fe7914e 100644
--- a/include/mcld/Support/Path.h
+++ b/include/mcld/Support/Path.h
@@ -10,8 +10,8 @@
 // filesystem (v3), but modified to remove exception handling and the
 // path class.
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_PATH_H
-#define MCLD_PATH_H
+#ifndef MCLD_SUPPORT_PATH_H
+#define MCLD_SUPPORT_PATH_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/PathCache.h b/include/mcld/Support/PathCache.h
index 50c6984..37857dc 100644
--- a/include/mcld/Support/PathCache.h
+++ b/include/mcld/Support/PathCache.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_PATHCACHE_H
-#define MCLD_PATHCACHE_H
+#ifndef MCLD_SUPPORT_PATHCACHE_H
+#define MCLD_SUPPORT_PATHCACHE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/RealPath.h b/include/mcld/Support/RealPath.h
index 6c0cd40..0369f25 100644
--- a/include/mcld/Support/RealPath.h
+++ b/include/mcld/Support/RealPath.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_REAL_PATH_H
-#define MCLD_REAL_PATH_H
+#ifndef MCLD_SUPPORT_REALPATH_H
+#define MCLD_SUPPORT_REALPATH_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/RegionFactory.h b/include/mcld/Support/RegionFactory.h
deleted file mode 100644
index fd90186..0000000
--- a/include/mcld/Support/RegionFactory.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===- RegionFactory.h ----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_REGION_FACTORY_H
-#define MCLD_SUPPORT_REGION_FACTORY_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <mcld/Config/Config.h>
-#include <mcld/Support/GCFactory.h>
-#include <mcld/Support/MemoryRegion.h>
-
-namespace mcld {
-
-class MemoryArea;
-
-/** \class RegionFactory
- *  \brief RegionFactory produces and destroys MemoryRegions
- *
- */
-class RegionFactory : public GCFactory<MemoryRegion, MCLD_REGION_CHUNK_SIZE>
-{
-public:
-  typedef GCFactory<MemoryRegion, MCLD_REGION_CHUNK_SIZE> Alloc;
-  typedef MemoryRegion::Address Address;
-  typedef MemoryRegion::ConstAddress ConstAddress;
-
-public:
-  MemoryRegion* produce(Address pVMAStart, size_t pSize);
-
-  void destruct(MemoryRegion* pRegion);
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Support/Space.h b/include/mcld/Support/Space.h
deleted file mode 100644
index cdf69b0..0000000
--- a/include/mcld/Support/Space.h
+++ /dev/null
@@ -1,99 +0,0 @@
-//===- Space.h ------------------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_MEMORY_SPACE_H
-#define MCLD_MEMORY_SPACE_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <llvm/Support/DataTypes.h>
-#include <mcld/ADT/TypeTraits.h>
-
-namespace mcld {
-
-class FileHandle;
-class MemoryRegion;
-
-/** \class Space
- *  \brief Space contains a chunk of memory space that does not overlap with
- *  the other Space.
- *
- */
-class Space
-{
-public:
-  enum Type
-  {
-    ALLOCATED_ARRAY,
-    MMAPED,
-    EXTERNAL,
-    UNALLOCATED
-  };
-
-  typedef NonConstTraits<uint8_t>::pointer Address;
-  typedef ConstTraits<uint8_t>::pointer ConstAddress;
-
-private:
-  Space();
-
-  ~Space();
-
-  Space(Type pType, void* pMemBuffer, size_t pSize);
-
-public:
-  void setStart(size_t pOffset)
-  { m_StartOffset = pOffset; }
-
-  Address memory()
-  { return m_Data; }
-
-  ConstAddress memory() const
-  { return m_Data; }
-
-  size_t start() const
-  { return m_StartOffset; }
-
-  size_t size() const
-  { return m_Size; }
-
-  Type type() const
-  { return m_Type; }
-
-  void addRegion(MemoryRegion& pRegion)
-  { ++m_RegionCount; }
-
-  void removeRegion(MemoryRegion& pRegion)
-  { --m_RegionCount; }
-
-  size_t numOfRegions() const
-  { return m_RegionCount; }
-
-  /// Create - Create a Space from external memory
-  static Space* Create(void* pMemBuffer, size_t pSize);
-
-  /// Create - Create a Space from FileHandler
-  static Space* Create(FileHandle& pHandler, size_t pOffset, size_t pSize);
-
-  static void Destroy(Space*& pSpace);
-  
-  static void Release(Space* pSpace, FileHandle& pHandler);
-
-  static void Sync(Space* pSpace, FileHandle& pHandler);
-
-private:
-  Address m_Data;
-  uint32_t m_StartOffset;
-  uint32_t m_Size;
-  uint16_t m_RegionCount;
-  Type m_Type : 2;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Support/SystemUtils.h b/include/mcld/Support/SystemUtils.h
index 8f8507a..f15fccf 100644
--- a/include/mcld/Support/SystemUtils.h
+++ b/include/mcld/Support/SystemUtils.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_SYSTEM_UTILS_H
-#define MCLD_SYSTEM_UTILS_H
+#ifndef MCLD_SUPPORT_SYSTEMUTILS_H
+#define MCLD_SUPPORT_SYSTEMUTILS_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/Target.h b/include/mcld/Support/Target.h
new file mode 100644
index 0000000..021fc2e
--- /dev/null
+++ b/include/mcld/Support/Target.h
@@ -0,0 +1,105 @@
+//===- Target.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SUPPORT_TARGET_H
+#define MCLD_SUPPORT_TARGET_H
+#include <string>
+#include <list>
+
+namespace llvm {
+class Target;
+class Triple;
+class TargetMachine;
+} // namespace of llvm
+
+namespace mcld {
+
+class MCLDTargetMachine;
+class TargetRegistry;
+class MCLinker;
+class LinkerScript;
+class LinkerConfig;
+class Module;
+class FileHandle;
+class DiagnosticLineInfo;
+class TargetLDBackend;
+
+/** \class Target
+ *  \brief Target collects target specific information
+ */
+class Target
+{
+  friend class mcld::MCLDTargetMachine;
+  friend class mcld::TargetRegistry;
+
+public:
+  typedef unsigned int (*TripleMatchQualityFnTy)(const llvm::Triple& pTriple);
+
+  typedef MCLDTargetMachine *(*TargetMachineCtorTy)(const llvm::Target &,
+                                                    const mcld::Target &,
+                                                    llvm::TargetMachine &,
+                                                    const std::string&);
+
+  typedef MCLinker *(*MCLinkerCtorTy)(const std::string& pTriple,
+                                      LinkerConfig&,
+                                      Module&,
+                                      FileHandle& pFileHandle);
+
+  typedef bool (*EmulationFnTy)(LinkerScript&, LinkerConfig&);
+
+  typedef TargetLDBackend  *(*TargetLDBackendCtorTy)(const LinkerConfig&);
+
+  typedef DiagnosticLineInfo *(*DiagnosticLineInfoCtorTy)(const mcld::Target&,
+                                                          const std::string&);
+
+public:
+  Target();
+
+  /// getName - get the target name
+  const char* name() const { return Name; }
+
+  unsigned int getTripleQuality(const llvm::Triple& pTriple) const;
+
+  /// createTargetMachine - create target-specific TargetMachine
+  MCLDTargetMachine* createTargetMachine(const std::string& pTriple,
+                                         const llvm::Target& pTarget,
+                                         llvm::TargetMachine& pTM) const;
+
+  /// createMCLinker - create target-specific MCLinker
+  MCLinker *createMCLinker(const std::string &pTriple,
+                           LinkerConfig& pConfig,
+                           Module& pModule,
+                           FileHandle& pFileHandle) const;
+
+  /// emulate - given MCLinker default values for the other aspects of the
+  /// target system.
+  bool emulate(LinkerScript& pScript, LinkerConfig& pConfig) const;
+
+  /// createLDBackend - create target-specific LDBackend
+  TargetLDBackend* createLDBackend(const LinkerConfig& pConfig) const;
+
+  /// createDiagnosticLineInfo - create target-specific DiagnosticLineInfo
+  DiagnosticLineInfo* createDiagnosticLineInfo(const mcld::Target& pTarget,
+                                               const std::string& pTriple) const;
+
+private:
+  /// Name - The target name
+  const char* Name;
+
+  TripleMatchQualityFnTy TripleMatchQualityFn;
+  TargetMachineCtorTy TargetMachineCtorFn;
+  MCLinkerCtorTy MCLinkerCtorFn;
+  EmulationFnTy EmulationFn;
+  TargetLDBackendCtorTy TargetLDBackendCtorFn;
+  DiagnosticLineInfoCtorTy DiagnosticLineInfoCtorFn;
+};
+
+} //end namespace mcld
+
+#endif
+
diff --git a/include/mcld/Support/TargetRegistry.h b/include/mcld/Support/TargetRegistry.h
index aabb06d..1ae6245 100644
--- a/include/mcld/Support/TargetRegistry.h
+++ b/include/mcld/Support/TargetRegistry.h
@@ -6,9 +6,11 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TARGET_REGISTRY_H
-#define MCLD_TARGET_REGISTRY_H
-#include <llvm/Support/TargetRegistry.h>
+#ifndef MCLD_SUPPORT_TARGETREGISTRY_H
+#define MCLD_SUPPORT_TARGETREGISTRY_H
+#include <mcld/Support/Target.h>
+#include <llvm/ADT/Triple.h>
+
 #include <string>
 #include <list>
 
@@ -21,122 +23,9 @@
 
 namespace mcld {
 
-class Module;
-class LinkerConfig;
-class LinkerScript;
-class MemoryArea;
-class MCLDTargetMachine;
-class TargetRegistry;
-class MCLinker;
-class TargetLDBackend;
-class AttributeFactory;
-class InputFactory;
-class ContextFactory;
-class DiagnosticLineInfo;
-
-//===----------------------------------------------------------------------===//
-/// Target - mcld::Target is an object adapter of llvm::Target
-//===----------------------------------------------------------------------===//
-class Target
-{
-  friend class mcld::MCLDTargetMachine;
-  friend class mcld::TargetRegistry;
-public:
-  typedef mcld::MCLDTargetMachine *(*TargetMachineCtorTy)(const mcld::Target &,
-                                                          llvm::TargetMachine &,
-                                                          const std::string&);
-
-  typedef MCLinker *(*MCLinkerCtorTy)(const std::string& pTriple,
-                                      LinkerConfig&,
-                                      Module&,
-                                      MemoryArea& pOutput);
-
-  typedef bool (*EmulationFnTy)(LinkerScript&, LinkerConfig&);
-
-  typedef TargetLDBackend  *(*TargetLDBackendCtorTy)(const llvm::Target&,
-                                                     const LinkerConfig&);
-
-  typedef DiagnosticLineInfo *(*DiagnosticLineInfoCtorTy)(const mcld::Target&,
-                                                          const std::string&);
-
-public:
-  Target();
-
-  void setTarget(const llvm::Target& pTarget)
-  { m_pT = &pTarget; }
-
-  mcld::MCLDTargetMachine *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 NULL;
-  }
-
-  /// createMCLinker - create target-specific MCLinker
-  ///
-  /// @return created MCLinker
-  MCLinker *createMCLinker(const std::string &pTriple,
-                           LinkerConfig& pConfig,
-                           Module& pModule,
-                           MemoryArea& pOutput) const {
-    if (!MCLinkerCtorFn)
-      return NULL;
-    return MCLinkerCtorFn(pTriple, pConfig, pModule, pOutput);
-  }
-
-  /// emulate - given MCLinker default values for the other aspects of the
-  /// target system.
-  bool emulate(LinkerScript& pScript, LinkerConfig& pConfig) const {
-    if (!EmulationFn)
-      return false;
-    return EmulationFn(pScript, pConfig);
-  }
-
-  /// createLDBackend - create target-specific LDBackend
-  ///
-  /// @return created TargetLDBackend
-  TargetLDBackend* createLDBackend(const LinkerConfig& pConfig) const
-  {
-    if (!TargetLDBackendCtorFn)
-      return NULL;
-    return TargetLDBackendCtorFn(*get(), pConfig);
-  }
-
-  /// createDiagnosticLineInfo - create target-specific DiagnosticLineInfo
-  DiagnosticLineInfo* createDiagnosticLineInfo(const mcld::Target& pTarget,
-                                               const std::string& pTriple) const
-  {
-    if (!DiagnosticLineInfoCtorFn)
-      return NULL;
-    return DiagnosticLineInfoCtorFn(pTarget, pTriple);
-  }
-
-  const llvm::Target* get() const { return m_pT; }
-
-private:
-  // -----  function pointers  ----- //
-  TargetMachineCtorTy TargetMachineCtorFn;
-  MCLinkerCtorTy MCLinkerCtorFn;
-  EmulationFnTy EmulationFn;
-  TargetLDBackendCtorTy TargetLDBackendCtorFn;
-  DiagnosticLineInfoCtorTy DiagnosticLineInfoCtorFn;
-
-  // -----  adapted llvm::Target  ----- //
-  const llvm::Target* m_pT;
-};
-
-//===----------------------------------------------------------------------===//
-/// TargetRegistry - mcld::TargetRegistry is an object adapter of
-/// llvm::TargetRegistry
-///
+/** \class TargetRegistry
+ *  \brief TargetRegistry is an object adapter of llvm::TargetRegistry
+ */
 class TargetRegistry
 {
 public:
@@ -161,7 +50,9 @@
   /// this is done by initializing all targets at program startup.
   ///
   /// @param T - The target being registered.
-  static void RegisterTarget(mcld::Target &T);
+  static void RegisterTarget(Target& pTarget,
+                             const char* pName,
+                             Target::TripleMatchQualityFnTy pQualityFn);
 
   /// RegisterTargetMachine - Register a TargetMachine implementation for the
   /// given target.
@@ -221,16 +112,23 @@
       T.DiagnosticLineInfoCtorFn = 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
+  /// lookupTarget - Look up MCLinker target
   ///
   /// @param Triple - The Triple string
   /// @param Error  - The returned error message
-  static const mcld::Target *lookupTarget(const std::string &Triple,
+  static const mcld::Target *lookupTarget(const std::string& pTriple,
+                                          std::string& pError);
+
+  /// lookupTarget - Look up MCLinker target by an architecture name
+  /// and a triple. If the architecture name is not empty, then the
+  /// the lookup is done mainly by architecture. Otherwise, the target
+  /// triple is used.
+  ///
+  /// @param pArch   - The architecture name
+  /// @param pTriple - The target triple
+  /// @param pError  - The returned error message
+  static const mcld::Target *lookupTarget(const std::string& pArchName,
+                                          llvm::Triple& pTriple,
                                           std::string &Error);
 };
 
@@ -240,22 +138,27 @@
 /// Target TheFooTarget; // The global target instance.
 ///
 /// extern "C" void MCLDInitializeFooTargetInfo() {
-///   RegisterTarget X(TheFooTarget, "foo", "Foo description");
+///   RegisterTarget<llvm::Foo> X(TheFooTarget, "foo", "Foo description");
 /// }
+template<llvm::Triple::ArchType TargetArchType = llvm::Triple::UnknownArch>
 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;
+public:
+  RegisterTarget(mcld::Target &pTarget, const char* pName) {
+    // if we've registered one, then return immediately.
+    TargetRegistry::iterator target, ie = TargetRegistry::end();
+    for (target = TargetRegistry::begin(); target != ie; ++target) {
+      if (0 == strcmp((*target)->name(), pName))
+        return;
     }
 
-    if (TIter != TEnd)
-      T.setTarget(*TIter);
+    TargetRegistry::RegisterTarget(pTarget, pName, &getTripleMatchQuality);
+  }
 
-    TargetRegistry::RegisterTarget(T);
+  static unsigned int getTripleMatchQuality(const llvm::Triple& pTriple) {
+    if (pTriple.getArch() == TargetArchType)
+      return 20;
+    return 0;
   }
 };
 
@@ -275,10 +178,11 @@
   }
 
 private:
-  static mcld::MCLDTargetMachine *Allocator(const mcld::Target &T,
-                                            llvm::TargetMachine& TM,
-                                            const std::string &Triple) {
-    return new TargetMachineImpl(TM, T, Triple);
+  static MCLDTargetMachine *Allocator(const llvm::Target& pLLVMTarget,
+                                      const mcld::Target& pMCLDTarget,
+                                      llvm::TargetMachine& pTM,
+                                      const std::string& pTriple) {
+    return new TargetMachineImpl(pTM, pLLVMTarget, pMCLDTarget, pTriple);
   }
 };
 
diff --git a/include/mcld/Support/TargetSelect.h b/include/mcld/Support/TargetSelect.h
index 7fcb74a..0b2be2a 100644
--- a/include/mcld/Support/TargetSelect.h
+++ b/include/mcld/Support/TargetSelect.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TARGET_SELECT_H
-#define MCLD_TARGET_SELECT_H
+#ifndef MCLD_SUPPORT_TARGETSELECT_H
+#define MCLD_SUPPORT_TARGETSELECT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/ToolOutputFile.h b/include/mcld/Support/ToolOutputFile.h
index 4dfc4e6..f1186c3 100644
--- a/include/mcld/Support/ToolOutputFile.h
+++ b/include/mcld/Support/ToolOutputFile.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_TOOL_OUTPUT_FILE_H
-#define MCLD_SUPPORT_TOOL_OUTPUT_FILE_H
+#ifndef MCLD_SUPPORT_TOOLOUTPUTFILE_H
+#define MCLD_SUPPORT_TOOLOUTPUTFILE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -23,12 +23,9 @@
 
 class Path;
 class FileHandle;
-class MemoryArea;
-class raw_mem_ostream;
 
 /** \class ToolOutputFile
- *  \brief ToolOutputFile contains a raw_mem_ostream and adds extra new
- *  features:
+ *  \brief ToolOutputFile has the following features:
  *   - The file is automatically deleted if the process is killed.
  *   - The file is automatically deleted when the TooOutputFile object is
  *     destoryed unless the client calls keep().
@@ -36,21 +33,21 @@
 class ToolOutputFile
 {
 public:
-  ToolOutputFile(const std::string& pPath,
+  ToolOutputFile(const sys::fs::Path& pPath,
                  FileHandle::OpenMode pMode,
                  FileHandle::Permission pPermission);
 
   ~ToolOutputFile();
 
-  /// mem_os - Return the contained raw_mem_ostream.
-  raw_mem_ostream &mem_os();
+  /// fd - Retutn the output file handle
+  FileHandle& fd() { return m_FileHandle; }
 
-  /// os - Return the contained formatted_raw_ostream
+  /// os - Return the contained raw_fd_ostream
+  llvm::raw_fd_ostream& os();
+
+  /// formatted_os - Return the contained formatted_raw_ostream
   llvm::formatted_raw_ostream& formatted_os();
 
-  /// memory - Return the contained MemoryArea.
-  MemoryArea& memory();
-
   /// keep - Indicate that the tool's job wrt this output file has been
   /// successful and the file should not be deleted.
   void keep();
@@ -59,7 +56,7 @@
   class CleanupInstaller
   {
   public:
-    explicit CleanupInstaller(const std::string& pPath);
+    explicit CleanupInstaller(const sys::fs::Path& pPath);
 
     ~CleanupInstaller();
 
@@ -67,19 +64,16 @@
     bool Keep;
 
   private:
-    std::string m_Path;
+    sys::fs::Path m_Path;
   }; 
 
 private:
   FileHandle m_FileHandle;
   CleanupInstaller m_Installer;
-  MemoryArea* m_pMemoryArea;
-  raw_mem_ostream* m_pOStream;
-  llvm::formatted_raw_ostream* m_pFOStream;
-
+  llvm::raw_fd_ostream* m_pFdOstream;
+  llvm::formatted_raw_ostream* m_pFormattedOstream;
 };
 
 } // namespace of mcld
 
 #endif
-
diff --git a/include/mcld/Support/UniqueGCFactory.h b/include/mcld/Support/UniqueGCFactory.h
index 3147bab..73c1110 100644
--- a/include/mcld/Support/UniqueGCFactory.h
+++ b/include/mcld/Support/UniqueGCFactory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_UNIQUE_GCFACTORY_H
-#define MCLD_UNIQUE_GCFACTORY_H
+#ifndef MCLD_SUPPORT_UNIQUEGCFACTORY_H
+#define MCLD_SUPPORT_UNIQUEGCFACTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Support/raw_mem_ostream.h b/include/mcld/Support/raw_mem_ostream.h
deleted file mode 100644
index b2db64a..0000000
--- a/include/mcld/Support/raw_mem_ostream.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===- raw_mem_ostream.h --------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_RAW_MEMORY_AREA_OSTREAM_H
-#define MCLD_RAW_MEMORY_AREA_OSTREAM_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <string>
-
-#include <llvm/Support/raw_ostream.h>
-
-namespace mcld {
-
-class MemoryArea;
-
-class raw_mem_ostream : public llvm::raw_ostream
-{
-public:
-  /// constructor - pMemoryArea must be writable.
-  explicit raw_mem_ostream(MemoryArea &pMemoryArea);
-
-  ~raw_mem_ostream();
-
-  MemoryArea& getMemoryArea() {
-    flush();
-    return m_MemoryArea;
-  }
-
-private:
-  /// write_impl - See raw_ostream::write_impl.
-  virtual void write_impl(const char *pPtr, size_t pSize);
-
-  /// current_pos - Return the current position within the stream, not
-  /// counting the bytes currently in the buffer.
-  virtual uint64_t current_pos() const;
-
-private:
-  MemoryArea& m_MemoryArea;
-  uint64_t m_Position;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Support/raw_ostream.h b/include/mcld/Support/raw_ostream.h
index 0e2cc40..6274e49 100644
--- a/include/mcld/Support/raw_ostream.h
+++ b/include/mcld/Support/raw_ostream.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_RAW_OSTREAM_H
-#define MCLD_RAW_OSTREAM_H
+#ifndef MCLD_SUPPORT_RAWOSTREAM_H
+#define MCLD_SUPPORT_RAWOSTREAM_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Target/DarwinLDBackend.h b/include/mcld/Target/DarwinLDBackend.h
index d55055a..9003812 100644
--- a/include/mcld/Target/DarwinLDBackend.h
+++ b/include/mcld/Target/DarwinLDBackend.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef DARWINLDBACKEND_H
-#define DARWINLDBACKEND_H
+#ifndef MCLD_TARGET_DARWINLDBACKEND_H
+#define MCLD_TARGET_DARWINLDBACKEND_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Target/ELFAttribute.h b/include/mcld/Target/ELFAttribute.h
new file mode 100644
index 0000000..7d9d30d
--- /dev/null
+++ b/include/mcld/Target/ELFAttribute.h
@@ -0,0 +1,125 @@
+//===- ELFAttribute.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_ELFATTRIBUTE_H
+#define MCLD_TARGET_ELFATTRIBUTE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/Target/ELFAttributeData.h>
+
+#include <llvm/ADT/SmallVector.h>
+#include <llvm/ADT/StringRef.h>
+
+namespace mcld {
+
+class ELFAttributeData;
+class GNULDBackend;
+class Input;
+class LDSection;
+class LinkerConfig;
+
+/** \class ELFAttribute
+ *  \brief ELFAttribute is the attribute section in an ELF file.
+ */
+class ELFAttribute
+{
+public:
+  // ARM [ABI-addenda], 2.2.3.
+  static const char   FormatVersion = 'A';
+  static const size_t FormatVersionFieldSize = sizeof(FormatVersion); // a byte
+  static const size_t SubsectionLengthFieldSize = 4; // a 4-byte integer
+
+  // MinimalELFAttributeSubsectionSize is the minimal number of bytes a valid
+  // subsection in ELF attribute section should have.
+  static const size_t MinimalELFAttributeSubsectionSize
+      = 1 /* Tag_File, see ARM [ABI-addenda], 2.2.4 */ +
+        4 /* byte-size, see ARM [ABI-addenda], 2.2.4 */;
+
+  // MinimalELFAttributeSectionSize is the minimal number of bytes a valid ELF
+  // attribute section should have.
+  static const size_t MinimalELFAttributeSectionSize
+      = FormatVersionFieldSize + SubsectionLengthFieldSize +
+        2 /* vendor-name, a char plus '\0', see ARM [ABI-addenda], 2.2.3 */ +
+        1 * MinimalELFAttributeSubsectionSize;
+
+public:
+  ELFAttribute(const GNULDBackend &pBackend, const LinkerConfig& pConfig)
+    : m_Backend(pBackend), m_Config(pConfig) { }
+
+  ~ELFAttribute();
+
+public:
+  /// merge - merge attributes from input (attribute) section
+  bool merge(const Input &pInput, LDSection &pInputAttrSectHdr);
+
+  /// sizeOutput - calculate the number of bytes required to encode this
+  /// attribute data section
+  size_t sizeOutput() const;
+
+  /// emit - encode and write out this attribute section
+  size_t emit(MemoryRegion &pRegion) const;
+
+  inline const GNULDBackend &backend() const { return m_Backend; }
+
+  inline const LinkerConfig &config() const { return m_Config; }
+
+  // Place vendor's attribute data under the management.
+  void registerAttributeData(ELFAttributeData& pAttrData);
+
+private:
+  /** \class Subsection
+   *  \brief A helper class to wrap ELFAttributeData and to provide general
+   *  interfaces for ELFAttribute to operate on
+   */
+  class Subsection {
+  public:
+    Subsection(ELFAttribute &pParent, ELFAttributeData &pAttrData)
+      : m_Parent(pParent), m_AttrData(pAttrData) { }
+
+  public:
+    bool isMyAttribute(llvm::StringRef pVendorName) const
+    {
+      return (m_AttrData.getVendorName() == pVendorName);
+    }
+
+    /// merge -  Merge the attributes from the section in the input data.
+    bool merge(const Input &pInput, ConstAddress pData, size_t pSize);
+
+    /// sizeOutput - calculate the number of bytes required to encode this
+    /// subsection
+    size_t sizeOutput() const;
+
+    /// emit - write out this attribute subsection to the buffer.
+    size_t emit(char *pBuf) const;
+
+  private:
+    // The attribute section this subsection belongs to
+    ELFAttribute &m_Parent;
+
+    // The attribute data containing in this subsection
+    ELFAttributeData &m_AttrData;
+  };
+
+  // Obtain the corresponding subsection of the specified vendor
+  Subsection *getSubsection(llvm::StringRef pVendorName) const;
+
+private:
+  const GNULDBackend &m_Backend;
+
+  const LinkerConfig &m_Config;
+
+  // There is at most two subsections ("aeabi" and "gnu") in most cases.
+  llvm::SmallVector<Subsection*, 2> m_Subsections;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Target/ELFAttributeData.h b/include/mcld/Target/ELFAttributeData.h
new file mode 100644
index 0000000..1cb9ad7
--- /dev/null
+++ b/include/mcld/Target/ELFAttributeData.h
@@ -0,0 +1,114 @@
+//===- ELFAttributeData.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_ELFATTRIBUTEDATA_H
+#define MCLD_TARGET_ELFATTRIBUTEDATA_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <stdint.h>
+#include <string>
+#include <utility>
+
+namespace mcld {
+
+class ELFAttributeValue;
+class Input;
+class LinkerConfig;
+
+/** \class ELFAttributeData
+ *  \brief ELFAttributeData handles data in vendor attribute subsection.
+ */
+class ELFAttributeData
+{
+public:
+  typedef uint32_t TagType;
+
+  // Generic attribute tags shared between all vendors
+  enum {
+    Tag_NULL          = 0,
+    Tag_File          = 1,
+    Tag_Section       = 2,
+    Tag_Symbol        = 3,
+  };
+
+public:
+  ELFAttributeData(const char* pVendor) : m_Vendor(pVendor) { }
+
+  virtual ~ELFAttributeData() { }
+
+public:
+  inline const std::string &getVendorName() const { return m_Vendor; }
+
+  /// getAttributeValue - query the data store for the attribute value of the
+  /// given tag.
+  virtual const ELFAttributeValue *getAttributeValue(TagType pTag) const = 0;
+
+  /// getOrCreateAttributeValue - obtain attribute value for the given tag and
+  /// create if it does not exist.
+  ///
+  /// It returns a pair containing the attribute value instance (guaranteed to
+  /// be non-NULL) and a boolean value indicating whether the instance is newly
+  /// created (true) or not (false.)
+  virtual std::pair<ELFAttributeValue*, bool>
+      getOrCreateAttributeValue(TagType pTag) = 0;
+
+  /// preMerge - hooks to call before starting merge the attribute data in an
+  /// input.
+  virtual bool preMerge(const Input &pInput) { return true; }
+
+  /// merge - implement logics to merge input attribute to the output.
+  virtual bool merge(const LinkerConfig& pConfig, const Input &pInput,
+                     TagType pTag, const ELFAttributeValue& pInAttr) = 0;
+
+  /// postMerge - hooks to call after finishing merge the attribute data from an
+  /// input.
+  virtual bool postMerge(const LinkerConfig& pConfig, const Input &pInput)
+  { return true; }
+
+  /// sizeOutput - obtain number of bytes required to encode the attribute data.
+  virtual size_t sizeOutput() const = 0;
+
+  /// emit - write out attribute data to the buffer and return the number of
+  /// bytes written
+  virtual size_t emit(char *pBuf) const = 0;
+
+public:
+  /// ReadTag - read an attribute tag from input buffer.
+  ///
+  /// If the read succeeds, pBuf moves to the new position just pass the end of
+  /// the tag in the buffer and pBufSize decreases the size of tag in the
+  /// buffer. Otherwise, this function will return false and change nothing
+  /// except leaving undefined value in pTag.
+  static bool ReadTag(TagType& pTag, const char* &pBuf, size_t &pBufSize);
+
+  /// ReadValue - read an attribute value from input buffer
+  ///
+  /// Similar with ReadTag() while this reads attribute value from the input
+  /// buffer. Note that the value type of the attribute must be properly set in
+  /// pValue prior the call.
+  static bool ReadValue(ELFAttributeValue& pValue, const char* &pBuf,
+                        size_t &pBufSize);
+
+  /// WriteAttribute - write an attribute tag plus value to buffer.
+  ///
+  /// On success, the pBuf moves to the new position just pass the end of the
+  /// attribute data just written. Otherwise, it returns false and leaves pBuf
+  /// in an undefined position. Note that buffer is guaranteed to be able to
+  /// contain the attribute data.
+  static bool WriteAttribute(TagType pTag, const ELFAttributeValue& pValue,
+                             char* &pBuf);
+
+private:
+  const std::string m_Vendor;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Target/ELFAttributeValue.h b/include/mcld/Target/ELFAttributeValue.h
new file mode 100644
index 0000000..0af3c97
--- /dev/null
+++ b/include/mcld/Target/ELFAttributeValue.h
@@ -0,0 +1,125 @@
+//===- ELFAttributeValue.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_ELFATTRIBUTEVALUE_H
+#define MCLD_TARGET_ELFATTRIBUTEVALUE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <string>
+
+namespace mcld
+{
+
+/** \class ELFAttributeValue
+ *  \brief ELFAttributeValue stroes the value of an attribute tag. The attribtue
+ *  tag itself is not stored in this object.
+ */
+class ELFAttributeValue
+{
+public:
+  // Type of value that an attribute tag holds.
+  enum Type {
+    // The value contains no data and has unknown type.
+    Uninitialized = 0,
+
+    // The value contains integer data.
+    Int           = 1L << 0,
+
+    // The value contains string data.
+    String        = 1L << 1,
+
+    // This is for attribute in which "default value" (0 for int type and empty
+    // string for string type) has special meaning for them. That is, the
+    // default value is "disabled" and meaningful for those attribute.
+    NoDefault     = 1L << 2,
+  };
+
+public:
+  ELFAttributeValue()
+    : m_Type(Uninitialized), m_IntValue(0), m_StringValue() { }
+
+  ~ELFAttributeValue() { }
+
+public:
+  unsigned int type() const
+  { return m_Type; }
+
+  void setType(unsigned int pType)
+  { m_Type = pType; }
+
+  unsigned int getIntValue() const
+  { return m_IntValue; }
+
+  void setIntValue(unsigned int pIntValue)
+  { m_IntValue = pIntValue; }
+
+  const std::string &getStringValue() const
+  { return m_StringValue; }
+
+  void setStringValue(const std::string &pStringValue)
+  { m_StringValue = pStringValue; }
+
+  void setStringValue(const char *pStringValue, size_t pSize)
+  { m_StringValue.assign(pStringValue, pSize); }
+
+  void setStringValue(const char *pStringValue)
+  { m_StringValue.assign(pStringValue); }
+
+  size_t getSize() const;
+
+  inline bool isUninitialized() const
+  { return (m_Type == Uninitialized); }
+
+  inline bool isInitialized() const
+  { return !isUninitialized(); }
+
+  inline bool isIntValue() const
+  { return (m_Type & Int); }
+
+  inline bool isStringValue() const
+  { return (m_Type & String); }
+
+  inline bool hasNoDefault() const
+  { return (m_Type & NoDefault); }
+
+  bool isDefaultValue() const;
+
+  // Returns true if this attribute value should be emitted to the output.
+  inline bool shouldEmit() const {
+    // Attribute with non-default value should be emitted.
+    return !isDefaultValue();
+  }
+
+  bool equals(const ELFAttributeValue& pValue) const;
+
+  bool operator==(const ELFAttributeValue& pValue) const
+  { return equals(pValue); }
+  bool operator!=(const ELFAttributeValue& pValue) const
+  { return !equals(pValue); }
+
+  /// reset - reset this value to the uninitialized state
+  void reset()
+  {
+    m_Type = Uninitialized;
+    m_IntValue = 0;
+    m_StringValue.clear();
+    return;
+  }
+
+private:
+  unsigned int m_Type;
+
+  unsigned int m_IntValue;
+  std::string m_StringValue;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Target/ELFDynamic.h b/include/mcld/Target/ELFDynamic.h
index 62f534d..c9b257f 100644
--- a/include/mcld/Target/ELFDynamic.h
+++ b/include/mcld/Target/ELFDynamic.h
@@ -6,14 +6,15 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_DYNAMIC_SECTION_H
-#define MCLD_ELF_DYNAMIC_SECTION_H
+#ifndef MCLD_TARGET_ELFDYNAMIC_H
+#define MCLD_TARGET_ELFDYNAMIC_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
-#include <llvm/Support/ELF.h>
 #include <mcld/LD/LDSection.h>
+#include <mcld/Support/FileOutputBuffer.h>
+#include <llvm/Support/ELF.h>
 #include <vector>
 #include <cstring>
 
@@ -22,7 +23,6 @@
 class ELFFileFormat;
 class GNULDBackend;
 class LinkerConfig;
-class MemoryRegion;
 
 namespace elf_dynamic {
 
diff --git a/include/mcld/Target/ELFEmulation.h b/include/mcld/Target/ELFEmulation.h
index 9d35792..2a79f11 100644
--- a/include/mcld/Target/ELFEmulation.h
+++ b/include/mcld/Target/ELFEmulation.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_EMULATION_H
-#define MCLD_ELF_EMULATION_H
+#ifndef MCLD_TARGET_ELFEMULATION_H
+#define MCLD_TARGET_ELFEMULATION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/Target/ELFMCLinker.h b/include/mcld/Target/ELFMCLinker.h
index 76f46e8..2cead3b 100644
--- a/include/mcld/Target/ELFMCLinker.h
+++ b/include/mcld/Target/ELFMCLinker.h
@@ -11,8 +11,8 @@
 // This pass set up default parameters for ELF.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_ELF_SECTION_LINKER_H
-#define MCLD_ELF_SECTION_LINKER_H
+#ifndef MCLD_TARGET_ELFMCLINKER_H
+#define MCLD_TARGET_ELFMCLINKER_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -22,13 +22,14 @@
 
 class Module;
 class Output;
+class FileHandle;
 
 class ELFMCLinker : public MCLinker
 {
 public:
   ELFMCLinker(LinkerConfig& pConfig,
               mcld::Module& pModule,
-              MemoryArea& pOutput);
+              FileHandle& pFileHandle);
 
   virtual ~ELFMCLinker();
 };
diff --git a/include/mcld/Target/GNUInfo.h b/include/mcld/Target/GNUInfo.h
index 86a29ba..247d817 100644
--- a/include/mcld/Target/GNUInfo.h
+++ b/include/mcld/Target/GNUInfo.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TARGET_GNU_INFO_H
-#define MCLD_TARGET_GNU_INFO_H
+#ifndef MCLD_TARGET_GNUINFO_H
+#define MCLD_TARGET_GNUINFO_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -36,7 +36,7 @@
   uint8_t OSABI() const;
 
   /// ABIVersion - the value of e_ident[EI_ABIVRESION]
-  uint8_t ABIVersion() const { return 0x0; }
+  virtual uint8_t ABIVersion() const { return 0x0; }
 
   /// defaultTextSegmentAddr - target should specify its own default start address
   /// of the text segment. esp. for exec.
@@ -65,7 +65,7 @@
   /// here. If target favors the different size, please override this function
   virtual uint64_t abiPageSize() const { return 0x1000; }
 
-private:
+protected:
   const llvm::Triple& m_Triple;
 };
 
diff --git a/include/mcld/Target/GNULDBackend.h b/include/mcld/Target/GNULDBackend.h
index 3384eae..0d23964 100644
--- a/include/mcld/Target/GNULDBackend.h
+++ b/include/mcld/Target/GNULDBackend.h
@@ -6,31 +6,21 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TARGET_GNU_LDBACKEND_H
-#define MCLD_TARGET_GNU_LDBACKEND_H
+#ifndef MCLD_TARGET_GNULDBACKEND_H
+#define MCLD_TARGET_GNULDBACKEND_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 #include <mcld/Target/TargetLDBackend.h>
 
-#include <llvm/Support/ELF.h>
-#include <mcld/ADT/HashTable.h>
-#include <mcld/ADT/HashEntry.h>
-#include <mcld/LD/ELFDynObjFileFormat.h>
-#include <mcld/LD/ELFExecFileFormat.h>
-#include <mcld/LD/ELFObjectFileFormat.h>
+#include <mcld/Module.h>
 #include <mcld/LD/GNUArchiveReader.h>
-#include <mcld/LD/ELFObjectReader.h>
 #include <mcld/LD/ELFDynObjReader.h>
 #include <mcld/LD/ELFBinaryReader.h>
+#include <mcld/LD/ELFObjectReader.h>
 #include <mcld/LD/ELFObjectWriter.h>
-#include <mcld/LD/ELFSegment.h>
-#include <mcld/LD/ELFSegmentFactory.h>
-#include <mcld/Target/ELFDynamic.h>
-#include <mcld/Target/GNUInfo.h>
 
-#include <mcld/Support/GCFactory.h>
-#include <mcld/Module.h>
+#include <llvm/Support/ELF.h>
 
 namespace mcld {
 
@@ -42,6 +32,15 @@
 class BranchIslandFactory;
 class StubFactory;
 class GNUInfo;
+class ELFFileFormat;
+class ELFSegmentFactory;
+class ELFAttribute;
+class ELFDynamic;
+class ELFDynObjFileFormat;
+class ELFExecFileFormat;
+class ELFObjectFileFormat;
+class LinkerScript;
+class Relocation;
 
 /** \class GNULDBackend
  *  \brief GNULDBackend provides a common interface for all GNU Unix-OS
@@ -110,6 +109,9 @@
   /// getSegmentStartAddr - this function returns the start address of the segment
   uint64_t getSegmentStartAddr(const LinkerScript& pScript) const;
 
+  /// sizeShstrtab - compute the size of .shstrtab
+  void sizeShstrtab(Module& pModule);
+
   /// sizeNamePools - compute the size of regular name pools
   /// In ELF executable files, regular name pools are .symtab, .strtab.,
   /// .dynsym, .dynstr, and .hash
@@ -120,25 +122,25 @@
                                    MemoryRegion& pRegion) const = 0;
 
   /// emitRegNamePools - emit regular name pools - .symtab, .strtab
-  virtual void emitRegNamePools(const Module& pModule, MemoryArea& pOutput);
+  virtual void emitRegNamePools(const Module& pModule, FileOutputBuffer& pOutput);
 
   /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
-  virtual void emitDynNamePools(Module& pModule, MemoryArea& pOutput);
+  virtual void emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput);
 
   /// emitELFHashTab - emit .hash
   virtual void emitELFHashTab(const Module::SymbolTable& pSymtab,
-                              MemoryArea& pOutput);
+                              FileOutputBuffer& pOutput);
 
   /// emitGNUHashTab - emit .gnu.hash
   virtual void emitGNUHashTab(Module::SymbolTable& pSymtab,
-                              MemoryArea& pOutput);
+                              FileOutputBuffer& pOutput);
 
   /// sizeInterp - compute the size of program interpreter's name
   /// In ELF executables, this is the length of dynamic linker's path name
   virtual void sizeInterp();
 
   /// emitInterp - emit the .interp
-  virtual void emitInterp(MemoryArea& pOutput);
+  virtual void emitInterp(FileOutputBuffer& pOutput);
 
   /// hasEntryInStrTab - symbol has an entry in a .strtab
   virtual bool hasEntryInStrTab(const LDSymbol& pSym) const;
@@ -169,16 +171,11 @@
   virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const
   { return (unsigned int)-1; }
 
-  /// numOfSegments - return the number of segments
-  /// if the target favors other ways to emit program header, please override
-  /// this function
-  size_t numOfSegments() const { return m_ELFSegmentTable.size(); }
+  /// elfSegmentTable - return the reference of the elf segment table
+  ELFSegmentFactory&       elfSegmentTable();
 
   /// elfSegmentTable - return the reference of the elf segment table
-  ELFSegmentFactory&       elfSegmentTable()       { return m_ELFSegmentTable; }
-
-  /// elfSegmentTable - return the reference of the elf segment table
-  const ELFSegmentFactory& elfSegmentTable() const { return m_ELFSegmentTable; }
+  const ELFSegmentFactory& elfSegmentTable() const;
 
   /// commonPageSize - the common page size of the target machine
   uint64_t commonPageSize() const;
@@ -198,6 +195,58 @@
   /// update the output section flags based on input section flags.
   virtual bool updateSectionFlags(LDSection& pTo, const LDSection& pFrom);
 
+  /// readRelocation - read ELF32_Rel entry
+  virtual bool readRelocation(const llvm::ELF::Elf32_Rel& pRel,
+                              uint32_t& pType,
+                              uint32_t& pSymIdx,
+                              uint32_t& pOffset) const;
+
+  /// readRelocation - read ELF32_Rela entry
+  virtual bool readRelocation(const llvm::ELF::Elf32_Rela& pRel,
+                              uint32_t& pType,
+                              uint32_t& pSymIdx,
+                              uint32_t& pOffset,
+                              int32_t& pAddend) const;
+
+  /// readRelocation - read ELF64_Rel entry
+  virtual bool readRelocation(const llvm::ELF::Elf64_Rel& pRel,
+                              uint32_t& pType,
+                              uint32_t& pSymIdx,
+                              uint64_t& pOffset) const;
+
+  /// readRel - read ELF64_Rela entry
+  virtual bool readRelocation(const llvm::ELF::Elf64_Rela& pRel,
+                              uint32_t& pType,
+                              uint32_t& pSymIdx,
+                              uint64_t& pOffset,
+                              int64_t& pAddend) const;
+
+  /// emitRelocation - write data to the ELF32_Rel entry
+  virtual void emitRelocation(llvm::ELF::Elf32_Rel& pRel,
+                              uint32_t pType,
+                              uint32_t pSymIdx,
+                              uint32_t pOffset) const;
+
+  /// emitRelocation - write data to the ELF32_Rela entry
+  virtual void emitRelocation(llvm::ELF::Elf32_Rela& pRel,
+                              uint32_t pType,
+                              uint32_t pSymIdx,
+                              uint32_t pOffset,
+                              int32_t pAddend) const;
+
+  /// emitRelocation - write data to the ELF64_Rel entry
+  virtual void emitRelocation(llvm::ELF::Elf64_Rel& pRel,
+                              uint32_t pType,
+                              uint32_t pSymIdx,
+                              uint64_t pOffset) const;
+
+  /// emitRelocation - write data to the ELF64_Rela entry
+  virtual void emitRelocation(llvm::ELF::Elf64_Rela& pRel,
+                              uint32_t pType,
+                              uint32_t pSymIdx,
+                              uint64_t pOffset,
+                              int64_t pAddend) const;
+
   /// symbolNeedsPLT - return whether the symbol needs a PLT entry
   /// @ref Google gold linker, symtab.h:596
   bool symbolNeedsPLT(const ResolveInfo& pSym) const;
@@ -223,11 +272,11 @@
 
   /// isDynamicSymbol
   /// @ref Google gold linker: symtab.cc:311
-  bool isDynamicSymbol(const LDSymbol& pSymbol);
+  bool isDynamicSymbol(const LDSymbol& pSymbol) const;
 
   /// isDynamicSymbol
   /// @ref Google gold linker: symtab.cc:311
-  bool isDynamicSymbol(const ResolveInfo& pResolveInfo);
+  bool isDynamicSymbol(const ResolveInfo& pResolveInfo) const;
 
   virtual ResolveInfo::Desc getSymDesc(uint16_t pShndx) const {
     return ResolveInfo::Define;
@@ -247,6 +296,9 @@
   LDSymbol& getTBSSSymbol();
   const LDSymbol& getTBSSSymbol() const;
 
+  /// getEntry - get the entry point name
+  llvm::StringRef getEntry(const Module& pModule) const;
+
   //  -----  relaxation  -----  //
   /// initBRIslandFactory - initialize the branch island factory for relaxation
   bool initBRIslandFactory();
@@ -267,7 +319,27 @@
   /// checkAndSetHasTextRel - check pSection flag to set HasTextRel
   void checkAndSetHasTextRel(const LDSection& pSection);
 
+  /// sortRelocation - sort the dynamic relocations to let dynamic linker
+  /// process relocations more efficiently
+  void sortRelocation(LDSection& pSection);
+
+  /// createAndSizeEhFrameHdr - This is seperated since we may add eh_frame
+  /// entry in the middle
+  void createAndSizeEhFrameHdr(Module& pModule);
+
+  /// attribute - the attribute section data.
+  ELFAttribute& attribute() { return *m_pAttribute; }
+
+  /// attribute - the attribute section data.
+  const ELFAttribute& attribute() const { return *m_pAttribute; }
+
 protected:
+  /// getRelEntrySize - the size in BYTE of rel type relocation
+  virtual size_t getRelEntrySize() = 0;
+
+  /// getRelEntrySize - the size in BYTE of rela type relocation
+  virtual size_t getRelaEntrySize() = 0;
+
   uint64_t getSymbolSize(const LDSymbol& pSymbol) const;
 
   uint64_t getSymbolInfo(const LDSymbol& pSymbol) const;
@@ -315,33 +387,19 @@
 
   /// 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;
-  }
+  inline uint32_t getSegmentFlag(const uint32_t pSectionFlag);
 
   /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
   void setupGNUStackInfo(Module& pModule);
 
-  /// setupRelro - setup the offset constraint of PT_RELRO
-  void setupRelro(Module& pModule);
+  /// setOutputSectionOffset - helper function to set output sections' offset.
+  void setOutputSectionOffset(Module& pModule);
 
-  /// setOutputSectionOffset - helper function to set a group of output sections'
-  /// offset, and set pSectBegin to pStartOffset if pStartOffset is not -1U.
-  void setOutputSectionOffset(Module& pModule,
-                              Module::iterator pSectBegin,
-                              Module::iterator pSectEnd,
-                              uint64_t pStartOffset = -1U);
+  /// setOutputSectionAddress - helper function to set output sections' address.
+  void setOutputSectionAddress(Module& pModule);
 
-  /// setOutputSectionOffset - helper function to set output sections' address.
-  void setOutputSectionAddress(Module& pModule,
-                               Module::iterator pSectBegin,
-                               Module::iterator pSectEnd);
+  /// placeOutputSections - place output sections based on SectionMap
+  void placeOutputSections(Module& pModule);
 
   /// layout - layout method
   void layout(Module& pModule);
@@ -359,7 +417,7 @@
   virtual void doPostLayout(Module& pModule, IRBuilder& pLinker) = 0;
 
   /// postProcessing - Backend can do any needed modification in the final stage
-  void postProcessing(MemoryArea& pOutput);
+  void postProcessing(FileOutputBuffer& pOutput);
 
   /// dynamic - the dynamic section of the target machine.
   virtual ELFDynamic& dynamic() = 0;
@@ -380,56 +438,48 @@
   virtual bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
   { return false; }
 
-  /// getRelEntrySize - the size in BYTE of rel type relocation
-  virtual size_t getRelEntrySize() = 0;
-
-  /// getRelEntrySize - the size in BYTE of rela type relocation
-  virtual size_t getRelaEntrySize() = 0;
-
 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_EXCEPTION,           // .eh_frame_hdr, .eh_frame, .gcc_except_table
-    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,           // default order
-    SHO_STRTAB               // .strtab
+    SHO_NULL = 0,        // NULL
+    SHO_INTERP,          // .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_EXCEPTION,       // .eh_frame_hdr, .eh_frame, .gcc_except_table
+    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,       // default order
+    SHO_STRTAB           // .strtab
   };
 
-  typedef std::pair<LDSection*, unsigned int> SHOEntry;
-
-  struct SHOCompare
+  // for -z combreloc
+  struct RelocCompare
   {
-    bool operator()(const SHOEntry& X, const SHOEntry& Y) const
-    { return X.second < Y.second; }
-  };
-
-  struct SymCompare
-  {
-    bool operator()(const LDSymbol* X, const LDSymbol* Y) const
-    { return (X==Y); }
+    RelocCompare(const GNULDBackend& pBackend)
+      : m_Backend(pBackend) {
+    }
+    bool operator()(const Relocation* X, const Relocation* Y) const;
+  private:
+    const GNULDBackend& m_Backend;
   };
 
   // for gnu style hash table
@@ -440,6 +490,12 @@
     bool operator()(const LDSymbol* X, const LDSymbol* Y) const;
   };
 
+  struct SymCompare
+  {
+    bool operator()(const LDSymbol* X, const LDSymbol* Y) const
+    { return (X==Y); }
+  };
+
   struct SymPtrHash
   {
     size_t operator()(const LDSymbol* pKey) const
@@ -467,7 +523,7 @@
   GNUInfo* m_pInfo;
 
   // ELF segment factory
-  ELFSegmentFactory m_ELFSegmentTable;
+  ELFSegmentFactory* m_pELFSegmentTable;
 
   // branch island factory
   BranchIslandFactory* m_pBRIslandFactory;
@@ -481,6 +537,9 @@
   // section .eh_frame_hdr
   EhFrameHdr* m_pEhFrameHdr;
 
+  // attribute section
+  ELFAttribute* m_pAttribute;
+
   // ----- dynamic flags ----- //
   // DF_TEXTREL of DT_FLAGS
   bool m_bHasTextRel;
diff --git a/include/mcld/Target/GOT.h b/include/mcld/Target/GOT.h
index 9b61bcd..eb73741 100644
--- a/include/mcld/Target/GOT.h
+++ b/include/mcld/Target/GOT.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_GLOBAL_OFFSET_TABLE_H
-#define MCLD_GLOBAL_OFFSET_TABLE_H
+#ifndef MCLD_TARGET_GOT_H
+#define MCLD_TARGET_GOT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -80,13 +80,6 @@
   // finalizeSectionSize - set LDSection size
   virtual void finalizeSectionSize();
 
-  /// reserve - 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 reserve(size_t pNum = 1) = 0;
-
 protected:
   LDSection& m_Section;
   SectionData* m_SectionData;
diff --git a/include/mcld/Target/KeyEntryMap.h b/include/mcld/Target/KeyEntryMap.h
new file mode 100644
index 0000000..8136687
--- /dev/null
+++ b/include/mcld/Target/KeyEntryMap.h
@@ -0,0 +1,204 @@
+//===- KeyEntryMap.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_KEYENTRYMAP_H
+#define MCLD_TARGET_KEYENTRYMAP_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <vector>
+#include <list>
+
+namespace mcld {
+
+/** \class KeyEntryMap
+ *  \brief KeyEntryMap is a <const KeyType*, ENTRY*> map.
+ */
+template<typename KEY, typename ENTRY>
+class KeyEntryMap
+{
+public:
+  typedef KEY   KeyType;
+  typedef ENTRY EntryType;
+
+private:
+  struct EntryPair {
+    EntryPair(EntryType* pEntry1, EntryType* pEntry2)
+     : entry1(pEntry1), entry2(pEntry2)
+    {}
+
+    EntryType* entry1;
+    EntryType* entry2;
+  };
+
+  /// EntryOrPair - A key may mapping to a signal entry or a pair of entries,
+  /// user is responsible for the type of Mapping.entry
+  union EntryOrPair {
+    EntryType* entry_ptr;
+    EntryPair* pair_ptr;
+  };
+
+  struct Mapping {
+    const KeyType* key;
+    EntryOrPair entry;
+  };
+
+  typedef std::vector<Mapping> KeyEntryPool;
+  typedef std::list<EntryPair> PairListType;
+
+public:
+  typedef typename KeyEntryPool::iterator iterator;
+  typedef typename KeyEntryPool::const_iterator const_iterator;
+
+public:
+  /// lookUp - look up the entry mapping to pKey
+  const EntryType* lookUp(const KeyType& pKey) const;
+  EntryType*       lookUp(const KeyType& pKey);
+
+  /// lookUpFirstEntry - look up the first entry mapping to pKey
+  const EntryType* lookUpFirstEntry(const KeyType& pKey) const;
+  EntryType*       lookUpFirstEntry(const KeyType& pKey);
+
+  /// lookUpSecondEntry - look up the second entry mapping to pKey
+  const EntryType* lookUpSecondEntry(const KeyType& pKey) const;
+  EntryType*       lookUpSecondEntry(const KeyType& pKey);
+
+  void record(const KeyType& pKey, EntryType& pEntry);
+  void record(const KeyType& pKey,
+              EntryType& pEntry1,
+              EntryType& pEntry2);
+
+  bool   empty() const { return m_Pool.empty(); }
+  size_t size () const { return m_Pool.size(); }
+
+  const_iterator begin() const { return m_Pool.begin(); }
+  iterator       begin()       { return m_Pool.begin(); }
+  const_iterator end  () const { return m_Pool.end();   }
+  iterator       end  ()       { return m_Pool.end();   }
+
+  void reserve(size_t pSize) { m_Pool.reserve(pSize); }
+
+private:
+  KeyEntryPool m_Pool;
+
+  /// m_Pairs - the EntryPairs
+  PairListType m_Pairs;
+};
+
+template<typename KeyType, typename EntryType>
+const EntryType*
+KeyEntryMap<KeyType, EntryType>::lookUp(const KeyType& pKey) const
+{
+  const_iterator mapping, mEnd = m_Pool.end();
+  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
+    if (mapping->key == &pKey) {
+      return mapping->entry.entry_ptr;
+    }
+  }
+
+  return NULL;
+}
+
+template<typename KeyType, typename EntryType>
+EntryType*
+KeyEntryMap<KeyType, EntryType>::lookUp(const KeyType& pKey)
+{
+  iterator mapping, mEnd = m_Pool.end();
+  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
+    if (mapping->key == &pKey) {
+      return mapping->entry.entry_ptr;
+    }
+  }
+
+  return NULL;
+}
+
+template<typename KeyType, typename EntryType>
+const EntryType*
+KeyEntryMap<KeyType, EntryType>::lookUpFirstEntry(const KeyType& pKey) const
+{
+  const_iterator mapping, mEnd = m_Pool.end();
+  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
+    if (mapping->key == &pKey) {
+      return mapping->entry.pair_ptr->entry1;
+    }
+  }
+
+  return NULL;
+}
+
+template<typename KeyType, typename EntryType>
+EntryType*
+KeyEntryMap<KeyType, EntryType>::lookUpFirstEntry(const KeyType& pKey)
+{
+  const_iterator mapping, mEnd = m_Pool.end();
+  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
+    if (mapping->key == &pKey) {
+      return mapping->entry.pair_ptr->entry1;
+    }
+  }
+
+  return NULL;
+}
+
+template<typename KeyType, typename EntryType>
+const EntryType*
+KeyEntryMap<KeyType, EntryType>::lookUpSecondEntry(const KeyType& pKey) const
+{
+  const_iterator mapping, mEnd = m_Pool.end();
+  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
+    if (mapping->key == &pKey) {
+      return mapping->entry.pair_ptr->entry2;
+    }
+  }
+
+  return NULL;
+}
+
+template<typename KeyType, typename EntryType>
+EntryType*
+KeyEntryMap<KeyType, EntryType>::lookUpSecondEntry(const KeyType& pKey)
+{
+  const_iterator mapping, mEnd = m_Pool.end();
+  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
+    if (mapping->key == &pKey) {
+      return mapping->entry.pair_ptr->entry2;
+    }
+  }
+
+  return NULL;
+}
+
+template<typename KeyType, typename EntryType>
+void
+KeyEntryMap<KeyType, EntryType>::record(const KeyType& pKey, EntryType& pEntry)
+{
+  Mapping mapping;
+  mapping.key = &pKey;
+  mapping.entry.entry_ptr = &pEntry;
+  m_Pool.push_back(mapping);
+}
+
+template<typename KeyType, typename EntryType>
+void
+KeyEntryMap<KeyType, EntryType>::record(const KeyType& pKey,
+                                  EntryType& pEntry1,
+                                  EntryType& pEntry2)
+{
+  Mapping mapping;
+  mapping.key = &pKey;
+  m_Pairs.push_back(EntryPair(&pEntry1, &pEntry2));
+  mapping.entry.pair_ptr = &m_Pairs.back();
+  m_Pool.push_back(mapping);
+}
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/OutputRelocSection.h b/include/mcld/Target/OutputRelocSection.h
index b0f8f2d..a109843 100644
--- a/include/mcld/Target/OutputRelocSection.h
+++ b/include/mcld/Target/OutputRelocSection.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_OUTPUT_RELOCATION_SECTION_H
-#define MCLD_OUTPUT_RELOCATION_SECTION_H
+#ifndef MCLD_TARGET_OUTPUTRELOCSECTION_H
+#define MCLD_TARGET_OUTPUTRELOCSECTION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -32,6 +32,9 @@
 
   ~OutputRelocSection();
 
+  /// create - create an dynamic relocation entry
+  Relocation* create();
+
   void reserveEntry(size_t pNum=1);
 
   Relocation* consumeEntry();
diff --git a/include/mcld/Target/PLT.h b/include/mcld/Target/PLT.h
index 5d91446..7305a74 100644
--- a/include/mcld/Target/PLT.h
+++ b/include/mcld/Target/PLT.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_PROCEDURE_LINKAGE_TABLE_H
-#define MCLD_PROCEDURE_LINKAGE_TABLE_H
+#ifndef MCLD_TARGET_PLT_H
+#define MCLD_TARGET_PLT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -22,7 +22,7 @@
 class ResolveInfo;
 
 /** \class PLTEntryDefaultBase
- *  \brief PLTEntryDefaultBase provides the default interface for PLE Entry
+ *  \brief PLTEntryDefaultBase provides the default interface for PLT Entry
  */
 class PLTEntryBase : public TargetFragment
 {
@@ -33,7 +33,7 @@
 
   virtual ~PLTEntryBase()
   {
-    delete m_pValue;
+    free(m_pValue);
   }
 
   void setValue(unsigned char* pValue)
@@ -81,10 +81,6 @@
 
   virtual ~PLT();
 
-  /// 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;
-
   // finalizeSectionSize - set LDSection size
   virtual void finalizeSectionSize() = 0;
 
diff --git a/include/mcld/Target/SymbolEntryMap.h b/include/mcld/Target/SymbolEntryMap.h
deleted file mode 100644
index fc5ea93..0000000
--- a/include/mcld/Target/SymbolEntryMap.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===- SymbolEntryMap.h ---------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_TARGET_SYMBOL_ENTRY_MAP_H
-#define MCLD_TARGET_SYMBOL_ENTRY_MAP_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-
-#include <vector>
-
-namespace mcld {
-
-class ResolveInfo;
-
-/** \class SymbolEntryMap
- *  \brief SymbolEntryMap is a <const ResolveInfo*, ENTRY*> map.
- */
-template<typename ENTRY>
-class SymbolEntryMap
-{
-public:
-  typedef ENTRY EntryType;
-
-private:
-  struct Mapping {
-    const ResolveInfo* symbol;
-    EntryType*   entry;
-  };
-
-  typedef std::vector<Mapping> SymbolEntryPool;
-
-public:
-  typedef typename SymbolEntryPool::iterator iterator;
-  typedef typename SymbolEntryPool::const_iterator const_iterator;
-
-public:
-  const EntryType* lookUp(const ResolveInfo& pSymbol) const;
-  EntryType*       lookUp(const ResolveInfo& pSymbol);
-
-  void record(const ResolveInfo& pSymbol, EntryType& pEntry);
-
-  bool   empty() const { return m_Pool.empty(); }
-  size_t size () const { return m_Pool.size(); }
-
-  const_iterator begin() const { return m_Pool.begin(); }
-  iterator       begin()       { return m_Pool.begin(); }
-  const_iterator end  () const { return m_Pool.end();   }
-  iterator       end  ()       { return m_Pool.end();   }
-
-  void reserve(size_t pSize) { m_Pool.reserve(pSize); }
-
-private:
-  SymbolEntryPool m_Pool;
-
-};
-
-template<typename EntryType>
-const EntryType*
-SymbolEntryMap<EntryType>::lookUp(const ResolveInfo& pSymbol) const
-{
-  const_iterator mapping, mEnd = m_Pool.end();
-  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
-    if (mapping->symbol == &pSymbol) {
-      return mapping->entry;
-    }
-  }
-
-  return NULL;
-}
-
-template<typename EntryType>
-EntryType*
-SymbolEntryMap<EntryType>::lookUp(const ResolveInfo& pSymbol)
-{
-  iterator mapping, mEnd = m_Pool.end();
-  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
-    if (mapping->symbol == &pSymbol) {
-      return mapping->entry;
-    }
-  }
-
-  return NULL;
-}
-
-template<typename EntryType>
-void
-SymbolEntryMap<EntryType>::record(const ResolveInfo& pSymbol, EntryType& pEntry)
-{
-  Mapping mapping;
-  mapping.symbol = &pSymbol;
-  mapping.entry = &pEntry;
-  m_Pool.push_back(mapping);
-}
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Target/TargetLDBackend.h b/include/mcld/Target/TargetLDBackend.h
index d3f14b2..29fb395 100644
--- a/include/mcld/Target/TargetLDBackend.h
+++ b/include/mcld/Target/TargetLDBackend.h
@@ -1,4 +1,4 @@
-//===-- llvm/Target/TargetLDBackend.h - Target LD Backend -----*- C++ -*-===//
+//===-- TargetLDBackend.h - Target LD Backend -------------------*- C++ -*-===//
 //
 //                     The MCLinker Project
 //
@@ -9,36 +9,34 @@
 #ifndef MCLD_TARGET_TARGETLDBACKEND_H
 #define MCLD_TARGET_TARGETLDBACKEND_H
 
+#include <llvm/ADT/StringRef.h>
 #include <llvm/Support/DataTypes.h>
+#include <mcld/LD/GarbageCollection.h>
 
 namespace mcld {
 
-class Module;
-class LinkerConfig;
-class IRBuilder;
-class Relocation;
-class RelocationFactory;
-class Relocator;
-class Layout;
 class ArchiveReader;
-class ObjectReader;
-class DynObjReader;
 class BinaryReader;
-class ObjectWriter;
+class BinaryWriter;
+class BranchIslandFactory;
+class DynObjReader;
 class DynObjWriter;
 class ExecWriter;
-class BinaryWriter;
-class LDFileFormat;
-class LDSymbol;
-class LDSection;
-class SectionData;
+class FileOutputBuffer;
+class SectionReachedListMap;
+class IRBuilder;
 class Input;
-class GOT;
-class MemoryArea;
-class MemoryAreaFactory;
-class BranchIslandFactory;
-class StubFactory;
+class LDSection;
+class LDSymbol;
+class Layout;
+class LinkerConfig;
+class Module;
 class ObjectBuilder;
+class ObjectReader;
+class ObjectWriter;
+class Relocator;
+class SectionData;
+class StubFactory;
 
 //===----------------------------------------------------------------------===//
 /// TargetLDBackend - Generic interface to target specific assembler backends.
@@ -84,7 +82,7 @@
   virtual void postLayout(Module& pModule, IRBuilder& pBuilder) = 0;
 
   /// postProcessing - Backend can do any needed modification in the final stage
-  virtual void postProcessing(MemoryArea& pOutput) = 0;
+  virtual void postProcessing(FileOutputBuffer& pOutput) = 0;
 
   /// section start offset in the output file
   virtual size_t sectionStartOffset() const = 0;
@@ -112,9 +110,17 @@
   virtual bool allocateCommonSymbols(Module& pModule) = 0;
 
   /// mergeSection - merge target dependent sections.
-  virtual bool mergeSection(Module& pModule, LDSection& pInputSection)
+  virtual bool mergeSection(Module& pModule,
+                            const Input& pInputFile,
+                            LDSection& pInputSection)
   { return true; }
 
+  /// setUpReachedSectionsForGC - set the reference between two sections for
+  /// some special target sections. GC will set up the reference for the Regular
+  /// and BSS sections. Backends can also set up the reference if need.
+  virtual void setUpReachedSectionsForGC(const Module& pModule,
+        GarbageCollection::SectionReachedListMap& pSectReachedListMap) const { }
+
   /// updateSectionFlags - update pTo's flags when merging pFrom
   /// update the output section flags based on input section flags.
   /// FIXME: (Luba) I know ELF need to merge flags, but I'm not sure if
@@ -130,6 +136,9 @@
   /// In ELF executables, this is the length of dynamic linker's path name
   virtual void sizeInterp() = 0;
 
+  /// getEntry - get the entry point name
+  virtual llvm::StringRef getEntry(const Module& pModule) const = 0;
+
   // -----  relaxation  ----- //
   virtual bool initBRIslandFactory() = 0;
   virtual bool initStubFactory() = 0;
@@ -144,6 +153,20 @@
   /// mayRelax - return true if the backend needs to do relaxation
   virtual bool mayRelax() = 0;
 
+  /// commonPageSize - the common page size of the target machine
+  virtual uint64_t commonPageSize() const = 0;
+
+  /// abiPageSize - the abi page size of the target machine
+  virtual uint64_t abiPageSize() const = 0;
+
+  /// sortRelocation - sort the dynamic relocations to let dynamic linker
+  /// process relocations more efficiently
+  virtual void sortRelocation(LDSection& pSection) = 0;
+
+  /// createAndSizeEhFrameHdr - This is seperated since we may add eh_frame
+  /// entry in the middle
+  virtual void createAndSizeEhFrameHdr(Module& pModule) = 0;
+
 protected:
   const LinkerConfig& config() const { return m_Config; }
 
diff --git a/include/mcld/TargetOptions.h b/include/mcld/TargetOptions.h
index dfdd773..5f7e339 100644
--- a/include/mcld/TargetOptions.h
+++ b/include/mcld/TargetOptions.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_TARGET_OPTIONS_H
-#define MCLD_TARGET_OPTIONS_H
+#ifndef MCLD_TARGETOPTIONS_H
+#define MCLD_TARGETOPTIONS_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -44,6 +44,10 @@
 
   void setTriple(const llvm::Triple& pTriple);
 
+  const std::string& getArch() const { return m_ArchName; }
+
+  void setArch(const std::string& pArchName);
+
   const std::string& getTargetCPU() const { return m_TargetCPU; }
 
   void setTargetCPU(const std::string& pCPU);
@@ -68,6 +72,7 @@
 
 private:
   llvm::Triple m_Triple;
+  std::string m_ArchName;
   std::string m_TargetCPU;
   std::string m_TargetFS;
   Endian m_Endian;