MCLinker upstream commit 9628cfb76b5a.

Change-Id: I6d12c63bdae94299558dc1cf42b489bb98748851
diff --git a/include/mcld/CodeGen/SectLinker.h b/include/mcld/CodeGen/SectLinker.h
index b31b968..4ed2907 100644
--- a/include/mcld/CodeGen/SectLinker.h
+++ b/include/mcld/CodeGen/SectLinker.h
@@ -43,7 +43,7 @@
 *  - provide an interface for target-specific SectLinekr
 *  - set up environment for MCLDDriver
 *  - control AsmPrinter, make sure AsmPrinter has already prepared
-*    all MCSectionDatas for linking
+*    all SectionDatas for linking
 *
 *  SectLinker resolves the absolue paths of input arguments.
 *
diff --git a/include/mcld/Config/Config.h b/include/mcld/Config/Config.h
index a6ce28a..ea92259 100644
--- a/include/mcld/Config/Config.h
+++ b/include/mcld/Config/Config.h
@@ -23,7 +23,7 @@
 # define MCLD_ON_WIN32 1
 #endif
 
-#define MCLD_VERSION "LionHead - 1.3.18"
+#define MCLD_VERSION "Phoenix - 1.4.0"
 
 #endif
 
diff --git a/include/mcld/LD/AlignFragment.h b/include/mcld/LD/AlignFragment.h
new file mode 100644
index 0000000..4c5582c
--- /dev/null
+++ b/include/mcld/LD/AlignFragment.h
@@ -0,0 +1,69 @@
+//===- AlignFragment.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LD_ALIGNFRAGMENT_H
+#define MCLD_LD_ALIGNFRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/Fragment.h>
+
+namespace mcld
+{
+
+class SectionData;
+
+class AlignFragment : public Fragment
+{
+public:
+  AlignFragment(unsigned int pAlignment, int64_t pValue, unsigned int pValueSize,
+                unsigned int pMaxBytesToEmit, SectionData *pSD = NULL);
+
+  unsigned int getAlignment() const { return m_Alignment; }
+
+  int64_t getValue() const { return m_Value; }
+
+  unsigned int getValueSize() const { return m_ValueSize; }
+
+  unsigned int getMaxBytesToEmit() const { return m_MaxBytesToEmit; }
+
+  bool hasEmitNops() const { return m_bEmitNops; }
+
+  void setEmitNops(bool pValue) { m_bEmitNops = pValue; }
+
+  static bool classof(const Fragment *F) {
+    return F->getKind() == Fragment::Alignment;
+  }
+  static bool classof(const AlignFragment *) { return true; }
+
+private:
+  /// Alignment - The alignment to ensure, in bytes.
+  unsigned int m_Alignment;
+
+  /// Value - Value to use for filling padding bytes.
+  int64_t m_Value;
+
+  /// ValueSize - The size of the integer (in bytes) of \arg Value.
+  unsigned int m_ValueSize;
+
+  /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
+  /// cannot be satisfied in this width then this fragment is ignored.
+  unsigned int m_MaxBytesToEmit;
+
+  /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
+  /// of using the provided value. The exact interpretation of this flag is
+  /// target dependent.
+  bool m_bEmitNops : 1;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Archive.h b/include/mcld/LD/Archive.h
new file mode 100644
index 0000000..12b574c
--- /dev/null
+++ b/include/mcld/LD/Archive.h
@@ -0,0 +1,243 @@
+//===- Archive.h ----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ARCHIVE_H
+#define MCLD_ARCHIVE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/ADT/HashEntry.h>
+#include <mcld/ADT/HashTable.h>
+#include <mcld/ADT/StringHash.h>
+#include <mcld/Support/GCFactory.h>
+#include <mcld/MC/InputTree.h>
+
+#include <vector>
+#include <string>
+
+namespace mcld
+{
+class InputTree;
+class Input;
+
+/** \class Archive
+ *  \brief This class define the interfacee to Archive files
+ */
+class Archive
+{
+public:
+  static const char   MAGIC[];             ///< magic string
+  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   STRTAB_NAME[];       ///< Name of string table
+  static const char   PAD[];               ///< inter-file align padding
+  static const char   MEMBER_MAGIC[];      ///< fmag field magic #
+
+  struct MemberHeader
+  {
+    char name[16];  ///< Name of the file member.
+    char date[12];  ///< File date, decimal seconds since Epoch
+    char uid[6];    ///< user id in ASCII decimal
+    char gid[6];    ///< group id in ASCII decimal
+    char mode[8];   ///< file mode in ASCII octal
+    char size[10];  ///< file size in ASCII decimal
+    char fmag[2];   ///< Always contains ARFILE_MAGIC_TERMINATOR
+  };
+
+private:
+  template<typename OFFSET_TYPE>
+  struct OffsetCompare
+  {
+    bool operator()(OFFSET_TYPE X, OFFSET_TYPE Y) const
+    { return (X == Y); }
+  };
+
+  struct MurmurHash3
+  {
+    size_t operator()(uint32_t pKey) const
+    {
+      size_t h;
+      h ^= h >> 16;
+      h *= 0x85ebca6b;
+      h ^= h >> 13;
+      h *= 0xc2b2ae35;
+      h ^= h >> 16;
+      return h;
+    }
+  };
+
+  typedef HashEntry<uint32_t,
+                    InputTree::iterator,
+                    OffsetCompare<uint32_t> > ObjectMemberEntryType;
+public:
+  typedef HashTable<ObjectMemberEntryType,
+                    MurmurHash3,
+                    EntryFactory<ObjectMemberEntryType> > ObjectMemberMapType;
+
+  struct ArchiveMember
+  {
+    Input* file;
+    InputTree::iterator lastPos;
+    InputTree::Mover* move;
+  };
+
+private:
+  typedef HashEntry<const llvm::StringRef,
+                    ArchiveMember,
+                    StringCompare<llvm::StringRef> > ArchiveMemberEntryType;
+
+public:
+  typedef HashTable<ArchiveMemberEntryType,
+                    StringHash<ELF>,
+                    EntryFactory<ArchiveMemberEntryType> > ArchiveMemberMapType;
+
+  struct Symbol
+  {
+  public:
+    enum Status
+    {
+      Include,
+      Exclude,
+      Unknown
+    };
+
+    Symbol(const char* pName,
+           uint32_t pOffset,
+           enum Status pStatus)
+     : name(pName), fileOffset(pOffset), status(pStatus)
+    {}
+
+    ~Symbol()
+    {}
+
+  public:
+    std::string name;
+    uint32_t fileOffset;
+    enum Status status;
+  };
+
+  typedef std::vector<Symbol*> SymTabType;
+
+public:
+  Archive(Input& pInputFile, InputFactory& pInputFactory);
+
+  ~Archive();
+
+  /// getARFile - get the Input& of the archive file
+  Input& getARFile();
+
+  /// getARFile - get the Input& of the archive file
+  const Input& getARFile() const;
+
+  /// inputs - get the input tree built from this archive
+  InputTree& inputs();
+
+  /// inputs - get the input tree built from this archive
+  const InputTree& inputs() const;
+
+  /// getObjectMemberMap - get the map that contains the included object files
+  ObjectMemberMapType& getObjectMemberMap();
+
+  /// getObjectMemberMap - get the map that contains the included object files
+  const ObjectMemberMapType& getObjectMemberMap() const;
+
+  /// numOfObjectMember - return the number of included object files
+  size_t numOfObjectMember() const;
+
+  /// addObjectMember - add a object in the object member map
+  /// @param pFileOffset - file offset in symtab represents a object file
+  /// @param pIter - the iterator in the input tree built from this archive
+  bool addObjectMember(uint32_t pFileOffset, InputTree::iterator pIter);
+
+  /// hasObjectMember - check if a object file is included or not
+  /// @param pFileOffset - file offset in symtab represents a object file
+  bool hasObjectMember(uint32_t pFileOffset) const;
+
+  /// getArchiveMemberMap - get the map that contains the included archive files
+  ArchiveMemberMapType& getArchiveMemberMap();
+
+  /// getArchiveMemberMap - get the map that contains the included archive files
+  const ArchiveMemberMapType& getArchiveMemberMap() const;
+
+  /// addArchiveMember - add an archive in the archive member map
+  /// @param pName    - the name of the new archive member
+  /// @param pLastPos - this records the point to insert the next node in the
+  ///                   subtree of this archive member
+  /// @param pMove    - this records the direction to insert the next node in
+  ///                   the subtree of this archive member
+  bool addArchiveMember(const llvm::StringRef& pName,
+                        InputTree::iterator pLastPos,
+                        InputTree::Mover* pMove);
+
+  /// hasArchiveMember - check if an archive file is included or not
+  bool hasArchiveMember(const llvm::StringRef& pName) const;
+
+  /// getArchiveMember - get a archive member
+  ArchiveMember* getArchiveMember(const llvm::StringRef& pName);
+
+  /// getSymbolTable - get the symtab
+  SymTabType& getSymbolTable();
+
+  /// getSymbolTable - get the symtab
+  const SymTabType& getSymbolTable() const;
+
+  /// setSymTabSize - set the memory size of symtab
+  void setSymTabSize(size_t pSize);
+
+  /// getSymTabSize - get the memory size of symtab
+  size_t getSymTabSize() const;
+
+  /// numOfSymbols - return the number of symbols in symtab
+  size_t numOfSymbols() const;
+
+  /// addSymbol - add a symtab entry to symtab
+  /// @param pName - symbol name
+  /// @param pFileOffset - file offset in symtab represents a object file
+  void
+  addSymbol(const char* pName,
+            uint32_t pFileOffset,
+            enum Symbol::Status pStatus = Archive::Symbol::Unknown);
+
+  /// getSymbolName - get the symbol name with the given index
+  const std::string& getSymbolName(size_t pSymIdx) const;
+
+  /// getObjFileOffset - get the file offset that represent a object file
+  uint32_t getObjFileOffset(size_t pSymIdx) const;
+
+  /// getSymbolStatus - get the status of a symbol
+  enum Symbol::Status getSymbolStatus(size_t pSymIdx) const;
+
+  /// setSymbolStatus - set the status of a symbol
+  void setSymbolStatus(size_t pSymIdx, enum Symbol::Status pStatus);
+
+  /// getStrTable - get the extended name table
+  std::string& getStrTable();
+
+  /// getStrTable - get the extended name table
+  const std::string& getStrTable() const;
+
+private:
+  typedef GCFactory<Symbol, 0> SymbolFactory;
+
+private:
+  Input& m_ArchiveFile;
+  InputTree *m_pInputTree;
+  ObjectMemberMapType m_ObjectMemberMap;
+  ArchiveMemberMapType m_ArchiveMemberMap;
+  SymbolFactory m_SymbolFactory;
+  SymTabType m_SymTab;
+  size_t m_SymTabSize;
+  std::string m_StrTab;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ArchiveReader.h b/include/mcld/LD/ArchiveReader.h
index 7d0aa58..5f24f49 100644
--- a/include/mcld/LD/ArchiveReader.h
+++ b/include/mcld/LD/ArchiveReader.h
@@ -11,13 +11,12 @@
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
-#include "mcld/LD/LDReader.h"
+#include <mcld/LD/LDReader.h>
 
 namespace mcld
 {
 
-class Input;
-class InputTree;
+class Archive;
 
 /** \class ArchiveReader
  *  \brief ArchiveReader provides an common interface for all archive readers.
@@ -31,23 +30,11 @@
 
 class ArchiveReader : public LDReader
 {
-protected:
-  struct ArchiveMemberHeader
-  {
-    char name[16];
-    char date[12];
-    char uid[6];
-    char gid[6];
-    char mode[8];
-    char size[10];
-    char finalMagic[2];
-  };
-
 public:
   ArchiveReader();
   virtual ~ArchiveReader();
 
-  virtual InputTree *readArchive(Input &input) = 0;
+  virtual bool readArchive(Archive& pArchive) = 0;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/BSDArchiveReader.h b/include/mcld/LD/BSDArchiveReader.h
index a275621..7abeecc 100644
--- a/include/mcld/LD/BSDArchiveReader.h
+++ b/include/mcld/LD/BSDArchiveReader.h
@@ -11,13 +11,13 @@
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
-#include "mcld/LD/ArchiveReader.h"
+#include <mcld/LD/ArchiveReader.h>
 
 namespace mcld
 {
 
 class Input;
-class InputTree;
+class Archive;
 
 /** \class BSDArchiveReader
  *  \brief BSDArchiveReader reads BSD-variant archive files.
@@ -29,7 +29,7 @@
   BSDArchiveReader();
   ~BSDArchiveReader();
 
-  InputTree *readArchive(Input &input);
+  bool readArchive(Archive& pArchive);
   bool isMyFormat(Input& pInput) const;
 };
 
diff --git a/include/mcld/LD/CIE.h b/include/mcld/LD/CIE.h
index 15e1d69..23dfa22 100644
--- a/include/mcld/LD/CIE.h
+++ b/include/mcld/LD/CIE.h
@@ -13,7 +13,7 @@
 #endif
 
 #include <llvm/Support/DataTypes.h>
-#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/LD/RegionFragment.h>
 
 namespace mcld
 {
@@ -22,7 +22,7 @@
  *  \brief Common Information Entry.
  *  The CIE structure refers to LSB Core Spec 4.1, chap.10.6. Exception Frames.
  */
-class CIE : public MCRegionFragment
+class CIE : public RegionFragment
 {
 public:
   explicit CIE(MemoryRegion& pRegion, uint8_t pFDEEncode);
diff --git a/include/mcld/LD/DiagCommonKinds.inc b/include/mcld/LD/DiagCommonKinds.inc
index ac3d0e1..835e1d4 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(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(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")
@@ -35,8 +35,7 @@
 DIAG(warn_illegal_input_section, DiagnosticEngine::Warning, "section `%0' should not appear in input file `%1': %2", "section `%0' should not appear in input file `%1': %2")
 DIAG(err_cannot_trace_file, DiagnosticEngine::Unreachable, "cannot identify the type (%0) of input file `%1'.\n  %2", "cannot identify the type (%0) of input file `%1'.\n  %2")
 DIAG(err_out_of_range_region, DiagnosticEngine::Unreachable, "requested memory region [%0, %1] is out of range.", "requested memory region [%0, %1] is out of range.")
-DIAG(debug_eh_unsupport, DiagnosticEngine::Debug, "unsupported eh_frame: %0", "unsupported eh_frame: %0")
-DIAG(note_ehframe, DiagnosticEngine::Note, "eh_frame: %0", "eh_frame: %0")
+DIAG(debug_eh_unsupport, DiagnosticEngine::Debug, "unsupported .eh_frame section in input: %0", "unsupported .eh_frame section in input: %0")
 DIAG(note_eh_cie, DiagnosticEngine::Note, "CIE length: %0, aug_string: %1, fde_encodeing: %2", "CIE length: %0, aug_string: %1, fde_encodeing: %2")
 DIAG(note_eh_fde, DiagnosticEngine::Note, "FDE length: %0, offset of PC Begin: %1", "FDE length: %0, offset of PC Begin: %1")
 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)")
diff --git a/include/mcld/LD/DiagGOTPLT.inc b/include/mcld/LD/DiagGOTPLT.inc
index f0d3d2c..172bceb 100644
--- a/include/mcld/LD/DiagGOTPLT.inc
+++ b/include/mcld/LD/DiagGOTPLT.inc
@@ -1,3 +1,5 @@
 DIAG(mips_got_symbol, DiagnosticEngine::Unreachable, "%0 is not a dynamic symbol, do not put it in global got", "%0 is not a dynamic symbol, do not put it in global got")
-DIAG(fail_allocate_memory, DiagnosticEngine::Fatal, "fial to allocate memory for %0", "fial to allocate memory for %0")
-DIAG(reserve_entry_number_mismatch, DiagnosticEngine::Unreachable, "The number of reserved entries for %0 is inconsist", "The number of reserved entries for %0 is inconsist")
+DIAG(fail_allocate_memory_got, DiagnosticEngine::Fatal, "fial to allocate memory for GOT", "fial to allocate memory for GOT")
+DIAG(fail_allocate_memory_plt, DiagnosticEngine::Fatal, "fial to allocate memory for PLT", "fial to allocate memory for PLT")
+DIAG(reserve_entry_number_mismatch_got, DiagnosticEngine::Unreachable, "The number of reserved entries for GOT is inconsist", "The number of reserved entries for GOT is inconsist")
+DIAG(reserve_entry_number_mismatch_plt, DiagnosticEngine::Unreachable, "The number of reserved entries for PLT is inconsist", "The number of reserved entries for PLT is inconsist")
diff --git a/include/mcld/LD/ELFReader.h b/include/mcld/LD/ELFReader.h
index a247804..f893be5 100644
--- a/include/mcld/LD/ELFReader.h
+++ b/include/mcld/LD/ELFReader.h
@@ -15,11 +15,14 @@
 #include <llvm/ADT/StringRef.h>
 #include <llvm/Support/ELF.h>
 #include <llvm/Support/Host.h>
-#include <llvm/MC/MCAssembler.h>
+
 #include <mcld/MC/MCLDInfo.h>
 #include <mcld/MC/MCLDInput.h>
 #include <mcld/MC/MCLinker.h>
-#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/LD/Fragment.h>
+#include <mcld/LD/FillFragment.h>
+#include <mcld/LD/AlignFragment.h>
+#include <mcld/LD/RegionFragment.h>
 #include <mcld/LD/ResolveInfo.h>
 #include <mcld/LD/LDContext.h>
 #include <mcld/Target/GNULDBackend.h>
@@ -124,6 +127,8 @@
 protected:
   LDFileFormat::Kind getLDSectionKind(uint32_t pType, const char* pName) const;
 
+  ResolveInfo::Type getSymType(uint8_t pInfo, uint16_t pShndx) const;
+
   ResolveInfo::Desc getSymDesc(uint16_t pShndx, const Input& pInput) const;
 
   ResolveInfo::Binding getSymBinding(uint8_t pBinding,
@@ -134,10 +139,10 @@
                        uint16_t pShndx,
                        const Input& pInput) const;
 
-  MCFragmentRef* getSymFragmentRef(Input& pInput,
-                                   MCLinker& pLinker,
-                                   uint16_t pShndx,
-                                   uint32_t pOffset) const;
+  FragmentRef* getSymFragmentRef(Input& pInput,
+                                 MCLinker& pLinker,
+                                 uint16_t pShndx,
+                                 uint32_t pOffset) const;
 
   ResolveInfo::Visibility getSymVisibility(uint8_t pVis) const;
 
diff --git a/include/mcld/LD/ELFReader.tcc b/include/mcld/LD/ELFReader.tcc
index 4f5c036..7c3f6d4 100644
--- a/include/mcld/LD/ELFReader.tcc
+++ b/include/mcld/LD/ELFReader.tcc
@@ -223,16 +223,16 @@
   MemoryRegion* region = pInput.memArea()->request(
            pInput.fileOffset() + pInputSectHdr.offset(), pInputSectHdr.size());
 
-  llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
+  SectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
 
-  llvm::MCFragment* frag = NULL;
+  Fragment* frag = NULL;
   if (NULL == region) {
     // If the input section's size is zero, we got a NULL region.
     // use a virtual fill fragment
-    frag = new llvm::MCFillFragment(0x0, 0, 0);
+    frag = new FillFragment(0x0, 0, 0);
   }
   else
-    frag = new MCRegionFragment(*region);
+    frag = new RegionFragment(*region);
 
   uint64_t size = pLinker.getLayout().appendFragment(*frag,
                                                      sect_data,
@@ -297,7 +297,7 @@
     }
 
     // get ld_type
-    ResolveInfo::Type ld_type = static_cast<ResolveInfo::Type>(st_info & 0xF);
+    ResolveInfo::Type ld_type = getSymType(st_info, st_shndx);
 
     // get ld_desc
     ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);
@@ -309,10 +309,10 @@
     uint64_t ld_value = getSymValue(st_value, st_shndx, pInput);
 
     // get the input fragment
-    MCFragmentRef* ld_frag_ref = getSymFragmentRef(pInput,
-                                                   pLinker,
-                                                   st_shndx,
-                                                   ld_value);
+    FragmentRef* ld_frag_ref = getSymFragmentRef(pInput,
+                                                 pLinker,
+                                                 st_shndx,
+                                                 ld_value);
 
     // get ld_vis
     ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);
@@ -381,7 +381,6 @@
                 reinterpret_cast<llvm::ELF::Elf32_Sym*>(symbol_region->start());
 
   uint32_t st_name  = 0x0;
-  uint32_t st_value = 0x0;
   uint32_t st_size  = 0x0;
   uint8_t  st_info  = 0x0;
   uint8_t  st_other = 0x0;
@@ -390,13 +389,11 @@
   st_other = entry->st_other;
   if (llvm::sys::isLittleEndianHost()) {
     st_name  = entry->st_name;
-    st_value = entry->st_value;
     st_size  = entry->st_size;
     st_shndx = entry->st_shndx;
   }
   else {
     st_name  = bswap32(entry->st_name);
-    st_value = bswap32(entry->st_value);
     st_size  = bswap32(entry->st_size);
     st_shndx = bswap16(entry->st_shndx);
   }
@@ -470,7 +467,7 @@
 
     ResolveInfo* resolve_info = symbol->resolveInfo();
 
-    MCFragmentRef* frag_ref =
+    FragmentRef* frag_ref =
          pLinker.getLayout().getFragmentRef(*pSection.getLink(), r_offset);
 
     if (NULL == frag_ref) {
@@ -518,7 +515,7 @@
 
     ResolveInfo* resolve_info = symbol->resolveInfo();
 
-    MCFragmentRef* frag_ref =
+    FragmentRef* frag_ref =
          pLinker.getLayout().getFragmentRef(*pSection.getLink(), r_offset);
 
     if (NULL == frag_ref) {
diff --git a/include/mcld/LD/ELFSectionMap.h b/include/mcld/LD/ELFSectionMap.h
new file mode 100644
index 0000000..e832fa9
--- /dev/null
+++ b/include/mcld/LD/ELFSectionMap.h
@@ -0,0 +1,30 @@
+//===- ELFSectionMap.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LD_ELF_SECTION_MAP_H
+#define MCLD_LD_ELF_SECTION_MAP_H
+
+#include <mcld/LD/SectionMap.h>
+
+namespace mcld
+{
+
+class ELFSectionMap : public SectionMap
+{
+public:
+  ELFSectionMap();
+
+  ~ELFSectionMap();
+
+  void initStandardMaps();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFWriter.h b/include/mcld/LD/ELFWriter.h
index 34a6483..3a73605 100644
--- a/include/mcld/LD/ELFWriter.h
+++ b/include/mcld/LD/ELFWriter.h
@@ -15,10 +15,6 @@
 #include <llvm/Support/ELF.h>
 #include <mcld/MC/MCLDOutput.h>
 
-namespace llvm {
-class MCSectionData;
-}
-
 namespace mcld
 {
 
@@ -27,6 +23,7 @@
 class GNULDBackend;
 class Relocation;
 class LDSection;
+class SectionData;
 
 /** \class ELFWriter
  *  \brief ELFWriter provides basic functions to write ELF sections, symbols,
@@ -93,12 +90,12 @@
 
   void emitRel(const Layout& pLayout,
                const Output& pOutput,
-               const llvm::MCSectionData& pSectionData,
+               const SectionData& pSectionData,
                MemoryRegion& pRegion) const;
 
   void emitRela(const Layout& pLayout,
                 const Output& pOutput,
-                const llvm::MCSectionData& pSectionData,
+                const SectionData& pSectionData,
                 MemoryRegion& pRegion) const;
 
 private:
diff --git a/include/mcld/LD/EhFrame.h b/include/mcld/LD/EhFrame.h
index c303240..9497d79 100644
--- a/include/mcld/LD/EhFrame.h
+++ b/include/mcld/LD/EhFrame.h
@@ -16,20 +16,22 @@
 #include <mcld/ADT/TypeTraits.h>
 #include <mcld/LD/CIE.h>
 #include <mcld/LD/FDE.h>
-#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/LD/RegionFragment.h>
 #include <mcld/Support/GCFactory.h>
 
 namespace mcld
 {
+
+class Input;
+class Layout;
+class SectionData;
+class TargetLDBackend;
+
 /** \class EhFrame
  *  \brief EhFrame represents .eh_frame section
  *  EhFrame is responsible to parse the input eh_frame sections and create
  *  the corresponding CIE and FDE entries.
  */
-
-class TargetLDBackend;
-class Input;
-
 class EhFrame
 {
 public:
@@ -47,14 +49,14 @@
 
   /// readEhFrame - read an .eh_frame section and create the corresponding
   /// CIEs and FDEs
-  /// @param pSD - the MCSectionData of this input eh_frame
+  /// @param pSD - the SectionData of this input eh_frame
   /// @param pSection - the input eh_frame
   /// @param pArea - the memory area which pSection is within.
   /// @ return - size of this eh_frame section, 0 if we do not recognize
   /// this eh_frame or this is an empty section
   uint64_t readEhFrame(Layout& pLayout,
                        const TargetLDBackend& pBackend,
-                       llvm::MCSectionData& pSD,
+                       SectionData& pSD,
                        const Input& pInput,
                        LDSection& pSection,
                        MemoryArea& pArea);
@@ -102,7 +104,7 @@
   { return m_fCanRecognizeAll; }
 
 private:
-  typedef std::vector<llvm::MCFragment*> FragListType;
+  typedef std::vector<Fragment*> FragListType;
 
 private:
   /// addCIE - parse and create a CIE entry
@@ -126,7 +128,7 @@
   /// @ref - GNU gold 1.11, ehframe.h, Eh_frame::skip_leb128.
   bool skipLEB128(ConstAddress* pp, ConstAddress pend);
 
-  /// deleteFragments - release the MemoryRegion and delete MCFragments in pList
+  /// deleteFragments - release the MemoryRegion and delete Fragments in pList
   void deleteFragments(FragListType& pList, MemoryArea& pArea);
 
 private:
diff --git a/include/mcld/LD/FDE.h b/include/mcld/LD/FDE.h
index bd52e78..760a584 100644
--- a/include/mcld/LD/FDE.h
+++ b/include/mcld/LD/FDE.h
@@ -6,15 +6,15 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_FRAME_DESCRIPTION_ENTRY_H
-#define MCLD_FRAME_DESCRIPTION_ENTRY_H
+#ifndef MCLD_LD_FRAME_DESCRIPTION_ENTRY_H
+#define MCLD_LD_FRAME_DESCRIPTION_ENTRY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
 #include <llvm/Support/DataTypes.h>
 #include <mcld/LD/CIE.h>
-#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/LD/RegionFragment.h>
 
 namespace mcld
 {
@@ -23,8 +23,7 @@
  *  \brief Frame Description Entry
  *  The FDE structure refers to LSB Core Spec 4.1, chap.10.6. Exception Frames.
  */
-
-class FDE : public MCRegionFragment
+class FDE : public RegionFragment
 {
 public:
   typedef uint32_t Offset;
diff --git a/include/mcld/LD/FillFragment.h b/include/mcld/LD/FillFragment.h
new file mode 100644
index 0000000..db29111
--- /dev/null
+++ b/include/mcld/LD/FillFragment.h
@@ -0,0 +1,56 @@
+//===- FillFragment.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LD_FILLFRAGMENT_H
+#define MCLD_LD_FILLFRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/DataTypes.h>
+
+#include <mcld/LD/Fragment.h>
+
+namespace mcld
+{
+
+class SectionData;
+
+class FillFragment : public Fragment
+{
+public:
+  FillFragment(int64_t pValue, unsigned int pValueSize, uint64_t pSize,
+               SectionData* pSD = NULL);
+
+  int64_t getValue() const { return m_Value; }
+
+  unsigned getValueSize() const { return m_ValueSize; }
+
+  uint64_t getSize() const { return m_Size; }
+
+  static bool classof(const Fragment *F)
+  { return F->getKind() == Fragment::Fillment; }
+
+  static bool classof(const FillFragment *) { return true; }
+
+private:
+  /// m_Value - Value used for filling bytes
+  int64_t m_Value;
+
+  /// m_ValueSize - The size (in bytes) of \arg Value to use when filling, or 0
+  /// if this is a virtual fill fragment.
+  unsigned int m_ValueSize;
+
+  /// m_Size - The number of bytes to insert.
+  uint64_t m_Size;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Fragment.h b/include/mcld/LD/Fragment.h
new file mode 100644
index 0000000..1baa8df
--- /dev/null
+++ b/include/mcld/LD/Fragment.h
@@ -0,0 +1,78 @@
+//===- Fragment.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_FRAGMENT_H
+#define MCLD_FRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/Support/DataTypes.h>
+
+#include <cstddef>
+
+namespace mcld
+{
+
+class SectionData;
+
+/** \class Fragment
+ *  \brief Fragment is the minimun linking unit of MCLinker.
+ */
+class Fragment : public llvm::ilist_node<Fragment>
+{
+public:
+  enum Type {
+    Alignment,
+    Fillment,
+    Region,
+    Relocation,
+    Target
+  };
+
+public:
+  Fragment();
+
+  Fragment(Type pKind, SectionData *pParent = NULL);
+
+  virtual ~Fragment();
+
+  Type getKind() const { return m_Kind; }
+
+  SectionData *getParent() const { return m_pParent; }
+
+  void setParent(SectionData *pValue) { m_pParent = pValue; }
+
+  uint64_t getOffset() const { return m_Offset; }
+
+  void setOffset(uint64_t pOffset) { m_Offset = pOffset; }
+
+  unsigned int getLayoutOrder() const { return m_LayoutOrder; }
+
+  void setLayoutOrder(unsigned int pValue) { m_LayoutOrder = pValue; }
+
+  static bool classof(const Fragment *O) { return true; }
+
+private:
+  Fragment(const Fragment& );            // DO NOT IMPLEMENT
+  Fragment& operator=(const Fragment& ); // DO NOT IMPLEMENT
+
+private:
+  Type m_Kind;
+  SectionData* m_pParent;
+
+  uint64_t m_Offset;
+  unsigned int m_LayoutOrder;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/FragmentRef.h b/include/mcld/LD/FragmentRef.h
new file mode 100644
index 0000000..20b94c2
--- /dev/null
+++ b/include/mcld/LD/FragmentRef.h
@@ -0,0 +1,86 @@
+//===- FragmentRef.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LD_FRAGMENT_REFERENCE_H
+#define MCLD_LD_FRAGMENT_REFERENCE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/ADT/SizeTraits.h>
+#include <mcld/ADT/TypeTraits.h>
+#include <mcld/LD/Fragment.h>
+
+namespace mcld
+{
+
+class Layout;
+
+/// compunteFragmentSize - compute the specific Fragment size
+uint64_t computeFragmentSize(const Layout& pLayout,
+                             const Fragment& pFrag);
+
+/** \class FragmentRef
+ *  \brief FragmentRef is a reference of a Fragment's contetnt.
+ *
+ */
+class FragmentRef
+{
+public:
+  typedef uint64_t Offset; // FIXME: use SizeTraits<T>::Offset
+  typedef NonConstTraits<unsigned char>::pointer Address;
+  typedef ConstTraits<unsigned char>::pointer ConstAddress;
+
+public:
+  FragmentRef();
+  FragmentRef(Fragment& pFrag, Offset pOffset = 0);
+  ~FragmentRef();
+
+  // -----  modifiers  ----- //
+  FragmentRef& assign(const FragmentRef& pCopy);
+
+  FragmentRef& assign(Fragment& pFrag, Offset pOffset = 0);
+
+  /// memcpy - copy memory
+  /// copy memory from the fragment to the pDesc.
+  /// @pDest - the destination address
+  /// @pNBytes - copies pNBytes from the fragment[offset()+pOffset]
+  /// @pOffset - additional offset. 
+  ///            the start address offset from fragment[offset()]
+  void memcpy(void* pDest, size_t pNBytes, Offset pOffset = 0) const;
+
+  // -----  observers  ----- //
+  Fragment* frag()
+  { return m_pFragment; }
+
+  const Fragment* frag() const
+  { return m_pFragment; }
+
+  Offset offset() const
+  { return m_Offset; }
+
+  // -----  dereference  ----- //
+  Address deref();
+
+  ConstAddress deref() const;
+
+  Address operator*()
+  { return deref(); }
+
+  ConstAddress operator*() const
+  { return deref(); }
+  
+private:
+  Fragment* m_pFragment;
+  Offset m_Offset;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/GNUArchiveReader.h b/include/mcld/LD/GNUArchiveReader.h
index 92c7e7a..39a9438 100644
--- a/include/mcld/LD/GNUArchiveReader.h
+++ b/include/mcld/LD/GNUArchiveReader.h
@@ -12,81 +12,74 @@
 #include <gtest.h>
 #endif
 
-#include "mcld/LD/ArchiveReader.h"
-
-#include <vector>
-#include <string>
-
-namespace llvm
-{
-class MemoryBuffer;
-
-}
+#include <mcld/LD/ArchiveReader.h>
+#include <mcld/LD/Archive.h>
 
 namespace mcld
 {
-class MemoryArea;
+class MemoryAreaFactory;
 class MCLDInfo;
 class Input;
-class InputTree;
+class ELFObjectReader;
+class Archive;
 
 /** \class GNUArchiveReader
  *  \brief GNUArchiveReader reads GNU archive files.
  */
 class GNUArchiveReader : public ArchiveReader
 {
-private:
-  struct SymbolTableEntry;
-
-  enum Constant
-  {
-    /// The length of the magic strign at the end of an archive member header.
-    HeaderFinalMagicSize = 2,
-    /// The length of the magic string at the start of an archive.
-    ArchiveMagicSize = 8
-  };
-  /// The magic string at the start of an archive.
-  static const char ArchiveMagic[ArchiveMagicSize];
-  static const char ThinArchiveMagic[ArchiveMagicSize];
-  /// The Magic string expected at the end of an archive member header.
-  static const char HeaderFinalMagic[HeaderFinalMagicSize];
-
 public:
-  explicit GNUArchiveReader(MCLDInfo &pLDInfo)
-  : m_pLDInfo(pLDInfo)
-  { }
+  explicit GNUArchiveReader(MCLDInfo& pLDInfo,
+                            MemoryAreaFactory& pMemAreaFactory,
+                            ELFObjectReader& pELFObjectReader);
 
-  ~GNUArchiveReader()
-  { }
+  ~GNUArchiveReader();
 
-  /// Read an archive and extract each member in.
-  /// Construct the coresponding Input for each member.
-  InputTree *readArchive(Input &input);
+  /// readArchive - read an archive, include the needed members, and build up
+  /// the subtree
+  bool readArchive(Archive& pArchive);
 
-  bool isMyFormat(Input &input) const;
-
-  LDReader::Endian endian(Input& pFile) const;
+  /// isMyFormat
+  bool isMyFormat(Input& input) const;
 
 private:
-  /// set up the archive, including
-  /// first, read symbol table
-  /// second, read extended file name which is used in thin archive
-  InputTree *setupNewArchive(Input &pInput, size_t off);
+  /// isArchive
+  bool isArchive(const char* pStr) const;
 
-  /// read the archive header, and return the member size
-  size_t readMemberHeader(MemoryArea &pArea,
-                   off_t off,
-                   std::string *p_Name,
-                   off_t *nestedOff,
-                   std::string &p_ExtendedName);
+  /// isThinArchive
+  bool isThinArchive(const char* pStr) const;
 
-  void readSymbolTable(MemoryArea &pArea,
-                      std::vector<SymbolTableEntry> &pSymbolTable,
-                      off_t start,
-                      size_t size);
+  /// isThinArchive
+  bool isThinArchive(Input& input) const;
+
+  /// readMemberHeader - read the header of a member in a archive file and then
+  /// return the corresponding archive member (it may be an input object or
+  /// another archive)
+  /// @param pArchiveRoot  - the archive root that holds the strtab (extended
+  ///                        name table)
+  /// @param pArchiveFile  - the archive that contains the needed object
+  /// @param pFileOffset   - file offset of the member header in the archive
+  /// @param pNestedOffset - used when we find a nested archive
+  Input* readMemberHeader(Archive& pArchiveRoot,
+                          Input& pArchiveFile,
+                          uint32_t pFileOffset,
+                          uint32_t& pNestedOffset);
+
+  /// readSymbolTable - read the archive symbol map (armap)
+  bool readSymbolTable(Archive& pArchive);
+
+  /// readStringTable - read the strtab for long file name of the archive
+  bool readStringTable(Archive& pArchive);
+
+  /// shouldIncludeSymbol - given a sym name from armap and check if we should
+  /// include the corresponding archive member, and then return the decision
+  enum Archive::Symbol::Status
+  shouldIncludeSymbol(const llvm::StringRef& pSymName) const;
 
 private:
-  MCLDInfo &m_pLDInfo;
+  MCLDInfo& m_LDInfo;
+  MemoryAreaFactory& m_MemAreaFactory;
+  ELFObjectReader& m_ELFObjectReader;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/LDSection.h b/include/mcld/LD/LDSection.h
index 4c793de..4c881ca 100644
--- a/include/mcld/LD/LDSection.h
+++ b/include/mcld/LD/LDSection.h
@@ -13,29 +13,20 @@
 #include <gtest.h>
 #endif
 
-#include <llvm/MC/MCSection.h>
-#include <llvm/MC/MCAssembler.h>
 #include <llvm/ADT/StringRef.h>
 #include <llvm/Support/DataTypes.h>
 #include <mcld/LD/LDFileFormat.h>
 #include <string>
 
-namespace llvm {
-
-class MCAsmInfo;
-class raw_ostream;
-
-} // namespace of llvm
-
 namespace mcld {
+
+class SectionData;
+
 /** \class LDSection
  *  \brief LDSection represents a section header entry. It is a unified
- *  abstraction for various file formats.
- *
- *  LDSection contains both the format-dependent data and LLVM specific data.
- *
+ *  abstraction of a section header entry for various file formats.
  */
-class LDSection : public llvm::MCSection
+class LDSection
 {
 public:
   LDSection(const std::string& pName,
@@ -85,7 +76,7 @@
   /// virtual image.
   ///   Before layouting, output's LDSection::offset() should return zero.
   ///   ELF uses sh_addralign to set alignment constraints. In LLVM, alignment
-  ///   constraint is set in MCSectionData::setAlignment. addr() contains the
+  ///   constraint is set in SectionData::setAlignment. addr() contains the
   ///   original ELF::sh_addr. Modulo sh_addr by sh_addralign is not necessary.
   ///   MachO uses the same scenario.
   ///
@@ -137,30 +128,13 @@
   void setType(uint32_t type)
   { m_Type = type; }
 
-  static bool classof(const MCSection *S)
-  { return S->getVariant() == SV_LDContext; }
-
-  static bool classof(const LDSection *)
-  { return true; }
-
-  // -----  methods for adapt to llvm::MCSection  ----- //
-  void PrintSwitchToSection(const llvm::MCAsmInfo &MAI,
-                            llvm::raw_ostream &OS) const
-  { }
-
-  bool UseCodeAlign() const
-  { return true; }
-
-  bool isVirtualSection() const
-  { return false; }
-
-  llvm::MCSectionData* getSectionData()
+  SectionData* getSectionData()
   { return m_pSectionData; }
 
-  const llvm::MCSectionData* getSectionData() const
+  const SectionData* getSectionData() const
   { return m_pSectionData; }
 
-  void setSectionData(llvm::MCSectionData* pSD)
+  void setSectionData(SectionData* pSD)
   { m_pSectionData = pSD; }
 
   bool hasSectionData() const
@@ -191,8 +165,7 @@
   size_t m_Info;
   LDSection* m_pLink;
 
-  // pointer to MCSectionData.
-  llvm::MCSectionData* m_pSectionData;
+  SectionData* m_pSectionData;
 
   // the index of the file
   size_t m_Index;
diff --git a/include/mcld/LD/LDSectionFactory.h b/include/mcld/LD/LDSectionFactory.h
index 49b11c7..b748a64 100644
--- a/include/mcld/LD/LDSectionFactory.h
+++ b/include/mcld/LD/LDSectionFactory.h
@@ -11,10 +11,12 @@
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
+
+#include <string>
+
 #include <mcld/Support/GCFactory.h>
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/LDFileFormat.h>
-#include <string>
 
 namespace mcld
 {
@@ -31,7 +33,7 @@
   ~LDSectionFactory();
 
   /// produce - produce an empty section information.
-  /// This function will create an empty MCSectionData and its LDSection.
+  /// This function will create an empty SectionData and its LDSection.
   /// @param pName - The name of the section.
   /// @param pKind - The kind of the section. Used to create default section map
   /// @param pType - sh_type in ELF.
diff --git a/include/mcld/LD/LDSymbol.h b/include/mcld/LD/LDSymbol.h
index 45c0b75..99b3885 100644
--- a/include/mcld/LD/LDSymbol.h
+++ b/include/mcld/LD/LDSymbol.h
@@ -12,11 +12,11 @@
 #include <gtest.h>
 #endif
 
-#include "mcld/ADT/Uncopyable.h"
-#include "mcld/LD/ResolveInfo.h"
-#include "mcld/MC/MCFragmentRef.h"
-#include <llvm/MC/MCAssembler.h>
-#include <assert.h>
+#include <cassert>
+
+#include <mcld/ADT/Uncopyable.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/FragmentRef.h>
 
 namespace mcld
 {
@@ -31,7 +31,7 @@
   // FIXME: use SizeTrait<32> or SizeTrait<64> instead of big type
   typedef ResolveInfo::SizeType SizeType;
   typedef uint64_t ValueType;
-  typedef MCFragmentRef::Offset Offset;
+  typedef FragmentRef::Offset Offset;
 
 public:
   LDSymbol();
@@ -86,7 +86,7 @@
   ValueType value() const
   { return m_Value; }
 
-  const MCFragmentRef* fragRef() const
+  const FragmentRef* fragRef() const
   { return m_pFragRef; }
 
   SizeType size() const
@@ -110,14 +110,14 @@
   void setValue(ValueType pValue)
   { m_Value = pValue; }
  
-  void setFragmentRef(MCFragmentRef* pFragmentRef);
+  void setFragmentRef(FragmentRef* pFragmentRef);
 
   void setResolveInfo(const ResolveInfo& pInfo);
 
 private:
   // -----  Symbol's fields  ----- //
   ResolveInfo* m_pResolveInfo;
-  MCFragmentRef* m_pFragRef;
+  FragmentRef* m_pFragRef;
   ValueType m_Value;
 
 };
diff --git a/include/mcld/LD/Layout.h b/include/mcld/LD/Layout.h
index 2b36126..4dc9897 100644
--- a/include/mcld/LD/Layout.h
+++ b/include/mcld/LD/Layout.h
@@ -6,20 +6,23 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_LAYOUT_H
-#define MCLD_LAYOUT_H
+#ifndef MCLD_LD_LAYOUT_H
+#define MCLD_LD_LAYOUT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
+
+#include <map>
+
 #include <llvm/ADT/ilist.h>
 #include <llvm/ADT/ilist_node.h>
 #include <llvm/ADT/DenseMap.h>
-#include <llvm/MC/MCAssembler.h>
-#include <mcld/MC/MCFragmentRef.h>
-#include <mcld/Support/GCFactory.h>
+
+#include <mcld/LD/FragmentRef.h>
 #include <mcld/LD/LDSection.h>
+#include <mcld/LD/SectionData.h>
 #include <mcld/MC/MCLDInfo.h>
-#include <map>
+#include <mcld/Support/GCFactory.h>
 
 namespace mcld
 {
@@ -49,17 +52,17 @@
   /// destructor
   ~Layout();
 
-  /// getInputLDSection - give a MCFragment, return the corresponding input
+  /// getInputLDSection - give a Fragment, return the corresponding input
   /// LDSection*
   ///
   /// @return return NULL if the fragment is not found in input
-  LDSection* getInputLDSection(const llvm::MCFragment& pFrag);
+  LDSection* getInputLDSection(const Fragment& pFrag);
 
-  /// getInputLDSection - give a MCFragment, return the corresponding input
+  /// getInputLDSection - give a Fragment, return the corresponding input
   /// LDSection*
   ///
   /// @return return NULL if the fragment is not found in input
-  const LDSection* getInputLDSection(const llvm::MCFragment& pFrag) const;
+  const LDSection* getInputLDSection(const Fragment& pFrag) const;
 
   /// getFragmentRef - give a LDSection in input file and an offset, return
   /// the fragment reference.
@@ -67,7 +70,7 @@
   /// @param pInputSection - the given input section
   /// @param pOffset - the offset, cannot be larger than this input section.
   /// @return if found, return the fragment. Otherwise, return NULL.
-  MCFragmentRef*
+  FragmentRef*
   getFragmentRef(const LDSection& pInputSection, uint64_t pOffset);
 
   /// getFragmentRef - give a fragment and a big offset, return the fragment
@@ -77,55 +80,53 @@
   /// @param pBigOffset - the offset, can be larger than the fragment, but can
   ///                     not larger than this input section.
   /// @return if found, return the fragment. Otherwise, return NULL.
-  MCFragmentRef*
-  getFragmentRef(const llvm::MCFragment& pFrag, uint64_t pBigOffset);
+  FragmentRef* getFragmentRef(const Fragment& pFrag, uint64_t pBigOffset);
 
   /// getOutputOffset - Get the offset of the given fragment inside the
-  /// the output's MCSectionData.
-  uint64_t getOutputOffset(const llvm::MCFragment& pFrag);
+  /// the output's SectionData.
+  uint64_t getOutputOffset(const Fragment& pFrag);
 
   /// getOutputOffset - Get the offset of the given fragment inside the
-  /// the output's MCSectionData.
-  uint64_t getOutputOffset(const llvm::MCFragment& pFrag) const;
+  /// the output's SectionData.
+  uint64_t getOutputOffset(const Fragment& pFrag) const;
 
   /// getOutputOffset - Get the offset of the given fragment inside
-  /// the output's MCSectionData.
+  /// the output's SectionData.
   ///
-  /// @return return -1 if the fragment is not found in output's MCSectionData.
+  /// @return return -1 if the fragment is not found in output's SectionData.
 
-  uint64_t getOutputOffset(const MCFragmentRef& pFragRef);
+  uint64_t getOutputOffset(const FragmentRef& pFragRef);
   /// getOutputOffset - Get the offset of the given fragment inside
-  /// the output's MCSectionData.
+  /// the output's SectionData.
   ///
-  /// @return return -1 if the fragment is not found in output's MCSectionData.
-  uint64_t getOutputOffset(const MCFragmentRef& pFragRef) const;
+  /// @return return -1 if the fragment is not found in output's SectionData.
+  uint64_t getOutputOffset(const FragmentRef& pFragRef) const;
 
-  /// getOutputLDSection - give a MCFragment, return the corresponding output
+  /// getOutputLDSection - give a Fragment, return the corresponding output
   /// LDSection*
   ///
   /// @return return NULL if the fragment is not found in the output
-  LDSection* getOutputLDSection(const llvm::MCFragment& pFrag);
+  LDSection* getOutputLDSection(const Fragment& pFrag);
 
-  /// getOutputLDSection - give a MCFragment, return the corresponding output
+  /// getOutputLDSection - give a Fragment, return the corresponding output
   /// LDSection*
   ///
   /// @return return NULL if the fragment is not found in the output
-  const LDSection* getOutputLDSection(const llvm::MCFragment& pFrag) const;
+  const LDSection* getOutputLDSection(const Fragment& pFrag) const;
 
   // -----  modifiers  ----- //
-  bool layout(Output& pOutput, const TargetLDBackend& pBackend, const MCLDInfo& pInfo);
+  bool layout(Output& pOutput,
+              const TargetLDBackend& pBackend, const MCLDInfo& pInfo);
 
   /// addInputRange
-  void addInputRange(const llvm::MCSectionData& pSD,
-                     const LDSection& pInputHdr);
+  void addInputRange(const SectionData& pSD, const LDSection& pInputHdr);
 
-  /// appendFragment - append the given MCFragment to the given MCSectionData,
-  /// and insert a MCAlignFragment to preserve the required align constraint if
+  /// appendFragment - append the given Fragment to the given SectionData,
+  /// and insert a AlignFragment to preserve the required align constraint if
   /// needed
   /// @return return the inserted size, i.e., the size of pFrag and alignment
   /// size if any
-  uint64_t appendFragment(llvm::MCFragment& pFrag,
-                          llvm::MCSectionData& pSD,
+  uint64_t appendFragment(Fragment& pFrag, SectionData& pSD,
                           uint32_t pAlignConstraint = 1);
 private:
   /** \class Range
@@ -140,14 +141,14 @@
 
   public:
     LDSection* header;
-    llvm::MCFragment* prevRear;
+    Fragment* prevRear;
   };
 
   typedef llvm::iplist<Range> RangeList;
 
-  typedef std::map<const llvm::MCSectionData*, RangeList*> SDRangeMap;
+  typedef std::map<const SectionData*, RangeList*> SDRangeMap;
 
-  typedef GCFactory<MCFragmentRef, 0> FragRefFactory;
+  typedef GCFactory<FragmentRef, 0> FragRefFactory;
 
 private:
   inline bool isFirstRange(const Range& pRange) const
@@ -169,7 +170,7 @@
   }
 
   // get the front fragment in the range.
-  inline llvm::MCFragment* getFront(Range& pRange) const
+  inline Fragment* getFront(Range& pRange) const
   {
     if (!pRange.header->hasSectionData())
       return NULL;
@@ -185,7 +186,7 @@
     return pRange.prevRear->getNextNode();
   }
 
-  inline const llvm::MCFragment* getFront(const Range& pRange) const
+  inline const Fragment* getFront(const Range& pRange) const
   {
     if (!pRange.header->hasSectionData())
       return NULL;
@@ -202,7 +203,7 @@
   }
 
   // get the rear fragment in the range.
-  inline llvm::MCFragment* getRear(Range& pRange) const
+  inline Fragment* getRear(Range& pRange) const
   {
     if (!pRange.header->hasSectionData())
       return NULL;
@@ -217,7 +218,7 @@
     return pRange.getNextNode()->prevRear;
   }
 
-  inline const llvm::MCFragment* getRear(const Range& pRange) const
+  inline const Fragment* getRear(const Range& pRange) const
   {
     if (!pRange.header->hasSectionData())
       return NULL;
@@ -232,23 +233,22 @@
     return pRange.getNextNode()->prevRear;
   }
 
-  MCFragmentRef* getFragmentRef(Range &pRange, uint64_t pOffset);
+  FragmentRef* getFragmentRef(Range &pRange, uint64_t pOffset);
 
-  MCFragmentRef* getFragmentRef(llvm::MCFragment& pFront,
-                                llvm::MCFragment& pRear,
-                                uint64_t pOffset);
+  FragmentRef*
+  getFragmentRef(Fragment& pFront, Fragment& pRear, uint64_t pOffset);
 
-  bool hasLayoutOrder(const llvm::MCFragment& pFragment) const
+  bool hasLayoutOrder(const Fragment& pFragment) const
   { return (pFragment.getLayoutOrder() != ~(0U)); }
 
-  bool hasLayoutOffset(const llvm::MCFragment& pFragment) const
-  { return (pFragment.Offset != ~UINT64_C(0)); }
+  bool hasLayoutOffset(const Fragment& pFragment) const
+  { return (pFragment.getOffset() != ~UINT64_C(0)); }
 
-  bool isValidOffset(const llvm::MCFragment& pFrag, uint64_t pTargetOffset) const;
+  bool isValidOffset(const Fragment& pFrag, uint64_t pTargetOffset) const;
 
-  void setFragmentLayoutOrder(llvm::MCFragment* pFragment);
+  void setFragmentLayoutOrder(Fragment* pFragment);
 
-  void setFragmentLayoutOffset(llvm::MCFragment* pFragment);
+  void setFragmentLayoutOffset(Fragment* pFragment);
 
   /// sortSectionOrder - perform sorting on m_SectionOrder to get final layout
   /// ordering
@@ -260,7 +260,7 @@
   /// a vector to describe the order of sections
   SectionOrder m_SectionOrder;
 
-  /// the map from MCSectionData* to its own RangeList.
+  /// the map from SectionData* to its own RangeList.
   SDRangeMap m_SDRangeMap;
 
   FragRefFactory m_FragRefFactory;
diff --git a/include/mcld/LD/NamePool.h b/include/mcld/LD/NamePool.h
index 79d55b9..1c0f8b3 100644
--- a/include/mcld/LD/NamePool.h
+++ b/include/mcld/LD/NamePool.h
@@ -12,19 +12,16 @@
 #include <gtest.h>
 #endif
 
+#include <utility>
+
 #include <llvm/ADT/StringRef.h>
+
 #include <mcld/ADT/HashTable.h>
 #include <mcld/ADT/StringHash.h>
 #include <mcld/ADT/Uncopyable.h>
 #include <mcld/LD/ResolveInfo.h>
 #include <mcld/LD/Resolver.h>
 #include <mcld/LD/ResolveInfoFactory.h>
-#include <utility>
-
-namespace llvm
-{
-  class MCSectionData;
-}
 
 namespace mcld
 {
@@ -32,6 +29,7 @@
 class Resolver;
 class StringTable;
 class SymbolTableIF;
+class SectionData;
 
 /** \class NamePool
  *  \brief Store symbol and search symbol by name. Can help symbol resolution.
diff --git a/include/mcld/LD/RegionFragment.h b/include/mcld/LD/RegionFragment.h
new file mode 100644
index 0000000..8aba1ef
--- /dev/null
+++ b/include/mcld/LD/RegionFragment.h
@@ -0,0 +1,51 @@
+//===- RegionFragment.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LD_REGION_FRAGMENT_H
+#define MCLD_LD_REGION_FRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/Fragment.h>
+#include <mcld/Support/MemoryRegion.h>
+
+namespace mcld
+{
+
+/** \class RegionFragment
+ *  \brief RegionFragment is a kind of Fragment containing mcld::MemoryRegion
+ */
+class RegionFragment : public Fragment
+{
+public:
+  RegionFragment(MemoryRegion& pRegion, SectionData* pSD = NULL);
+
+  ~RegionFragment();
+
+  MemoryRegion& getRegion()
+  { return m_Region; }
+
+  const MemoryRegion& getRegion() const
+  { return m_Region; }
+
+  static bool classof(const Fragment *F)
+  { return F->getKind() == Fragment::Region; }
+
+  static bool classof(const RegionFragment *)
+  { return true; }
+
+private:
+  MemoryRegion& m_Region;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Relocation.h b/include/mcld/LD/Relocation.h
index 09ff6e4..fa77e64 100644
--- a/include/mcld/LD/Relocation.h
+++ b/include/mcld/LD/Relocation.h
@@ -6,14 +6,16 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef LD_RELOCATION_H
-#define LD_RELOCATION_H
+#ifndef MCLD_LD_RELOCATION_H
+#define MCLD_LD_RELOCATION_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 #include <llvm/ADT/ilist_node.h>
 #include <llvm/Support/DataTypes.h>
-#include <mcld/MC/MCFragmentRef.h>
+
+#include <mcld/LD/Fragment.h>
+#include <mcld/LD/FragmentRef.h>
 #include <mcld/LD/ResolveInfo.h>
 #include <mcld/LD/LDSymbol.h>
 
@@ -24,7 +26,7 @@
 class RelocationFactory;
 class MCLDInfo;
 
-class Relocation : public llvm::MCFragment
+class Relocation : public Fragment
 {
 friend class RelocationFactory;
 
@@ -35,7 +37,7 @@
 
 private:
   Relocation(Type pType,
-             MCFragmentRef* pTargetRef,
+             FragmentRef* pTargetRef,
              Address pAddend,
              DWord pTargetData);
 
@@ -71,11 +73,11 @@
   const DWord& target() const;
 
   /// targetRef - the reference of the target data
-  MCFragmentRef& targetRef()
+  FragmentRef& targetRef()
   { return m_TargetAddress; }
 
   /// targetRef - the reference of the target data
-  const MCFragmentRef& targetRef() const
+  const FragmentRef& targetRef() const
   { return m_TargetAddress; }
 
   void apply(RelocationFactory& pRelocFactory, const MCLDInfo& pLDInfo);
@@ -87,9 +89,9 @@
 
   void setSymInfo(ResolveInfo* pSym);
 
-  // Relocation is a kind of MCFragment with type of FT_Reloc
-  static bool classof(const MCFragment *F)
-  { return F->getKind() == MCFragment::FT_Reloc;}
+  // Relocation is a kind of Fragment with type of FT_Reloc
+  static bool classof(const Fragment *F)
+  { return F->getKind() == Fragment::Relocation; }
   static bool classof(const Relocation *) { return true; }
 
 private:
@@ -102,8 +104,8 @@
   /// m_pSymInfo - resolved symbol info of relocation target symbol
   ResolveInfo* m_pSymInfo;
 
-  /// m_TargetAddress - MCFragmentRef of the place being relocated
-  MCFragmentRef m_TargetAddress;
+  /// m_TargetAddress - FragmentRef of the place being relocated
+  FragmentRef m_TargetAddress;
 
   /// m_Addend - the addend
   Address m_Addend;
diff --git a/include/mcld/LD/RelocationFactory.h b/include/mcld/LD/RelocationFactory.h
index 717a709..cde120f 100644
--- a/include/mcld/LD/RelocationFactory.h
+++ b/include/mcld/LD/RelocationFactory.h
@@ -6,8 +6,8 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef LD_RELOCATION_FACTORY_H
-#define LD_RELOCATION_FACTORY_H
+#ifndef MCLD_LD_RELOCATION_FACTORY_H
+#define MCLD_LD_RELOCATION_FACTORY_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
@@ -19,7 +19,7 @@
 
 class LDSymbol;
 class ResolveInfo;
-class MCFragmentRef;
+class FragmentRef;
 class Layout;
 class GOT;
 class TargetLDBackend;
@@ -60,7 +60,7 @@
   /// @param pFragRef - the place to apply the relocation
   /// @param pAddend - the addend of the relocation entry
   Relocation* produce(Type pType,
-                      MCFragmentRef& pFragRef,
+                      FragmentRef& pFragRef,
                       Address pAddend = 0);
 
   /// produceEmptyEntry - produce an empty relocation which
diff --git a/include/mcld/LD/SectionData.h b/include/mcld/LD/SectionData.h
new file mode 100644
index 0000000..8666195
--- /dev/null
+++ b/include/mcld/LD/SectionData.h
@@ -0,0 +1,80 @@
+//===- SectionData.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LD_SECTION_DATA_H
+#define MCLD_LD_SECTION_DATA_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/ilist.h>
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/Support/DataTypes.h>
+
+#include <mcld/LD/Fragment.h>
+
+namespace mcld
+{
+
+class LDSection;
+
+/** \class SectionData
+ *  \brief SectionData provides a container for all Fragments.
+ */
+class SectionData
+{
+private:
+  SectionData(const SectionData &);            // DO NOT IMPLEMENT
+  SectionData& operator=(const SectionData &); // DO NOT IMPLEMENT
+
+public:
+  typedef llvm::iplist<Fragment> FragmentListType;
+  typedef FragmentListType::iterator iterator;
+  typedef FragmentListType::const_iterator const_iterator;
+
+  typedef FragmentListType::reverse_iterator reverse_iterator;
+  typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
+
+public:
+  explicit SectionData(const LDSection &pSection);
+
+  const LDSection &getSection() const { return *m_pSection; }
+
+  unsigned int getAlignment() const { return m_Alignment; }
+  void setAlignment(unsigned int pValue) { m_Alignment = pValue; }
+
+  FragmentListType &getFragmentList() { return m_Fragments; }
+  const FragmentListType &getFragmentList() const { return m_Fragments; }
+
+  iterator begin() { return m_Fragments.begin(); }
+  const_iterator begin() const { return m_Fragments.begin(); }
+
+  iterator end() { return m_Fragments.end(); }
+  const_iterator end() const { return m_Fragments.end(); }
+
+  reverse_iterator rbegin() { return m_Fragments.rbegin(); }
+  const_reverse_iterator rbegin() const { return m_Fragments.rbegin(); }
+
+  reverse_iterator rend() { return m_Fragments.rend(); }
+  const_reverse_iterator rend() const { return m_Fragments.rend(); }
+
+  size_t size() const { return m_Fragments.size(); }
+
+  bool empty() const { return m_Fragments.empty(); }
+
+private:
+  FragmentListType m_Fragments;
+  const LDSection* m_pSection;
+  unsigned int m_Alignment;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/SectionMerger.h b/include/mcld/LD/SectionMerger.h
index 40f1453..a9ca0c6 100644
--- a/include/mcld/LD/SectionMerger.h
+++ b/include/mcld/LD/SectionMerger.h
@@ -14,7 +14,7 @@
 
 #include <vector>
 #include <string>
-#include <llvm/MC/MCAssembler.h>
+
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/LDContext.h>
 #include <mcld/LD/SectionMap.h>
@@ -47,7 +47,7 @@
   LDSection* getOutputSectHdr(const std::string& pName);
 
   /// getOutputSectData - return a associated output section data
-  llvm::MCSectionData* getOutputSectData(const std::string& pName);
+  SectionData* getOutputSectData(const std::string& pName);
 
   /// addMapping - add a mapping as creating one new output LDSection
   /// @param pName - a input section name
diff --git a/include/mcld/LD/TargetFragment.h b/include/mcld/LD/TargetFragment.h
new file mode 100644
index 0000000..92af5a0
--- /dev/null
+++ b/include/mcld/LD/TargetFragment.h
@@ -0,0 +1,49 @@
+//===- TargetFragment.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LD_TARGET_FRAGMENT_H
+#define MCLD_LD_TARGET_FRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/Fragment.h>
+
+namespace mcld
+{
+
+class SectionData;
+
+/** \class TargetFragment
+ *  \brief TargetFragment is a kind of MCFragment inherited by
+ *  target-depedent Fragment.
+ */
+class TargetFragment : public Fragment
+{
+protected:
+  TargetFragment(Fragment::Type pKind, SectionData* pSD = NULL)
+    : Fragment(pKind, pSD) {}
+
+public:
+  virtual ~TargetFragment() {}
+
+  virtual size_t getSize() const = 0;
+
+public:
+  static bool classof(const Fragment *F)
+  { return F->getKind() == Fragment::Target; }
+
+  static bool classof(const TargetFragment *)
+  { return true; }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCBitcodeInterceptor.h b/include/mcld/MC/MCBitcodeInterceptor.h
deleted file mode 100644
index 182b157..0000000
--- a/include/mcld/MC/MCBitcodeInterceptor.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===- MCBitcodeInterceptor.h ---------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_BITCODE_INTERCEPTOR_H
-#define MCLD_BITCODE_INTERCEPTOR_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <llvm/MC/MCObjectWriter.h>
-
-
-namespace llvm
-{
-  class MCStreamer;
-  class MCObjectStreamer;
-  class MCAsmLayout;
-  class MCAssembler;
-  class MCFixup;
-  class MCFragment;
-  class MCSymbol;
-  class MCSymbolData;
-  class MCSymbolRefExpr;
-  class MCValue;
-  class raw_ostream;
-} // namespace of llvm
-
-namespace mcld
-{
-
-class MCLDInfo;
-class TargetLDBackend;
-
-/** \class MCBitcodeInterceptor
- *  \brief MCBitcodeInterceptor converts bitcode into LDContext
- *
- *  @see LDContext
- *  @see MCObjectWriter
- */
-class MCBitcodeInterceptor : public llvm::MCObjectWriter
-{
-public:
-  MCBitcodeInterceptor(llvm::MCObjectStreamer&, TargetLDBackend&, MCLDInfo&);
-  ~MCBitcodeInterceptor();
-
-  void ExecutePostLayoutBinding(llvm::MCAssembler &Asm,
-                                const llvm::MCAsmLayout &Layout);
-
-  /// RecordRelocation - record relocations
-  //  make a LDRelocation and recordds in the LDContext.
-  void RecordRelocation(const llvm::MCAssembler &Asm,
-                        const llvm::MCAsmLayout &Layout,
-                        const llvm::MCFragment *Fragment,
-                        const llvm::MCFixup &Fixup,
-                        llvm::MCValue Target,
-                        uint64_t &FixedValue);
-
-  /// WriteObject - not really write out a object. Instead, load data to
-  /// LDContext
-  void WriteObject(llvm::MCAssembler &Asm, const llvm::MCAsmLayout &Layout);
-
-private:
-  TargetLDBackend& m_Backend;
-  MCLDInfo& m_LDInfo;
-
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/MC/MCDataFragment.h b/include/mcld/MC/MCDataFragment.h
deleted file mode 100644
index 63ae497..0000000
--- a/include/mcld/MC/MCDataFragment.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//===- MCDataFragment.h ---------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCDATAFRAGMENT_H
-#define MCDATAFRAGMENT_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <llvm/MC/MCAssembler.h>
-#include <llvm/MC/MCInst.h>
-#include <llvm/ADT/SmallString.h>
-#include "mcld/LD/Relocation.h"
-
-namespace mcld
-{
-
-/** \class MCDataFragment
- *  \brief MCDataFragment for mcld
- */
-class MCDataFragment : public  llvm::MCFragment
-{
-public:
-   typedef std::vector<Relocation*> RelocationsType;
-private:
-
-  ///  m_pFragment - llvm MCDataFragment for this MCDataFragment
-  llvm::MCDataFragment* m_pFragment;
-
-  /// m_Relocation - The list of relocations in this fragment
-  RelocationsType m_Relocations;
-
-public:
-  typedef RelocationsType::const_iterator const_relocation_iterator;
-  typedef RelocationsType::iterator relocation_iterator;
-
-public:
-  MCDataFragment(llvm::MCDataFragment& pFragment)
-    : m_pFragment(&pFragment) {
-    setParent( pFragment.getParent() );
-    setAtom( pFragment.getAtom() );
-    setLayoutOrder( pFragment.getLayoutOrder());
-  }
-  ~MCDataFragment(){}
-
-  // ------ observers ------//
-  llvm::SmallString<32> &getContents() { return m_pFragment->getContents();  }
-  const llvm::SmallString<32> &getContents() const { return m_pFragment->getContents();  }
-
-  // relocation access
-  void addRelocation(Relocation &pReloc){  m_Relocations.push_back(&pReloc); }
-
-  RelocationsType &getRelocations() { return m_Relocations; }
-  const RelocationsType &getRelcoations() const { return m_Relocations; }
-
-  relocation_iterator relocation_begin() { return m_Relocations.begin(); }
-  const_relocation_iterator relocation_begin() const { return m_Relocations.begin(); }
-
-  relocation_iterator relocation_end() {return m_Relocations.end();}
-  const_relocation_iterator relocation_end() const {return m_Relocations.end();}
-
-  size_t relocations_size() const { return m_Relocations.size(); }
-
-  // fragment identification
-  static bool classof(const MCFragment *pF) {
-    return pF->getKind() == llvm::MCFragment::FT_Data;
-  }
-  static bool classof(const MCDataFragment *) { return true; }
-
-  // overwrite parent method
-  FragmentType getKind() const { return m_pFragment->getKind(); }
-
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/MC/MCInstFragment.h b/include/mcld/MC/MCInstFragment.h
deleted file mode 100644
index 6dbbc85..0000000
--- a/include/mcld/MC/MCInstFragment.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//===- MCInstFragment.h ---------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCINSTFRAGMENT_H
-#define MCINSTFRAGMENT_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <llvm/MC/MCAssembler.h>
-#include <llvm/MC/MCInst.h>
-#include <llvm/ADT/SmallString.h>
-#include <llvm/ADT/ilist.h>
-#include "mcld/LD/Relocation.h"
-
-
-namespace mcld
-{
-
-/** \class MCInstFragment
- *  \brief MCInstFragment for mcld
- */
-class MCInstFragment : public  llvm::MCFragment
-{
-public:
-  typedef std::vector<Relocation*> RelocationsType;
-private:
-
-  ///  m_pFragment - llvm MCInstFragment for this MCInstFragment
-  llvm::MCInstFragment* m_pFragment;
-
-  /// m_Relocation - The list of relocations in this fragment
-  RelocationsType m_Relocations;
-
-public:
-  typedef RelocationsType::const_iterator const_relocation_iterator;
-  typedef RelocationsType::iterator relocation_iterator;
-
-public:
-  MCInstFragment( llvm::MCInstFragment& pFragment )
-      : m_pFragment(&pFragment){
-    setParent( pFragment.getParent() );
-    setAtom( pFragment.getAtom() );
-    setLayoutOrder( pFragment.getLayoutOrder());
-  }
-  ~MCInstFragment(){}
-
-  // ------ observers ------//
-  llvm::SmallVectorImpl<char> &getCode() { return m_pFragment->getCode(); }
-  const llvm::SmallVectorImpl<char> &getCode() const { return m_pFragment->getCode(); }
-
-  unsigned getInstSize() const { return m_pFragment->getCode().size(); }
-
-  llvm::MCInst &getInst() { return m_pFragment->getInst(); }
-  const llvm::MCInst &getInst() const { return m_pFragment->getInst(); }
-
-  // ----- modifiers ------//
-  void setInst(llvm::MCInst pValue) { m_pFragment->setInst(pValue); }
-
-  // relocation access
-  void addRelocation(Relocation &pReloc){  m_Relocations.push_back(&pReloc); }
-
-  RelocationsType &getRelocations() { return m_Relocations; }
-  const RelocationsType &getRelcoations() const { return m_Relocations; }
-
-  relocation_iterator relocation_begin() { return m_Relocations.begin(); }
-  const_relocation_iterator relocation_begin() const { return m_Relocations.begin(); }
-
-  relocation_iterator relocation_end() {return m_Relocations.end();}
-  const_relocation_iterator relocation_end() const {return m_Relocations.end();}
-
-  size_t relocations_size() const { return m_Relocations.size(); }
-
-  // fragment identification
-  static bool classof(const MCFragment *pF) {
-    return pF->getKind() == llvm::MCFragment::FT_Inst;
-  }
-  static bool classof(const MCInstFragment *) { return true; }
-
-  // overwrite parent method
-  FragmentType getKind() const { return m_pFragment->getKind(); }
-
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/MC/MCLDDriver.h b/include/mcld/MC/MCLDDriver.h
index ec8acf5..2259186 100644
--- a/include/mcld/MC/MCLDDriver.h
+++ b/include/mcld/MC/MCLDDriver.h
@@ -28,13 +28,16 @@
 class TargetLDBackend;
 class MemoryAreaFactory;
 
-//===----------------------------------------------------------------------===//
-/// MCLDDriver - MCLDDriver prepares parameters for MCLinker.
-///
+/** \class MCLDDriver
+ *  \brief MCLDDriver prepares parameters for MCLinker.
+ */
 class MCLDDriver
 {
 public:
-  MCLDDriver(MCLDInfo& pLDInfo, TargetLDBackend& pLDBackend);
+  MCLDDriver(MCLDInfo& pLDInfo,
+             TargetLDBackend& pLDBackend,
+             MemoryAreaFactory& pAreaFactory);
+
   ~MCLDDriver();
 
   /// initMCLinker - initialize MCLinker
@@ -53,20 +56,9 @@
   ///  - check every Input has a correct Attribute
   bool linkable() const;
 
-  /// readSections - read all input section headers
-  bool readSections();
-
   /// mergeSections - put allinput sections into output sections
   bool mergeSections();
 
-  /// readSymbolTables - read symbol tables from the input files.
-  ///  for each input file, loads its symbol table from file.
-  bool readSymbolTables();
-
-  /// mergeSymbolTables - merge the symbol tables of input files into the
-  /// output's symbol table.
-  bool mergeSymbolTables();
-
   /// addStandardSymbols - shared object and executable files need some
   /// standard symbols
   ///   @return if there are some input symbols with the same name to the
@@ -128,6 +120,7 @@
   TargetLDBackend &m_LDBackend;
   MCLinker* m_pLinker;
   SectionMap m_SectionMap;
+  MemoryAreaFactory &m_AreaFactory;
 };
 
 } // end namespace mcld
diff --git a/include/mcld/MC/MCLDFile.h b/include/mcld/MC/MCLDFile.h
index f77fe82..c780cb8 100644
--- a/include/mcld/MC/MCLDFile.h
+++ b/include/mcld/MC/MCLDFile.h
@@ -11,8 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef MCLD_LDFILE_H
-#define MCLD_LDFILE_H
+#ifndef MCLD_LD_FILE_H
+#define MCLD_LD_FILE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
diff --git a/include/mcld/MC/MCLinker.h b/include/mcld/MC/MCLinker.h
index f592d6e..9fe78d8 100644
--- a/include/mcld/MC/MCLinker.h
+++ b/include/mcld/MC/MCLinker.h
@@ -17,8 +17,11 @@
 #include <gtest.h>
 #endif
 
+#include <set>
+#include <string>
+
 #include <llvm/ADT/ilist.h>
-#include <llvm/MC/MCAssembler.h>
+
 #include <mcld/LD/StaticResolver.h>
 #include <mcld/LD/LDSectionFactory.h>
 #include <mcld/LD/LDFileFormat.h>
@@ -30,8 +33,6 @@
 #include <mcld/MC/SymbolCategory.h>
 #include <mcld/Support/GCFactory.h>
 #include <mcld/Support/GCFactoryListTraits.h>
-#include <set>
-#include <string>
 
 namespace mcld {
 
@@ -39,6 +40,7 @@
 class MCLDInfo;
 class LDSection;
 class LDSectionFactory;
+class SectionData;
 class SectionMap;
 class Output;
 class EhFrame;
@@ -78,7 +80,7 @@
                       ResolveInfo::Binding pBinding,
                       ResolveInfo::SizeType pSize,
                       LDSymbol::ValueType pValue,
-                      MCFragmentRef* pFragmentRef,
+                      FragmentRef* pFragmentRef,
                       ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
 
   /// defineSymbol - add a symbol
@@ -108,7 +110,7 @@
                          ResolveInfo::Binding pBinding,
                          ResolveInfo::SizeType pSize,
                          LDSymbol::ValueType pValue,
-                         MCFragmentRef* pFragmentRef,
+                         FragmentRef* pFragmentRef,
                          ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
 
   bool finalizeSymbols();
@@ -136,7 +138,7 @@
                                       uint32_t pAlign = 0x0);
 
   /// getOrCreateSectData - for reader to map and perform section merging immediately
-  llvm::MCSectionData& getOrCreateSectData(LDSection& pSection);
+  SectionData& getOrCreateSectData(LDSection& pSection);
 
   // -----  eh_frame sections  ----- //
   /// addEhFrame - add an exception handling section
@@ -157,7 +159,7 @@
   Relocation* addRelocation(Relocation::Type pType,
                             const LDSymbol& pSym,
                             ResolveInfo& pResolveInfo,
-                            MCFragmentRef& pFragmentRef,
+                            FragmentRef& pFragmentRef,
                             const LDSection& pSection,
                             Relocation::Address pAddend = 0);
 
@@ -201,7 +203,7 @@
                                    ResolveInfo::Binding pBinding,
                                    ResolveInfo::SizeType pSize,
                                    LDSymbol::ValueType pValue,
-                                   MCFragmentRef* pFragmentRef,
+                                   FragmentRef* pFragmentRef,
                                    ResolveInfo::Visibility pVisibility);
 
   LDSymbol* defineAndResolveSymbolForcefully(const llvm::StringRef& pName,
@@ -211,7 +213,7 @@
                                              ResolveInfo::Binding pBinding,
                                              ResolveInfo::SizeType pSize,
                                              LDSymbol::ValueType pValue,
-                                             MCFragmentRef* pFragmentRef,
+                                             FragmentRef* pFragmentRef,
                                              ResolveInfo::Visibility pVisibility);
 
   LDSymbol* defineSymbolAsRefered(const llvm::StringRef& pName,
@@ -221,7 +223,7 @@
                                   ResolveInfo::Binding pBinding,
                                   ResolveInfo::SizeType pSize,
                                   LDSymbol::ValueType pValue,
-                                  MCFragmentRef* pFragmentRef,
+                                  FragmentRef* pFragmentRef,
                                   ResolveInfo::Visibility pVisibility);
 
   LDSymbol* defineAndResolveSymbolAsRefered(const llvm::StringRef& pName,
@@ -231,7 +233,7 @@
                                             ResolveInfo::Binding pBinding,
                                             ResolveInfo::SizeType pSize,
                                             LDSymbol::ValueType pValue,
-                                            MCFragmentRef* pFragmentRef,
+                                            FragmentRef* pFragmentRef,
                                             ResolveInfo::Visibility pVisibility);
 
   bool shouldForceLocal(const ResolveInfo& pInfo) const;
@@ -242,7 +244,7 @@
                                 ResolveInfo::Binding pBinding,
                                 ResolveInfo::SizeType pSize,
                                 LDSymbol::ValueType pValue,
-                                MCFragmentRef* pFragmentRef,
+                                FragmentRef* pFragmentRef,
                                 ResolveInfo::Visibility pVisibility);
 
   LDSymbol* addSymbolFromObject(const llvm::StringRef& pName,
@@ -251,13 +253,13 @@
                                 ResolveInfo::Binding pBinding,
                                 ResolveInfo::SizeType pSize,
                                 LDSymbol::ValueType pValue,
-                                MCFragmentRef* pFragmentRef,
+                                FragmentRef* pFragmentRef,
                                 ResolveInfo::Visibility pVisibility);
 private:
   typedef GCFactory<LDSymbol, 0> LDSymbolFactory;
-  typedef GCFactory<llvm::MCSectionData, 0> LDSectionDataFactory;
-  typedef llvm::iplist<llvm::MCFragment,
-                       GCFactoryListTraits<llvm::MCFragment> > RelocationListType;
+  typedef GCFactory<SectionData, 0> LDSectionDataFactory;
+  typedef llvm::iplist<Fragment,
+                       GCFactoryListTraits<Fragment> > RelocationListType;
   typedef std::set<LDSymbol*> ForceLocalSymbolTable;
   typedef std::vector<LDSymbol*> OutputSymbolTable;
 
diff --git a/include/mcld/MC/MCLinker.tcc b/include/mcld/MC/MCLinker.tcc
index d6c5744..b13e48d 100644
--- a/include/mcld/MC/MCLinker.tcc
+++ b/include/mcld/MC/MCLinker.tcc
@@ -15,7 +15,7 @@
                               ResolveInfo::Binding pBinding,
                               ResolveInfo::SizeType pSize,
                               LDSymbol::ValueType pValue,
-                              MCFragmentRef* pFragmentRef,
+                              FragmentRef* pFragmentRef,
                               ResolveInfo::Visibility pVisibility)
 {
   llvm::StringRef symbol_name = pName;
@@ -62,7 +62,7 @@
                                  ResolveInfo::Binding pBinding,
                                  ResolveInfo::SizeType pSize,
                                  LDSymbol::ValueType pValue,
-                                 MCFragmentRef* pFragmentRef,
+                                 FragmentRef* pFragmentRef,
                                  ResolveInfo::Visibility pVisibility)
 {
   // These if/return should be optimized by compiler.
diff --git a/include/mcld/MC/MCRegionFragment.h b/include/mcld/MC/MCRegionFragment.h
deleted file mode 100644
index 7dd088b..0000000
--- a/include/mcld/MC/MCRegionFragment.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===- MCRegionFragment.h - MCFragment containing MemoryRegion ------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MCLD_REGION_FRAGMENT_H
-#define MCLD_REGION_FRAGMENT_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-
-#include <mcld/Support/MemoryRegion.h>
-#include <llvm/MC/MCAssembler.h>
-
-namespace mcld
-{
-
-/** \class MCRegionFragment
- *  \brief MCRegionFragment is a kind of MCFragment containing 
- *  mcld::MemoryRegion
- */
-class MCRegionFragment : public llvm::MCFragment
-{
-public:
-  MCRegionFragment(MemoryRegion& pRegion, llvm::MCSectionData* pSD = 0);
-  ~MCRegionFragment();
-
-  MemoryRegion& getRegion()
-  { return m_Region; }
-
-  const MemoryRegion& getRegion() const
-  { return m_Region; }
-
-  static bool classof(const MCFragment *F)
-  { return F->getKind() == llvm::MCFragment::FT_Region; }
-
-  static bool classof(const MCRegionFragment *)
-  { return true; }
-
-private:
-  MemoryRegion& m_Region;
-  llvm::MCSectionData* m_pSectionData;
-
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/MC/MCTargetFragment.h b/include/mcld/MC/MCTargetFragment.h
deleted file mode 100644
index 4050708..0000000
--- a/include/mcld/MC/MCTargetFragment.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===- MCTargetFragment.h - MCFragment containing MemoryRegion ------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MCLD_TARGET_FRAGMENT_H
-#define MCLD_TARGET_FRAGMENT_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-
-#include <llvm/MC/MCAssembler.h>
-
-namespace mcld
-{
-
-/** \class MCTargetFragment
- *  \brief MCTargetFragment is a kind of MCFragment inherited by
- *  target-depedent MCFragment.
- */
-class MCTargetFragment : public llvm::MCFragment
-{
-protected:
-  MCTargetFragment(llvm::MCFragment::FragmentType pKind,
-                   llvm::MCSectionData* pSD = 0) :
-                   llvm::MCFragment(pKind, pSD) {}
-
-public:
-  virtual ~MCTargetFragment() {}
-
-  virtual size_t getSize() const = 0;
-
-public:
-  static bool classof(const MCFragment *F)
-  { return F->getKind() == llvm::MCFragment::FT_Target; }
-
-  static bool classof(const MCTargetFragment *)
-  { return true; }
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Support/Path.h b/include/mcld/Support/Path.h
index 54b75c5..de49d3e 100644
--- a/include/mcld/Support/Path.h
+++ b/include/mcld/Support/Path.h
@@ -88,6 +88,7 @@
   std::string string() const;
 
   // -----  decomposition  ----- //
+  Path parent_path() const;
   Path stem() const;
   Path extension() const;
 
diff --git a/include/mcld/Target/GNULDBackend.h b/include/mcld/Target/GNULDBackend.h
index 9f3e308..d05fe72 100644
--- a/include/mcld/Target/GNULDBackend.h
+++ b/include/mcld/Target/GNULDBackend.h
@@ -65,7 +65,9 @@
   virtual ~GNULDBackend();
 
   // -----  readers/writers  ----- //
-  bool initArchiveReader(MCLinker& pLinker, MCLDInfo& pInfo);
+  bool initArchiveReader(MCLinker& pLinker,
+                         MCLDInfo& pInfo,
+                         MemoryAreaFactory& pMemAreaFactory);
   bool initObjectReader(MCLinker& pLinker);
   bool initDynObjReader(MCLinker& pLinker);
   bool initObjectWriter(MCLinker& pLinker);
diff --git a/include/mcld/Target/GOT.h b/include/mcld/Target/GOT.h
index eb0873a..5621778 100644
--- a/include/mcld/Target/GOT.h
+++ b/include/mcld/Target/GOT.h
@@ -6,29 +6,30 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_GOT_H
-#define MCLD_GOT_H
+#ifndef MCLD_GLOBAL_OFFSET_TABLE_H
+#define MCLD_GLOBAL_OFFSET_TABLE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
 #include <mcld/LD/LDSection.h>
-#include <mcld/MC/MCTargetFragment.h>
+#include <mcld/LD/TargetFragment.h>
 
 namespace mcld
 {
 
 class GOT;
 class ResolveInfo;
+class SectionData;
 
 /** \class GOTEntry
  *  \brief The entry of Global Offset Table
  */
-class GOTEntry : public MCTargetFragment
+class GOTEntry : public TargetFragment
 {
 public:
   explicit GOTEntry(uint64_t pContent, size_t pEntrySize,
-                    llvm::MCSectionData* pParent);
+                    SectionData* pParent);
 
   virtual ~GOTEntry();
 
@@ -41,8 +42,8 @@
   void setContent(uint64_t pValue)
   { f_Content = pValue; }
 
-  static bool classof(const MCFragment *pFrag)
-  { return pFrag->getKind() == llvm::MCFragment::FT_Target; }
+  static bool classof(const Fragment *pFrag)
+  { return pFrag->getKind() == Fragment::Target; }
 
   static bool classof(const GOTEntry* pFrag)
   { return true; }
@@ -62,9 +63,7 @@
 class GOT
 {
 protected:
-  GOT(LDSection& pSection,
-      llvm::MCSectionData& pSectionData,
-      size_t pEntrySize);
+  GOT(LDSection& pSection, SectionData& pSectionData, size_t pEntrySize);
 
 public:
   virtual ~GOT();
@@ -75,10 +74,10 @@
   const LDSection& getSection() const
   { return m_Section; }
 
-  llvm::MCSectionData& getSectionData()
+  SectionData& getSectionData()
   { return m_SectionData; }
 
-  const llvm::MCSectionData& getSectionData() const
+  const SectionData& getSectionData() const
   { return m_SectionData; }
 
 public:
@@ -96,7 +95,7 @@
 
 protected:
   LDSection& m_Section;
-  llvm::MCSectionData& m_SectionData;
+  SectionData& m_SectionData;
   size_t f_EntrySize;
 };
 
diff --git a/include/mcld/Target/OutputRelocSection.h b/include/mcld/Target/OutputRelocSection.h
index fe83f2a..b75952b 100644
--- a/include/mcld/Target/OutputRelocSection.h
+++ b/include/mcld/Target/OutputRelocSection.h
@@ -12,8 +12,8 @@
 #include <gtest.h>
 #endif
 
-#include <llvm/MC/MCAssembler.h>
 #include <llvm/ADT/DenseMap.h>
+#include <mcld/LD/SectionData.h>
 #include <mcld/LD/RelocationFactory.h>
 
 namespace mcld
@@ -29,8 +29,8 @@
 {
 public:
   OutputRelocSection(LDSection& pSection,
-                   llvm::MCSectionData& pSectionData,
-                   unsigned int pEntrySize);
+                     SectionData& pSectionData,
+                     unsigned int pEntrySize);
 
   ~OutputRelocSection();
 
@@ -45,14 +45,14 @@
 
   typedef SymRelMapType::iterator SymRelMapIterator;
 
-  typedef llvm::MCSectionData::iterator MCFragmentIterator;
+  typedef SectionData::iterator FragmentIterator;
 
 private:
   /// m_pSection - LDSection of this Section
   LDSection* m_pSection;
 
-  /// m_SectionData - MCSectionData which contains the dynamic relocations
-  llvm::MCSectionData* m_pSectionData;
+  /// m_SectionData - SectionData which contains the dynamic relocations
+  SectionData* m_pSectionData;
 
   /// m_EntryBytes - size of a relocation entry
   unsigned int m_EntryBytes;
@@ -61,7 +61,7 @@
   bool m_isVisit;
 
   /// m_ValidEntryIterator - point to the first valid entry
-  MCFragmentIterator m_ValidEntryIterator;
+  FragmentIterator m_ValidEntryIterator;
 
   /// m_SymRelMap - map the resolved symbol to the Relocation entry
   SymRelMapType m_SymRelMap;
diff --git a/include/mcld/Target/PLT.h b/include/mcld/Target/PLT.h
index 6a7522a..2a4f641 100644
--- a/include/mcld/Target/PLT.h
+++ b/include/mcld/Target/PLT.h
@@ -6,27 +6,29 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef PROCEDURE_LINKAGE_TABLE_H
-#define PROCEDURE_LINKAGE_TABLE_H
+#ifndef MCLD_PROCEDURE_LINKAGE_TABLE_H
+#define MCLD_PROCEDURE_LINKAGE_TABLE_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
-#include <mcld/LD/LDSection.h>
-#include <mcld/MC/MCTargetFragment.h>
 #include <llvm/ADT/ilist.h>
 
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/TargetFragment.h>
+
 namespace mcld
 {
 
+class SectionData;
 class ResolveInfo;
 
 /** \class PLTEntry
  */
-class PLTEntry : public MCTargetFragment
+class PLTEntry : public TargetFragment
 {
 public:
-  PLTEntry(size_t pSize, llvm::MCSectionData* pParent);
+  PLTEntry(size_t pSize, SectionData* pParent);
   virtual ~PLTEntry();
 
   size_t getEntrySize() const
@@ -39,7 +41,7 @@
   { return m_pContent; }
 
   //Used by llvm::cast<>.
-  static bool classof(const MCFragment *O)
+  static bool classof(const Fragment *O)
   { return true; }
 
   size_t getSize() const
@@ -56,13 +58,13 @@
 class PLT
 {
 public:
-  PLT(LDSection& pSection, llvm::MCSectionData& pSectionData);
+  PLT(LDSection& pSection, SectionData& pSectionData);
   virtual ~PLT();
 
   const LDSection& getSection() const
   { return m_Section; }
 
-  const llvm::MCSectionData& getSectionData() const
+  const SectionData& getSectionData() const
   { return m_SectionData; }
 
 public:
@@ -77,7 +79,7 @@
 
 protected:
   LDSection& m_Section;
-  llvm::MCSectionData& m_SectionData;
+  SectionData& m_SectionData;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/Target/TargetLDBackend.h b/include/mcld/Target/TargetLDBackend.h
index 205e1f2..f4c02b5 100644
--- a/include/mcld/Target/TargetLDBackend.h
+++ b/include/mcld/Target/TargetLDBackend.h
@@ -33,6 +33,7 @@
 class Input;
 class LDFileFormat;
 class GOT;
+class MemoryAreaFactory;
 
 //===----------------------------------------------------------------------===//
 /// TargetLDBackend - Generic interface to target specific assembler backends.
@@ -74,7 +75,9 @@
                               const LDSection& pSection) = 0;
 
   // -----  format dependent  ----- //
-  virtual bool initArchiveReader(MCLinker&, MCLDInfo&) = 0;
+  virtual bool initArchiveReader(MCLinker&,
+                                 MCLDInfo&,
+                                 MemoryAreaFactory&) = 0;
   virtual bool initObjectReader(MCLinker&) = 0;
   virtual bool initDynObjReader(MCLinker&) = 0;
   virtual bool initObjectWriter(MCLinker&) = 0;
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index e24596c..822ff36 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -7,14 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "mcld/CodeGen/SectLinker.h"
-#include "mcld/CodeGen/SectLinkerOption.h"
-#include "mcld/MC/MCBitcodeInterceptor.h"
-#include "mcld/MC/MCLDFile.h"
-#include "mcld/Support/RealPath.h"
-#include "mcld/Support/TargetRegistry.h"
-#include "mcld/Target/TargetMachine.h"
-#include "mcld/Target/TargetLDBackend.h"
+#include <mcld/CodeGen/SectLinker.h>
+#include <mcld/CodeGen/SectLinkerOption.h>
+#include <mcld/MC/MCLDFile.h>
+#include <mcld/Support/RealPath.h>
+#include <mcld/Support/TargetRegistry.h>
+#include <mcld/Target/TargetMachine.h>
+#include <mcld/Target/TargetLDBackend.h>
 
 #include <llvm/ADT/OwningPtr.h>
 #include <llvm/Analysis/Passes.h>
@@ -55,6 +54,7 @@
 
 //===----------------------------------------------------------------------===//
 /// Arguments
+//===----------------------------------------------------------------------===//
 // Enable or disable FastISel. Both options are needed, because
 // FastISel is enabled by default with -fast, and we wish to be
 // able to enable or disable fast-isel independently from -O0.
@@ -91,6 +91,7 @@
 
 //===---------------------------------------------------------------------===//
 /// LLVMTargetMachine
+//===----------------------------------------------------------------------===//
 mcld::LLVMTargetMachine::LLVMTargetMachine(llvm::TargetMachine &pTM,
                                            const mcld::Target& pTarget,
                                            const std::string& pTriple )
@@ -265,17 +266,19 @@
                                                 llvm::MCContext *&Context)
 {
   const MCAsmInfo &MAI = *getTM().getMCAsmInfo();
+  const MCInstrInfo &MII = *getTM().getInstrInfo();
+  const MCRegisterInfo &MRI = *getTM().getRegisterInfo();
   const MCSubtargetInfo &STI = getTM().getSubtarget<MCSubtargetInfo>();
 
   MCInstPrinter *InstPrinter =
     getTarget().get()->createMCInstPrinter(MAI.getAssemblerDialect(), MAI,
-                                           *(getTM().getInstrInfo()),
+                                           MII,
                                            Context->getRegisterInfo(), STI);
 
   MCCodeEmitter* MCE = 0;
   MCAsmBackend *MAB = 0;
   if (ArgShowMCEncoding) {
-    MCE = getTarget().get()->createMCCodeEmitter(*(getTM().getInstrInfo()), STI, *Context);
+    MCE = getTarget().get()->createMCCodeEmitter(MII, MRI, STI, *Context);
     MAB = getTarget().get()->createMCAsmBackend(m_Triple);
   }
 
@@ -308,8 +311,11 @@
                                                  llvm::MCContext *&Context)
 {
   // MCCodeEmitter
+  const MCInstrInfo &MII = *getTM().getInstrInfo();
+  const MCRegisterInfo &MRI = *getTM().getRegisterInfo();
   const MCSubtargetInfo &STI = getTM().getSubtarget<MCSubtargetInfo>();
-  MCCodeEmitter* MCE = getTarget().get()->createMCCodeEmitter(*getTM().getInstrInfo(), STI, *Context);
+  MCCodeEmitter* MCE =
+    getTarget().get()->createMCCodeEmitter(MII, MRI, STI, *Context);
 
   // MCAsmBackend
   MCAsmBackend* MAB = getTarget().get()->createMCAsmBackend(m_Triple);
@@ -342,50 +348,10 @@
                                               MCLDFile::Type pOutputLinkType,
                                               llvm::MCContext *&Context)
 {
-// FIXME: when MCLinker can directly turn bitcode into shared object, turn on this
-// block of code.
-#if 0
-  // Initialize MCAsmStreamer first, than chain its output into SectLinker.
-  // MCCodeEmitter
-  const MCSubtargetInfo &STI = getTM().getSubtarget<MCSubtargetInfo>();
-  MCCodeEmitter* MCE = getTarget().get()->createMCCodeEmitter(*getTM().getInstrInfo(),
-                                                              STI,
-                                                              *Context);
-  // MCAsmBackend
-  MCAsmBackend *MAB = getTarget().get()->createMCAsmBackend(m_Triple);
-  if (MCE == 0 || MAB == 0)
-    return true;
-
-  // now, we have MCCodeEmitter and MCAsmBackend, we can create AsmStreamer.
-  MCStreamer* AsmStreamer =
-    getTarget().get()->createMCObjectStreamer(m_Triple,
-                                              *Context,
-                                              *MAB,
-                                              llvm::nulls(),
-                                              MCE,
-                                              getTM().hasMCRelaxAll(),
-                                              getTM().hasMCNoExecStack());
-  if (0 == AsmStreamer)
-    return true;
-
-  AsmStreamer->InitSections();
-  AsmPrinter* printer = getTarget().get()->createAsmPrinter(getTM(), *AsmStreamer);
-  if (0 == printer)
-    return true;
-  pPM.add(printer);
-#endif
   TargetLDBackend* ldBackend = getTarget().createLDBackend(m_Triple);
   if (0 == ldBackend)
     return true;
 
-// FIXME: when MCLinker can directly turn bitcode into shared object, turn on this
-// block of code.
-#if 0
-  MCBitcodeInterceptor* objReader = new MCBitcodeInterceptor(
-                                 static_cast<MCObjectStreamer&>(*AsmStreamer),
-                                 *ldBackend,
-                                 getLDInfo());
-#endif
   // set up output's SOName
   if (pOutputLinkType == MCLDFile::DynObj &&
       pLinkerOpt->info().output().name().empty()) {
diff --git a/lib/CodeGen/SectLinker.cpp b/lib/CodeGen/SectLinker.cpp
index 4f32c4f..0e4c3ad 100644
--- a/lib/CodeGen/SectLinker.cpp
+++ b/lib/CodeGen/SectLinker.cpp
@@ -77,7 +77,7 @@
   initializeInputTree(PosDepOpts);
   initializeInputOutput(info);
   // Now, all input arguments are prepared well, send it into MCLDDriver
-  m_pLDDriver = new MCLDDriver(info, *m_pLDBackend);
+  m_pLDDriver = new MCLDDriver(info, *m_pLDBackend, *memAreaFactory());
 
   return false;
 }
@@ -133,16 +133,11 @@
     return true;
 
 
-  // 6. - read all sections
-  if (!m_pLDDriver->readSections() ||
-      !m_pLDDriver->mergeSections())
+  // 6. - merge all sections
+  if (!m_pLDDriver->mergeSections())
     return true;
 
-  // 7. - read all symbol tables of input files and resolve them
-  if (!m_pLDDriver->readSymbolTables())
-    return true;
-
-  // 7.a - add standard symbols and target-dependent symbols
+  // 7. - add standard symbols and target-dependent symbols
   // m_pLDDriver->addUndefSymbols();
   if (!m_pLDDriver->addStandardSymbols() ||
       !m_pLDDriver->addTargetSymbols())
@@ -157,7 +152,7 @@
   // 10. - linear layout
   m_pLDDriver->layout();
 
-  // 10.b - post-layout
+  // 10.b - post-layout (create segment, instruction relaxing)
   m_pLDDriver->postlayout();
 
   // 11. - finalize symbol value
diff --git a/lib/LD/AlignFragment.cpp b/lib/LD/AlignFragment.cpp
new file mode 100644
index 0000000..5154b0b
--- /dev/null
+++ b/lib/LD/AlignFragment.cpp
@@ -0,0 +1,27 @@
+//===- AlignFragment.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/AlignFragment.h>
+
+#include <mcld/LD/SectionData.h>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// AlignFragment
+//===----------------------------------------------------------------------===//
+AlignFragment::AlignFragment(unsigned int pAlignment,
+                             int64_t pValue,
+                             unsigned int pValueSize,
+                             unsigned int pMaxBytesToEmit,
+                             SectionData *pSD)
+  : Fragment(Fragment::Alignment, pSD), m_Alignment(pAlignment),
+    m_Value(pValue), m_ValueSize(pValueSize), m_MaxBytesToEmit(pMaxBytesToEmit),
+    m_bEmitNops(false) {
+}
+
diff --git a/lib/LD/Android.mk b/lib/LD/Android.mk
index d7cccfa..d3c9dd8 100644
--- a/lib/LD/Android.mk
+++ b/lib/LD/Android.mk
@@ -5,6 +5,8 @@
 # =====================================================
 
 mcld_ld_SRC_FILES := \
+  AlignFragment.cpp \
+  Archive.cpp \
   ArchiveReader.cpp \
   BranchIsland.cpp  \
   CIE.cpp \
@@ -22,6 +24,9 @@
   EhFrameHdr.cpp  \
   ExecWriter.cpp  \
   FDE.cpp \
+  FillFragment.cpp \
+  Fragment.cpp \
+  FragmentRef.cpp \
   Layout.cpp  \
   LDContext.cpp \
   LDFileFormat.cpp  \
@@ -33,11 +38,13 @@
   MsgHandler.cpp  \
   NamePool.cpp  \
   ObjectWriter.cpp  \
+  RegionFragment.cpp \
   Relocation.cpp  \
   RelocationFactory.cpp \
   ResolveInfo.cpp \
   ResolveInfoFactory.cpp  \
   Resolver.cpp  \
+  SectionData.cpp \
   SectionMap.cpp  \
   SectionMerger.cpp \
   StaticResolver.cpp  \
diff --git a/lib/LD/Archive.cpp b/lib/LD/Archive.cpp
new file mode 100644
index 0000000..2805541
--- /dev/null
+++ b/lib/LD/Archive.cpp
@@ -0,0 +1,229 @@
+//===- Archive.cpp --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/Archive.h>
+#include <mcld/MC/InputFactory.h>
+#include <llvm/ADT/StringRef.h>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// Archive
+const char   Archive::MAGIC[]            = "!<arch>\n";
+const char   Archive::THIN_MAGIC[]       = "!<thin>\n";
+const size_t Archive::MAGIC_LEN          = sizeof(Archive::MAGIC) - 1;
+const char   Archive::SVR4_SYMTAB_NAME[] = "/               ";
+const char   Archive::STRTAB_NAME[]      = "//              ";
+const char   Archive::PAD[]              = "\n";
+const char   Archive::MEMBER_MAGIC[]     = "`\n";
+
+Archive::Archive(Input& pInputFile, InputFactory& pInputFactory)
+ : m_ArchiveFile(pInputFile),
+   m_pInputTree(NULL),
+   m_SymbolFactory(32)
+{
+  m_pInputTree = new InputTree(pInputFactory);
+}
+
+Archive::~Archive()
+{
+  delete m_pInputTree;
+}
+
+/// getARFile - get the Input& of the archive file
+Input& Archive::getARFile()
+{
+  return m_ArchiveFile;
+}
+
+/// getARFile - get the Input& of the archive file
+const Input& Archive::getARFile() const
+{
+  return m_ArchiveFile;
+}
+
+/// inputs - get the input tree built from this archive 
+InputTree& Archive::inputs()
+{
+  return *m_pInputTree;
+}
+
+/// inputs - get the input tree built from this archive 
+const InputTree& Archive::inputs() const
+{
+  return *m_pInputTree;
+}
+
+/// getObjectMemberMap - get the map that contains the included object files
+Archive::ObjectMemberMapType& Archive::getObjectMemberMap()
+{
+  return m_ObjectMemberMap;
+}
+
+/// getObjectMemberMap - get the map that contains the included object files
+const Archive::ObjectMemberMapType& Archive::getObjectMemberMap() const
+{
+  return m_ObjectMemberMap;
+}
+
+/// numOfObjectMember - return the number of included object files
+size_t Archive::numOfObjectMember() const
+{
+  return m_ObjectMemberMap.numOfEntries();
+}
+
+/// addObjectMember - add a object in the object member map
+/// @param pFileOffset - file offset in symtab represents a object file
+/// @param pIter - the iterator in the input tree built from this archive
+bool Archive::addObjectMember(uint32_t pFileOffset, InputTree::iterator pIter)
+{
+  bool exist;
+  ObjectMemberEntryType* entry = m_ObjectMemberMap.insert(pFileOffset, exist);
+  if (!exist)
+    entry->setValue(pIter);
+  return !exist;
+}
+
+/// hasObjectMember - check if a object file is included or not
+/// @param pFileOffset - file offset in symtab represents a object file
+bool Archive::hasObjectMember(uint32_t pFileOffset) const
+{
+  return (m_ObjectMemberMap.find(pFileOffset) != m_ObjectMemberMap.end());
+}
+
+/// getArchiveMemberMap - get the map that contains the included archive files
+Archive::ArchiveMemberMapType& Archive::getArchiveMemberMap()
+{
+  return m_ArchiveMemberMap;
+}
+
+/// getArchiveMemberMap - get the map that contains the included archive files
+const Archive::ArchiveMemberMapType& Archive::getArchiveMemberMap() const
+{
+  return m_ArchiveMemberMap;
+}
+
+/// addArchiveMember - add an archive in the archive member map
+/// @param pName    - the name of the new archive member
+/// @param pLastPos - this records the point to insert the next node in the
+///                   subtree of this archive member
+/// @param pMove    - this records the direction to insert the next node in the
+///                   subtree of this archive member
+bool Archive::addArchiveMember(const llvm::StringRef& pName,
+                               InputTree::iterator pLastPos,
+                               InputTree::Mover* pMove)
+{
+  bool exist;
+  ArchiveMemberEntryType* entry = m_ArchiveMemberMap.insert(pName, exist);
+  if (!exist) {
+    ArchiveMember& ar = entry->value();
+    ar.file = *pLastPos;
+    ar.lastPos = pLastPos;
+    ar.move = pMove;
+  }
+  return !exist;
+}
+
+/// hasArchiveMember - check if an archive file is included or not
+bool Archive::hasArchiveMember(const llvm::StringRef& pName) const
+{
+  return (m_ArchiveMemberMap.find(pName) != m_ArchiveMemberMap.end());
+}
+
+/// getArchiveMember - get a archive member
+Archive::ArchiveMember* Archive::getArchiveMember(const llvm::StringRef& pName)
+{
+  ArchiveMemberMapType::iterator it = m_ArchiveMemberMap.find(pName);
+  if (it != m_ArchiveMemberMap.end())
+    return &(it.getEntry()->value());
+  return NULL;
+}
+
+/// getSymbolTable - get the symtab
+Archive::SymTabType& Archive::getSymbolTable()
+{
+  return m_SymTab;
+}
+
+/// getSymbolTable - get the symtab
+const Archive::SymTabType& Archive::getSymbolTable() const
+{
+  return m_SymTab;
+}
+
+/// setSymTabSize - set the memory size of symtab
+void Archive::setSymTabSize(size_t pSize)
+{
+  m_SymTabSize = pSize;
+}
+
+/// getSymTabSize - get the memory size of symtab
+size_t Archive::getSymTabSize() const
+{
+  return m_SymTabSize;
+}
+
+/// numOfSymbols - return the number of symbols in symtab
+size_t Archive::numOfSymbols() const
+{
+  return m_SymTab.size();
+}
+
+/// addSymbol - add a symtab entry to symtab
+/// @param pName - symbol name
+/// @param pFileOffset - file offset in symtab represents a object file
+void Archive::addSymbol(const char* pName,
+                        uint32_t pFileOffset,
+                        enum Archive::Symbol::Status pStatus)
+{
+  Symbol* entry = m_SymbolFactory.allocate();
+  new (entry) Symbol(pName, pFileOffset, pStatus);
+  m_SymTab.push_back(entry);
+}
+
+/// getSymbolName - get the symbol name with the given index
+const std::string& Archive::getSymbolName(size_t pSymIdx) const
+{
+  assert(pSymIdx < numOfSymbols());
+  return m_SymTab[pSymIdx]->name;
+}
+
+/// getObjFileOffset - get the file offset that represent a object file
+uint32_t Archive::getObjFileOffset(size_t pSymIdx) const
+{
+  assert(pSymIdx < numOfSymbols());
+  return m_SymTab[pSymIdx]->fileOffset;
+}
+
+/// getSymbolStatus - get the status of a symbol
+enum Archive::Symbol::Status Archive::getSymbolStatus(size_t pSymIdx) const
+{
+  assert(pSymIdx < numOfSymbols());
+  return m_SymTab[pSymIdx]->status;
+}
+
+/// setSymbolStatus - set the status of a symbol
+void Archive::setSymbolStatus(size_t pSymIdx,
+                              enum Archive::Symbol::Status pStatus)
+{
+  assert(pSymIdx < numOfSymbols());
+  m_SymTab[pSymIdx]->status = pStatus;
+}
+
+/// getStrTable - get the extended name table
+std::string& Archive::getStrTable()
+{
+  return m_StrTab;
+}
+
+/// getStrTable - get the extended name table
+const std::string& Archive::getStrTable() const
+{
+  return m_StrTab;
+}
+
diff --git a/lib/LD/BSDArchiveReader.cpp b/lib/LD/BSDArchiveReader.cpp
index 079153b..bd59844 100644
--- a/lib/LD/BSDArchiveReader.cpp
+++ b/lib/LD/BSDArchiveReader.cpp
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 #include <mcld/MC/MCLDInput.h>
-#include <mcld/MC/InputTree.h>
 #include <mcld/LD/BSDArchiveReader.h>
+#include <mcld/LD/Archive.h>
 
 using namespace mcld;
 
@@ -20,10 +20,10 @@
 {
 }
 
-InputTree *BSDArchiveReader::readArchive(Input &input)
+bool BSDArchiveReader::readArchive(Archive& pArchive)
 {
   // TODO
-  return NULL;
+  return true;
 }
 
 bool BSDArchiveReader::isMyFormat(Input& pInput) const
diff --git a/lib/LD/CIE.cpp b/lib/LD/CIE.cpp
index c2f4317..5ddb166 100644
--- a/lib/LD/CIE.cpp
+++ b/lib/LD/CIE.cpp
@@ -11,11 +11,11 @@
 
 using namespace mcld;
 
-//==========================
+//===----------------------------------------------------------------------===//
 // CIE
-
+//===----------------------------------------------------------------------===//
 CIE::CIE(MemoryRegion& pRegion, uint8_t pFDEEncode)
-  : MCRegionFragment(pRegion), m_FDEEncoding(pFDEEncode) {
+  : RegionFragment(pRegion), m_FDEEncoding(pFDEEncode) {
 }
 
 CIE::~CIE()
diff --git a/lib/LD/DiagnosticEngine.cpp b/lib/LD/DiagnosticEngine.cpp
index 8b209c9..173b4f2 100644
--- a/lib/LD/DiagnosticEngine.cpp
+++ b/lib/LD/DiagnosticEngine.cpp
@@ -25,9 +25,6 @@
 {
   if (m_OwnPrinter && m_pPrinter != NULL)
     delete m_pPrinter;
-
-  if (NULL != m_pLineInfo)
-    delete m_pLineInfo;
 }
 
 void DiagnosticEngine::reset(const MCLDInfo& pLDInfo)
diff --git a/lib/LD/ELFObjectReader.cpp b/lib/LD/ELFObjectReader.cpp
index c69149c..e645567 100644
--- a/lib/LD/ELFObjectReader.cpp
+++ b/lib/LD/ELFObjectReader.cpp
@@ -6,20 +6,21 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include <llvm/Support/ELF.h>
-#include <llvm/ADT/Twine.h>
-#include <mcld/LD/ELFObjectReader.h>
-#include <mcld/LD/ELFReader.h>
-#include <mcld/MC/MCLDInput.h>
-#include <mcld/MC/MCLinker.h>
-#include <mcld/MC/MCRegionFragment.h>
-#include <mcld/Target/GNULDBackend.h>
-#include <mcld/Support/MsgHandling.h>
 
 #include <string>
 #include <cassert>
 
-using namespace llvm;
+#include <llvm/Support/ELF.h>
+#include <llvm/ADT/Twine.h>
+
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/LD/RegionFragment.h>
+#include <mcld/LD/ELFReader.h>
+#include <mcld/LD/ELFObjectReader.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/Support/MsgHandling.h>
+
 using namespace mcld;
 
 //==========================
@@ -176,10 +177,9 @@
                                                llvm::ELF::SHT_NOBITS,
                                                llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE);
 
-        llvm::MCSectionData& sect_data = m_Linker.getOrCreateSectData(**section);
-                                         /*  value, valsize, size*/
-        llvm::MCFillFragment* frag =
-                    new llvm::MCFillFragment(0x0,   1,       (*section)->size());
+        SectionData& sect_data = m_Linker.getOrCreateSectData(**section);
+                                            /*  value, valsize, size*/
+        FillFragment* frag = new FillFragment(0x0,   1,       (*section)->size());
 
         uint64_t size = m_Linker.getLayout().appendFragment(*frag,
                                                             sect_data,
diff --git a/lib/LD/ELFReader.cpp b/lib/LD/ELFReader.cpp
index d74d314..fce4e8b 100644
--- a/lib/LD/ELFReader.cpp
+++ b/lib/LD/ELFReader.cpp
@@ -11,6 +11,7 @@
 #include <llvm/ADT/Twine.h>
 #include <llvm/Support/ELF.h>
 #include <llvm/Support/Host.h>
+
 #include <mcld/MC/MCLinker.h>
 #include <mcld/LD/ELFReader.h>
 #include <mcld/Target/GNULDBackend.h>
@@ -86,6 +87,21 @@
   return LDFileFormat::MetaData;
 }
 
+/// getSymType
+ResolveInfo::Type ELFReaderIF::getSymType(uint8_t pInfo, uint16_t pShndx) const
+{
+  ResolveInfo::Type result = static_cast<ResolveInfo::Type>(pInfo & 0xF);
+  if (llvm::ELF::SHN_ABS == pShndx && ResolveInfo::Section == result) {
+    // In Mips, __gp_disp is a special section symbol. Its name comes from
+    // .strtab, not .shstrtab. However, it is unique. Only it is also a ABS
+    // symbol. So here is a tricky to identify __gp_disp and convert it to
+    // Object symbol.
+    return ResolveInfo::Object;
+  }
+
+  return result;
+}
+
 /// getSymDesc
 ResolveInfo::Desc ELFReaderIF::getSymDesc(uint16_t pShndx, const Input& pInput) const
 {
@@ -135,7 +151,7 @@
 }
 
 /// getSymFragmentRef
-MCFragmentRef*
+FragmentRef*
 ELFReaderIF::getSymFragmentRef(Input& pInput,
                                MCLinker& pLinker,
                                uint16_t pShndx,
@@ -151,7 +167,7 @@
     unreachable(diag::unreachable_invalid_section_idx) << pShndx
                                                        << pInput.path().native();
 
-  MCFragmentRef* result = pLinker.getLayout().getFragmentRef(*sect_hdr, pOffset);
+  FragmentRef* result = pLinker.getLayout().getFragmentRef(*sect_hdr, pOffset);
   return result;
 }
 
diff --git a/lib/LD/ELFSectionMap.cpp b/lib/LD/ELFSectionMap.cpp
new file mode 100644
index 0000000..9d433d7
--- /dev/null
+++ b/lib/LD/ELFSectionMap.cpp
@@ -0,0 +1,87 @@
+//===- ELFSectionMap.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Support/MsgHandling.h>
+#include <mcld/LD/ELFSectionMap.h>
+
+using namespace mcld;
+
+struct NameMap {
+  const char* from;
+  const char* to;
+};
+
+// Common mappings of ELF and other formants. Now only ELF specific mappings
+// are added
+static const NameMap map[] =
+{
+  {".text", ".text"},
+  {".rodata", ".rodata"},
+  {".data.rel.ro.local", ".data.rel.ro.local"},
+  {".data.rel.ro", ".data.rel.ro"},
+  {".data", ".data"},
+  {".bss", ".bss"},
+  {".tdata", ".tdata"},
+  {".tbss", ".tbss"},
+  {".init_array", ".init_array"},
+  {".fini_array", ".fini_array"},
+  // TODO: Support DT_INIT_ARRAY for all constructors?
+  {".ctors", ".ctors"},
+  {".dtors", ".dtors"},
+  {".sdata", ".sdata"},
+  {".sbss", ".sbss"},
+  // FIXME: in GNU ld, if we are creating a shared object .sdata2 and .sbss2
+  // sections would be handled differently.
+  {".sdata2", ".sdata"},
+  {".sbss2", ".sbss"},
+  {".lrodata", ".lrodata"},
+  {".ldata", ".ldata"},
+  {".lbss", ".lbss"},
+  {".gcc_except_table", ".gcc_except_table"},
+  {".gnu.linkonce.d.rel.ro.local", ".data.rel.ro.local"},
+  {".gnu.linkonce.d.rel.ro", ".data.rel.ro"},
+  {".gnu.linkonce.t", ".text"},
+  {".gnu.linkonce.r", ".rodata"},
+  {".gnu.linkonce.d", ".data"},
+  {".gnu.linkonce.b", ".bss"},
+  {".gnu.linkonce.s", ".sdata"},
+  {".gnu.linkonce.sb", ".sbss"},
+  {".gnu.linkonce.s2", ".sdata"},
+  {".gnu.linkonce.sb2", ".sbss"},
+  {".gnu.linkonce.wi", ".debug_info"},
+  {".gnu.linkonce.td", ".tdata"},
+  {".gnu.linkonce.tb", ".tbss"},
+  {".gnu.linkonce.lr", ".lrodata"},
+  {".gnu.linkonce.l", ".ldata"},
+  {".gnu.linkonce.lb", ".lbss"},
+};
+
+static const int map_size = (sizeof(map) / sizeof(map[0]));
+
+ELFSectionMap::ELFSectionMap()
+{
+}
+
+ELFSectionMap::~ELFSectionMap()
+{
+}
+
+void ELFSectionMap::initStandardMaps()
+{
+  for (unsigned int i = 0; i < map_size; ++i) {
+    bool exist = false;
+    NamePair& pair = append(map[i].from, map[i].to, exist);
+    if (exist) {
+      warning(diag::warn_duplicate_std_sectmap) << map[i].from
+                                                << map[i].to
+                                                << pair.from
+                                                << pair.to;
+    }
+  }
+}
+
diff --git a/lib/LD/ELFWriter.cpp b/lib/LD/ELFWriter.cpp
index 2f2d898..bf3152a 100644
--- a/lib/LD/ELFWriter.cpp
+++ b/lib/LD/ELFWriter.cpp
@@ -6,14 +6,19 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+
+#include <cstdlib>
+#include <cstring>
+
 #include <llvm/Support/ELF.h>
-#include <llvm/Support/ErrorHandling.h>
-#include <llvm/MC/MCAssembler.h>
+#include <llvm/Support/Casting.h>
+
 #include <mcld/ADT/SizeTraits.h>
-#include <mcld/Support/MemoryRegion.h>
 #include <mcld/MC/MCLDInfo.h>
 #include <mcld/MC/MCLinker.h>
-#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/LD/AlignFragment.h>
+#include <mcld/LD/FillFragment.h>
+#include <mcld/LD/RegionFragment.h>
 #include <mcld/LD/ELFWriter.h>
 #include <mcld/LD/LDSymbol.h>
 #include <mcld/LD/LDSection.h>
@@ -21,8 +26,7 @@
 #include <mcld/LD/ELFSegment.h>
 #include <mcld/LD/ELFSegmentFactory.h>
 #include <mcld/Target/GNULDBackend.h>
-#include <cstdlib>
-#include <cstring>
+#include <mcld/Support/MemoryRegion.h>
 
 using namespace llvm::ELF;
 using namespace mcld;
@@ -397,21 +401,21 @@
                            const LDSection& pSection,
                            MemoryRegion& pRegion) const
 {
-  const llvm::MCSectionData* data = pSection.getSectionData();
-  llvm::MCSectionData::const_iterator fragIter, fragEnd = data->end();
+  const SectionData* data = pSection.getSectionData();
+  SectionData::const_iterator fragIter, fragEnd = data->end();
   size_t cur_offset = 0;
   for (fragIter = data->begin(); fragIter != fragEnd; ++fragIter) {
     size_t size = computeFragmentSize(pLayout, *fragIter);
     switch(fragIter->getKind()) {
-      case llvm::MCFragment::FT_Region: {
-        const MCRegionFragment& region_frag = llvm::cast<MCRegionFragment>(*fragIter);
+      case Fragment::Region: {
+        const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter);
         const uint8_t* from = region_frag.getRegion().start();
         memcpy(pRegion.getBuffer(cur_offset), from, size);
         break;
       }
-      case llvm::MCFragment::FT_Align: {
+      case Fragment::Alignment: {
         // TODO: emit values with different sizes (> 1 byte), and emit nops
-        llvm::MCAlignFragment& align_frag = llvm::cast<llvm::MCAlignFragment>(*fragIter);
+        AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter);
         uint64_t count = size / align_frag.getValueSize();
         switch (align_frag.getValueSize()) {
           case 1u:
@@ -425,8 +429,8 @@
         }
         break;
       }
-      case llvm::MCFragment::FT_Fill: {
-        llvm::MCFillFragment& fill_frag = llvm::cast<llvm::MCFillFragment>(*fragIter);
+      case Fragment::Fillment: {
+        FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter);
         if (0 == size ||
             0 == fill_frag.getValueSize() ||
             0 == fill_frag.getSize()) {
@@ -442,19 +446,10 @@
         }
         break;
       }
-      case llvm::MCFragment::FT_Data:
-      case llvm::MCFragment::FT_Inst:
-      case llvm::MCFragment::FT_Org:
-      case llvm::MCFragment::FT_Dwarf:
-      case llvm::MCFragment::FT_DwarfFrame:
-      case llvm::MCFragment::FT_LEB: {
-        llvm::report_fatal_error("unsupported fragment yet.\n");
-        break;
-      }
-      case llvm::MCFragment::FT_Reloc:
+      case Fragment::Relocation:
         llvm::report_fatal_error("relocation fragment should not be in a regular section.\n");
         break;
-      case llvm::MCFragment::FT_Target:
+      case Fragment::Target:
         llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
         break;
       default:
@@ -471,13 +466,13 @@
                                const LDSection& pSection,
                                MemoryRegion& pRegion) const
 {
-  const llvm::MCSectionData* SectionData = pSection.getSectionData();
-  assert(SectionData && "SectionData is NULL in emitRelocation!");
+  const SectionData* sect_data = pSection.getSectionData();
+  assert(NULL != sect_data && "SectionData is NULL in emitRelocation!");
 
   if (pSection.type() == SHT_REL)
-    emitRel(pLayout, pOutput, *SectionData, pRegion);
+    emitRel(pLayout, pOutput, *sect_data, pRegion);
   else if (pSection.type() == SHT_RELA)
-    emitRela(pLayout, pOutput, *SectionData, pRegion);
+    emitRela(pLayout, pOutput, *sect_data, pRegion);
   else
     llvm::report_fatal_error("unsupported relocation section type!");
 }
@@ -486,31 +481,29 @@
 /// emitRel
 void ELFWriter::emitRel(const Layout& pLayout,
                         const Output& pOutput,
-                        const llvm::MCSectionData& pSectionData,
+                        const SectionData& pSectionData,
                         MemoryRegion& pRegion) const
 {
   Elf32_Rel* rel = reinterpret_cast<Elf32_Rel*>(pRegion.start());
 
   Relocation* relocation = 0;
-  MCFragmentRef* FragmentRef = 0;
+  FragmentRef* frag_ref = 0;
 
-  for (llvm::MCSectionData::const_iterator it = pSectionData.begin(),
+  for (SectionData::const_iterator it = pSectionData.begin(),
        ie = pSectionData.end(); it != ie; ++it, ++rel) {
 
     relocation = &(llvm::cast<Relocation>(*it));
-    FragmentRef = &(relocation->targetRef());
+    frag_ref = &(relocation->targetRef());
 
     if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
       rel->r_offset = static_cast<Elf32_Addr>(
-                      llvm::cast<LDSection>(
-                      FragmentRef->frag()->getParent()->getSection()).addr() +
-                      pLayout.getOutputOffset(*FragmentRef));
+                      frag_ref->frag()->getParent()->getSection().addr() +
+                      pLayout.getOutputOffset(*frag_ref));
     }
     else {
       rel->r_offset = static_cast<Elf32_Addr>(
-                      llvm::cast<LDSection>(
-                      FragmentRef->frag()->getParent()->getSection()).offset() +
-                      pLayout.getOutputOffset(*FragmentRef));
+                      frag_ref->frag()->getParent()->getSection().offset() +
+                      pLayout.getOutputOffset(*frag_ref));
     }
 
     Elf32_Word Index;
@@ -527,31 +520,29 @@
 /// emitRela
 void ELFWriter::emitRela(const Layout& pLayout,
                          const Output& pOutput,
-                         const llvm::MCSectionData& pSectionData,
+                         const SectionData& pSectionData,
                          MemoryRegion& pRegion) const
 {
   Elf32_Rela* rel = reinterpret_cast<Elf32_Rela*>(pRegion.start());
 
   Relocation* relocation = 0;
-  MCFragmentRef* FragmentRef = 0;
+  FragmentRef* frag_ref = 0;
 
-  for (llvm::MCSectionData::const_iterator it = pSectionData.begin(),
+  for (SectionData::const_iterator it = pSectionData.begin(),
        ie = pSectionData.end(); it != ie; ++it, ++rel) {
 
     relocation = &(llvm::cast<Relocation>(*it));
-    FragmentRef = &(relocation->targetRef());
+    frag_ref = &(relocation->targetRef());
 
     if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
       rel->r_offset = static_cast<Elf32_Addr>(
-                      llvm::cast<LDSection>(
-                      FragmentRef->frag()->getParent()->getSection()).addr() +
-                      pLayout.getOutputOffset(*FragmentRef));
+                      frag_ref->frag()->getParent()->getSection().addr() +
+                      pLayout.getOutputOffset(*frag_ref));
     }
     else {
       rel->r_offset = static_cast<Elf32_Addr>(
-                      llvm::cast<LDSection>(
-                      FragmentRef->frag()->getParent()->getSection()).offset() +
-                      pLayout.getOutputOffset(*FragmentRef));
+                      frag_ref->frag()->getParent()->getSection().offset() +
+                      pLayout.getOutputOffset(*frag_ref));
     }
 
     Elf32_Word Index;
diff --git a/lib/LD/EhFrame.cpp b/lib/LD/EhFrame.cpp
index 4a84b00..bc5ed1d 100644
--- a/lib/LD/EhFrame.cpp
+++ b/lib/LD/EhFrame.cpp
@@ -6,13 +6,16 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+
 #include <mcld/LD/EhFrame.h>
-#include <mcld/MC/MCLinker.h>
-#include <mcld/Support/MsgHandling.h>
-#include <mcld/Target/TargetLDBackend.h>
+
 #include <llvm/Support/Dwarf.h>
 #include <llvm/Support/Host.h>
 
+#include <mcld/MC/MCLinker.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <mcld/Support/MsgHandling.h>
+
 using namespace mcld;
 
 //==========================
@@ -27,7 +30,7 @@
 
 uint64_t EhFrame::readEhFrame(Layout& pLayout,
                               const TargetLDBackend& pBackend,
-                              llvm::MCSectionData& pSD,
+                              SectionData& pSD,
                               const Input& pInput,
                               LDSection& pSection,
                               MemoryArea& pArea)
@@ -36,7 +39,6 @@
                      pInput.fileOffset() + pSection.offset(), pSection.size());
   // an empty .eh_frame
   if (NULL == region) {
-    note(diag::note_ehframe) << "an empty eh_frame";
     return 0;
   }
 
@@ -50,13 +52,12 @@
   // This CIE is a terminator if the Length field is 0, return 0 to handled it
   // as an ordinary input.
   if (0 == len) {
-    note(diag::note_ehframe) << "a terminator";
     pArea.release(region);
     return 0;
   }
 
   if (0xffffffff == len) {
-    debug(diag::debug_eh_unsupport) << "64-bit eh_frame";
+    debug(diag::debug_eh_unsupport) << pInput.name();
     pArea.release(region);
     m_fCanRecognizeAll = false;
     return 0;
@@ -68,7 +69,7 @@
   while (p < eh_end) {
 
     if (eh_end - p < 4) {
-      debug(diag::debug_eh_unsupport) << "CIE or FDE size smaller than 4";
+      debug(diag::debug_eh_unsupport) << pInput.name();
       m_fCanRecognizeAll = false;
       break;
     }
@@ -79,20 +80,19 @@
     // the zero length entry should be the end of the section
     if (0 == len) {
       if (p < eh_end) {
-        debug(diag::debug_eh_unsupport) << "Non-end entry with zero length";
+        debug(diag::debug_eh_unsupport) << pInput.name();
         m_fCanRecognizeAll = false;
       }
       break;
     }
     if (0xffffffff == len) {
-      debug(diag::debug_eh_unsupport) << "64-bit eh_frame";
+      debug(diag::debug_eh_unsupport) << pInput.name();
       m_fCanRecognizeAll = false;
       break;
     }
 
     if (eh_end - p < 4) {
-      debug(diag::debug_eh_unsupport) <<
-        "CIE:ID field / FDE: CIE Pointer field";
+      debug(diag::debug_eh_unsupport) << pInput.name();
       m_fCanRecognizeAll = false;
       break;
     }
@@ -127,6 +127,7 @@
   }
 
   if (!m_fCanRecognizeAll) {
+    debug(diag::debug_eh_unsupport) << pInput.name();
     pArea.release(region);
     deleteFragments(frag_list, pArea);
     return 0;
@@ -156,7 +157,6 @@
 
   // the version should be 1
   if (1 != *p) {
-    debug(diag::debug_eh_unsupport) << "CIE version";
     return false;
   }
   ++p;
@@ -171,17 +171,14 @@
 
   // skip the Code Alignment Factor
   if (!skipLEB128(&p, cie_end)) {
-    debug(diag::debug_eh_unsupport) << "unrecognized Code Alignment Factor";
     return false;
   }
   // skip the Data Alignment Factor
   if (!skipLEB128(&p, cie_end)) {
-    debug(diag::debug_eh_unsupport) << "unrecognized Data Alignment Factor";
     return false;
   }
   // skip the Return Address Register
   if (cie_end - p < 1) {
-    debug(diag::debug_eh_unsupport) << "unrecognized Return Address Register";
     return false;
   }
   ++p;
@@ -189,7 +186,6 @@
   // the Augmentation String start with 'eh' is a CIE from gcc before 3.0,
   // in LSB Core Spec 3.0RC1. We do not support it.
   if (aug_str[0] == 'e' && aug_str[1] == 'h') {
-    debug(diag::debug_eh_unsupport) << "augmentation string `eh`";
     return false;
   }
 
@@ -203,21 +199,17 @@
 
     // skip the Augumentation Data Length
     if (!skipLEB128(&p, cie_end)) {
-      debug(diag::debug_eh_unsupport) <<
-        "unrecognized Augmentation Data Length";
       return false;
     }
 
     while (aug_str != aug_str_end) {
       switch (*aug_str) {
         default:
-          debug(diag::debug_eh_unsupport) << "augmentation string";
           return false;
 
         // LDSA encoding (1 byte)
         case 'L':
           if (cie_end - p < 1) {
-            debug(diag::debug_eh_unsupport) << "augmentation string `L`";
             return false;
           }
           ++p;
@@ -229,7 +221,6 @@
         case 'P': {
           // the first argument
           if (cie_end - p < 1) {
-            debug(diag::debug_eh_unsupport) << "augmentation string `P`";
             return false;
           }
           uint8_t per_encode = *p;
@@ -237,12 +228,10 @@
           // get the length of the second argument
           uint32_t per_length = 0;
           if (0x60 == (per_encode & 0x60)) {
-            debug(diag::debug_eh_unsupport) << "augmentation string `P`";
             return false;
           }
           switch (per_encode & 7) {
             default:
-              debug(diag::debug_eh_unsupport) << "augmentation string `P`";
               return false;
             case llvm::dwarf::DW_EH_PE_udata2:
               per_length = 2;
@@ -263,14 +252,12 @@
             per_align += per_length - 1;
             per_align &= ~(per_length -1);
             if (static_cast<uint32_t>(cie_end - p) < per_align) {
-              debug(diag::debug_eh_unsupport) << "augmentation string `P`";
               return false;
             }
             p += per_align;
           }
           // skip the second argument
           if (static_cast<uint32_t>(cie_end - p) < per_length) {
-            debug(diag::debug_eh_unsupport) << "augmentation string `P`";
             return false;
           }
           p += per_length;
@@ -280,7 +267,6 @@
         // FDE encoding (1 byte)
         case 'R':
           if (cie_end - p < 1) {
-            debug(diag::debug_eh_unsupport) << "augmentation string `R`";
             return false;
           }
           fde_encoding = *p;
@@ -291,7 +277,6 @@
             case llvm::dwarf::DW_EH_PE_absptr:
               break;
             default:
-              debug(diag::debug_eh_unsupport) << "FDE encoding";
               return false;
           }
           ++p;
@@ -309,7 +294,7 @@
   // create and push back the CIE entry
   CIE* entry = new CIE(pRegion, fde_encoding);
   m_CIEs.push_back(entry);
-  pFragList.push_back(static_cast<llvm::MCFragment*>(entry));
+  pFragList.push_back(static_cast<Fragment*>(entry));
   return true;
 }
 
@@ -326,7 +311,6 @@
 
   // get the entry offset of the PC Begin
   if (fde_end - p < 1) {
-    debug(diag::debug_eh_unsupport) << "FDE PC Begin";
     return false;
   }
   FDE::Offset pc_offset = static_cast<FDE::Offset>(p - fde_start);
@@ -335,7 +319,7 @@
   // create and push back the FDE entry
   FDE* entry = new FDE(pRegion, **(m_CIEs.end() -1), pc_offset);
   m_FDEs.push_back(entry);
-  pFragList.push_back(static_cast<llvm::MCFragment*>(entry));
+  pFragList.push_back(static_cast<Fragment*>(entry));
   return true;
 }
 
@@ -363,9 +347,9 @@
 
 void EhFrame::deleteFragments(FragListType& pList, MemoryArea& pArea)
 {
-  MCRegionFragment* frag = NULL;
+  RegionFragment* frag = NULL;
   for (FragListType::iterator it = pList.begin(); it != pList.end(); ++it) {
-    frag = static_cast<MCRegionFragment*>(*it);
+    frag = static_cast<RegionFragment*>(*it);
     pArea.release(&(frag->getRegion()));
     delete *it;
   }
diff --git a/lib/LD/FDE.cpp b/lib/LD/FDE.cpp
index b70f7e1..1aa196b 100644
--- a/lib/LD/FDE.cpp
+++ b/lib/LD/FDE.cpp
@@ -6,19 +6,19 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include <mcld/LD/EhFrame.h>
+
 #include <mcld/LD/FDE.h>
+#include <mcld/LD/EhFrame.h>
 
 using namespace mcld;
 
-//==========================
+//===----------------------------------------------------------------------===//
 // FDE
-
+//===----------------------------------------------------------------------===//
 FDE::FDE(MemoryRegion& pRegion, const CIE& pCIE, Offset pPCBeginOffset)
-  : MCRegionFragment(pRegion), m_CIE(pCIE), m_PCBeginOffset(pPCBeginOffset) {
+  : RegionFragment(pRegion), m_CIE(pCIE), m_PCBeginOffset(pPCBeginOffset) {
 }
 
 FDE::~FDE()
 {
 }
-
diff --git a/lib/LD/FillFragment.cpp b/lib/LD/FillFragment.cpp
new file mode 100644
index 0000000..8f127ca
--- /dev/null
+++ b/lib/LD/FillFragment.cpp
@@ -0,0 +1,28 @@
+//===- FillFragment.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/LD/FillFragment.h>
+#include <mcld/LD/SectionData.h>
+#include <cassert>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// FillFragment
+//===----------------------------------------------------------------------===//
+FillFragment::FillFragment(int64_t pValue,
+                           unsigned int pValueSize,
+                           uint64_t pSize,
+                           SectionData* pSD)
+  : Fragment(Fragment::Fillment, pSD), m_Value(pValue), m_ValueSize(pValueSize),
+    m_Size(pSize) {
+  assert((!m_ValueSize || (m_Size % m_ValueSize) == 0) &&
+           "Fill size must be a multiple of the value size!");
+}
+
diff --git a/lib/LD/Fragment.cpp b/lib/LD/Fragment.cpp
new file mode 100644
index 0000000..6e1e3a7
--- /dev/null
+++ b/lib/LD/Fragment.cpp
@@ -0,0 +1,34 @@
+//===- Fragment.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/LD/Fragment.h>
+
+#include <llvm/Support/DataTypes.h>
+
+#include <mcld/LD/SectionData.h>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// Fragment
+//===----------------------------------------------------------------------===//
+Fragment::Fragment()
+  : m_Kind(Type(~0)), m_pParent(NULL), m_Offset(~uint64_t(0)), m_LayoutOrder(~(0U)) {
+}
+
+Fragment::Fragment(Type pKind, SectionData *pParent)
+  : m_Kind(pKind), m_pParent(pParent), m_Offset(~uint64_t(0)), m_LayoutOrder(~(0U)) {
+  if (NULL != m_pParent)
+    m_pParent->getFragmentList().push_back(this);
+}
+
+Fragment::~Fragment()
+{
+}
+
diff --git a/lib/LD/FragmentRef.cpp b/lib/LD/FragmentRef.cpp
new file mode 100644
index 0000000..9ae8e4d
--- /dev/null
+++ b/lib/LD/FragmentRef.cpp
@@ -0,0 +1,150 @@
+//===- FragmentRef.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/LD/FragmentRef.h>
+
+#include <cstring>
+#include <cassert>
+
+#include <llvm/Support/MathExtras.h>
+#include <llvm/Support/Casting.h>
+
+#include <mcld/LD/AlignFragment.h>
+#include <mcld/LD/FillFragment.h>
+#include <mcld/LD/RegionFragment.h>
+#include <mcld/LD/TargetFragment.h>
+#include <mcld/LD/Layout.h>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// Helper Functions
+//===----------------------------------------------------------------------===//
+/// compunteFragmentSize - compute the specific Fragment size
+uint64_t mcld::computeFragmentSize(const Layout& pLayout,
+                                   const Fragment& pFrag)
+{
+  switch (pFrag.getKind()) {
+    case Fragment::Fillment:
+      return static_cast<const FillFragment&>(pFrag).getSize();
+
+    case Fragment::Alignment: {
+      uint64_t offset = pLayout.getOutputOffset(pFrag);
+      const AlignFragment& align_frag = llvm::cast<AlignFragment>(pFrag);
+      uint64_t size = llvm::OffsetToAlignment(offset, align_frag.getAlignment());
+      if (size > align_frag.getMaxBytesToEmit())
+        return 0;
+      return size;
+    }
+
+    case Fragment::Region:
+      return llvm::cast<RegionFragment>(pFrag).getRegion().size();
+
+    case Fragment::Target:
+      return llvm::cast<TargetFragment>(pFrag).getSize();
+
+    case Fragment::Relocation:
+      assert(0 && "the size of FT_Reloc fragment is handled by backend");
+      return 0;
+
+    default:
+      assert(0 && "invalid fragment kind");
+      return 0;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// FragmentRef
+//===----------------------------------------------------------------------===//
+FragmentRef::FragmentRef()
+  : m_pFragment(NULL), m_Offset(0) {
+}
+
+FragmentRef::FragmentRef(Fragment& pFrag,
+                         FragmentRef::Offset pOffset)
+  : m_pFragment(&pFrag), m_Offset(pOffset) {
+}
+
+FragmentRef::~FragmentRef()
+{
+  m_pFragment = NULL;
+  m_Offset = 0;
+}
+
+FragmentRef& FragmentRef::assign(const FragmentRef& pCopy)
+{
+  m_pFragment = const_cast<Fragment*>(pCopy.m_pFragment);
+  m_Offset = pCopy.m_Offset;
+  return *this;
+}
+
+FragmentRef& FragmentRef::assign(Fragment& pFrag, FragmentRef::Offset pOffset)
+{
+  m_pFragment = &pFrag;
+  m_Offset = pOffset;
+  return *this;
+}
+
+void FragmentRef::memcpy(void* pDest, size_t pNBytes, Offset pOffset) const
+{
+  // check if the offset is still in a legal range.
+  if (NULL == m_pFragment)
+    return;
+  unsigned int total_offset = m_Offset + pOffset;
+  switch(m_pFragment->getKind()) {
+    case Fragment::Region: {
+      RegionFragment* region_frag = static_cast<RegionFragment*>(m_pFragment);
+      unsigned int total_length = region_frag->getRegion().size();
+      if (total_length < (total_offset+pNBytes))
+        pNBytes = total_length - total_offset;
+
+      std::memcpy(pDest, region_frag->getRegion().getBuffer(total_offset), pNBytes);
+      return;
+    }
+    case Fragment::Alignment:
+    case Fragment::Fillment:
+    default:
+      return;
+  }
+}
+
+FragmentRef::Address FragmentRef::deref()
+{
+  if (NULL == m_pFragment)
+    return NULL;
+  Address base = NULL;
+  switch(m_pFragment->getKind()) {
+    case Fragment::Region:
+      base = static_cast<RegionFragment*>(m_pFragment)->getRegion().getBuffer();
+      break;
+    case Fragment::Alignment:
+    case Fragment::Fillment:
+    default:
+      return NULL;
+  }
+  return base + m_Offset;
+}
+
+FragmentRef::ConstAddress FragmentRef::deref() const
+{
+  if (NULL == m_pFragment)
+    return NULL;
+  ConstAddress base = NULL;
+  switch(m_pFragment->getKind()) {
+    case Fragment::Region:
+      base = static_cast<const RegionFragment*>(m_pFragment)->getRegion().getBuffer();
+      break;
+    case Fragment::Alignment:
+    case Fragment::Fillment:
+    default:
+      return NULL;
+  }
+  return base + m_Offset;
+}
+
diff --git a/lib/LD/GNUArchiveReader.cpp b/lib/LD/GNUArchiveReader.cpp
index 0a64752..55c8c76 100644
--- a/lib/LD/GNUArchiveReader.cpp
+++ b/lib/LD/GNUArchiveReader.cpp
@@ -10,343 +10,384 @@
 #include <mcld/MC/MCLDInput.h>
 #include <mcld/MC/InputTree.h>
 #include <mcld/LD/GNUArchiveReader.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/ELFObjectReader.h>
 #include <mcld/Support/FileSystem.h>
+#include <mcld/Support/FileHandle.h>
 #include <mcld/Support/MemoryArea.h>
 #include <mcld/Support/MemoryRegion.h>
 #include <mcld/Support/MemoryAreaFactory.h>
 #include <mcld/Support/MsgHandling.h>
+#include <mcld/Support/Path.h>
 #include <mcld/ADT/SizeTraits.h>
 
-#include <llvm/Support/system_error.h>
+#include <llvm/ADT/StringRef.h>
 #include <llvm/Support/Host.h>
 
-#include <sstream>
-#include <string>
-#include <vector>
+#include <cstring>
 #include <cstdlib>
 
 using namespace mcld;
 
-typedef uint32_t elfWord;
-
-
-/// Archive Header, Magic number
-const char GNUArchiveReader::ArchiveMagic[ArchiveMagicSize] = { '!', '<', 'a', 'r', 'c', 'h', '>', '\n' };
-const char GNUArchiveReader::ThinArchiveMagic[ArchiveMagicSize] = { '!', '<', 't', 'h', 'i', 'n', '>', '\n' };
-const char GNUArchiveReader::HeaderFinalMagic[HeaderFinalMagicSize] = { '`', '\n' };
-
-
-struct GNUArchiveReader::SymbolTableEntry
+GNUArchiveReader::GNUArchiveReader(MCLDInfo& pLDInfo,
+                                   MemoryAreaFactory& pMemAreaFactory,
+                                   ELFObjectReader& pELFObjectReader)
+ : m_LDInfo(pLDInfo),
+   m_MemAreaFactory(pMemAreaFactory),
+   m_ELFObjectReader(pELFObjectReader)
 {
-  off_t fileOffset;
-  std::string name;
-};
-
-
-
-/// convert string to size_t
-template<class Type>
-Type stringToType(const std::string &str)
-{
-  Type n;
-  std::stringstream ss(str);
-  ss >> n;
-  return n;
 }
 
+GNUArchiveReader::~GNUArchiveReader()
+{
+}
 
-/// GNUArchiveReader Operations
-/// Public API
-bool GNUArchiveReader::isMyFormat(Input &pInput) const
+/// isMyFormat
+bool GNUArchiveReader::isMyFormat(Input& pInput) const
 {
   assert(pInput.hasMemArea());
+  MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
+                                                   Archive::MAGIC_LEN);
+  const char* str = reinterpret_cast<const char*>(region->getBuffer());
 
-  MemoryRegion *region = pInput.memArea()->request(0, ArchiveMagicSize);
-  if (!region)
-    llvm::report_fatal_error("can't request MemoryRegion for archive magic");
+  bool result = false;
+  assert(NULL != str);
+  if (isArchive(str) || isThinArchive(str))
+    result = true;
 
-  const char *p_buffer = reinterpret_cast<char *> (region->getBuffer());
+  pInput.memArea()->release(region);
+  return result;
+}
 
-  /// check archive format.
-  if (memcmp(p_buffer, ArchiveMagic, ArchiveMagicSize) != 0
-      && memcmp(p_buffer, ThinArchiveMagic, ArchiveMagicSize) != 0) {
-    return false;
-  }
+/// isArchive
+bool GNUArchiveReader::isArchive(const char* pStr) const
+{
+  return (0 == memcmp(pStr, Archive::MAGIC, Archive::MAGIC_LEN));
+}
+
+/// isThinArchive
+bool GNUArchiveReader::isThinArchive(const char* pStr) const
+{
+  return (0 == memcmp(pStr, Archive::THIN_MAGIC, Archive::MAGIC_LEN));
+}
+
+/// isThinArchive
+bool GNUArchiveReader::isThinArchive(Input& pInput) const
+{
+  assert(pInput.hasMemArea());
+  MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
+                                                   Archive::MAGIC_LEN);
+  const char* str = reinterpret_cast<const char*>(region->getBuffer());
+
+  bool result = false;
+  assert(NULL != str);
+  if (isThinArchive(str))
+    result = true;
+
+  pInput.memArea()->release(region);
+  return result;
+}
+
+bool GNUArchiveReader::readArchive(Archive& pArchive)
+{
+  // read the symtab of the archive
+  readSymbolTable(pArchive);
+
+  // read the strtab of the archive
+  readStringTable(pArchive);
+
+  // add root archive to ArchiveMemberMap
+  pArchive.addArchiveMember(pArchive.getARFile().name(),
+                            pArchive.inputs().root(),
+                            &InputTree::Downward);
+
+  // include the needed members in the archive and build up the input tree
+  bool willSymResolved;
+  do {
+    willSymResolved = false;
+    for (size_t idx = 0; idx < pArchive.numOfSymbols(); ++idx) {
+      // bypass if we already decided to include this symbol or not
+      if (Archive::Symbol::Unknown != pArchive.getSymbolStatus(idx))
+        continue;
+
+      // bypass if another symbol with the same object file offset is included
+      if (pArchive.hasObjectMember(pArchive.getObjFileOffset(idx))) {
+        pArchive.setSymbolStatus(idx, Archive::Symbol::Include);
+        continue;
+      }
+
+      // check if we should include this defined symbol
+      Archive::Symbol::Status status =
+        shouldIncludeSymbol(pArchive.getSymbolName(idx));
+      if (Archive::Symbol::Unknown != status)
+        pArchive.setSymbolStatus(idx, status);
+
+      if (Archive::Symbol::Include == status) {
+        Input* cur_archive = &(pArchive.getARFile());
+        Input* member = cur_archive;
+        uint32_t file_offset = pArchive.getObjFileOffset(idx);
+        while ((member != NULL) && (Input::Object != member->type())) {
+          uint32_t nested_offset = 0;
+          // use the file offset in current archive to find out the member we
+          // want to include
+          member = readMemberHeader(pArchive,
+                                    *cur_archive,
+                                    file_offset,
+                                    nested_offset);
+          assert(member != NULL);
+          // bypass if we get an archive that is already in the map
+          if (Input::Archive == member->type()) {
+              cur_archive = member;
+              file_offset = nested_offset;
+              continue;
+          }
+
+          // insert a node into the subtree of current archive.
+          Archive::ArchiveMember* parent =
+            pArchive.getArchiveMember(cur_archive->name());
+
+          assert(NULL != parent);
+          pArchive.inputs().insert(parent->lastPos, *(parent->move), *member);
+
+          // move the iterator to new created node, and also adjust the
+          // direction to Afterward for next insertion in this subtree
+          parent->move->move(parent->lastPos);
+          parent->move = &InputTree::Afterward;
+
+          if (m_ELFObjectReader.isMyFormat(*member)) {
+            member->setType(Input::Object);
+            pArchive.addObjectMember(pArchive.getObjFileOffset(idx),
+                                     parent->lastPos);
+            m_ELFObjectReader.readObject(*member);
+            m_ELFObjectReader.readSections(*member);
+            m_ELFObjectReader.readSymbols(*member);
+          }
+          else if (isMyFormat(*member)) {
+            member->setType(Input::Archive);
+            // when adding a new archive node, set the iterator to archive
+            // itself, and set the direction to Downward
+            pArchive.addArchiveMember(member->name(),
+                                      parent->lastPos,
+                                      &InputTree::Downward);
+            cur_archive = member;
+            file_offset = nested_offset;
+          }
+        } // end of while
+        willSymResolved = true;
+      } // end of if
+    } // end of for
+  } while (willSymResolved);
+
   return true;
 }
 
-LDReader::Endian GNUArchiveReader::endian(Input& pFile) const
+/// readMemberHeader - read the header of a member in a archive file and then
+/// return the corresponding archive member (it may be an input object or
+/// another archive)
+/// @param pArchiveRoot  - the archive root that holds the strtab (extended
+///                        name table)
+/// @param pArchiveFile  - the archive that contains the needed object
+/// @param pFileOffset   - file offset of the member header in the archive
+/// @param pNestedOffset - used when we find a nested archive
+Input* GNUArchiveReader::readMemberHeader(Archive& pArchiveRoot,
+                                          Input& pArchiveFile,
+                                          uint32_t pFileOffset,
+                                          uint32_t& pNestedOffset)
 {
-  return LDReader::BigEndian;
-}
+  assert(pArchiveFile.hasMemArea());
 
-InputTree *GNUArchiveReader::readArchive(Input &pInput)
-{
-  return setupNewArchive(pInput, 0);
-}
+  MemoryRegion* header_region =
+    pArchiveFile.memArea()->request((pArchiveFile.fileOffset() + pFileOffset),
+                                    sizeof(Archive::MemberHeader));
+  const Archive::MemberHeader* header =
+    reinterpret_cast<const Archive::MemberHeader*>(header_region->getBuffer());
 
-/// Read Input as archive. First create a null InputTree.
-/// Then Construct Input object for corresponding member of this archive
-/// and insert the Input object into the InputTree.
-/// Finally, return the InputTree.
-InputTree *GNUArchiveReader::setupNewArchive(Input &pInput,
-                                            size_t off)
-{
-  assert(pInput.hasMemArea());
-  MemoryRegion *region = pInput.memArea()->request(off, ArchiveMagicSize);
+  assert(0 == memcmp(header->fmag, Archive::MEMBER_MAGIC, 2));
 
-  if (!region)
-    llvm::report_fatal_error("can't request MemoryRegion for archive magic");
+  // int size = atoi(header->size);
 
-  const char *pFile = reinterpret_cast<char *> (region->getBuffer());
-
-  /// check archive format.
-  bool isThinArchive;
-  isThinArchive = memcmp(pFile, ThinArchiveMagic, ArchiveMagicSize) == 0;
-  if(!isThinArchive && memcmp(pFile, ArchiveMagic, ArchiveMagicSize) != 0)
-    llvm::report_fatal_error("Fail : archive magic number is not matched");
-
-  InputTree *resultTree = new InputTree(m_pLDInfo.inputFactory());
-  std::vector<SymbolTableEntry> symbolTable;
-  std::string archiveMemberName;
-  std::string extendedName;
-
-  off += ArchiveMagicSize ;
-  size_t symbolTableSize = readMemberHeader(*pInput.memArea(), off, &archiveMemberName,
-                                            NULL, extendedName);
-  /// read archive symbol table
-  if(archiveMemberName.empty())
-  {
-    readSymbolTable(*pInput.memArea(), symbolTable,
-                    off+sizeof(ArchiveMemberHeader), symbolTableSize);
-    off = off + sizeof(ArchiveMemberHeader) + symbolTableSize;
+  // parse the member name and nested offset if any
+  std::string member_name;
+  llvm::StringRef name_field(header->name, 16);
+  if ('/' != header->name[0]) {
+    // this is an object file in an archive
+    size_t pos = name_field.find_first_of('/');
+    member_name.assign(name_field.substr(0, pos).str());
   }
-  else
-  {
-    llvm::report_fatal_error("fatal error : need symbol table\n");
-    return NULL;
+  else {
+    // this is an object/archive file in a thin archive
+    size_t begin = 1;
+    size_t end = name_field.find_first_of(" :");
+    uint32_t name_offset = 0;
+    // parse the name offset
+    name_field.substr(begin, end - begin).getAsInteger(10, name_offset);
+
+    if (':' == name_field[end]) {
+      // there is a nested offset
+      begin = end + 1;
+      end = name_field.find_first_of(' ', begin);
+      name_field.substr(begin, end - begin).getAsInteger(10, pNestedOffset);
+    }
+
+    // get the member name from the extended name table
+    begin = name_offset;
+    end = pArchiveRoot.getStrTable().find_first_of('\n', begin);
+    member_name.assign(pArchiveRoot.getStrTable().substr(begin, end - begin -1));
   }
 
-  if((off&1) != 0)
-    ++off;
-
-  size_t extendedSize = readMemberHeader(*pInput.memArea(), off, &archiveMemberName,
-                                          NULL, extendedName);
-  /// read long Name table if exist
-  if(archiveMemberName == "/")
-  {
-    off += sizeof(ArchiveMemberHeader);
-    MemoryRegion *extended_name_region = pInput.memArea()->request(off, extendedSize);
-    pFile = reinterpret_cast<char *>(extended_name_region->getBuffer());
-    extendedName.assign(pFile, extendedSize);
-
+  Input* member = NULL;
+  if (!isThinArchive(pArchiveFile)) {
+    // this is an object file in an archive
+    member =
+      m_LDInfo.inputFactory().produce(member_name,
+                                      pArchiveFile.path(),
+                                      Input::Unknown,
+                                      (pFileOffset +
+                                       sizeof(Archive::MemberHeader)));
+    assert(member != NULL);
+    member->setMemArea(pArchiveFile.memArea());
+    LDContext *input_context = m_LDInfo.contextFactory().produce();
+    member->setContext(input_context);
   }
+  else {
+    // this is a member in a thin archive
+    // try to find if this is a archive already in the map first
+    Archive::ArchiveMember* ar_member =
+      pArchiveRoot.getArchiveMember(member_name);
+    if (NULL != ar_member) {
+      return ar_member->file;
+    }
 
-  /// traverse all the archive members
-  InputTree::iterator node = resultTree->root();
-  std::set<std::string> haveSeen;
-  for(unsigned i=0 ; i<symbolTable.size() ; ++i)
-  {
-    /// We shall get each member at this archive.
-    /// Construct a corresponding mcld::Input, and insert it into
-    /// the original InputTree, resultTree.
-    off_t nestedOff = 0;
-
-    readMemberHeader(*pInput.memArea(), symbolTable[i].fileOffset, &archiveMemberName,
-                      &nestedOff, extendedName);
-
-    if(haveSeen.find(archiveMemberName)==haveSeen.end())
-      haveSeen.insert(archiveMemberName);
+    // get nested file path, the nested file's member name is the relative
+    // path to the archive containing it.
+    sys::fs::Path input_path(pArchiveFile.path().parent_path());
+    if (!input_path.empty())
+      input_path.append(member_name);
     else
-      continue;
+      input_path.assign(member_name);
+    member =
+      m_LDInfo.inputFactory().produce(member_name, input_path, Input::Unknown);
 
-    if(!isThinArchive)
-    {
-      /// New a Input object and assign fileOffset in MCLDFile.
-      /// Insert the object to resultTree and move ahead.
-      off_t fileOffset = symbolTable[i].fileOffset + sizeof(ArchiveMemberHeader);
-      Input *insertObjectFile = m_pLDInfo.inputFactory().produce(archiveMemberName,
-                                                                 pInput.path(),
-                                                                 MCLDFile::Object,
-                                                                 fileOffset);
-      resultTree->insert<InputTree::Positional>(node, *insertObjectFile);
-      if(i==0)
-        node.move<InputTree::Inclusive>();
-      else
-        node.move<InputTree::Positional>();
-
-      continue;
+    assert(member != NULL);
+    MemoryArea* input_memory =
+      m_MemAreaFactory.produce(member->path(), FileHandle::ReadOnly);
+    if (input_memory->handler()->isGood()) {
+      member->setMemArea(input_memory);
     }
-    
-    /// TODO:(Duo)
-    /// adjust the relative pathname
-    /// For example
-    /// thin archive pathname : "/usr/lib/thin.a"
-    ///           Member name : "member.a"
-    /// pathname after adjust : "/usr/lib/member.a"
-    sys::fs::RealPath realPath(archiveMemberName);
-    if(nestedOff > 0)
-    {
-      /// This is a member of a nested archive.
-      /// Create an Input for this archive ,and recursive call setupNewArchive
-      /// Finally, merge the new InputTree with the old one
-      Input *newArchive = m_pLDInfo.inputFactory().produce(archiveMemberName,
-                                                           realPath,
-                                                           MCLDFile::Archive,
-                                                           0);
-
-      resultTree->insert<InputTree::Positional>(node, *newArchive);
-      if(i==0)
-        node.move<InputTree::Inclusive>();
-      else
-        node.move<InputTree::Positional>();
-      InputTree *newArchiveTree = setupNewArchive(*newArchive, 0);
-      resultTree->merge<InputTree::Inclusive>(node, *newArchiveTree);
-      continue;
+    else {
+      error(diag::err_cannot_open_input) << member->name() << member->path();
+      return NULL;
     }
-    /// External member , open it as normal object file
-    /// add new Input to InputTree
-    Input *insertObjectFile = m_pLDInfo.inputFactory().produce(archiveMemberName,
-                                                               realPath,
-                                                               MCLDFile::Object,
-                                                               0);
-    resultTree->insert<InputTree::Positional>(node, *insertObjectFile);
-    if(i==0)
-      node.move<InputTree::Inclusive>();
-    else
-      node.move<InputTree::Positional>();
+    LDContext *input_context = m_LDInfo.contextFactory().produce(input_path);
+    member->setContext(input_context);
   }
-  return resultTree;
+
+  pArchiveFile.memArea()->release(header_region);
+  return member;
 }
 
-
-/// Parse the member header and return the size of member
-/// Archive member names in System 5 style :
-///
-/// "/                  " - symbol table, must be the first member
-/// "//                 " - long name table
-/// "filename.o/        " - regular file with short name
-/// "/5566              " - name at offset 5566 at long name table
-
-size_t GNUArchiveReader::readMemberHeader(MemoryArea &pArea,
-                                           off_t off,
-                                           std::string *p_Name,
-                                           off_t *p_NestedOff,
-                                           std::string &p_ExtendedName)
+/// readSymbolTable - read the archive symbol map (armap)
+bool GNUArchiveReader::readSymbolTable(Archive& pArchive)
 {
-  MemoryRegion *region = pArea.request(off, sizeof(ArchiveMemberHeader));
-  const char *pFile = reinterpret_cast<char *>(region->getBuffer());
-  const ArchiveMemberHeader *header = reinterpret_cast<const ArchiveMemberHeader *>(pFile);
+  assert(pArchive.getARFile().hasMemArea());
 
-  /// check magic number of member header
-  if(memcmp(header->finalMagic, HeaderFinalMagic, sizeof HeaderFinalMagic))
-  {
-    llvm::report_fatal_error("archive member header magic number false");
-    return 0;
-  }
+  MemoryRegion* header_region =
+    pArchive.getARFile().memArea()->request((pArchive.getARFile().fileOffset() +
+                                             Archive::MAGIC_LEN),
+                                            sizeof(Archive::MemberHeader));
+  const Archive::MemberHeader* header =
+    reinterpret_cast<const Archive::MemberHeader*>(header_region->getBuffer());
+  assert(0 == memcmp(header->fmag, Archive::MEMBER_MAGIC, 2));
 
-  /// evaluate member size
-  std::string sizeString(header->size, sizeof(header->size)+1);
-  size_t memberSize = stringToType<size_t>(sizeString);
-  if(memberSize == 0)
-  {
-    llvm::report_fatal_error("member Size Error");
-    return 0;
-  }
+  int symtab_size = atoi(header->size);
+  pArchive.setSymTabSize(symtab_size);
 
-  if(header->name[0] != '/')
-  {
-    /// This is a regular file with short name
-    const char* nameEnd = strchr(header->name, '/');
-    size_t nameLen = ((nameEnd == NULL) ? 0 : (nameEnd - header->name));
-    if((nameLen <= 0) || (nameLen >= sizeof(header->name)))
-    {
-      llvm::report_fatal_error("header name format error\n");
-      return 0;
-    }
-    p_Name->assign(header->name, nameLen);
+  MemoryRegion* symtab_region =
+    pArchive.getARFile().memArea()->request((pArchive.getARFile().fileOffset() +
+                                             Archive::MAGIC_LEN +
+                                             sizeof(Archive::MemberHeader)),
+                                            symtab_size);
+  const uint32_t* data =
+    reinterpret_cast<const uint32_t*>(symtab_region->getBuffer());
 
-    if(!p_NestedOff)
-      p_NestedOff = 0;
-  }
-  else if(header->name[1] == ' ')
-  {
-    /// This is symbol table
-    if(!p_Name->empty())
-      p_Name->clear();
-  }
-  else if(header->name[1] == '/')
-  {
-    /// This is long name table
-    p_Name->assign(1,'/');
-  }
+  // read the number of symbols
+  uint32_t number = 0;
+  if (llvm::sys::isLittleEndianHost())
+    number = bswap32(*data);
   else
-  {
-    /// This is regular file with long name
-    char *end;
-    long extendedNameOff = strtol(header->name+1, &end, 10);
-    long nestedOff = 0;
-    if(*end == ':')
-      nestedOff = strtol(end+1, &end, 10);
+    number = *data;
 
-    if(*end != ' '
-       || extendedNameOff < 0
-       || static_cast<size_t>(extendedNameOff) >= p_ExtendedName.size())
-    {
-      llvm::report_fatal_error("extended name");
-      return 0;
-    }
+  // set up the pointers for file offset and name offset
+  ++data;
+  const char* name = reinterpret_cast<const char*>(data + number);
 
-    const char *name = p_ExtendedName.data() + extendedNameOff;
-    const char *nameEnd = strchr(name, '\n');
-    if(nameEnd[-1] != '/'
-       || static_cast<size_t>(nameEnd-name) > p_ExtendedName.size())
-    {
-      llvm::report_fatal_error("p_ExtendedName substring is not end with / \n");
-      return 0;
-    }
-    p_Name->assign(name, nameEnd-name-1);
-    if(p_NestedOff)
-     *p_NestedOff = nestedOff;
+  // add the archive symbols
+  for (uint32_t i = 0; i < number; ++i) {
+    if (llvm::sys::isLittleEndianHost())
+      pArchive.addSymbol(name, bswap32(*data));
+    else
+      pArchive.addSymbol(name, *data);
+    name += strlen(name) + 1;
+    ++data;
   }
 
-  return memberSize;
+  pArchive.getARFile().memArea()->release(header_region);
+  pArchive.getARFile().memArea()->release(symtab_region);
+  return true;
 }
 
-void GNUArchiveReader::readSymbolTable(MemoryArea &pArea,
-                                       std::vector<SymbolTableEntry> &pSymbolTable,
-                                       off_t start,
-                                       size_t size)
+/// readStringTable - read the strtab for long file name of the archive
+bool GNUArchiveReader::readStringTable(Archive& pArchive)
 {
-  MemoryRegion *region = pArea.request(start, size);
-  const char *pFile = reinterpret_cast<char *>(region->getBuffer());
-  const elfWord *p_Word = reinterpret_cast<const elfWord *>(pFile);
-  unsigned int symbolNum = *p_Word;
+  size_t offset = Archive::MAGIC_LEN +
+                  sizeof(Archive::MemberHeader) +
+                  pArchive.getSymTabSize();
 
-  /// Portable Issue on Sparc platform
-  /// Intel, ARM and Mips are littel-endian , Sparc is little-endian after verion 9
-  /// symbolNum in symbol table is always big-endian
-  if(llvm::sys::isLittleEndianHost())
-    symbolNum = bswap32(symbolNum);
-  ++p_Word;
+  if (0x0 != (offset & 1))
+    ++offset;
 
-  const char *p_Name = reinterpret_cast<const char *>(p_Word + symbolNum);
+  assert(pArchive.getARFile().hasMemArea());
 
-  for(unsigned int i=0 ; i<symbolNum ; ++i)
-  {
-    SymbolTableEntry entry;
-    /// member offset
-    unsigned int memberOffset = *p_Word;
-    if(llvm::sys::isLittleEndianHost())
-      memberOffset = bswap32(memberOffset);
-    entry.fileOffset = static_cast<off_t>(memberOffset);
-    ++p_Word;
-    /// member name
-    off_t nameEnd = strlen(p_Name) + 1;
-    entry.name.assign(p_Name, nameEnd);
-    p_Name += nameEnd;
-    /// the symbol is found in symbol pool
-    if (m_pLDInfo.getNamePool().findSymbol(entry.name))
-      pSymbolTable.push_back(entry);
-  }
+  MemoryRegion* header_region =
+    pArchive.getARFile().memArea()->request((pArchive.getARFile().fileOffset() +
+                                             offset),
+                                            sizeof(Archive::MemberHeader));
+  const Archive::MemberHeader* header =
+    reinterpret_cast<const Archive::MemberHeader*>(header_region->getBuffer());
+
+  assert(0 == memcmp(header->fmag, Archive::MEMBER_MAGIC, 2));
+
+  int strtab_size = atoi(header->size);
+
+  MemoryRegion* strtab_region =
+    pArchive.getARFile().memArea()->request((pArchive.getARFile().fileOffset() +
+                                             offset +
+                                             sizeof(Archive::MemberHeader)),
+                                            strtab_size);
+  const char* strtab =
+    reinterpret_cast<const char*>(strtab_region->getBuffer());
+
+  pArchive.getStrTable().assign(strtab, strtab_size);
+
+  pArchive.getARFile().memArea()->release(header_region);
+  pArchive.getARFile().memArea()->release(strtab_region);
+  return true;
 }
+
+/// shouldIncludeStatus - given a sym name from armap and check if including
+/// the corresponding archive member, and then return the decision
+enum Archive::Symbol::Status
+GNUArchiveReader::shouldIncludeSymbol(const llvm::StringRef& pSymName) const
+{
+  // TODO: handle symbol version issue and user defined symbols
+  ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pSymName);
+  if (NULL != info) {
+    if (!info->isUndef())
+      return Archive::Symbol::Exclude;
+    if (info->isWeak())
+      return Archive::Symbol::Unknown;
+    return Archive::Symbol::Include;
+  }
+  return Archive::Symbol::Unknown;
+}
+
diff --git a/lib/LD/LDSection.cpp b/lib/LD/LDSection.cpp
index 1ec9c13..2aad917 100644
--- a/lib/LD/LDSection.cpp
+++ b/lib/LD/LDSection.cpp
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 #include <mcld/LD/LDSection.h>
-#include <llvm/MC/SectionKind.h>
 
 using namespace mcld;
 
@@ -18,8 +17,7 @@
                      uint64_t pSize,
                      uint64_t pOffset,
                      uint64_t pAddr)
-  : llvm::MCSection(llvm::MCSection::SV_LDContext, llvm::SectionKind::getMetadata()),
-    m_Name(pName),
+  : m_Name(pName),
     m_Kind(pKind),
     m_Type(pType),
     m_Flag(pFlag),
diff --git a/lib/LD/LDSymbol.cpp b/lib/LD/LDSymbol.cpp
index f26e052..f088b5c 100644
--- a/lib/LD/LDSymbol.cpp
+++ b/lib/LD/LDSymbol.cpp
@@ -6,7 +6,9 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include "mcld/LD/LDSymbol.h"
+
+#include <mcld/LD/LDSymbol.h>
+
 #include <cstring>
 
 using namespace mcld;
@@ -33,7 +35,7 @@
   return (*this);
 }
 
-void LDSymbol::setFragmentRef(MCFragmentRef* pFragmentRef)
+void LDSymbol::setFragmentRef(FragmentRef* pFragmentRef)
 {
   m_pFragRef = pFragmentRef;
 }
diff --git a/lib/LD/Layout.cpp b/lib/LD/Layout.cpp
index bc91cee..1650556 100644
--- a/lib/LD/Layout.cpp
+++ b/lib/LD/Layout.cpp
@@ -7,22 +7,29 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <llvm/ADT/Twine.h>
-#include <mcld/ADT/SizeTraits.h>
 #include <mcld/LD/Layout.h>
+
+#include <cassert>
+
+#include <llvm/ADT/Twine.h>
+
+#include <mcld/ADT/SizeTraits.h>
 #include <mcld/LD/LDContext.h>
 #include <mcld/LD/LDFileFormat.h>
 #include <mcld/LD/LDSection.h>
+#include <mcld/LD/Fragment.h>
+#include <mcld/LD/FillFragment.h>
+#include <mcld/LD/AlignFragment.h>
 #include <mcld/MC/MCLinker.h>
 #include <mcld/MC/MCLDInfo.h>
 #include <mcld/Support/MsgHandling.h>
 #include <mcld/Target/TargetLDBackend.h>
-#include <cassert>
 
 using namespace mcld;
 
 //===----------------------------------------------------------------------===//
 // Range
+//===----------------------------------------------------------------------===//
 Layout::Range::Range()
   : header(NULL),
     prevRear(NULL) {
@@ -39,6 +46,7 @@
 
 //===----------------------------------------------------------------------===//
 // Layout
+//===----------------------------------------------------------------------===//
 Layout::Layout()
   : m_FragRefFactory(32) /** magic number **/ {
 }
@@ -47,23 +55,25 @@
 {
 }
 
-void Layout::setFragmentLayoutOrder(llvm::MCFragment* pFrag)
+void Layout::setFragmentLayoutOrder(Fragment* pFrag)
 {
   if (NULL == pFrag)
     return;
-  // compute the most-recent fragment whose order was set.
-  llvm::MCFragment* first = pFrag;
 
+  /// find the most-recent fragment whose order was set.
+  Fragment* first = pFrag;
   while (!hasLayoutOrder(*first)) {
     if (NULL == first->getPrevNode())
       break;
     first = first->getPrevNode();
   }
 
-  // set all layout order
-  unsigned int layout_order = 0;
-  llvm::MCFragment* frag_not_set = NULL;
+  /// set all layout order
 
+  // find the first fragment who has no order.
+  // find the last order of the fragment
+  unsigned int layout_order = 0;
+  Fragment* frag_not_set = NULL;
   if (NULL == first->getPrevNode()) {
     layout_order = 0;
     frag_not_set = first;
@@ -73,7 +83,7 @@
     frag_not_set = first->getNextNode();
   }
 
-  // set up all layout order
+  // for all fragments that has no order, set up its order
   while(NULL != frag_not_set) {
     frag_not_set->setLayoutOrder(layout_order);
     ++layout_order;
@@ -84,12 +94,13 @@
 /// setFragmentLayoutOffset - set the fragment's layout offset. This function
 /// also set up the layout offsets of all the fragments in the same range.
 /// If the offset of the fragment was set before, return immediately.
-void Layout::setFragmentLayoutOffset(llvm::MCFragment* pFrag)
+void Layout::setFragmentLayoutOffset(Fragment* pFrag)
 {
   if (NULL == pFrag)
     return;
-  // compute the most-recent fragment whose offset was set.
-  llvm::MCFragment* first = pFrag;
+
+  // find the most-recent fragment whose offset was set.
+  Fragment* first = pFrag;
 
   while (!hasLayoutOffset(*first)) {
     if (NULL == first->getPrevNode())
@@ -99,19 +110,19 @@
 
   // set all layout order
   uint64_t offset = 0;
-  llvm::MCFragment* frag_not_set = NULL;
+  Fragment* frag_not_set = NULL;
   if (NULL == first->getPrevNode()) {
     offset = 0;
     frag_not_set = first;
   }
   else {
-    offset = first->Offset;
+    offset = first->getOffset();
     offset += computeFragmentSize(*this, *first);
     frag_not_set = first->getNextNode();
   }
 
   while(NULL != frag_not_set) {
-    frag_not_set->Offset = offset;
+    frag_not_set->setOffset(offset);
     offset += computeFragmentSize(*this, *frag_not_set);
     frag_not_set = frag_not_set->getNextNode();
   }
@@ -120,7 +131,8 @@
 /// addInputRange
 ///   1. add a new range <pInputHdr, previous rear fragment>
 ///   2. compute the layout order of all previous ranges.
-void Layout::addInputRange(const llvm::MCSectionData& pSD,
+///   2. compute the layout offset of all previous ranges.
+void Layout::addInputRange(const SectionData& pSD,
                            const LDSection& pInputHdr)
 {
   RangeList* range_list = NULL;
@@ -141,12 +153,12 @@
   // set up previous rear of the range.
   // FIXME: in current design, we can not add a range before finishing adding
   // fragments in the previous range. If the limitation keeps, we can set
-  // prevRear to the last fragment in the MCSectionData simply.
+  // prevRear to the last fragment in the SectionData simply.
   //
   // if the pSD's fragment list is empty, the range.prevRear keeps NULL.
   if (!pSD.getFragmentList().empty()) {
     range->prevRear =
-                  const_cast<llvm::MCFragment*>(&pSD.getFragmentList().back());
+                  const_cast<Fragment*>(&pSD.getFragmentList().back());
   }
 
   // compute the layout order of the previous range.
@@ -156,24 +168,24 @@
   }
 }
 
-/// appendFragment - append the given MCFragment to the given MCSectionData,
+/// appendFragment - append the given Fragment to the given SectionData,
 /// and insert a MCAlignFragment to preserve the required align constraint if
 /// needed
-uint64_t Layout::appendFragment(llvm::MCFragment& pFrag,
-                                llvm::MCSectionData& pSD,
+uint64_t Layout::appendFragment(Fragment& pFrag,
+                                SectionData& pSD,
                                 uint32_t pAlignConstraint)
 {
-  // insert MCAlignFragment into MCSectionData first if needed
-  llvm::MCAlignFragment* align_frag = NULL;
+  // insert MCAlignFragment into SectionData first if needed
+  AlignFragment* align_frag = NULL;
   if (pAlignConstraint > 1) {
-    align_frag = new llvm::MCAlignFragment(pAlignConstraint, // alignment
-                                           0x0, // the filled value
-                                           1u,  // the size of filled value
-                                           pAlignConstraint - 1, // max bytes to emit
-                                           &pSD);
+    align_frag = new AlignFragment(pAlignConstraint, // alignment
+                                   0x0, // the filled value
+                                   1u,  // the size of filled value
+                                   pAlignConstraint - 1, // max bytes to emit
+                                   &pSD);
   }
 
-  // append the fragment to the MCSectionData
+  // append the fragment to the SectionData
   pFrag.setParent(&pSD);
   pSD.getFragmentList().push_back(&pFrag);
 
@@ -188,30 +200,30 @@
   setFragmentLayoutOffset(&pFrag);
 
   if (NULL != align_frag)
-    return pFrag.Offset - align_frag->Offset + computeFragmentSize(*this, pFrag);
+    return pFrag.getOffset() - align_frag->getOffset() + computeFragmentSize(*this, pFrag);
   else
     return computeFragmentSize(*this, pFrag);
 }
 
-/// getInputLDSection - give a MCFragment, return the corresponding input
+/// getInputLDSection - give a Fragment, return the corresponding input
 /// LDSection*
 LDSection*
-Layout::getInputLDSection(const llvm::MCFragment& pFrag)
+Layout::getInputLDSection(const Fragment& pFrag)
 {
-  const llvm::MCSectionData* sect_data = pFrag.getParent();
-  // check the MCSectionData
+  const SectionData* sect_data = pFrag.getParent();
+  // check the SectionData
   if (NULL == sect_data) {
     llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
-                             llvm::Twine(" any MCSectionData.\n"));
+                             llvm::Twine(" any SectionData.\n"));
   }
 
-  // check the MCSectionData's range list
+  // check the SectionData's range list
   if (0 == m_SDRangeMap.count(sect_data)) {
     llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
-                             llvm::Twine("the input's MCSectionData is not ") +
+                             llvm::Twine("the input's SectionData is not ") +
                              llvm::Twine("registered in the Layout.\nPlease ") +
                              llvm::Twine("use MCLinker::getOrCreateSectData() ") +
-                             llvm::Twine("to get input's MCSectionData.\n"));
+                             llvm::Twine("to get input's SectionData.\n"));
   }
 
   RangeList* range_list = m_SDRangeMap[sect_data];
@@ -237,25 +249,25 @@
   }
 }
 
-/// getInputLDSection - give a MCFragment, return the corresponding input
+/// getInputLDSection - give a Fragment, return the corresponding input
 /// LDSection*
 const LDSection*
-Layout::getInputLDSection(const llvm::MCFragment& pFrag) const
+Layout::getInputLDSection(const Fragment& pFrag) const
 {
-  const llvm::MCSectionData* sect_data = pFrag.getParent();
-  // check the MCSectionData
+  const SectionData* sect_data = pFrag.getParent();
+  // check the SectionData
   if (NULL == sect_data) {
     llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
-                             llvm::Twine(" any MCSectionData.\n"));
+                             llvm::Twine(" any SectionData.\n"));
   }
 
-  // check the MCSectionData's range list
+  // check the SectionData's range list
   if (0 == m_SDRangeMap.count(sect_data)) {
     llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
-                             llvm::Twine("the input's MCSectionData is not ") +
+                             llvm::Twine("the input's SectionData is not ") +
                              llvm::Twine("registered in the Layout.\nPlease ") +
                              llvm::Twine("use MCLinker::getOrCreateSectData() ") +
-                             llvm::Twine("to get input's MCSectionData.\n"));
+                             llvm::Twine("to get input's SectionData.\n"));
   }
 
   SDRangeMap::const_iterator range_list_iter = m_SDRangeMap.find(sect_data);
@@ -283,37 +295,36 @@
 }
 
 /// getOutputLDSection
-LDSection* Layout::getOutputLDSection(const llvm::MCFragment& pFrag)
+LDSection* Layout::getOutputLDSection(const Fragment& pFrag)
 {
-  llvm::MCSectionData* sect_data = pFrag.getParent();
+  SectionData* sect_data = pFrag.getParent();
   if (NULL == sect_data)
     return NULL;
 
-  return const_cast<LDSection*>(llvm::cast<LDSection>(&sect_data->getSection()));
+  return const_cast<LDSection*>(&sect_data->getSection());
 }
 
 /// getOutputLDSection
-const LDSection* Layout::getOutputLDSection(const llvm::MCFragment& pFrag) const
+const LDSection* Layout::getOutputLDSection(const Fragment& pFrag) const
 {
-  const llvm::MCSectionData* sect_data = pFrag.getParent();
+  const SectionData* sect_data = pFrag.getParent();
   if (NULL == sect_data)
     return NULL;
 
-  return llvm::cast<LDSection>(&sect_data->getSection());
+  return &sect_data->getSection();
 }
 
 /// getFragmentRef - assume the ragne exist, find the fragment reference
-MCFragmentRef*
-Layout::getFragmentRef(Layout::Range& pRange, uint64_t pOffset)
+FragmentRef* Layout::getFragmentRef(Layout::Range& pRange, uint64_t pOffset)
 {
   if (isEmptyRange(pRange))
     return NULL;
 
-  llvm::MCFragment* front = getFront(pRange);
+  Fragment* front = getFront(pRange);
   if (NULL == front)
     return NULL;
 
-  llvm::MCFragment* rear = getRear(pRange);
+  Fragment* rear = getRear(pRange);
   if (NULL == rear)
     return NULL;
 
@@ -323,13 +334,11 @@
 // @param pFront is the first fragment in the range.
 // @param pRear is the last fragment in the range.
 // @pOffset is the offset started from pFront.
-MCFragmentRef*
-Layout::getFragmentRef(llvm::MCFragment& pFront,
-                       llvm::MCFragment& pRear,
-                       uint64_t pOffset)
+FragmentRef*
+Layout::getFragmentRef(Fragment& pFront, Fragment& pRear, uint64_t pOffset)
 {
-  llvm::MCFragment* front = &pFront;
-  llvm::MCFragment* rear  = &pRear;
+  Fragment* front = &pFront;
+  Fragment* rear  = &pRear;
 
   if (!hasLayoutOffset(*rear)) {
     // compute layout order, offset
@@ -338,12 +347,12 @@
   }
 
   // compute the offset from overall start fragment.
-  uint64_t target_offset = pFront.Offset + pOffset;
+  uint64_t target_offset = pFront.getOffset() + pOffset;
 
   // from front to rear, find the offset which is as large as possible
   // but smaller than the target_offset.
   while (front != rear) {
-    if (llvm::MCFragment::FT_Align == front->getKind()) {
+    if (Fragment::Alignment == front->getKind()) {
       // alignment fragments were not counted in target_offset.
       // Count in the size of alignment fragmen in target_offset here.
       uint64_t align_size = 0x0;
@@ -355,33 +364,33 @@
       else {
         // If the alignment fragment is not the last fragment, the alignment
         // fragment's size is the distance between the two fragment.
-        align_size = front->getNextNode()->Offset - front->Offset;
+        align_size = front->getNextNode()->getOffset() - front->getOffset();
       }
       target_offset += align_size;
       front = front->getNextNode();
       continue;
     }
 
-    if (target_offset >= front->getNextNode()->Offset) {
+    if (target_offset >= front->getNextNode()->getOffset()) {
       front = front->getNextNode();
     }
     else {
       // found
-      MCFragmentRef* result = m_FragRefFactory.allocate();
-      new (result) MCFragmentRef(*front, target_offset - front->Offset);
+      FragmentRef* result = m_FragRefFactory.allocate();
+      new (result) FragmentRef(*front, target_offset - front->getOffset());
       return result;
     }
   }
 
   if (front == rear) {
-    if (llvm::MCFragment::FT_Align == front->getKind())
+    if (Fragment::Alignment == front->getKind())
       return NULL;
 
     if (!isValidOffset(*front, target_offset))
       return NULL;
 
-    MCFragmentRef* result = m_FragRefFactory.allocate();
-    new (result) MCFragmentRef(*front, target_offset - front->Offset);
+    FragmentRef* result = m_FragRefFactory.allocate();
+    new (result) FragmentRef(*front, target_offset - front->getOffset());
     return result;
   }
   return NULL;
@@ -389,11 +398,11 @@
 
 /// getFragmentRef - give a LDSection in input file and an offset, return
 /// the fragment reference.
-MCFragmentRef*
+FragmentRef*
 Layout::getFragmentRef(const LDSection& pInputSection, uint64_t pOffset)
 {
   // find out which SectionData covers the range of input section header
-  const llvm::MCSectionData* sect_data = pInputSection.getSectionData();
+  const SectionData* sect_data = pInputSection.getSectionData();
 
   // check range list
   if (0 == m_SDRangeMap.count(sect_data))
@@ -428,21 +437,21 @@
 /// @param pBigOffset - the offset, can be larger than the fragment, but can
 ///                     not larger than this input section.
 /// @return if found, return the fragment. Otherwise, return NULL.
-MCFragmentRef*
-Layout::getFragmentRef(const llvm::MCFragment& pFrag, uint64_t pBigOffset)
+FragmentRef*
+Layout::getFragmentRef(const Fragment& pFrag, uint64_t pBigOffset)
 {
   if (!hasLayoutOffset(pFrag)) {
     // compute layout order, offset
-    setFragmentLayoutOrder(const_cast<llvm::MCFragment*>(&pFrag));
-    setFragmentLayoutOffset(const_cast<llvm::MCFragment*>(&pFrag));
+    setFragmentLayoutOrder(const_cast<Fragment*>(&pFrag));
+    setFragmentLayoutOffset(const_cast<Fragment*>(&pFrag));
   }
 
   // find out which SectionData covers the range of input section header
-  const llvm::MCSectionData* sect_data = pFrag.getParent();
+  const SectionData* sect_data = pFrag.getParent();
 
   // check range list
   if (0 == m_SDRangeMap.count(sect_data)) {
-    llvm::report_fatal_error(llvm::Twine("MCSectionData has no") +
+    llvm::report_fatal_error(llvm::Twine("SectionData has no") +
                              llvm::Twine(" correponding range list.\n"));
   }
 
@@ -452,13 +461,13 @@
   RangeList* range_list = m_SDRangeMap[sect_data];
 
   // find out the specific part in SectionData range
-  uint64_t target_offset = pBigOffset + pFrag.Offset;
+  uint64_t target_offset = pBigOffset + pFrag.getOffset();
 
   RangeList::iterator range, rangeEnd = range_list->end();
   for (range = range_list->begin(); range != rangeEnd; ++range) {
     if (isEmptyRange(*range))
       continue;
-    if (getRear(*range)->Offset >= target_offset) {
+    if (getRear(*range)->getOffset() >= target_offset) {
       break;
     }
   }
@@ -472,17 +481,17 @@
   return getFragmentRef(*range, pBigOffset);
 }
 
-uint64_t Layout::getOutputOffset(const llvm::MCFragment& pFrag)
+uint64_t Layout::getOutputOffset(const Fragment& pFrag)
 {
   if (!hasLayoutOffset(pFrag)) {
     // compute layout order, offset
-    setFragmentLayoutOrder(const_cast<llvm::MCFragment*>(&pFrag));
-    setFragmentLayoutOffset(const_cast<llvm::MCFragment*>(&pFrag));
+    setFragmentLayoutOrder(const_cast<Fragment*>(&pFrag));
+    setFragmentLayoutOffset(const_cast<Fragment*>(&pFrag));
   }
-  return pFrag.Offset;
+  return pFrag.getOffset();
 }
 
-uint64_t Layout::getOutputOffset(const llvm::MCFragment& pFrag) const
+uint64_t Layout::getOutputOffset(const Fragment& pFrag) const
 {
   if (!hasLayoutOffset(pFrag)) {
     llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
@@ -490,15 +499,15 @@
                              llvm::Twine(__func__) +
                              llvm::Twine(" can not be used before layout().\n"));
   }
-  return pFrag.Offset;
+  return pFrag.getOffset();
 }
 
-uint64_t Layout::getOutputOffset(const MCFragmentRef& pFragRef)
+uint64_t Layout::getOutputOffset(const FragmentRef& pFragRef)
 {
   return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
 }
 
-uint64_t Layout::getOutputOffset(const MCFragmentRef& pFragRef) const
+uint64_t Layout::getOutputOffset(const FragmentRef& pFragRef) const
 {
   return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
 }
@@ -534,6 +543,10 @@
   }
 }
 
+/// layout - layout the sections
+///   1. finalize fragment offset
+///   2. compute section order
+///   3. finalize section offset
 bool Layout::layout(Output& pOutput,
                     const TargetLDBackend& pBackend,
                     const MCLDInfo& pInfo)
@@ -544,6 +557,7 @@
   LDContext& output_context = *pOutput.context();
   LDContext::sect_iterator it, itEnd = output_context.sectEnd();
   for (it = output_context.sectBegin(); it != itEnd; ++it) {
+    // calculate 1. all fragment offset, and 2. the section order
     LDSection* sect = *it;
 
     switch (sect->kind()) {
@@ -559,8 +573,7 @@
           if (NULL != sect->getSectionData() &&
               !sect->getSectionData()->getFragmentList().empty()) {
             // make sure that all fragments are valid
-            llvm::MCFragment& frag =
-              sect->getSectionData()->getFragmentList().back();
+            Fragment& frag = sect->getSectionData()->getFragmentList().back();
             setFragmentLayoutOrder(&frag);
             setFragmentLayoutOffset(&frag);
           }
@@ -604,15 +617,17 @@
 
   // Backend defines the section start offset for section 1.
   uint64_t offset = pBackend.sectionStartOffset();
-  // compute the section offset and handle alignment also. And ignore section 0
-  // (NULL in ELF/COFF), and MachO starts from section 1.
+
   for (size_t index = 1; index < m_SectionOrder.size(); ++index) {
-    // we should not preserve file space for the BSS section.
-    if (LDFileFormat::BSS != m_SectionOrder[index - 1]->kind())
+    // compute the section offset and handle alignment also. And ignore section 0
+    // (NULL in ELF/COFF), and MachO starts from section 1.
+
+    if (LDFileFormat::BSS != m_SectionOrder[index - 1]->kind()) {
+      // we should not preserve file space for the BSS section.
       offset += m_SectionOrder[index - 1]->size();
+    }
 
     alignAddress(offset, m_SectionOrder[index]->align());
-
     m_SectionOrder[index]->setOffset(offset);
   }
 
@@ -627,15 +642,15 @@
   return true;
 }
 
-bool Layout::isValidOffset(const llvm::MCFragment& pFrag, uint64_t pTargetOffset) const
+bool Layout::isValidOffset(const Fragment& pFrag, uint64_t pTargetOffset) const
 {
   uint64_t size = computeFragmentSize(*this, pFrag);
   if (0x0 == size)
-    return (pTargetOffset == pFrag.Offset);
+    return (pTargetOffset == pFrag.getOffset());
 
   if (NULL != pFrag.getNextNode())
-    return (pTargetOffset >= pFrag.Offset && pTargetOffset < pFrag.getNextNode()->Offset);
+    return (pTargetOffset >= pFrag.getOffset() && pTargetOffset < pFrag.getNextNode()->getOffset());
 
-  return (pTargetOffset >= pFrag.Offset && pTargetOffset < (pFrag.Offset + size));
+  return (pTargetOffset >= pFrag.getOffset() && pTargetOffset < (pFrag.getOffset() + size));
 }
 
diff --git a/lib/LD/RegionFragment.cpp b/lib/LD/RegionFragment.cpp
new file mode 100644
index 0000000..7508ed5
--- /dev/null
+++ b/lib/LD/RegionFragment.cpp
@@ -0,0 +1,24 @@
+//===- RegionFragment.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/LD/RegionFragment.h>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// RegionFragment
+//===----------------------------------------------------------------------===//
+RegionFragment::RegionFragment(MemoryRegion& pRegion, SectionData* pSD)
+  : Fragment(Fragment::Region, pSD), m_Region(pRegion) {
+}
+
+RegionFragment::~RegionFragment()
+{
+}
+
diff --git a/lib/LD/Relocation.cpp b/lib/LD/Relocation.cpp
index 4a901ba..0c95e06 100644
--- a/lib/LD/Relocation.cpp
+++ b/lib/LD/Relocation.cpp
@@ -6,7 +6,7 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include <llvm/MC/MCAssembler.h>
+
 #include <mcld/LD/Relocation.h>
 #include <mcld/LD/RelocationFactory.h>
 #include <mcld/LD/Layout.h>
@@ -15,10 +15,10 @@
 using namespace mcld;
 
 Relocation::Relocation(Relocation::Type pType,
-                       MCFragmentRef* pTargetRef,
+                       FragmentRef* pTargetRef,
                        Relocation::Address pAddend,
                        Relocation::DWord pTargetData)
-  : MCFragment(llvm::MCFragment::FT_Reloc),
+  : Fragment(Fragment::Relocation),
     m_Type(pType),
     m_TargetData(pTargetData),
     m_pSymInfo(NULL),
@@ -42,8 +42,7 @@
 {
   if (m_pSymInfo->type() == ResolveInfo::Section &&
      m_pSymInfo->outSymbol()->hasFragRef()) {
-    return llvm::cast<LDSection>(
-      m_pSymInfo->outSymbol()->fragRef()->frag()->getParent()->getSection()).addr();
+    return m_pSymInfo->outSymbol()->fragRef()->frag()->getParent()->getSection().addr();
   }
   return m_pSymInfo->outSymbol()->value();
 }
diff --git a/lib/LD/RelocationFactory.cpp b/lib/LD/RelocationFactory.cpp
index 2bcfeb3..828acb2 100644
--- a/lib/LD/RelocationFactory.cpp
+++ b/lib/LD/RelocationFactory.cpp
@@ -6,17 +6,22 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+
 #include <mcld/LD/RelocationFactory.h>
-#include <mcld/Target/GOT.h>
-#include <mcld/Target/TargetLDBackend.h>
-#include <llvm/Support/Host.h>
+
 #include <cstring>
 #include <cassert>
 
+#include <llvm/Support/Host.h>
+
+#include <mcld/Target/GOT.h>
+#include <mcld/Target/TargetLDBackend.h>
+
 using namespace mcld;
 
-//==========================
+//===----------------------------------------------------------------------===//
 // RelocationFactory
+//===----------------------------------------------------------------------===//
 RelocationFactory::RelocationFactory(size_t pNum)
   : GCFactory<Relocation, 0>(pNum),
     m_pLayout(NULL) {
@@ -27,7 +32,7 @@
 }
 
 Relocation* RelocationFactory::produce(RelocationFactory::Type pType,
-                                       MCFragmentRef& pFragRef,
+                                       FragmentRef& pFragRef,
                                        Address pAddend)
 {
   // target_data is the place where the relocation applys to.
diff --git a/lib/LD/SectionData.cpp b/lib/LD/SectionData.cpp
new file mode 100644
index 0000000..d1858ba
--- /dev/null
+++ b/lib/LD/SectionData.cpp
@@ -0,0 +1,19 @@
+//===- SectionData.cpp ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/SectionData.h>
+#include <mcld/LD/LDSection.h>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// SectionData
+//===----------------------------------------------------------------------===//
+SectionData::SectionData(const LDSection &pSection)
+  : m_pSection(&pSection), m_Alignment(1) {
+}
diff --git a/lib/LD/SectionMap.cpp b/lib/LD/SectionMap.cpp
index 9d32391..7bcd809 100644
--- a/lib/LD/SectionMap.cpp
+++ b/lib/LD/SectionMap.cpp
@@ -47,7 +47,7 @@
   // TODO: handle the cases such as overriding the exist mapping and drawing
   //       exception from the given SECTIONS command
   iterator it;
-  for (it = begin(); it != end(); ++it) {
+  for (it = m_SectMap.begin(); it != m_SectMap.end(); ++it) {
     if (pInput == (*it).inputSubStr)
       return false;
   }
@@ -131,8 +131,8 @@
 bool SectionMap::initStdSectionMap()
 {
   for (int i = 0; i < m_StdSectionMapSize; ++i) {
-    if (!push_back(m_StdSectionMap[i].from, m_StdSectionMap[i].to))
-      return false;
+    struct Mapping mapping = { m_StdSectionMap[i].from, m_StdSectionMap[i].to};
+    m_SectMap.push_back(mapping);
   }
   return true;
 }
diff --git a/lib/LD/SectionMerger.cpp b/lib/LD/SectionMerger.cpp
index f3a5b65..1817e0b 100644
--- a/lib/LD/SectionMerger.cpp
+++ b/lib/LD/SectionMerger.cpp
@@ -60,7 +60,7 @@
   return section;
 }
 
-llvm::MCSectionData* SectionMerger::getOutputSectData(const std::string& pName)
+SectionData* SectionMerger::getOutputSectData(const std::string& pName)
 {
   return getOutputSectHdr(pName)->getSectionData();
 }
diff --git a/lib/LD/StaticResolver.cpp b/lib/LD/StaticResolver.cpp
index 09cbc11..6401262 100644
--- a/lib/LD/StaticResolver.cpp
+++ b/lib/LD/StaticResolver.cpp
@@ -103,7 +103,6 @@
       }
       case DUND:
       case DUNDW: {
-        old->override(pNew);
         old->overrideVisibility(pNew);
         old->setDynamic();
         pOverride = false;
diff --git a/lib/MC/Android.mk b/lib/MC/Android.mk
index b184116..30ca202 100644
--- a/lib/MC/Android.mk
+++ b/lib/MC/Android.mk
@@ -5,8 +5,6 @@
   ContextFactory.cpp  \
   InputFactory.cpp  \
   InputTree.cpp \
-  MCBitcodeInterceptor.cpp  \
-  MCFragmentRef.cpp \
   MCLDAttribute.cpp \
   MCLDDirectory.cpp \
   MCLDDriver.cpp  \
@@ -16,7 +14,6 @@
   MCLDOptions.cpp \
   MCLDOutput.cpp  \
   MCLinker.cpp  \
-  MCRegionFragment.cpp  \
   SearchDirs.cpp  \
   SymbolCategory.cpp  \
   ZOption.cpp
diff --git a/lib/MC/MCBitcodeInterceptor.cpp b/lib/MC/MCBitcodeInterceptor.cpp
deleted file mode 100644
index a79c904..0000000
--- a/lib/MC/MCBitcodeInterceptor.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-//===- MCBitcodeInterceptor.cpp -------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/LD/Relocation.h>
-#include <mcld/MC/MCBitcodeInterceptor.h>
-#include <mcld/MC/MCLDInfo.h>
-#include <mcld/Target/TargetLDBackend.h>
-#include <llvm/MC/MCAssembler.h>
-#include <llvm/MC/MCExpr.h>
-#include <llvm/MC/MCValue.h>
-#include <llvm/MC/MCFixup.h>
-#include <llvm/MC/MCFixupKindInfo.h>
-#include <llvm/MC/MCSymbol.h>
-#include <llvm/MC/MCAsmLayout.h>
-#include <llvm/MC/MCAsmBackend.h>
-#include <llvm/MC/MCAssembler.h>
-#include <llvm/Support/raw_ostream.h>
-#include <llvm/MC/MCObjectStreamer.h>
-#include <llvm/Support/Casting.h>
-#include <llvm/Support/ELF.h>
-
-using namespace llvm;
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// non-member functions
-
-//===----------------------------------------------------------------------===//
-// MCBitcodeInterceptor
-MCBitcodeInterceptor::MCBitcodeInterceptor(MCObjectStreamer &pStreamer,
-                                           TargetLDBackend& pBackend,
-                                           MCLDInfo& pLDInfo)
-  : MCObjectWriter(llvm::nulls(),
-                   pStreamer.getAssembler().getWriter().isLittleEndian()),
-    m_Backend(pBackend),
-    m_LDInfo(pLDInfo) {
-  pStreamer.getAssembler().setWriter(*this);
-}
-
-MCBitcodeInterceptor::~MCBitcodeInterceptor()
-{
-}
-
-void MCBitcodeInterceptor::ExecutePostLayoutBinding(MCAssembler &Asm,
-                                                 const MCAsmLayout &Layout)
-{
-}
-
-
-void MCBitcodeInterceptor::RecordRelocation(const MCAssembler &Asm,
-                                         const MCAsmLayout &Layout,
-                                         const MCFragment *Fragment,
-                                         const MCFixup &Fixup,
-                                         MCValue Target,
-                                         uint64_t &FixedValue)
-{
-}
-
-/// WriteObject - not really write out a object. Instead, load data to LDContext
-void MCBitcodeInterceptor::WriteObject(MCAssembler &Asm,
-                                       const MCAsmLayout &Layout)
-{
-}
-
-
diff --git a/lib/MC/MCFragmentRef.cpp b/lib/MC/MCFragmentRef.cpp
deleted file mode 100644
index 69a865e..0000000
--- a/lib/MC/MCFragmentRef.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-//===- MCFragmentRef.cpp --------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <llvm/Support/MathExtras.h>
-#include <mcld/MC/MCFragmentRef.h>
-#include <mcld/MC/MCRegionFragment.h>
-#include <mcld/MC/MCTargetFragment.h>
-#include <mcld/LD/Layout.h>
-#include <cstring>
-#include <cassert>
-
-using namespace mcld;
-
-/// compunteFragmentSize - compute the specific MCFragment size
-uint64_t mcld::computeFragmentSize(const Layout& pLayout,
-                                   const llvm::MCFragment& pFrag)
-{
-  switch (pFrag.getKind()) {
-    case llvm::MCFragment::FT_Data:
-      return static_cast<const llvm::MCDataFragment&>(pFrag).getContents().size();
-    case llvm::MCFragment::FT_Fill:
-      return static_cast<const llvm::MCFillFragment&>(pFrag).getSize();
-    case llvm::MCFragment::FT_Inst:
-      return static_cast<const llvm::MCInstFragment&>(pFrag).getInstSize();
-
-    case llvm::MCFragment::FT_LEB:
-      return static_cast<const llvm::MCLEBFragment&>(pFrag).getContents().size();
-
-    case llvm::MCFragment::FT_Align: {
-      uint64_t offset = pLayout.getOutputOffset(pFrag);
-      const llvm::MCAlignFragment& align_frag = static_cast<const llvm::MCAlignFragment&>(pFrag);
-      uint64_t size = llvm::OffsetToAlignment(offset, align_frag.getAlignment());
-      if (size > align_frag.getMaxBytesToEmit())
-        return 0;
-      return size;
-    }
-
-    case llvm::MCFragment::FT_Org: {
-      // TODO
-      assert(0 && "FT_Org: Not implemented yet");
-      return 0;
-    }
-
-    case llvm::MCFragment::FT_Dwarf:
-      return static_cast<const llvm::MCDwarfLineAddrFragment&>(pFrag).getContents().size();
-    case llvm::MCFragment::FT_DwarfFrame:
-      return static_cast<const llvm::MCDwarfCallFrameFragment&>(pFrag).getContents().size();
-
-    case llvm::MCFragment::FT_Region:
-      return static_cast<const MCRegionFragment&>(pFrag).getRegion().size();
-
-    case llvm::MCFragment::FT_Target:
-      return static_cast<const MCTargetFragment&>(pFrag).getSize();
-
-    case llvm::MCFragment::FT_Reloc:
-      assert(0 && "the size of FT_Reloc fragment is handled by backend");
-      return 0;
-
-    default:
-      assert(0 && "invalid fragment kind");
-      return 0;
-  }
-}
-
-//==========================
-// MCFragmentRef
-MCFragmentRef::MCFragmentRef()
-  : m_pFragment(NULL), m_Offset(0) {
-}
-
-MCFragmentRef::MCFragmentRef(llvm::MCFragment& pFrag,
-                             MCFragmentRef::Offset pOffset)
-  : m_pFragment(&pFrag), m_Offset(pOffset) {
-}
-
-MCFragmentRef::~MCFragmentRef()
-{
-  m_pFragment = NULL;
-  m_Offset = 0;
-}
-
-MCFragmentRef& MCFragmentRef::assign(const MCFragmentRef& pCopy)
-{
-  m_pFragment = const_cast<llvm::MCFragment*>(pCopy.m_pFragment);
-  m_Offset = pCopy.m_Offset;
-  return *this;
-}
-
-MCFragmentRef& MCFragmentRef::assign(llvm::MCFragment& pFrag, MCFragmentRef::Offset pOffset)
-{
-  m_pFragment = &pFrag;
-  m_Offset = pOffset;
-  return *this;
-}
-
-void MCFragmentRef::memcpy(void* pDest, size_t pNBytes, Offset pOffset) const
-{
-  // check if the offset is still in a legal range.
-  if (NULL == m_pFragment)
-    return;
-  unsigned int total_offset = m_Offset + pOffset;
-  switch(m_pFragment->getKind()) {
-    case llvm::MCFragment::FT_Inst: {
-      llvm::MCInstFragment* inst_frag = static_cast<llvm::MCInstFragment*>(m_pFragment);
-      unsigned int total_length = inst_frag->getCode().size();
-      if (total_length < (total_offset+pNBytes))
-        pNBytes = total_length - total_offset;
-
-      std::memcpy(pDest, (inst_frag->getCode().data()+total_offset), pNBytes);
-      return;
-    }
-    case llvm::MCFragment::FT_Data: {
-      llvm::MCDataFragment* data_frag = static_cast<llvm::MCDataFragment*>(m_pFragment);
-      unsigned int total_length = data_frag->getContents().size();
-      if (total_length < (total_offset+pNBytes))
-        pNBytes = total_length - total_offset;
-
-      std::memcpy(pDest, (data_frag->getContents().data()+total_offset), pNBytes);
-      return;
-    }
-    case llvm::MCFragment::FT_Region: {
-      MCRegionFragment* region_frag = static_cast<mcld::MCRegionFragment*>(m_pFragment);
-      unsigned int total_length = region_frag->getRegion().size();
-      if (total_length < (total_offset+pNBytes))
-        pNBytes = total_length - total_offset;
-
-      std::memcpy(pDest, region_frag->getRegion().getBuffer(total_offset), pNBytes);
-      return;
-    }
-    case llvm::MCFragment::FT_Align:
-    case llvm::MCFragment::FT_Fill:
-    case llvm::MCFragment::FT_Org:
-    case llvm::MCFragment::FT_Dwarf:
-    case llvm::MCFragment::FT_DwarfFrame:
-    case llvm::MCFragment::FT_LEB:
-    default:
-      return;
-  }
-}
-
-MCFragmentRef::Address MCFragmentRef::deref()
-{
-  if (NULL == m_pFragment)
-    return NULL;
-  Address base = NULL;
-  switch(m_pFragment->getKind()) {
-    case llvm::MCFragment::FT_Inst:
-      base = (Address)static_cast<llvm::MCInstFragment*>(m_pFragment)->getCode().data();
-      break;
-    case llvm::MCFragment::FT_Data:
-      base = (Address)static_cast<llvm::MCDataFragment*>(m_pFragment)->getContents().data();
-      break;
-    case llvm::MCFragment::FT_Region:
-      base = static_cast<mcld::MCRegionFragment*>(m_pFragment)->getRegion().getBuffer();
-      break;
-    case llvm::MCFragment::FT_Align:
-    case llvm::MCFragment::FT_Fill:
-    case llvm::MCFragment::FT_Org:
-    case llvm::MCFragment::FT_Dwarf:
-    case llvm::MCFragment::FT_DwarfFrame:
-    case llvm::MCFragment::FT_LEB:
-    default:
-      return NULL;
-  }
-  return base + m_Offset;
-}
-
-MCFragmentRef::ConstAddress MCFragmentRef::deref() const
-{
-  if (NULL == m_pFragment)
-    return NULL;
-  ConstAddress base = NULL;
-  switch(m_pFragment->getKind()) {
-    case llvm::MCFragment::FT_Inst:
-      base = (ConstAddress)static_cast<const llvm::MCInstFragment*>(m_pFragment)->getCode().data();
-      break;
-    case llvm::MCFragment::FT_Data:
-      base = (ConstAddress)static_cast<const llvm::MCDataFragment*>(m_pFragment)->getContents().data();
-      break;
-    case llvm::MCFragment::FT_Region:
-      base = static_cast<const mcld::MCRegionFragment*>(m_pFragment)->getRegion().getBuffer();
-      break;
-    case llvm::MCFragment::FT_Align:
-    case llvm::MCFragment::FT_Fill:
-    case llvm::MCFragment::FT_Org:
-    case llvm::MCFragment::FT_Dwarf:
-    case llvm::MCFragment::FT_DwarfFrame:
-    case llvm::MCFragment::FT_LEB:
-    default:
-      return NULL;
-  }
-  return base + m_Offset;
-}
-
diff --git a/lib/MC/MCLDDriver.cpp b/lib/MC/MCLDDriver.cpp
index a86983d..a1af124 100644
--- a/lib/MC/MCLDDriver.cpp
+++ b/lib/MC/MCLDDriver.cpp
@@ -21,14 +21,18 @@
 #include <mcld/Support/MemoryAreaFactory.h>
 #include <mcld/Target/TargetLDBackend.h>
 #include <mcld/Support/MsgHandling.h>
+#include <mcld/LD/Archive.h>
 
 using namespace llvm;
 using namespace mcld;
 
-MCLDDriver::MCLDDriver(MCLDInfo& pLDInfo, TargetLDBackend& pLDBackend)
+MCLDDriver::MCLDDriver(MCLDInfo& pLDInfo,
+                       TargetLDBackend& pLDBackend,
+                       MemoryAreaFactory& pAreaFactory)
   : m_LDInfo(pLDInfo),
     m_LDBackend(pLDBackend),
-    m_pLinker(NULL) {
+    m_pLinker(NULL),
+    m_AreaFactory(pAreaFactory) {
 
 }
 
@@ -36,82 +40,6 @@
 {
   if (NULL != m_pLinker)
     delete m_pLinker;
-
-}
-
-void MCLDDriver::normalize()
-{
-  // -----  set up inputs  ----- //
-  InputTree::dfs_iterator input, inEnd = m_LDInfo.inputs().dfs_end();
-  for (input = m_LDInfo.inputs().dfs_begin(); input!=inEnd; ++input) {
-    // already got type - for example, bitcode or external OIR (object
-    // intermediate representation)
-    if ((*input)->type() == Input::Script ||
-        (*input)->type() == Input::Object ||
-        (*input)->type() == Input::DynObj  ||
-        (*input)->type() == Input::Archive ||
-        (*input)->type() == Input::External)
-      continue;
-
-    // is a relocatable object file
-    if (m_LDBackend.getObjectReader()->isMyFormat(**input)) {
-      (*input)->setType(Input::Object);
-      m_LDBackend.getObjectReader()->readObject(**input);
-    }
-    // is a shared object file
-    else if (m_LDBackend.getDynObjReader()->isMyFormat(**input)) {
-      (*input)->setType(Input::DynObj);
-      m_LDBackend.getDynObjReader()->readDSO(**input);
-    }
-    // is an archive
-    else if (m_LDBackend.getArchiveReader()->isMyFormat(*(*input))) {
-      (*input)->setType(Input::Archive);
-      mcld::InputTree* archive_member =
-                          m_LDBackend.getArchiveReader()->readArchive(**input);
-      if(NULL == archive_member)  {
-        error(diag::err_empty_input) << (*input)->name() << (*input)->path();
-        return;
-      }
-
-      m_LDInfo.inputs().merge<InputTree::Inclusive>(input, *archive_member);
-    }
-    else {
-      fatal(diag::err_unrecognized_input_file) << (*input)->path()
-                                               << m_LDInfo.triple().str();
-    }
-  } // end of for
-}
-
-bool MCLDDriver::linkable() const
-{
-  // check we have input and output files
-  if (m_LDInfo.inputs().empty()) {
-    error(diag::err_no_inputs);
-    return false;
-  }
-
-  // check all attributes are legal
-  mcld::AttributeFactory::const_iterator attr, attrEnd = m_LDInfo.attrFactory().end();
-  for (attr=m_LDInfo.attrFactory().begin(); attr!=attrEnd; ++attr) {
-    if (!m_LDInfo.attrFactory().constraint().isLegal((**attr))) {
-      return false;
-    }
-  }
-
-  // can not mix -static with shared objects
-  mcld::InputTree::const_bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
-  for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
-    if ((*input)->type() == mcld::Input::DynObj) {
-      if((*input)->attribute()->isStatic()) {
-        error(diag::err_mixed_shared_static_objects)
-                                        << (*input)->name() << (*input)->path();
-        return false;
-      }
-    }
-  }
-
-  // can not mix -r with shared objects
-  return true;
 }
 
 /// initMCLinker - initialize MCLinker
@@ -126,7 +54,8 @@
   // initialize the readers and writers
   // Because constructor can not be failed, we initalize all readers and
   // writers outside the MCLinker constructors.
-  if (!m_LDBackend.initArchiveReader(*m_pLinker, m_LDInfo) ||
+  if (!m_LDBackend.initObjectReader(*m_pLinker) ||
+      !m_LDBackend.initArchiveReader(*m_pLinker, m_LDInfo, m_AreaFactory) ||
       !m_LDBackend.initObjectReader(*m_pLinker) ||
       !m_LDBackend.initDynObjReader(*m_pLinker) ||
       !m_LDBackend.initObjectWriter(*m_pLinker) ||
@@ -189,18 +118,78 @@
   return true;
 }
 
-/// readSections - read all input section headers
-bool MCLDDriver::readSections()
+void MCLDDriver::normalize()
 {
-  // Bitcode is read by the other path. This function reads sections in object
-  // files.
-  mcld::InputTree::bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
-  for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
-    if ((*input)->type() == Input::Object) {
-      if (!m_LDBackend.getObjectReader()->readSections(**input))
-        return false;
+  // -----  set up inputs  ----- //
+  InputTree::iterator input, inEnd = m_LDInfo.inputs().end();
+  for (input = m_LDInfo.inputs().begin(); input!=inEnd; ++input) {
+    // already got type - for example, bitcode or external OIR (object
+    // intermediate representation)
+    if ((*input)->type() == Input::Script ||
+        (*input)->type() == Input::Object ||
+        (*input)->type() == Input::DynObj  ||
+        (*input)->type() == Input::Archive ||
+        (*input)->type() == Input::External)
+      continue;
+
+    // is a relocatable object file
+    if (m_LDBackend.getObjectReader()->isMyFormat(**input)) {
+      (*input)->setType(Input::Object);
+      m_LDBackend.getObjectReader()->readObject(**input);
+      m_LDBackend.getObjectReader()->readSections(**input);
+      m_LDBackend.getObjectReader()->readSymbols(**input);
+    }
+    // is a shared object file
+    else if (m_LDBackend.getDynObjReader()->isMyFormat(**input)) {
+      (*input)->setType(Input::DynObj);
+      m_LDBackend.getDynObjReader()->readDSO(**input);
+      m_LDBackend.getDynObjReader()->readSymbols(**input);
+    }
+    // is an archive
+    else if (m_LDBackend.getArchiveReader()->isMyFormat(**input)) {
+      (*input)->setType(Input::Archive);
+      Archive archive(**input, m_LDInfo.inputFactory());
+      m_LDBackend.getArchiveReader()->readArchive(archive);
+      if(archive.numOfObjectMember() > 0) {
+        m_LDInfo.inputs().merge<InputTree::Inclusive>(input, archive.inputs());
+      }
+    }
+    else {
+      fatal(diag::err_unrecognized_input_file) << (*input)->path()
+                                               << m_LDInfo.triple().str();
+    }
+  } // end of for
+}
+
+bool MCLDDriver::linkable() const
+{
+  // check we have input and output files
+  if (m_LDInfo.inputs().empty()) {
+    error(diag::err_no_inputs);
+    return false;
+  }
+
+  // check all attributes are legal
+  mcld::AttributeFactory::const_iterator attr, attrEnd = m_LDInfo.attrFactory().end();
+  for (attr=m_LDInfo.attrFactory().begin(); attr!=attrEnd; ++attr) {
+    if (!m_LDInfo.attrFactory().constraint().isLegal((**attr))) {
+      return false;
     }
   }
+
+  // can not mix -static with shared objects
+  mcld::InputTree::const_bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
+  for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
+    if ((*input)->type() == mcld::Input::DynObj) {
+      if((*input)->attribute()->isStatic()) {
+        error(diag::err_mixed_shared_static_objects)
+                                        << (*input)->name() << (*input)->path();
+        return false;
+      }
+    }
+  }
+
+  // can not mix -r with shared objects
   return true;
 }
 
@@ -212,26 +201,6 @@
   return true;
 }
 
-/// readSymbolTables - read symbol tables from the input files.
-///  for each input file, loads its symbol table from file.
-bool MCLDDriver::readSymbolTables()
-{
-  mcld::InputTree::dfs_iterator input, inEnd = m_LDInfo.inputs().dfs_end();
-  for (input=m_LDInfo.inputs().dfs_begin(); input!=inEnd; ++input) {
-    switch((*input)->type()) {
-    case Input::DynObj:
-      if (!m_LDBackend.getDynObjReader()->readSymbols(**input))
-        return false;
-      break;
-    case Input::Object:
-      if (!m_LDBackend.getObjectReader()->readSymbols(**input))
-        return false;
-      break;
-    }
-  }
-  return true;
-}
-
 /// addStandardSymbols - shared object and executable files need some
 /// standard symbols
 ///   @return if there are some input symbols with the same name to the
diff --git a/lib/MC/MCLinker.cpp b/lib/MC/MCLinker.cpp
index 7321e49..e9fb327 100644
--- a/lib/MC/MCLinker.cpp
+++ b/lib/MC/MCLinker.cpp
@@ -1,4 +1,4 @@
-//===- MCLinker.cpp -----------------------------------------------------===//
+//===- MCLinker.cpp -------------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -11,6 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 #include <mcld/MC/MCLinker.h>
+
+#include <llvm/Support/Host.h>
+#include <llvm/Support/raw_ostream.h>
+
 #include <mcld/MC/MCLDInput.h>
 #include <mcld/MC/MCLDInfo.h>
 #include <mcld/LD/Resolver.h>
@@ -19,13 +23,13 @@
 #include <mcld/LD/LDSectionFactory.h>
 #include <mcld/LD/SectionMap.h>
 #include <mcld/LD/RelocationFactory.h>
+#include <mcld/LD/FillFragment.h>
+#include <mcld/LD/RegionFragment.h>
 #include <mcld/LD/EhFrame.h>
 #include <mcld/LD/EhFrameHdr.h>
 #include <mcld/Support/MemoryRegion.h>
 #include <mcld/Support/MsgHandling.h>
 #include <mcld/Target/TargetLDBackend.h>
-#include <llvm/Support/Host.h>
-#include <llvm/Support/raw_ostream.h>
 
 using namespace mcld;
 
@@ -50,6 +54,9 @@
     delete m_pSectionMerger;
 }
 
+//===----------------------------------------------------------------------===//
+// Symbol Operations
+//===----------------------------------------------------------------------===//
 /// addSymbolFromObject - add a symbol from object file and resolve it
 /// immediately
 LDSymbol* MCLinker::addSymbolFromObject(const llvm::StringRef& pName,
@@ -58,7 +65,7 @@
                                         ResolveInfo::Binding pBinding,
                                         ResolveInfo::SizeType pSize,
                                         LDSymbol::ValueType pValue,
-                                        MCFragmentRef* pFragmentRef,
+                                        FragmentRef* pFragmentRef,
                                         ResolveInfo::Visibility pVisibility)
 {
 
@@ -165,7 +172,7 @@
                                         ResolveInfo::Binding pBinding,
                                         ResolveInfo::SizeType pSize,
                                         LDSymbol::ValueType pValue,
-                                        MCFragmentRef* pFragmentRef,
+                                        FragmentRef* pFragmentRef,
                                         ResolveInfo::Visibility pVisibility)
 {
   // We merge sections when reading them. So we do not need symbols with
@@ -236,7 +243,7 @@
                                            ResolveInfo::Binding pBinding,
                                            ResolveInfo::SizeType pSize,
                                            LDSymbol::ValueType pValue,
-                                           MCFragmentRef* pFragmentRef,
+                                           FragmentRef* pFragmentRef,
                                            ResolveInfo::Visibility pVisibility)
 {
   ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName);
@@ -306,13 +313,13 @@
                                            ResolveInfo::Binding pBinding,
                                            ResolveInfo::SizeType pSize,
                                            LDSymbol::ValueType pValue,
-                                           MCFragmentRef* pFragmentRef,
+                                           FragmentRef* pFragmentRef,
                                            ResolveInfo::Visibility pVisibility)
 {
   ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName);
 
-  if (NULL == info || !info->isUndef()) {
-    // only undefined symbol can make a reference.
+  if (NULL == info || !(info->isUndef() || info->isDyn())) {
+    // only undefined symbol and dynamic symbol can make a reference.
     return NULL;
   }
 
@@ -357,7 +364,7 @@
                                                      ResolveInfo::Binding pBinding,
                                                      ResolveInfo::SizeType pSize,
                                                      LDSymbol::ValueType pValue,
-                                                     MCFragmentRef* pFragmentRef,
+                                                     FragmentRef* pFragmentRef,
                                                      ResolveInfo::Visibility pVisibility)
 {
   // Result is <info, existent, override>
@@ -403,13 +410,13 @@
                                                     ResolveInfo::Binding pBinding,
                                                     ResolveInfo::SizeType pSize,
                                                     LDSymbol::ValueType pValue,
-                                                    MCFragmentRef* pFragmentRef,
+                                                    FragmentRef* pFragmentRef,
                                                     ResolveInfo::Visibility pVisibility)
 {
   ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName);
 
-  if (NULL == info || !info->isUndef()) {
-    // only undefined symbol can make a reference
+  if (NULL == info || !(info->isUndef() || info->isDyn())) {
+    // only undefined symbol and dynamic symbol can make a reference.
     return NULL;
   }
 
@@ -424,6 +431,54 @@
                                           pVisibility);
 }
 
+bool MCLinker::finalizeSymbols()
+{
+  SymbolCategory::iterator symbol, symEnd = m_OutputSymbols.end();
+  for (symbol = m_OutputSymbols.begin(); symbol != symEnd; ++symbol) {
+
+    if ((*symbol)->resolveInfo()->isAbsolute() ||
+        (*symbol)->resolveInfo()->type() == ResolveInfo::File) {
+      // absolute symbols or symbols with function type should have
+      // zero value
+      (*symbol)->setValue(0x0);
+      continue;
+    }
+
+    if ((*symbol)->hasFragRef()) {
+      // set the virtual address of the symbol. If the output file is
+      // relocatable object file, the section's virtual address becomes zero.
+      // And the symbol's value become section relative offset.
+      uint64_t value = getLayout().getOutputOffset(*(*symbol)->fragRef());
+      assert(NULL != (*symbol)->fragRef()->frag());
+      uint64_t addr  = getLayout().getOutputLDSection(*(*symbol)->fragRef()->frag())->addr();
+      (*symbol)->setValue(value + addr);
+      continue;
+    }
+  }
+
+  // finialize target-dependent symbols
+  return m_Backend.finalizeSymbols(*this, m_LDInfo.output());
+}
+
+bool MCLinker::shouldForceLocal(const ResolveInfo& pInfo) const
+{
+  // forced local symbol matches all rules:
+  // 1. We are not doing incremental linking.
+  // 2. The symbol is with Hidden or Internal visibility.
+  // 3. The symbol should be global or weak. Otherwise, local symbol is local.
+  // 4. The symbol is defined or common
+  if (m_LDInfo.output().type() != Output::Object &&
+      (pInfo.visibility() == ResolveInfo::Hidden ||
+         pInfo.visibility() == ResolveInfo::Internal) &&
+      (pInfo.isGlobal() || pInfo.isWeak()) &&
+      (pInfo.isDefine() || pInfo.isCommon()))
+    return true;
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Section Operations
+//===----------------------------------------------------------------------===//
 /// createSectHdr - create the input section header
 LDSection& MCLinker::createSectHdr(const std::string& pName,
                                    LDFileFormat::Kind pKind,
@@ -475,12 +530,12 @@
   return *output_sect;
 }
 
-/// getOrCreateSectData - get or create MCSectionData
+/// getOrCreateSectData - get or create SectionData
 /// pSection is input LDSection
-llvm::MCSectionData& MCLinker::getOrCreateSectData(LDSection& pSection)
+SectionData& MCLinker::getOrCreateSectData(LDSection& pSection)
 {
   // if there is already a section data pointed by section, return it.
-  llvm::MCSectionData* sect_data = pSection.getSectionData();
+  SectionData* sect_data = pSection.getSectionData();
   if (NULL != sect_data) {
     m_Layout.addInputRange(*sect_data, pSection);
     return *sect_data;
@@ -500,22 +555,37 @@
     return *sect_data;
   }
 
-  // if the output LDSection also has no MCSectionData, then create one.
+  // if the output LDSection also has no SectionData, then create one.
   sect_data = m_LDSectDataFactory.allocate();
-  new (sect_data) llvm::MCSectionData(*output_sect);
+  new (sect_data) SectionData(*output_sect);
   pSection.setSectionData(sect_data);
   output_sect->setSectionData(sect_data);
   m_Layout.addInputRange(*sect_data, pSection);
   return *sect_data;
 }
 
+void MCLinker::initSectionMap()
+{
+  assert(m_LDInfo.output().hasContext());
+  if (NULL == m_pSectionMerger)
+    m_pSectionMerger = new SectionMerger(m_SectionMap, *m_LDInfo.output().context());
+}
+
+bool MCLinker::layout()
+{
+  return m_Layout.layout(m_LDInfo.output(), m_Backend, m_LDInfo);
+}
+
+//===----------------------------------------------------------------------===//
+// Relocation Operations
+//===----------------------------------------------------------------------===//
 /// addRelocation - add a relocation entry in MCLinker (only for object file)
 ///
 /// All symbols should be read and resolved before calling this function.
 Relocation* MCLinker::addRelocation(Relocation::Type pType,
                                     const LDSymbol& pSym,
                                     ResolveInfo& pResolveInfo,
-                                    MCFragmentRef& pFragmentRef,
+                                    FragmentRef& pFragmentRef,
                                     const LDSection& pSection,
                                     Relocation::Address pAddend)
 {
@@ -548,7 +618,7 @@
   RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
 
   for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
-    llvm::MCFragment* frag = (llvm::MCFragment*)relocIter;
+    Fragment* frag = (Fragment*)relocIter;
     static_cast<Relocation*>(frag)->apply(*m_Backend.getRelocFactory(), m_LDInfo);
   }
   return true;
@@ -565,7 +635,7 @@
   RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
   for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
 
-    llvm::MCFragment* frag = (llvm::MCFragment*)relocIter;
+    Fragment* frag = (Fragment*)relocIter;
     Relocation* reloc = static_cast<Relocation*>(frag);
 
     // get output file offset
@@ -600,63 +670,9 @@
   m_LDInfo.output().memArea()->clear();
 }
 
-void MCLinker::initSectionMap()
-{
-  assert(m_LDInfo.output().hasContext());
-  if (NULL == m_pSectionMerger)
-    m_pSectionMerger = new SectionMerger(m_SectionMap, *m_LDInfo.output().context());
-}
-
-bool MCLinker::layout()
-{
-  return m_Layout.layout(m_LDInfo.output(), m_Backend, m_LDInfo);
-}
-
-bool MCLinker::finalizeSymbols()
-{
-  SymbolCategory::iterator symbol, symEnd = m_OutputSymbols.end();
-  for (symbol = m_OutputSymbols.begin(); symbol != symEnd; ++symbol) {
-
-    if ((*symbol)->resolveInfo()->isAbsolute() ||
-        (*symbol)->resolveInfo()->type() == ResolveInfo::File) {
-      // absolute symbols or symbols with function type should have
-      // zero value
-      (*symbol)->setValue(0x0);
-      continue;
-    }
-
-    if ((*symbol)->hasFragRef()) {
-      // set the virtual address of the symbol. If the output file is
-      // relocatable object file, the section's virtual address becomes zero.
-      // And the symbol's value become section relative offset.
-      uint64_t value = getLayout().getOutputOffset(*(*symbol)->fragRef());
-      assert(NULL != (*symbol)->fragRef()->frag());
-      uint64_t addr  = getLayout().getOutputLDSection(*(*symbol)->fragRef()->frag())->addr();
-      (*symbol)->setValue(value + addr);
-      continue;
-    }
-  }
-
-  // finialize target-dependent symbols
-  return m_Backend.finalizeSymbols(*this, m_LDInfo.output());
-}
-
-bool MCLinker::shouldForceLocal(const ResolveInfo& pInfo) const
-{
-  // forced local symbol matches all rules:
-  // 1. We are not doing incremental linking.
-  // 2. The symbol is with Hidden or Internal visibility.
-  // 3. The symbol should be global or weak. Otherwise, local symbol is local.
-  // 4. The symbol is defined or common
-  if (m_LDInfo.output().type() != Output::Object &&
-      (pInfo.visibility() == ResolveInfo::Hidden ||
-         pInfo.visibility() == ResolveInfo::Internal) &&
-      (pInfo.isGlobal() || pInfo.isWeak()) &&
-      (pInfo.isDefine() || pInfo.isCommon()))
-    return true;
-  return false;
-}
-
+//===----------------------------------------------------------------------===//
+// Exception Handling Operations
+//===----------------------------------------------------------------------===//
 /// addEhFrame - add an exception handling section
 /// @param pSection - the input section
 /// @param pArea - the memory area which pSection is within.
@@ -667,7 +683,7 @@
   uint64_t size = 0;
 
   // get the SectionData of this eh_frame
-  llvm::MCSectionData& sect_data = getOrCreateSectData(pSection);
+  SectionData& sect_data = getOrCreateSectData(pSection);
 
   // parse the eh_frame if the option --eh-frame-hdr is given
   if (m_LDInfo.options().hasEhFrameHdr()) {
@@ -687,14 +703,14 @@
   MemoryRegion* region = pArea.request(pInput.fileOffset() + pSection.offset(),
                                        pSection.size());
 
-  llvm::MCFragment* frag = NULL;
+  Fragment* frag = NULL;
   if (NULL == region) {
     // If the input section's size is zero, we got a NULL region.
     // use a virtual fill fragment
-    frag = new llvm::MCFillFragment(0x0, 0, 0);
+    frag = new FillFragment(0x0, 0, 0);
   }
   else
-    frag = new MCRegionFragment(*region);
+    frag = new RegionFragment(*region);
 
   size = m_Layout.appendFragment(*frag, sect_data, pSection.align());
   return size;
diff --git a/lib/MC/MCRegionFragment.cpp b/lib/MC/MCRegionFragment.cpp
deleted file mode 100644
index 59b109a..0000000
--- a/lib/MC/MCRegionFragment.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===- MCRegionFragment.cpp - MCRegionFragment implementation -------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "mcld/MC/MCRegionFragment.h"
-
-using namespace mcld;
-using namespace llvm;
-
-//==========================
-// MCRegionFragment
-MCRegionFragment::MCRegionFragment(MemoryRegion& pRegion, MCSectionData* pSD)
-  : MCFragment((llvm::MCFragment::FragmentType)FT_Region, pSD), m_Region(pRegion) {
-}
-
-MCRegionFragment::~MCRegionFragment()
-{
-}
-
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index cc15e37..891b2bb 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -16,9 +16,9 @@
 
 using namespace mcld;
 
-//--------------------------------------------------
+//===----------------------------------------------------------------------===//
 // parser<mcld::sys::fs::Path>
-//
+//===----------------------------------------------------------------------===//
 bool parser<mcld::sys::fs::Path>::parse(llvm::cl::Option &O,
                        llvm::StringRef ArgName,
                        llvm::StringRef Arg,
@@ -52,9 +52,9 @@
   // do nothing
 }
 
-//--------------------------------------------------
+//===----------------------------------------------------------------------===//
 // parser<mcld::MCLDDirectory>
-//
+//===----------------------------------------------------------------------===//
 bool parser<mcld::MCLDDirectory>::parse(llvm::cl::Option &O,
                                 llvm::StringRef ArgName,
                                 llvm::StringRef Arg,
@@ -86,9 +86,9 @@
   // do nothing
 }
 
-//--------------------------------------------------
+//===----------------------------------------------------------------------===//
 // parser<mcld::ZOption>
-//
+//===----------------------------------------------------------------------===//
 bool parser<mcld::ZOption>::parse(llvm::cl::Option &O,
                                   llvm::StringRef ArgName,
                                   llvm::StringRef Arg,
diff --git a/lib/Support/FileHandle.cpp b/lib/Support/FileHandle.cpp
index f6b898c..6d43a4c 100644
--- a/lib/Support/FileHandle.cpp
+++ b/lib/Support/FileHandle.cpp
@@ -219,9 +219,6 @@
   return true;
 }
 
-#include <iostream>
-using namespace std;
-
 bool FileHandle::mmap(void*& pMemBuffer, size_t pStartOffset, size_t pLength)
 {
   if (!isOpened()) {
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
index e35132f..7f516f6 100644
--- a/lib/Support/Path.cpp
+++ b/lib/Support/Path.cpp
@@ -140,6 +140,14 @@
     m_PathName.erase(begin+1,pSepPos-begin-1);
 }
 
+Path Path::parent_path() const
+{
+  size_t end_pos = m_PathName.find_last_of(separator);
+  if (end_pos != StringType::npos)
+    return Path(m_PathName.substr(0, end_pos));
+  return Path();
+}
+
 Path Path::stem() const
 {
   size_t begin_pos = m_PathName.find_last_of(separator)+1;
diff --git a/lib/Support/Unix/System.inc b/lib/Support/Unix/System.inc
index 716aaa2..a7ec15f 100644
--- a/lib/Support/Unix/System.inc
+++ b/lib/Support/Unix/System.inc
@@ -6,7 +6,7 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include <string>
+#include <cstring>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -16,7 +16,7 @@
 
 char *strerror(int errnum)
 {
-  return ::strerror(errnum);
+  return std::strerror(errnum);
 }
 
 } // namespace of sys
diff --git a/lib/Target/ARM/ARMGOT.cpp b/lib/Target/ARM/ARMGOT.cpp
index af37768..200bcb5 100644
--- a/lib/Target/ARM/ARMGOT.cpp
+++ b/lib/Target/ARM/ARMGOT.cpp
@@ -7,10 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 #include "ARMGOT.h"
+
+#include <new>
+
+#include <llvm/Support/Casting.h>
+
 #include <mcld/LD/LDFileFormat.h>
 #include <mcld/Support/MemoryRegion.h>
 #include <mcld/Support/MsgHandling.h>
-#include <new>
 
 namespace {
   const size_t ARMGOTEntrySize = 4;
@@ -20,7 +24,7 @@
 
 //===----------------------------------------------------------------------===//
 // ARMGOT
-ARMGOT::ARMGOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+ARMGOT::ARMGOT(LDSection& pSection, SectionData& pSectionData)
              : GOT(pSection, pSectionData, ARMGOTEntrySize),
                m_NormalGOTIterator(), m_GOTPLTIterator(),
                m_GOTPLTBegin(), m_GOTPLTEnd()
@@ -33,7 +37,7 @@
                                         &m_SectionData);
 
     if (!Entry)
-      fatal(diag::fail_allocate_memory) << "GOT0";
+      fatal(diag::fail_allocate_memory_got);
 
     m_Section.setSize(m_Section.size() + ARMGOTEntrySize);
   }
@@ -66,7 +70,7 @@
                                         &m_SectionData);
 
     if (!Entry)
-      fatal(diag::fail_allocate_memory) << "GOTEntry";
+      fatal(diag::fail_allocate_memory_got);
 
     m_Section.setSize(m_Section.size() + ARMGOTEntrySize);
   }
@@ -79,7 +83,7 @@
     got_entry= new GOTEntry(0, getEntrySize(),&(getSectionData()));
 
     if (!got_entry)
-      fatal(diag::fail_allocate_memory) << "GOTEntry";
+      fatal(diag::fail_allocate_memory_got);
 
     m_Section.setSize(m_Section.size() + getEntrySize());
 
diff --git a/lib/Target/ARM/ARMGOT.h b/lib/Target/ARM/ARMGOT.h
index 90f0f53..13d3424 100644
--- a/lib/Target/ARM/ARMGOT.h
+++ b/lib/Target/ARM/ARMGOT.h
@@ -12,7 +12,10 @@
 #include <gtest.h>
 #endif
 
+#include <llvm/ADT/DenseMap.h>
+
 #include <mcld/Target/GOT.h>
+#include <mcld/LD/SectionData.h>
 
 namespace mcld
 {
@@ -27,15 +30,15 @@
   typedef llvm::DenseMap<const ResolveInfo*, GOTEntry*> SymbolIndexMapType;
 
 public:
-  typedef llvm::MCSectionData::iterator iterator;
-  typedef llvm::MCSectionData::const_iterator const_iterator;
+  typedef SectionData::iterator iterator;
+  typedef SectionData::const_iterator const_iterator;
 
   enum {
     ARMGOT0Num = 3
   };
 
 public:
-  ARMGOT(LDSection &pSection, llvm::MCSectionData& pSectionData);
+  ARMGOT(LDSection &pSection, SectionData& pSectionData);
 
   ~ARMGOT();
 
diff --git a/lib/Target/ARM/ARMLDBackend.cpp b/lib/Target/ARM/ARMLDBackend.cpp
index 81915c9..a44f1da 100644
--- a/lib/Target/ARM/ARMLDBackend.cpp
+++ b/lib/Target/ARM/ARMLDBackend.cpp
@@ -6,28 +6,34 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include <llvm/ADT/Triple.h>
-#include <llvm/ADT/Twine.h>
-#include <llvm/Support/ELF.h>
-
-#include <mcld/LD/SectionMap.h>
-#include <mcld/MC/MCLDInfo.h>
-#include <mcld/MC/MCLDOutput.h>
-#include <mcld/MC/MCLinker.h>
-#include <mcld/MC/MCRegionFragment.h>
-#include <mcld/Support/MemoryRegion.h>
-#include <mcld/Support/MsgHandling.h>
-#include <mcld/Support/TargetRegistry.h>
-
-#include <cstring>
-
 #include "ARM.h"
 #include "ARMELFDynamic.h"
 #include "ARMLDBackend.h"
 #include "ARMRelocationFactory.h"
 
+#include <cstring>
+
+#include <llvm/ADT/Triple.h>
+#include <llvm/ADT/Twine.h>
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/Casting.h>
+
+#include <mcld/LD/SectionMap.h>
+#include <mcld/LD/FillFragment.h>
+#include <mcld/LD/AlignFragment.h>
+#include <mcld/LD/RegionFragment.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/Support/MsgHandling.h>
+#include <mcld/Support/TargetRegistry.h>
+
 using namespace mcld;
 
+//===----------------------------------------------------------------------===//
+// ARMGNULDBackend
+//===----------------------------------------------------------------------===//
 ARMGNULDBackend::ARMGNULDBackend()
   : m_pRelocFactory(NULL),
     m_pGOT(NULL),
@@ -176,7 +182,7 @@
 
 void ARMGNULDBackend::createARMGOT(MCLinker& pLinker, const Output& pOutput)
 {
-  // get .got LDSection and create MCSectionData
+  // get .got LDSection and create SectionData
   ELFFileFormat* file_format = getOutputFormat(pOutput);
 
   LDSection& got = file_format->getGOT();
@@ -218,11 +224,11 @@
   // get .plt and .rel.plt LDSection
   LDSection& plt = file_format->getPLT();
   LDSection& relplt = file_format->getRelPlt();
-  // create MCSectionData and ARMPLT
+  // create SectionData and ARMPLT
   m_pPLT = new ARMPLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOT);
   // set info of .rel.plt to .plt
   relplt.setLink(&plt);
-  // create MCSectionData and ARMRelDynSection
+  // create SectionData and ARMRelDynSection
   m_pRelPLT = new OutputRelocSection(relplt,
                                      pLinker.getOrCreateSectData(relplt),
                                      8);
@@ -233,9 +239,9 @@
 {
   ELFFileFormat* file_format = getOutputFormat(pOutput);
 
-  // get .rel.dyn LDSection and create MCSectionData
+  // get .rel.dyn LDSection and create SectionData
   LDSection& reldyn = file_format->getRelDyn();
-  // create MCSectionData and ARMRelDynSection
+  // create SectionData and ARMRelDynSection
   m_pRelDyn = new OutputRelocSection(reldyn,
                                      pLinker.getOrCreateSectData(reldyn),
                                      8);
@@ -274,9 +280,9 @@
                                    llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
   }
 
-  // get or create corresponding BSS MCSectionData
+  // get or create corresponding BSS SectionData
   assert(NULL != bss_sect_hdr);
-  llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(
+  SectionData& bss_section = pLinker.getOrCreateSectData(
                                      *bss_sect_hdr);
 
   // Determine the alignment by the symbol value
@@ -284,7 +290,7 @@
   uint32_t addralign = bitclass() / 8;
 
   // allocate space in BSS for the copy symbol
-  llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, pSym.size());
+  Fragment* frag = new FillFragment(0x0, 1, pSym.size());
   uint64_t size = pLinker.getLayout().appendFragment(*frag,
                                                      bss_section,
                                                      addralign);
@@ -763,22 +769,21 @@
       &pSection == m_pEXTAB) {
     // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab
     // directly from the input file.
-    const llvm::MCSectionData* sect_data = pSection.getSectionData();
-    llvm::MCSectionData::const_iterator frag_iter, frag_end = sect_data->end();
+    const SectionData* sect_data = pSection.getSectionData();
+    SectionData::const_iterator frag_iter, frag_end = sect_data->end();
     uint8_t* out_offset = pRegion.start();
     for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
       size_t size = computeFragmentSize(pLayout, *frag_iter);
       switch(frag_iter->getKind()) {
-        case llvm::MCFragment::FT_Region: {
-          const MCRegionFragment& region_frag =
-            llvm::cast<MCRegionFragment>(*frag_iter);
+        case Fragment::Region: {
+          const RegionFragment& region_frag =
+            llvm::cast<RegionFragment>(*frag_iter);
           const uint8_t* start = region_frag.getRegion().start();
           memcpy(out_offset, start, size);
           break;
         }
-        case llvm::MCFragment::FT_Align: {
-          llvm::MCAlignFragment& align_frag =
-            llvm::cast<llvm::MCAlignFragment>(*frag_iter);
+        case Fragment::Alignment: {
+          AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
           uint64_t count = size / align_frag.getValueSize();
           switch (align_frag.getValueSize()) {
             case 1u:
@@ -844,16 +849,16 @@
   MemoryRegion* region = pInput.memArea()->request(
           pInput.fileOffset() + pInputSectHdr.offset(), pInputSectHdr.size());
 
-  llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
+  SectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
 
-  llvm::MCFragment* frag = NULL;
+  Fragment* frag = NULL;
   if (NULL == region) {
     // If the input section's size is zero, we got a NULL region.
     // use a virtual fill fragment
-    frag = new llvm::MCFillFragment(0x0, 0, 0);
+    frag = new FillFragment(0x0, 0, 0);
   }
   else
-    frag = new MCRegionFragment(*region);
+    frag = new RegionFragment(*region);
 
   uint64_t size = pLinker.getLayout().appendFragment(*frag,
                                                      sect_data,
diff --git a/lib/Target/ARM/ARMLDBackend.h b/lib/Target/ARM/ARMLDBackend.h
index 3e46cd7..981228e 100644
--- a/lib/Target/ARM/ARMLDBackend.h
+++ b/lib/Target/ARM/ARMLDBackend.h
@@ -155,7 +155,7 @@
   /// call back target backend to emit the data.
   ///
   /// Backends handle the target-special tables (plt, gp,...) by themselves.
-  /// Backend can put the data of the tables in MCSectionData directly
+  /// Backend can put the data of the tables in SectionData directly
   ///  - LDSection.getSectionData can get the section data.
   /// Or, backend can put the data into special data structure
   ///  - backend can maintain its own map<LDSection, table> to get the table
diff --git a/lib/Target/ARM/ARMPLT.cpp b/lib/Target/ARM/ARMPLT.cpp
index 015d767..c9bc333 100644
--- a/lib/Target/ARM/ARMPLT.cpp
+++ b/lib/Target/ARM/ARMPLT.cpp
@@ -8,10 +8,13 @@
 //===----------------------------------------------------------------------===//
 #include "ARMGOT.h"
 #include "ARMPLT.h"
-#include <llvm/Support/raw_ostream.h>
+
+#include <new>
+
+#include <llvm/Support/Casting.h>
+
 #include <mcld/Support/MemoryRegion.h>
 #include <mcld/Support/MsgHandling.h>
-#include <new>
 
 namespace {
 
@@ -33,17 +36,17 @@
 
 using namespace mcld;
 
-ARMPLT0::ARMPLT0(llvm::MCSectionData* pParent)
+ARMPLT0::ARMPLT0(SectionData* pParent)
   : PLTEntry(sizeof(arm_plt0), pParent) {}
 
-ARMPLT1::ARMPLT1(llvm::MCSectionData* pParent)
+ARMPLT1::ARMPLT1(SectionData* pParent)
   : PLTEntry(sizeof(arm_plt1), pParent) {}
 
 //===----------------------------------------------------------------------===//
 // ARMPLT
 
 ARMPLT::ARMPLT(LDSection& pSection,
-               llvm::MCSectionData& pSectionData,
+               SectionData& pSectionData,
                ARMGOT &pGOTPLT)
   : PLT(pSection, pSectionData), m_GOT(pGOTPLT), m_PLTEntryIterator() {
   ARMPLT0* plt0_entry = new ARMPLT0(&m_SectionData);
@@ -65,7 +68,7 @@
     plt1_entry = new (std::nothrow) ARMPLT1(&m_SectionData);
 
     if (!plt1_entry)
-      fatal(diag::fail_allocate_memory) << "ARMPLT1";
+      fatal(diag::fail_allocate_memory_plt);
 
     m_Section.setSize(m_Section.size() + plt1_entry->getEntrySize());
 
@@ -166,7 +169,7 @@
   data = static_cast<uint32_t*>(malloc(plt0->getEntrySize()));
 
   if (!data)
-    fatal(diag::fail_allocate_memory) << "plt0";
+    fatal(diag::fail_allocate_memory_plt);
 
   memcpy(data, arm_plt0, plt0->getEntrySize());
   data[4] = offset;
@@ -203,7 +206,7 @@
     Out = static_cast<uint32_t*>(malloc(plt1->getEntrySize()));
 
     if (!Out)
-      fatal(diag::fail_allocate_memory) << "plt1";
+      fatal(diag::fail_allocate_memory_plt);
 
     // Offset is the distance between the last PLT entry and the associated
     // GOT entry.
diff --git a/lib/Target/ARM/ARMPLT.h b/lib/Target/ARM/ARMPLT.h
index f55aaa3..db36563 100644
--- a/lib/Target/ARM/ARMPLT.h
+++ b/lib/Target/ARM/ARMPLT.h
@@ -9,6 +9,7 @@
 #ifndef MCLD_ARM_PLT_H
 #define MCLD_ARM_PLT_H
 
+#include <mcld/LD/SectionData.h>
 #include <mcld/Target/PLT.h>
 
 namespace mcld {
@@ -19,12 +20,12 @@
 
 class ARMPLT0 : public PLTEntry {
 public:
-  ARMPLT0(llvm::MCSectionData* pParent);
+  ARMPLT0(SectionData* pParent);
 };
 
 class ARMPLT1 : public PLTEntry {
 public:
-  ARMPLT1(llvm::MCSectionData* pParent);
+  ARMPLT1(SectionData* pParent);
 };
 
 /** \class ARMPLT
@@ -35,13 +36,11 @@
   typedef llvm::DenseMap<const ResolveInfo*, ARMPLT1*> SymbolIndexType;
 
 public:
-  typedef llvm::MCSectionData::iterator iterator;
-  typedef llvm::MCSectionData::const_iterator const_iterator;
+  typedef SectionData::iterator iterator;
+  typedef SectionData::const_iterator const_iterator;
 
 public:
-  ARMPLT(LDSection& pSection,
-         llvm::MCSectionData& pSectionData,
-         ARMGOT& pGOTPLT);
+  ARMPLT(LDSection& pSection, SectionData& pSectionData, ARMGOT& pGOTPLT);
   ~ARMPLT();
 
 // Override virtual function.
diff --git a/lib/Target/ARM/ARMRelocationFactory.cpp b/lib/Target/ARM/ARMRelocationFactory.cpp
index 3d4b0dc..cc561db 100644
--- a/lib/Target/ARM/ARMRelocationFactory.cpp
+++ b/lib/Target/ARM/ARMRelocationFactory.cpp
@@ -169,7 +169,7 @@
       rel_entry.targetRef().assign(got_entry);
     }
     else {
-      fatal(diag::reserve_entry_number_mismatch) << "GOT";
+      fatal(diag::reserve_entry_number_mismatch_got);
     }
   }
   return got_entry;
@@ -216,7 +216,7 @@
       rel_entry.setSymInfo(rsym);
     }
     else {
-      fatal(diag::reserve_entry_number_mismatch) << "PLT";
+      fatal(diag::reserve_entry_number_mismatch_plt);
     }
   }
   return plt_entry;
diff --git a/lib/Target/GNULDBackend.cpp b/lib/Target/GNULDBackend.cpp
index 69d0927..f81133f 100644
--- a/lib/Target/GNULDBackend.cpp
+++ b/lib/Target/GNULDBackend.cpp
@@ -6,27 +6,34 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include <llvm/Support/ELF.h>
-#include <mcld/ADT/SizeTraits.h>
+
 #include <mcld/Target/GNULDBackend.h>
+
+#include <string>
+#include <cstring>
+#include <cassert>
+
+#include <llvm/Support/ELF.h>
+
+#include <mcld/ADT/SizeTraits.h>
+#include <mcld/LD/LDSymbol.h>
+#include <mcld/LD/Layout.h>
+#include <mcld/LD/FillFragment.h>
 #include <mcld/MC/MCLDInfo.h>
 #include <mcld/MC/MCLDOutput.h>
 #include <mcld/MC/InputTree.h>
 #include <mcld/MC/SymbolCategory.h>
-#include <mcld/LD/LDSymbol.h>
-#include <mcld/LD/Layout.h>
+#include <mcld/MC/MCLinker.h>
 #include <mcld/Support/MemoryArea.h>
 #include <mcld/Support/MemoryRegion.h>
 #include <mcld/Support/MsgHandling.h>
-#include <mcld/MC/MCLinker.h>
-#include <string>
-#include <cstring>
-#include <cassert>
+#include <mcld/Support/MemoryAreaFactory.h>
 
 using namespace mcld;
 
 //===----------------------------------------------------------------------===//
 // GNULDBackend
+//===----------------------------------------------------------------------===//
 GNULDBackend::GNULDBackend()
   : m_pArchiveReader(NULL),
     m_pObjectReader(NULL),
@@ -97,10 +104,16 @@
     return defaultTextSegmentAddr();
 }
 
-bool GNULDBackend::initArchiveReader(MCLinker&, MCLDInfo &pInfo)
+bool GNULDBackend::initArchiveReader(MCLinker& pLinker,
+                                     MCLDInfo& pInfo,
+                                     MemoryAreaFactory& pMemAreaFactory)
 {
-  if (NULL == m_pArchiveReader)
-    m_pArchiveReader = new GNUArchiveReader(pInfo);
+  if (NULL == m_pArchiveReader) {
+    assert(NULL != m_pObjectReader);
+    m_pArchiveReader = new GNUArchiveReader(pInfo,
+                                            pMemAreaFactory,
+                                            *m_pObjectReader);
+  }
   return true;
 }
 
@@ -164,7 +177,7 @@
 
   // -----  section symbols  ----- //
   // .preinit_array
-  MCFragmentRef* preinit_array = NULL;
+  FragmentRef* preinit_array = NULL;
   if (file_format->hasPreInitArray()) {
     preinit_array = pLinker.getLayout().getFragmentRef(
                    *(file_format->getPreInitArray().getSectionData()->begin()),
@@ -194,7 +207,7 @@
                                              ResolveInfo::Hidden);
 
   // .init_array
-  MCFragmentRef* init_array = NULL;
+  FragmentRef* init_array = NULL;
   if (file_format->hasInitArray()) {
     init_array = pLinker.getLayout().getFragmentRef(
                       *(file_format->getInitArray().getSectionData()->begin()),
@@ -225,7 +238,7 @@
                                              ResolveInfo::Hidden);
 
   // .fini_array
-  MCFragmentRef* fini_array = NULL;
+  FragmentRef* fini_array = NULL;
   if (file_format->hasFiniArray()) {
     fini_array = pLinker.getLayout().getFragmentRef(
                      *(file_format->getFiniArray().getSectionData()->begin()),
@@ -256,7 +269,7 @@
                                              ResolveInfo::Hidden);
 
   // .stack
-  MCFragmentRef* stack = NULL;
+  FragmentRef* stack = NULL;
   if (file_format->hasStack()) {
     stack = pLinker.getLayout().getFragmentRef(
                           *(file_format->getStack().getSectionData()->begin()),
@@ -1283,9 +1296,9 @@
 
   assert(NULL != bss_sect && NULL !=tbss_sect);
 
-  // get or create corresponding BSS MCSectionData
-  llvm::MCSectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect);
-  llvm::MCSectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect);
+  // get or create corresponding BSS SectionData
+  SectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect);
+  SectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect);
 
   // remember original BSS size
   uint64_t bss_offset  = bss_sect->size();
@@ -1302,8 +1315,8 @@
       // when emitting the regular name pools. We must change the symbols'
       // description here.
       (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
-      llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
-      (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
+      (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0));
 
       if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
         // allocate TLS common symbol in tbss section
@@ -1328,8 +1341,8 @@
     // when emitting the regular name pools. We must change the symbols'
     // description here.
     (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
-    llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
-    (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
+    (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0));
 
     if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
       // allocate TLS common symbol in tbss section
@@ -1366,33 +1379,38 @@
     interp_seg->addSection(&file_format->getInterp());
   }
 
+  // FIXME: Should we consider -z relro here?
   if (pInfo.options().hasRelro()) {
     // if -z relro is given, we need to adjust sections' offset again, and let
     // PT_GNU_RELRO end on a common page boundary
     LDContext::SectionTable& sect_table = pOutput.context()->getSectionTable();
-    size_t idx = 0;
-    while (idx < pOutput.context()->numOfSections()) {
-      // find the first non-relro section, and align its offset to a page
-      // boundary
+
+    size_t idx;
+    for (idx = 0; idx < pOutput.context()->numOfSections(); ++idx) {
+      // find the first non-relro section
       if (getSectionOrder(pOutput, *sect_table[idx], pInfo) > SHO_RELRO_LAST) {
-        uint64_t offset = sect_table[idx]->offset();
-        alignAddress(offset, commonPageSize(pInfo));
-        sect_table[idx]->setOffset(offset);
-        ++idx;
         break;
       }
-      ++idx;
     }
-    while (idx < pOutput.context()->numOfSections()) {
-      // adjust the remaining sections' offset
-      uint64_t offset = sect_table[idx - 1]->offset();
-      if (LDFileFormat::BSS != sect_table[idx - 1]->kind())
-        offset += sect_table[idx - 1]->size();
+
+    // align the first non-relro section to page boundary
+    uint64_t offset = sect_table[idx]->offset();
+    alignAddress(offset, commonPageSize(pInfo));
+    sect_table[idx]->setOffset(offset);
+
+    // set up remaining section's offset
+    for (++idx; idx < pOutput.context()->numOfSections(); ++idx) {
+      uint64_t offset;
+      size_t prev_idx = idx - 1;
+      if (LDFileFormat::BSS == sect_table[prev_idx]->kind())
+        offset = sect_table[prev_idx]->offset();
+      else
+        offset = sect_table[prev_idx]->offset() + sect_table[prev_idx]->size();
+
       alignAddress(offset, sect_table[idx]->align());
       sect_table[idx]->setOffset(offset);
-      ++idx;
     }
-  }
+  } // relro
 
   uint32_t cur_seg_flag, prev_seg_flag = getSegmentFlag(0);
   uint64_t padding = 0;
@@ -1411,7 +1429,7 @@
          LDFileFormat::Null == (*sect)->kind()) {
       // create new PT_LOAD segment
       load_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_LOAD);
-      load_seg->setAlign(commonPageSize(pInfo));
+      load_seg->setAlign(abiPageSize(pInfo));
 
       // check if this segment needs padding
       padding = 0;
@@ -1585,7 +1603,7 @@
   }
 }
 
-/// postLayout -Backend can do any needed modification after layout
+/// postLayout - Backend can do any needed modification after layout
 void GNULDBackend::postLayout(const Output& pOutput,
                               const MCLDInfo& pInfo,
                               MCLinker& pLinker)
diff --git a/lib/Target/GOT.cpp b/lib/Target/GOT.cpp
index a05b574..f9e7b91 100644
--- a/lib/Target/GOT.cpp
+++ b/lib/Target/GOT.cpp
@@ -6,7 +6,9 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+
 #include <mcld/Target/GOT.h>
+
 #include <cstring>
 #include <cstdlib>
 
@@ -14,9 +16,9 @@
 
 //===----------------------------------------------------------------------===//
 // GOTEntry
-GOTEntry::GOTEntry(uint64_t pContent, size_t pEntrySize,
-                   llvm::MCSectionData* pParent)
-  : MCTargetFragment(llvm::MCFragment::FT_Target, pParent),
+//===----------------------------------------------------------------------===//
+GOTEntry::GOTEntry(uint64_t pContent, size_t pEntrySize, SectionData* pParent)
+  : TargetFragment(Fragment::Target, pParent),
     f_Content(pContent), m_EntrySize(pEntrySize) {
 }
 
@@ -26,8 +28,9 @@
 
 //===----------------------------------------------------------------------===//
 // GOT
+//===----------------------------------------------------------------------===//
 GOT::GOT(LDSection& pSection,
-         llvm::MCSectionData& pSectionData,
+         SectionData& pSectionData,
          size_t pEntrySize)
   : m_Section(pSection),
     m_SectionData(pSectionData),
diff --git a/lib/Target/Mips/MipsGOT.cpp b/lib/Target/Mips/MipsGOT.cpp
index 57e5c70..42ef972 100644
--- a/lib/Target/Mips/MipsGOT.cpp
+++ b/lib/Target/Mips/MipsGOT.cpp
@@ -7,10 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "MipsGOT.h"
+
+#include <llvm/Support/Casting.h>
+
 #include <mcld/LD/ResolveInfo.h>
 #include <mcld/Support/MemoryRegion.h>
 #include <mcld/Support/MsgHandling.h>
-#include "MipsGOT.h"
 
 namespace {
   const size_t MipsGOTEntrySize = 4;
@@ -21,7 +24,7 @@
 
 //===----------------------------------------------------------------------===//
 // MipsGOT
-MipsGOT::MipsGOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+MipsGOT::MipsGOT(LDSection& pSection, SectionData& pSectionData)
   : GOT(pSection, pSectionData, MipsGOTEntrySize),
     m_pLocalNum(0)
 {
@@ -31,7 +34,7 @@
       new (std::nothrow) GOTEntry(0, MipsGOTEntrySize, &m_SectionData);
 
     if (NULL == entry)
-      fatal(diag::fail_allocate_memory) << "GOT0";
+      fatal(diag::fail_allocate_memory_got);
 
     m_Section.setSize(m_Section.size() + MipsGOTEntrySize);
   }
@@ -94,7 +97,7 @@
       new (std::nothrow) GOTEntry(0, MipsGOTEntrySize, &m_SectionData);
 
     if (NULL == entry)
-      fatal(diag::fail_allocate_memory) << "GOTEntry";
+      fatal(diag::fail_allocate_memory_got);
 
     m_Section.setSize(m_Section.size() + MipsGOTEntrySize);
   }
diff --git a/lib/Target/Mips/MipsGOT.h b/lib/Target/Mips/MipsGOT.h
index 2f04ef4..23a3ded 100644
--- a/lib/Target/Mips/MipsGOT.h
+++ b/lib/Target/Mips/MipsGOT.h
@@ -12,7 +12,10 @@
 #include <gtest.h>
 #endif
 
+#include <llvm/ADT/DenseMap.h>
+
 #include <mcld/Target/GOT.h>
+#include <mcld/LD/SectionData.h>
 
 namespace mcld
 {
@@ -29,11 +32,11 @@
   typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolTypeMapType;
 
 public:
-  typedef llvm::MCSectionData::iterator iterator;
-  typedef llvm::MCSectionData::const_iterator const_iterator;
+  typedef SectionData::iterator iterator;
+  typedef SectionData::const_iterator const_iterator;
 
 public:
-  MipsGOT(LDSection& pSection, llvm::MCSectionData& pSectionData);
+  MipsGOT(LDSection& pSection, SectionData& pSectionData);
 
   iterator begin();
   iterator end();
diff --git a/lib/Target/Mips/MipsLDBackend.cpp b/lib/Target/Mips/MipsLDBackend.cpp
index 87e43b8..e8b68ea 100644
--- a/lib/Target/Mips/MipsLDBackend.cpp
+++ b/lib/Target/Mips/MipsLDBackend.cpp
@@ -7,9 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "Mips.h"
+#include "MipsELFDynamic.h"
+#include "MipsLDBackend.h"
+#include "MipsRelocationFactory.h"
+
 #include <llvm/ADT/Triple.h>
 #include <llvm/Support/ELF.h>
 
+#include <mcld/LD/FillFragment.h>
 #include <mcld/LD/SectionMap.h>
 #include <mcld/MC/MCLDInfo.h>
 #include <mcld/MC/MCLinker.h>
@@ -18,11 +24,6 @@
 #include <mcld/Support/TargetRegistry.h>
 #include <mcld/Target/OutputRelocSection.h>
 
-#include "Mips.h"
-#include "MipsELFDynamic.h"
-#include "MipsLDBackend.h"
-#include "MipsRelocationFactory.h"
-
 enum {
   // The original o32 abi.
   E_MIPS_ABI_O32    = 0x00001000,
@@ -67,21 +68,6 @@
 
 void MipsGNULDBackend::initTargetSections(MCLinker& pLinker)
 {
-  // Set up .dynamic
-  ELFFileFormat* file_format = NULL;
-  switch(pLinker.getLDInfo().output().type()) {
-    case Output::DynObj:
-      file_format = getDynObjFileFormat();
-      break;
-    case Output::Exec:
-      file_format = getExecFileFormat();
-      break;
-    case Output::Object:
-    default:
-      // TODO: not support yet
-      return;
-  }
-  file_format->getDynamic().setFlag(llvm::ELF::SHF_ALLOC);
 }
 
 void MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput)
@@ -213,6 +199,14 @@
   return 0x80000;
 }
 
+uint64_t MipsGNULDBackend::abiPageSize(const MCLDInfo& pInfo) const
+{
+  if (pInfo.options().maxPageSize() > 0)
+    return pInfo.options().maxPageSize();
+  else
+    return static_cast<uint64_t>(0x10000);
+}
+
 void MipsGNULDBackend::doPreLayout(const Output& pOutput,
                                    const MCLDInfo& pInfo,
                                    MCLinker& pLinker)
@@ -498,7 +492,8 @@
 /// finalizeSymbol - finalize the symbol value
 bool MipsGNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput)
 {
-  m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0);
+  if (NULL != m_pGpDispSymbol)
+    m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0);
   return true;
 }
 
@@ -550,9 +545,9 @@
 
   assert(NULL != bss_sect && NULL != tbss_sect);
 
-  // get or create corresponding BSS MCSectionData
-  llvm::MCSectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect);
-  llvm::MCSectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect);
+  // get or create corresponding BSS SectionData
+  SectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect);
+  SectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect);
 
   // remember original BSS size
   uint64_t bss_offset  = bss_sect->size();
@@ -569,8 +564,8 @@
       // when emitting the regular name pools. We must change the symbols'
       // description here.
       (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
-      llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
-      (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
+      (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0));
 
       if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
         // allocate TLS common symbol in tbss section
@@ -596,8 +591,8 @@
     // when emitting the regular name pools. We must change the symbols'
     // description here.
     (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
-    llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
-    (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
+    (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0));
 
     if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
       // allocate TLS common symbol in tbss section
@@ -879,9 +874,9 @@
 {
   ELFFileFormat* file_format = getOutputFormat(pOutput);
 
-  // get .rel.dyn LDSection and create MCSectionData
+  // get .rel.dyn LDSection and create SectionData
   LDSection& reldyn = file_format->getRelDyn();
-  // create MCSectionData and ARMRelDynSection
+  // create SectionData and ARMRelDynSection
   m_pRelDyn = new OutputRelocSection(reldyn,
                                      pLinker.getOrCreateSectData(reldyn),
                                      8);
diff --git a/lib/Target/Mips/MipsLDBackend.h b/lib/Target/Mips/MipsLDBackend.h
index f9742ed..84f2277 100644
--- a/lib/Target/Mips/MipsLDBackend.h
+++ b/lib/Target/Mips/MipsLDBackend.h
@@ -78,6 +78,9 @@
 
   uint64_t defaultTextSegmentAddr() const;
 
+  /// abiPageSize - the abi page size of the target machine
+  uint64_t abiPageSize(const MCLDInfo& pInfo) const;
+
   /// preLayout - Backend can do any needed modification before layout
   void doPreLayout(const Output& pOutput,
                    const MCLDInfo& pInfo,
@@ -101,7 +104,7 @@
   /// call back target backend to emit the data.
   ///
   /// Backends handle the target-special tables (plt, gp,...) by themselves.
-  /// Backend can put the data of the tables in MCSectionData directly
+  /// Backend can put the data of the tables in SectionData directly
   ///  - LDSection.getSectionData can get the section data.
   /// Or, backend can put the data into special data structure
   ///  - backend can maintain its own map<LDSection, table> to get the table
diff --git a/lib/Target/Mips/MipsRelocationFactory.cpp b/lib/Target/Mips/MipsRelocationFactory.cpp
index e9d26f8..a9a34b2 100644
--- a/lib/Target/Mips/MipsRelocationFactory.cpp
+++ b/lib/Target/Mips/MipsRelocationFactory.cpp
@@ -131,7 +131,7 @@
       got_entry.setContent(pReloc.symValue());
     }
     else {
-      fatal(diag::reserve_entry_number_mismatch) << "GOT";
+      fatal(diag::reserve_entry_number_mismatch_got);
     }
   }
 
diff --git a/lib/Target/OutputRelocSection.cpp b/lib/Target/OutputRelocSection.cpp
index dbb8194..c5bb9a8 100644
--- a/lib/Target/OutputRelocSection.cpp
+++ b/lib/Target/OutputRelocSection.cpp
@@ -6,18 +6,21 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include <mcld/LD/LDSection.h>
+
 #include <mcld/Target/OutputRelocSection.h>
+
+#include <llvm/Support/Casting.h>
+
+#include <mcld/LD/LDSection.h>
 #include <mcld/Support/MsgHandling.h>
 
 using namespace mcld;
 
-//==========================
+//===----------------------------------------------------------------------===//
 // OutputRelocSection
-
-
+//===----------------------------------------------------------------------===//
 OutputRelocSection::OutputRelocSection(LDSection& pSection,
-                                       llvm::MCSectionData& pSectionData,
+                                       SectionData& pSectionData,
                                        unsigned int pEntrySize)
   : m_pSection(&pSection),
     m_pSectionData(&pSectionData),
diff --git a/lib/Target/PLT.cpp b/lib/Target/PLT.cpp
index a29dfd8..782d974 100644
--- a/lib/Target/PLT.cpp
+++ b/lib/Target/PLT.cpp
@@ -6,16 +6,18 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+
 #include <mcld/Target/PLT.h>
 
 using namespace mcld;
 
 class GOT;
 
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
 // PLTEntry
-PLTEntry::PLTEntry(size_t pSize, llvm::MCSectionData* pParent)
-   : MCTargetFragment(llvm::MCFragment::FT_Target, pParent),
+//===----------------------------------------------------------------------===//
+PLTEntry::PLTEntry(size_t pSize, SectionData* pParent)
+   : TargetFragment(Fragment::Target, pParent),
      m_EntrySize(pSize), m_pContent(NULL)
 {
 }
@@ -28,9 +30,10 @@
   }
 }
 
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
 // PLT
-PLT::PLT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+//===----------------------------------------------------------------------===//
+PLT::PLT(LDSection& pSection, SectionData& pSectionData)
   :m_Section(pSection),
    m_SectionData(pSectionData)
 {
diff --git a/lib/Target/X86/X86GOT.cpp b/lib/Target/X86/X86GOT.cpp
index 91c7d65..518cc36 100644
--- a/lib/Target/X86/X86GOT.cpp
+++ b/lib/Target/X86/X86GOT.cpp
@@ -7,10 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 #include "X86GOT.h"
-#include <mcld/LD/LDFileFormat.h>
-#include <mcld/Support/MsgHandling.h>
+
 #include <new>
 
+#include <llvm/Support/Casting.h>
+
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/LD/SectionData.h>
+#include <mcld/Support/MsgHandling.h>
+
 namespace {
   const size_t X86GOTEntrySize = 4;
 }
@@ -19,7 +24,8 @@
 
 //===----------------------------------------------------------------------===//
 // X86GOT
-X86GOT::X86GOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+//===----------------------------------------------------------------------===//
+X86GOT::X86GOT(LDSection& pSection, SectionData& pSectionData)
              : GOT(pSection, pSectionData, X86GOTEntrySize),
                m_GOTIterator(), m_fIsVisit(false)
 {
@@ -38,7 +44,7 @@
                                         &m_SectionData);
 
     if (!Entry)
-      fatal(diag::fail_allocate_memory) << "GOTEntry";
+      fatal(diag::fail_allocate_memory_got);
 
     m_Section.setSize(m_Section.size() + X86GOTEntrySize);
   }
diff --git a/lib/Target/X86/X86GOT.h b/lib/Target/X86/X86GOT.h
index d758de0..91cc3e8 100644
--- a/lib/Target/X86/X86GOT.h
+++ b/lib/Target/X86/X86GOT.h
@@ -6,14 +6,16 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef MCLD_X86_GOT_H
-#define MCLD_X86_GOT_H
+#ifndef MCLD_TARGET_X86_GOT_H
+#define MCLD_TARGET_X86_GOT_H
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
 
 #include "X86PLT.h"
+
 #include <mcld/Target/GOT.h>
+#include <mcld/LD/SectionData.h>
 
 namespace mcld
 {
@@ -28,11 +30,11 @@
   typedef llvm::DenseMap<const ResolveInfo*, GOTEntry*> SymbolIndexMapType;
 
 public:
-  typedef llvm::MCSectionData::iterator iterator;
-  typedef llvm::MCSectionData::const_iterator const_iterator;
+  typedef SectionData::iterator iterator;
+  typedef SectionData::const_iterator const_iterator;
 
 public:
-  X86GOT(LDSection& pSection, llvm::MCSectionData& pSectionData);
+  X86GOT(LDSection& pSection, SectionData& pSectionData);
 
   ~X86GOT();
 
diff --git a/lib/Target/X86/X86GOTPLT.cpp b/lib/Target/X86/X86GOTPLT.cpp
index 2ba5669..49f3449 100644
--- a/lib/Target/X86/X86GOTPLT.cpp
+++ b/lib/Target/X86/X86GOTPLT.cpp
@@ -6,10 +6,15 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+
 #include "X86GOTPLT.h"
+
+#include <new>
+
+#include <llvm/Support/Casting.h>
+
 #include <mcld/LD/LDFileFormat.h>
 #include <mcld/Support/MsgHandling.h>
-#include <new>
 
 namespace {
   const uint64_t X86GOTPLTEntrySize = 4;
@@ -19,7 +24,8 @@
 
 //===----------------------------------------------------------------------===//
 // X86GOTPLT
-X86GOTPLT::X86GOTPLT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+//===----------------------------------------------------------------------===//
+X86GOTPLT::X86GOTPLT(LDSection& pSection, SectionData& pSectionData)
   : GOT(pSection, pSectionData, X86GOTPLTEntrySize), m_GOTPLTIterator()
 {
   GOTEntry* Entry = 0;
@@ -30,7 +36,7 @@
                                         &m_SectionData);
 
     if (!Entry)
-      fatal(diag::fail_allocate_memory) << "GOT0";
+      fatal(diag::fail_allocate_memory_got);
 
     m_Section.setSize(m_Section.size() + X86GOTPLTEntrySize);
   }
@@ -84,7 +90,7 @@
   for (size_t i = 0; i < pNum; ++i) {
     got_entry = new GOTEntry(0, getEntrySize(),&(getSectionData()));
     if (!got_entry)
-      fatal(diag::fail_allocate_memory) << "GOT";
+      fatal(diag::fail_allocate_memory_got);
 
     m_Section.setSize(m_Section.size() + getEntrySize());
   }
diff --git a/lib/Target/X86/X86GOTPLT.h b/lib/Target/X86/X86GOTPLT.h
index ae9f0f7..7ca695b 100644
--- a/lib/Target/X86/X86GOTPLT.h
+++ b/lib/Target/X86/X86GOTPLT.h
@@ -12,28 +12,30 @@
 #include <gtest.h>
 #endif
 
+#include <llvm/ADT/DenseMap.h>
+
 #include <mcld/Target/GOT.h>
+#include <mcld/LD/SectionData.h>
 
 namespace mcld
 {
 class LDSection;
 
+const unsigned int X86GOTPLT0Num = 3;
+
 /** \class X86GOTPLT
  *  \brief X86 .got.plt section.
  */
-
-const unsigned int X86GOTPLT0Num = 3;
-
 class X86GOTPLT : public GOT
 {
   typedef llvm::DenseMap<const ResolveInfo*, GOTEntry*> SymbolIndexMapType;
 
 public:
-  typedef llvm::MCSectionData::iterator iterator;
-  typedef llvm::MCSectionData::const_iterator const_iterator;
+  typedef SectionData::iterator iterator;
+  typedef SectionData::const_iterator const_iterator;
 
 public:
-  X86GOTPLT(LDSection &pSection, llvm::MCSectionData& pSectionData);
+  X86GOTPLT(LDSection &pSection, SectionData& pSectionData);
 
   ~X86GOTPLT();
 
diff --git a/lib/Target/X86/X86LDBackend.cpp b/lib/Target/X86/X86LDBackend.cpp
index 2355afc..d02e621 100644
--- a/lib/Target/X86/X86LDBackend.cpp
+++ b/lib/Target/X86/X86LDBackend.cpp
@@ -13,11 +13,14 @@
 #include "X86RelocationFactory.h"
 
 #include <llvm/ADT/Triple.h>
+#include <llvm/Support/Casting.h>
+
 #include <mcld/LD/SectionMap.h>
+#include <mcld/LD/FillFragment.h>
+#include <mcld/LD/RegionFragment.h>
 #include <mcld/MC/MCLDInfo.h>
 #include <mcld/MC/MCLDOutput.h>
 #include <mcld/MC/MCLinker.h>
-#include <mcld/MC/MCRegionFragment.h>
 #include <mcld/Support/MemoryRegion.h>
 #include <mcld/Support/MsgHandling.h>
 #include <mcld/Support/TargetRegistry.h>
@@ -106,7 +109,7 @@
 
 void X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput)
 {
-  // get .got LDSection and create MCSectionData
+  // get .got LDSection and create SectionData
   ELFFileFormat* file_format = getOutputFormat(pOutput);
 
   LDSection& got = file_format->getGOT();
@@ -115,7 +118,7 @@
 
 void X86GNULDBackend::createX86GOTPLT(MCLinker& pLinker, const Output& pOutput)
 {
-  // get .got.plt LDSection and create MCSectionData
+  // get .got.plt LDSection and create SectionData
   ELFFileFormat* file_format = getOutputFormat(pOutput);
 
   LDSection& gotplt = file_format->getGOTPLT();
@@ -158,12 +161,12 @@
   LDSection& plt = file_format->getPLT();
   LDSection& relplt = file_format->getRelPlt();
   assert(m_pGOTPLT != NULL);
-  // create MCSectionData and X86PLT
+  // create SectionData and X86PLT
   m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOTPLT, pOutput);
 
   // set info of .rel.plt to .plt
   relplt.setLink(&plt);
-  // create MCSectionData and X86RelDynSection
+  // create SectionData and X86RelDynSection
   m_pRelPLT = new OutputRelocSection(relplt,
                                      pLinker.getOrCreateSectData(relplt),
                                      8);
@@ -172,11 +175,11 @@
 void X86GNULDBackend::createX86RelDyn(MCLinker& pLinker,
                                       const Output& pOutput)
 {
-  // get .rel.dyn LDSection and create MCSectionData
+  // get .rel.dyn LDSection and create SectionData
   ELFFileFormat* file_format = getOutputFormat(pOutput);
 
   LDSection& reldyn = file_format->getRelDyn();
-  // create MCSectionData and X86RelDynSection
+  // create SectionData and X86RelDynSection
   m_pRelDyn = new OutputRelocSection(reldyn,
                                      pLinker.getOrCreateSectData(reldyn),
                                      8);
@@ -215,9 +218,9 @@
                                    llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
   }
 
-  // get or create corresponding BSS MCSectionData
+  // get or create corresponding BSS SectionData
   assert(NULL != bss_sect_hdr);
-  llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(
+  SectionData& bss_section = pLinker.getOrCreateSectData(
                                      *bss_sect_hdr);
 
   // Determine the alignment by the symbol value
@@ -225,7 +228,7 @@
   uint32_t addralign = bitclass() / 8;
 
   // allocate space in BSS for the copy symbol
-  llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, pSym.size());
+  Fragment* frag = new FillFragment(0x0, 1, pSym.size());
   uint64_t size = pLinker.getLayout().appendFragment(*frag,
                                                      bss_section,
                                                      addralign);
diff --git a/lib/Target/X86/X86PLT.cpp b/lib/Target/X86/X86PLT.cpp
index 2396a21..cbdb568 100644
--- a/lib/Target/X86/X86PLT.cpp
+++ b/lib/Target/X86/X86PLT.cpp
@@ -1,4 +1,4 @@
-//===- X86PLT.cpp -----------------------------------------------------------===//
+//===- X86PLT.cpp ---------------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -8,12 +8,18 @@
 //===----------------------------------------------------------------------===//
 #include "X86GOTPLT.h"
 #include "X86PLT.h"
-#include <llvm/Support/raw_ostream.h>
-#include <llvm/Support/ELF.h>
-#include <mcld/MC/MCLDOutput.h>
-#include <mcld/Support/MsgHandling.h>
+
 #include <new>
 
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/Casting.h>
+
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/Support/MsgHandling.h>
+
+//===----------------------------------------------------------------------===//
+// PLT entry data
+//===----------------------------------------------------------------------===//
 namespace {
 
 const uint8_t x86_dyn_plt0[] = {
@@ -44,17 +50,17 @@
 
 namespace mcld {
 
-X86PLT0::X86PLT0(llvm::MCSectionData* pParent, unsigned int pSize)
+X86PLT0::X86PLT0(SectionData* pParent, unsigned int pSize)
   : PLTEntry(pSize, pParent) { }
 
-X86PLT1::X86PLT1(llvm::MCSectionData* pParent, unsigned int pSize)
+X86PLT1::X86PLT1(SectionData* pParent, unsigned int pSize)
   : PLTEntry(pSize, pParent) { }
 
 //===----------------------------------------------------------------------===//
 // X86PLT
-
+//===----------------------------------------------------------------------===//
 X86PLT::X86PLT(LDSection& pSection,
-               llvm::MCSectionData& pSectionData,
+               SectionData& pSectionData,
                X86GOTPLT &pGOTPLT,
                const Output& pOutput)
   : PLT(pSection, pSectionData),
@@ -94,7 +100,7 @@
     plt1_entry = new (std::nothrow) X86PLT1(&m_SectionData, m_PLT1Size);
 
     if (!plt1_entry)
-      fatal(diag::fail_allocate_memory) << "X86PLT1";
+      fatal(diag::fail_allocate_memory_plt);
 
     m_Section.setSize(m_Section.size() + plt1_entry->getEntrySize());
 
@@ -152,7 +158,7 @@
   data = static_cast<unsigned char*>(malloc(plt0->getEntrySize()));
 
   if (!data)
-    fatal(diag::fail_allocate_memory) << "plt0";
+    fatal(diag::fail_allocate_memory_plt);
 
   memcpy(data, m_PLT0, plt0->getEntrySize());
 
@@ -200,7 +206,7 @@
     data = static_cast<unsigned char*>(malloc(plt1->getEntrySize()));
 
     if (!data)
-      fatal(diag::fail_allocate_memory) << "plt1";
+      fatal(diag::fail_allocate_memory_plt);
 
     memcpy(data, m_PLT1, plt1->getEntrySize());
 
diff --git a/lib/Target/X86/X86PLT.h b/lib/Target/X86/X86PLT.h
index 6c7002a..1669a49 100644
--- a/lib/Target/X86/X86PLT.h
+++ b/lib/Target/X86/X86PLT.h
@@ -1,4 +1,4 @@
-//===- X86PLT.h -----------------------------------------------------===//
+//===- X86PLT.h -----------------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -6,10 +6,13 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef X86_PLT_H
-#define X86_PLT_H
+#ifndef MCLD_TARGET_X86_PLT_H
+#define MCLD_TARGET_X86_PLT_H
+
+#include <llvm/ADT/DenseMap.h>
 
 #include <mcld/Target/PLT.h>
+#include <mcld/LD/SectionData.h>
 
 namespace mcld {
 
@@ -17,14 +20,16 @@
 class GOTEntry;
 class Output;
 
-class X86PLT0 : public PLTEntry {
+class X86PLT0 : public PLTEntry
+{
 public:
-  X86PLT0(llvm::MCSectionData* pParent, unsigned int pSize);
+  X86PLT0(SectionData* pParent, unsigned int pSize);
 };
 
-class X86PLT1 : public PLTEntry {
+class X86PLT1 : public PLTEntry
+{
 public:
-  X86PLT1(llvm::MCSectionData* pParent, unsigned int pSize);
+  X86PLT1(SectionData* pParent, unsigned int pSize);
 };
 
 /** \class X86PLT
@@ -35,12 +40,12 @@
   typedef llvm::DenseMap<const ResolveInfo*, X86PLT1*> SymbolIndexType;
 
 public:
-  typedef llvm::MCSectionData::iterator iterator;
-  typedef llvm::MCSectionData::const_iterator const_iterator;
+  typedef SectionData::iterator iterator;
+  typedef SectionData::const_iterator const_iterator;
 
 public:
   X86PLT(LDSection& pSection,
-         llvm::MCSectionData& pSectionData,
+         SectionData& pSectionData,
          X86GOTPLT& pGOTPLT,
          const Output& pOutput);
   ~X86PLT();
diff --git a/lib/Target/X86/X86RelocationFactory.cpp b/lib/Target/X86/X86RelocationFactory.cpp
index 71fa344..f603b6e 100644
--- a/lib/Target/X86/X86RelocationFactory.cpp
+++ b/lib/Target/X86/X86RelocationFactory.cpp
@@ -132,7 +132,7 @@
       rel_entry.targetRef().assign(got_entry);
     }
     else {
-      fatal(diag::reserve_entry_number_mismatch) << "GOT";
+      fatal(diag::reserve_entry_number_mismatch_got);
     }
   }
   return got_entry;
@@ -182,7 +182,7 @@
       rel_entry.setSymInfo(rsym);
     }
     else {
-      fatal(diag::reserve_entry_number_mismatch) << "PLT";
+      fatal(diag::reserve_entry_number_mismatch_plt);
     }
   }
   return plt_entry;
diff --git a/lib/Target/X86/X86SectLinker.cpp b/lib/Target/X86/X86SectLinker.cpp
index a888f47..2954d1f 100644
--- a/lib/Target/X86/X86SectLinker.cpp
+++ b/lib/Target/X86/X86SectLinker.cpp
@@ -47,3 +47,4 @@
   // Register the linker frontend
   mcld::TargetRegistry::RegisterSectLinker(TheX86Target, createX86SectLinker);
 }
+
diff --git a/tools/llvm-mcld/llvm-mcld.cpp b/tools/llvm-mcld/llvm-mcld.cpp
index 726e08e..f4201d2 100644
--- a/tools/llvm-mcld/llvm-mcld.cpp
+++ b/tools/llvm-mcld/llvm-mcld.cpp
@@ -113,11 +113,6 @@
   cl::init(false));
 
 static cl::opt<bool>
-PrintCode("print-machineinstrs",
-  cl::desc("Print generated machine code"),
-  cl::init(false));
-
-static cl::opt<bool>
 DisableFPElim("disable-fp-elim",
   cl::desc("Disable frame pointer elimination optimization"),
   cl::init(false));
@@ -127,10 +122,18 @@
   cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"),
   cl::init(false));
 
-static cl::opt<bool>
-DisableExcessPrecision("disable-excess-fp-precision",
-  cl::desc("Disable optimizations that may increase FP precision"),
-  cl::init(false));
+static cl::opt<llvm::FPOpFusion::FPOpFusionMode>
+FuseFPOps("fuse-fp-ops",
+  cl::desc("Enable aggresive formation of fused FP ops"),
+  cl::init(FPOpFusion::Standard),
+  cl::values(
+    clEnumValN(FPOpFusion::Fast, "fast",
+               "Fuse FP ops whenever profitable"),
+    clEnumValN(FPOpFusion::Standard, "standard",
+               "Only fuse 'blessed' FP ops."),
+    clEnumValN(FPOpFusion::Strict, "strict",
+               "Only fuse FP ops when the result won't be effected."),
+    clEnumValEnd));
 
 static cl::opt<bool>
 EnableUnsafeFPMath("enable-unsafe-fp-math",
@@ -214,11 +217,6 @@
   cl::desc("Realign stack if needed"),
   cl::init(true));
 
-static cl::opt<bool>
-DisableSwitchTables(cl::Hidden, "disable-jump-tables",
-  cl::desc("Do not generate jump tables."),
-  cl::init(false));
-
 static cl::opt<std::string>
 TrapFuncName("trap-func", cl::Hidden,
   cl::desc("Emit a call to trap function rather than a trap instruction"),
@@ -1041,10 +1039,9 @@
 
   TargetOptions Options;
   Options.LessPreciseFPMADOption = EnableFPMAD;
-  Options.PrintMachineCode = PrintCode;
   Options.NoFramePointerElim = DisableFPElim;
   Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf;
-  Options.NoExcessFPPrecision = DisableExcessPrecision;
+  Options.AllowFPOpFusion = FuseFPOps;
   Options.UnsafeFPMath = EnableUnsafeFPMath;
   Options.NoInfsFPMath = EnableNoInfsFPMath;
   Options.NoNaNsFPMath = EnableNoNaNsFPMath;
@@ -1060,7 +1057,6 @@
   Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
   Options.StackAlignmentOverride = OverrideStackAlignment;
   Options.RealignStack = EnableRealignStack;
-  Options.DisableJumpTables = DisableSwitchTables;
   Options.TrapFuncName = TrapFuncName;
   Options.EnableSegmentedStacks = SegmentedStacks;
 
diff --git a/tools/mcld/include/alone/Config/Config.h.in b/tools/mcld/include/alone/Config/Config.h.in
index edb8721..6618b08 100644
--- a/tools/mcld/include/alone/Config/Config.h.in
+++ b/tools/mcld/include/alone/Config/Config.h.in
@@ -1,8 +1,15 @@
 #ifndef ALONE_CONFIG_CONFIG_H
 #define ALONE_CONFIG_CONFIG_H
 
-#define PROVIDE_@PROVIDE_ALONE_TARGET@_CODEGEN
-#define DEFAULT_@DEFAULT_ALONE_TARGET@_CODEGEN
+#if defined(TARGET_BUILD)
+  #define PROVIDE_@PROVIDE_ALONE_TARGET@_CODEGEN
+  #define DEFAULT_@DEFAULT_ALONE_TARGET@_CODEGEN
+#else
+  #define PROVIDE_ARM_CODEGEN
+  #define PROVIDE_X86_CODEGEN
+  #define PROVIDE_MIPS_CODEGEN
+  #define DEFAULT_@DEFAULT_ALONE_TARGET@_CODEGEN
+#endif
 
 #define DEFAULT_ARM_TRIPLE_STRING "armv7-none-linux-gnueabi"
 #define DEFAULT_X86_TRIPLE_STRING "i686-unknown-linux"
diff --git a/tools/mcld/include/alone/Support/LinkerConfig.h b/tools/mcld/include/alone/Support/LinkerConfig.h
index 37689d2..f29e557 100644
--- a/tools/mcld/include/alone/Support/LinkerConfig.h
+++ b/tools/mcld/include/alone/Support/LinkerConfig.h
@@ -6,13 +6,13 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+
 #ifndef ALONE_SUPPORT_LINKER_CONFIG_H
 #define ALONE_SUPPORT_LINKER_CONFIG_H
 
 #include <string>
 
 #include <mcld/MC/MCLDInfo.h>
-#include <mcld/MC/MCLDFile.h>
 #include <mcld/Support/TargetRegistry.h>
 #include <mcld/LD/DiagnosticLineInfo.h>
 #include <mcld/LD/DiagnosticPrinter.h>
@@ -21,15 +21,17 @@
 
 class LinkerConfig {
 private:
-  //===----------------------------------------------------------------------===//
+  //===--------------------------------------------------------------------===//
   // Available Configurations
-  //===----------------------------------------------------------------------===//
-  std::string mTriple;
+  //===--------------------------------------------------------------------===//
+  const std::string mTriple;
+  bool mShared;
+  std::string mSOName;
 
 private:
-  //===----------------------------------------------------------------------===//
+  //===--------------------------------------------------------------------===//
   // These are generated by LinkerConfig during initialize().
-  //===----------------------------------------------------------------------===//
+  //===--------------------------------------------------------------------===//
   const mcld::Target *mTarget;
   bool initializeTarget();
 
@@ -39,10 +41,11 @@
   mcld::DiagnosticLineInfo *mDiagLineInfo;
   mcld::DiagnosticPrinter *mDiagPrinter;
   bool initializeDiagnostic();
+
 public:
-  //===----------------------------------------------------------------------===//
+  //===--------------------------------------------------------------------===//
   // Getters
-  //===----------------------------------------------------------------------===//
+  //===--------------------------------------------------------------------===//
   inline const std::string &getTriple() const
   { return mTriple; }
 
@@ -55,16 +58,26 @@
   inline const mcld::MCLDInfo* getLDInfo() const
   { return mLDInfo; }
 
-  inline void setSOName(const std::string &pSOName)
-  { mLDInfo->output().setSOName(pSOName); }
+  inline bool isShared() const
+  { return mShared; }
 
-  inline void setDyld(const std::string &pDyld)
-  { mLDInfo->options().setDyld(pDyld); }
+  inline std::string getSOName() const
+  { return mSOName; }
+
+  void setShared(bool pEnable = true);
+
+  void setBsymbolic(bool pEnable = true);
+
+  void setSOName(const std::string &pSOName);
+
+  void setDyld(const std::string &pDyld);
 
   void setSysRoot(const std::string &pSysRoot);
 
   void addWrap(const std::string &pWrapSymbol);
 
+  void addPortable(const std::string &pPortableSymbol);
+
   void addSearchDir(const std::string &pDir);
 
 public:
diff --git a/tools/mcld/include/alone/Support/Log.h b/tools/mcld/include/alone/Support/Log.h
new file mode 100644
index 0000000..bc91d44
--- /dev/null
+++ b/tools/mcld/include/alone/Support/Log.h
@@ -0,0 +1,18 @@
+//===- Log.h --------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ALONE_SUPPORT_LOG_H
+#define ALONE_SUPPORT_LOG_H
+
+#include <cstdio>
+
+#define ALOGE(fmt, args...) \
+printf("%s:%s:%d: "fmt, __FILE__, __FUNCTION__, __LINE__, args)
+
+#endif // ALONE_SUPPORT_LOG_H
diff --git a/tools/mcld/include/alone/Support/MemoryFactory.h b/tools/mcld/include/alone/Support/MemoryFactory.h
index 2247d2c..132d20f 100644
--- a/tools/mcld/include/alone/Support/MemoryFactory.h
+++ b/tools/mcld/include/alone/Support/MemoryFactory.h
@@ -19,10 +19,9 @@
 
 namespace alone {
 
-class MemoryFactory : public mcld::MemoryAreaFactory
-{
+class MemoryFactory : public mcld::MemoryAreaFactory {
 public:
-  MemoryFactory();
+  MemoryFactory() : mcld::MemoryAreaFactory(32) { }
 
   ~MemoryFactory() { }
 
diff --git a/tools/mcld/include/alone/Support/TargetLinkerConfigs.h b/tools/mcld/include/alone/Support/TargetLinkerConfigs.h
index 229a9bd..40bc812 100644
--- a/tools/mcld/include/alone/Support/TargetLinkerConfigs.h
+++ b/tools/mcld/include/alone/Support/TargetLinkerConfigs.h
@@ -6,6 +6,7 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+
 #ifndef ALONE_SUPPORT_TARGET_LINKER_CONFIGS_H
 #define ALONE_SUPPORT_TARGET_LINKER_CONFIGS_H
 
diff --git a/tools/mcld/lib/Core/Linker.cpp b/tools/mcld/lib/Core/Linker.cpp
index 9ab21cc..a9ebc1f 100644
--- a/tools/mcld/lib/Core/Linker.cpp
+++ b/tools/mcld/lib/Core/Linker.cpp
@@ -95,6 +95,7 @@
   delete mDriver;
   delete mBackend;
   delete mMemAreaFactory;
+  delete mRoot;
 }
 
 enum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig) {
@@ -103,7 +104,7 @@
     return kDelegateLDInfo;
   }
 
-  mRoot = &mLDInfo->inputs().root();
+  mRoot = new mcld::InputTree::iterator(mLDInfo->inputs().root());
   mShared = pConfig.isShared();
   mSOName = pConfig.getSOName();
 
@@ -122,10 +123,10 @@
     return kCreateBackend;
   }
 
-  mDriver = new mcld::MCLDDriver(*mLDInfo, *mBackend);
-
   mMemAreaFactory = new MemoryFactory();
 
+  mDriver = new mcld::MCLDDriver(*mLDInfo, *mBackend, *mMemAreaFactory);
+
   mDriver->initMCLinker();
 
   return kSuccess;
@@ -354,14 +355,10 @@
 enum Linker::ErrorCode Linker::link() {
   mDriver->normalize();
 
-  if (!mDriver->readSections() || !mDriver->mergeSections()) {
+  if (!mDriver->mergeSections()) {
     return kReadSections;
   }
 
-  if (!mDriver->readSymbolTables()) {
-    return kReadSymbols;
-  }
-
   if (!mDriver->addStandardSymbols() || !mDriver->addTargetSymbols()) {
     return kAddAdditionalSymbols;
   }
diff --git a/tools/mcld/lib/Support/Initialization.cpp b/tools/mcld/lib/Support/Initialization.cpp
index 83803f7..9a95f74 100644
--- a/tools/mcld/lib/Support/Initialization.cpp
+++ b/tools/mcld/lib/Support/Initialization.cpp
@@ -7,22 +7,22 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <cstdio>
-#include <cstdlib>
-#include <string>
-
-#include "alone/Config/Config.h"
 #include "alone/Support/Initialization.h"
 
+#include <cstdlib>
+
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/Support/TargetSelect.h>
+
 #include <mcld/Support/TargetSelect.h>
 #include <mcld/Support/TargetRegistry.h>
 
-#include <llvm/Support/TargetSelect.h>
-#include <llvm/Support/ErrorHandling.h>
+#include "alone/Config/Config.h"
+#include "alone/Support/Log.h"
 
 namespace {
 
-void llvm_error_handler(void *pUserData, const std::string& pMessage) {
+void llvm_error_handler(void *pUserData, const std::string &pMessage) {
   ALOGE("%s", pMessage.c_str());
   ::exit(1);
 }
@@ -31,6 +31,7 @@
 
 void alone::init::Initialize() {
   static bool is_initialized = false;
+
   if (is_initialized) {
     return;
   }
@@ -41,6 +42,9 @@
 
 #if defined(PROVIDE_ARM_CODEGEN)
   LLVMInitializeARMAsmPrinter();
+# if USE_DISASSEMBLER
+  LLVMInitializeARMDisassembler();
+# endif
   LLVMInitializeARMTargetMC();
   LLVMInitializeARMTargetInfo();
   LLVMInitializeARMTarget();
@@ -52,6 +56,9 @@
 
 #if defined(PROVIDE_MIPS_CODEGEN)
   LLVMInitializeMipsAsmPrinter();
+# if USE_DISASSEMBLER
+  LLVMInitializeMipsDisassembler();
+# endif
   LLVMInitializeMipsTargetMC();
   LLVMInitializeMipsTargetInfo();
   LLVMInitializeMipsTarget();
@@ -63,6 +70,9 @@
 
 #if defined(PROVIDE_X86_CODEGEN)
   LLVMInitializeX86AsmPrinter();
+# if USE_DISASSEMBLER
+  LLVMInitializeX86Disassembler();
+# endif
   LLVMInitializeX86TargetMC();
   LLVMInitializeX86TargetInfo();
   LLVMInitializeX86Target();
@@ -76,4 +86,3 @@
 
   return;
 }
-
diff --git a/tools/mcld/lib/Support/LinkerConfig.cpp b/tools/mcld/lib/Support/LinkerConfig.cpp
index 30506a8..ea30e69 100644
--- a/tools/mcld/lib/Support/LinkerConfig.cpp
+++ b/tools/mcld/lib/Support/LinkerConfig.cpp
@@ -91,7 +91,7 @@
 }
 
 void LinkerConfig::setSOName(const std::string &pSOName) {
-  mLDInfo->output().setSOName(pSOName);
+  mSOName = pSOName;
   return;
 }
 
diff --git a/tools/mcld/lib/Support/MemoryFactory.cpp b/tools/mcld/lib/Support/MemoryFactory.cpp
deleted file mode 100644
index 0d368dc..0000000
--- a/tools/mcld/lib/Support/MemoryFactory.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-//===- MemoryFactory.cpp --------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "alone/Support/MemoryFactory.h"
-
-using namespace alone;
-
-MemoryFactory::MemoryFactory()
-  : mcld::MemoryAreaFactory(32) {
-}
-
diff --git a/tools/mcld/lib/Support/TargetLinkerConfigs.cpp b/tools/mcld/lib/Support/TargetLinkerConfigs.cpp
index 8854f79..f2ddd6f 100644
--- a/tools/mcld/lib/Support/TargetLinkerConfigs.cpp
+++ b/tools/mcld/lib/Support/TargetLinkerConfigs.cpp
@@ -24,8 +24,7 @@
 // ARM
 //===----------------------------------------------------------------------===//
 #if defined(PROVIDE_ARM_CODEGEN)
-ARMLinkerConfig::ARMLinkerConfig()
-  : LinkerConfig(DEFAULT_ARM_TRIPLE_STRING) {
+ARMLinkerConfig::ARMLinkerConfig() : LinkerConfig(DEFAULT_ARM_TRIPLE_STRING) {
 
   // set up target-dependent constraints of attributes
   getLDInfo()->attrFactory().constraint().enableWholeArchive();
@@ -37,17 +36,13 @@
   getLDInfo()->attrFactory().predefined().setDynamic();
 
   // set up target dependent options
-  if (getLDInfo()->options().sysroot().empty())
+  if (getLDInfo()->options().sysroot().empty()) {
     getLDInfo()->options().setSysroot(gDefaultSysroot);
+  }
 
-  if (!getLDInfo()->options().hasDyld())
+  if (!getLDInfo()->options().hasDyld()) {
     getLDInfo()->options().setDyld(gDefaultDyld);
-
-  // set up default search path
-  addSearchDir("=/lib");
-  addSearchDir("=/usr/lib");
-
-  return;
+  }
 }
 #endif // defined(PROVIDE_ARM_CODEGEN)
 
@@ -68,17 +63,13 @@
   getLDInfo()->attrFactory().predefined().setDynamic();
 
   // set up target dependent options
-  if (getLDInfo()->options().sysroot().empty())
+  if (getLDInfo()->options().sysroot().empty()) {
     getLDInfo()->options().setSysroot(gDefaultSysroot);
+  }
 
-  if (!getLDInfo()->options().hasDyld())
+  if (!getLDInfo()->options().hasDyld()) {
     getLDInfo()->options().setDyld(gDefaultDyld);
-
-  // set up default search path
-  addSearchDir("=/lib");
-  addSearchDir("=/usr/lib");
-
-  return;
+  }
 }
 #endif // defined(PROVIDE_MIPS_CODEGEN)
 
@@ -98,17 +89,13 @@
   getLDInfo()->attrFactory().predefined().setDynamic();
 
   // set up target dependent options
-  if (getLDInfo()->options().sysroot().empty())
+  if (getLDInfo()->options().sysroot().empty()) {
     getLDInfo()->options().setSysroot(gDefaultSysroot);
+  }
 
-  if (!getLDInfo()->options().hasDyld())
+  if (!getLDInfo()->options().hasDyld()) {
     getLDInfo()->options().setDyld(gDefaultDyld);
-
-  // set up default search path
-  addSearchDir("=/lib");
-  addSearchDir("=/usr/lib");
-
-  return;
+  }
 }
 
 X86_32LinkerConfig::X86_32LinkerConfig()
diff --git a/tools/mcld/main.cpp b/tools/mcld/main.cpp
index 37610b8..ef525f5 100644
--- a/tools/mcld/main.cpp
+++ b/tools/mcld/main.cpp
@@ -6,6 +6,7 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+
 #include <stdlib.h>
 #include <string>
 
@@ -16,6 +17,8 @@
 #include <llvm/Support/raw_ostream.h>
 #include <llvm/Support/system_error.h>
 
+#include <mcld/Config/Config.h>
+
 #include <alone/Config/Config.h>
 #include <alone/Support/LinkerConfig.h>
 #include <alone/Support/Initialization.h>
@@ -28,18 +31,18 @@
 // Compiler Options
 //===----------------------------------------------------------------------===//
 #ifdef TARGET_BUILD
-const std::string OptTargetTripe(DEFAULT_TARGET_TRIPLE_STRING);
+static const std::string OptTargetTripe(DEFAULT_TARGET_TRIPLE_STRING);
 #else
-llvm::cl::opt<std::string>
+static llvm::cl::opt<std::string>
 OptTargetTriple("mtriple",
-               llvm::cl::desc("Specify the target triple (default: "
-                              DEFAULT_TARGET_TRIPLE_STRING ")"),
-               llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING),
-               llvm::cl::value_desc("triple"));
+                llvm::cl::desc("Specify the target triple (default: "
+                                DEFAULT_TARGET_TRIPLE_STRING ")"),
+                llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING),
+                llvm::cl::value_desc("triple"));
 
-llvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden,
-                                llvm::cl::desc("Alias for -mtriple"),
-                                llvm::cl::aliasopt(OptTargetTriple));
+static llvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden,
+                                        llvm::cl::desc("Alias for -mtriple"),
+                                        llvm::cl::aliasopt(OptTargetTriple));
 #endif
 
 //===----------------------------------------------------------------------===//
@@ -58,17 +61,18 @@
                   llvm::cl::value_desc("filename"));
 
 static llvm::cl::opt<std::string>
-OptSysRoot("sysroot",
-           llvm::cl::desc("Use directory as the location of the sysroot, overriding "
-                    "the configure-time default."),
+OptSysRoot("sysroot", llvm::cl::desc("Use directory as the location of the "
+                                     "sysroot, overriding the configure-time "
+                                     "default."),
            llvm::cl::value_desc("directory"),
            llvm::cl::ValueRequired);
 
 static llvm::cl::list<std::string>
 OptSearchDirList("L",
                  llvm::cl::ZeroOrMore,
-                 llvm::cl::desc("Add path searchdir to the list of paths that ld will "
-                          "search for archive libraries and ld control scripts."),
+                 llvm::cl::desc("Add path searchdir to the list of paths that "
+                                "mcld will search for archive libraries and "
+                                "mcld control scripts."),
                  llvm::cl::value_desc("searchdir"),
                  llvm::cl::Prefix);
 
@@ -83,6 +87,11 @@
           llvm::cl::desc("Create a shared library."),
           llvm::cl::init(false));
 
+static llvm::cl::opt<bool>
+OptBsymbolic("Bsymbolic",
+             llvm::cl::desc("Bind references within the shared library."),
+             llvm::cl::init(true));
+
 static llvm::cl::opt<std::string>
 OptDyld("dynamic-linker",
         llvm::cl::desc("Set the name of the dynamic linker."),
@@ -94,7 +103,7 @@
 static llvm::cl::list<std::string>
 OptInputObjectFiles(llvm::cl::Positional,
                     llvm::cl::desc("[input object files]"),
-                    llvm::cl::ZeroOrMore);
+                    llvm::cl::OneOrMore);
 
 static llvm::cl::list<std::string>
 OptNameSpecList("l",
@@ -113,25 +122,32 @@
             llvm::cl::desc("Use a wrap function fo symbol."),
             llvm::cl::value_desc("symbol"));
 
+static llvm::cl::list<std::string>
+OptPortableList("portable",
+                llvm::cl::ZeroOrMore,
+                llvm::cl::desc("Use a portable function to symbol."),
+                llvm::cl::value_desc("symbol"));
+
 //===----------------------------------------------------------------------===//
 // Helper Functions
 //===----------------------------------------------------------------------===//
 // Override "mcld -version"
-void MCLDVersionPrinter() {
+static void MCLDVersionPrinter() {
   llvm::raw_ostream &os = llvm::outs();
   os << "mcld (The MCLinker Project, http://mclinker.googlecode.com/):\n"
+     << "  version: "MCLD_VERSION"\n"
      << "  Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n";
 
   os << "\n";
 
   os << "LLVM (http://llvm.org/):\n";
+
   return;
 }
 
 #define DEFAULT_OUTPUT_PATH "a.out"
 static inline
-std::string DetermineOutputFilename(const std::string pOutputPath)
-{
+std::string DetermineOutputFilename(const std::string &pOutputPath) {
   if (!pOutputPath.empty()) {
     return pOutputPath;
   }
@@ -160,8 +176,7 @@
 }
 
 static inline
-bool ConfigLinker(Linker &pLinker, const std::string &pOutputFilename)
-{
+bool ConfigLinker(Linker &pLinker, const std::string &pOutputFilename) {
   LinkerConfig* config = NULL;
 
 #ifdef TARGET_BUILD
@@ -174,36 +189,57 @@
     return false;
   }
 
-  // Setup the configuration accroding to the value of command line options.
-  // 1. set up soname
-  if (!OptSOName.empty())
+  // Setup the configuration accroding to the command line options.
+
+  // 1. Set up soname.
+  if (!OptSOName.empty()) {
     config->setSOName(OptSOName);
-  else
+  } else {
     config->setSOName(pOutputFilename);
+  }
 
-  // 2. if given, set up sysroot
-  if (!OptSysRoot.empty())
+  // 2. If given, set up sysroot.
+  if (!OptSysRoot.empty()) {
     config->setSysRoot(OptSysRoot);
+  }
 
-  // 3. if given, set up dynamic linker path.
-  if (!OptDyld.empty())
+  // 3. If given, set up dynamic linker path.
+  if (!OptDyld.empty()) {
     config->setDyld(OptDyld);
+  }
 
-  // 4. if given, set up wrapped symbols
-  llvm::cl::list<std::string>::iterator wrap, wEnd = OptWrapList.end();
-  for (wrap = OptWrapList.begin(); wrap != wEnd; ++wrap)
+  // 4. If given, set up wrapped symbols.
+  llvm::cl::list<std::string>::iterator wrap, wrap_end = OptWrapList.end();
+  for (wrap = OptWrapList.begin(); wrap != wrap_end; ++wrap) {
     config->addWrap(*wrap);
+  }
 
-  // 5. if given, set up search directories
-  llvm::cl::list<std::string>::iterator sdir, sdirEnd = OptSearchDirList.end();
-  for (sdir = OptSearchDirList.begin(); sdir != sdirEnd; ++sdir)
+  // 5. If given, set up portable symbols.
+  llvm::cl::list<std::string>::iterator portable, portable_end = OptPortableList.end();
+  for (portable = OptPortableList.begin(); portable != portable_end; ++portable) {
+    config->addPortable(*portable);
+  }
+
+  // 6. if given, set up search directories.
+  llvm::cl::list<std::string>::iterator sdir, sdir_end = OptSearchDirList.end();
+  for (sdir = OptSearchDirList.begin(); sdir != sdir_end; ++sdir) {
     config->addSearchDir(*sdir);
+  }
+
+  // set up default search directories
+  config->addSearchDir("=/lib");
+  config->addSearchDir("=/usr/lib");
+
+  // 7. Set up output's type.
+  config->setShared(OptShared);
+
+  // 8. Set up -Bsymbolic.
+  config->setBsymbolic(OptBsymbolic);
 
   Linker::ErrorCode result = pLinker.config(*config);
-
   if (Linker::kSuccess != result) {
     llvm::errs() << "Failed to configure the linker! (detail: "
-                << Linker::GetErrorString(result) << ")\n";
+                 << Linker::GetErrorString(result) << ")\n";
     return false;
   }
 
@@ -211,11 +247,11 @@
 }
 
 static inline
-bool PrepareInputOutput(Linker& pLinker, const std::string &pOutputPath)
-{
-  // -----  set output  ----- //
-  // FIXME: In MCLinker, we have to set up output before setting up inputs.
-  // This constraint is wired, and we should break this constraint.
+bool PrepareInputOutput(Linker &pLinker, const std::string &pOutputPath) {
+  // -----  Set output  ----- //
+
+  // FIXME: Current MCLinker requires one to set up output before inputs. The
+  // constraint will be relaxed in the furture.
   Linker::ErrorCode result = pLinker.setOutput(pOutputPath);
 
   if (Linker::kSuccess != result) {
@@ -225,57 +261,54 @@
     return false;
   }
 
-  // -----  set inputs  ----- //
-  llvm::cl::list<std::string>::iterator fileIt = OptInputObjectFiles.begin();
-  llvm::cl::list<std::string>::iterator libIt  = OptNameSpecList.begin();
+  // -----  Set inputs  ----- //
+  llvm::cl::list<std::string>::iterator file_it = OptInputObjectFiles.begin();
+  llvm::cl::list<std::string>::iterator lib_it  = OptNameSpecList.begin();
 
-  llvm::cl::list<std::string>::iterator fileBegin = OptInputObjectFiles.begin();
-  llvm::cl::list<std::string>::iterator libBegin = OptNameSpecList.begin();
-  llvm::cl::list<std::string>::iterator fileEnd = OptInputObjectFiles.end();
-  llvm::cl::list<std::string>::iterator libEnd = OptNameSpecList.end();
+  llvm::cl::list<std::string>::iterator file_begin = OptInputObjectFiles.begin();
+  llvm::cl::list<std::string>::iterator lib_begin = OptNameSpecList.begin();
+  llvm::cl::list<std::string>::iterator file_end = OptInputObjectFiles.end();
+  llvm::cl::list<std::string>::iterator lib_end = OptNameSpecList.end();
 
-  unsigned libPos = 0, filePos = 0;
+  unsigned lib_pos = 0, file_pos = 0;
   while (true) {
-    if (libIt != libEnd)
-      libPos = OptNameSpecList.getPosition(libIt - libBegin);
-    else
-      libPos = 0;
-
-    if (fileIt != fileEnd)
-      filePos = OptInputObjectFiles.getPosition(fileIt - fileBegin);
-    else
-      filePos = 0;
-
-    if ( filePos != 0 && (libPos == 0 || filePos < libPos) ) {
-      result = pLinker.addObject(*fileIt);
-      if (Linker::kSuccess != result) {
-        llvm::errs() << "Failed to open the input file! (detail: "
-                     << *fileIt << ": "
-                     << Linker::GetErrorString(result) << ")\n";
-        return false;
-      }
-      ++fileIt;
-    }
-    else if ( libPos != 0 && (filePos == 0 || libPos < filePos) ) {
-      result = pLinker.addNameSpec(*libIt);
-      if (Linker::kSuccess != result) {
-        llvm::errs() << "Failed to open the namespec! (detail: "
-                     << *libIt << ": "
-                     << Linker::GetErrorString(result) << ")\n";
-        return false;
-      }
-      ++libIt;
+    if (lib_it != lib_end) {
+      lib_pos = OptNameSpecList.getPosition(lib_it - lib_begin);
+    } else {
+      lib_pos = 0;
     }
 
-    else
+    if (file_it != file_end) {
+      file_pos = OptInputObjectFiles.getPosition(file_it - file_begin);
+    } else {
+      file_pos = 0;
+    }
+
+    if ((file_pos != 0) && ((lib_pos == 0) || (file_pos < lib_pos))) {
+      result = pLinker.addObject(*file_it);
+      if (Linker::kSuccess != result) {
+        llvm::errs() << "Failed to open the input file! (detail: " << *file_it
+                     << ": " << Linker::GetErrorString(result) << ")\n";
+        return false;
+      }
+      ++file_it;
+    } else if ((lib_pos != 0) && ((file_pos == 0) || (lib_pos < file_pos))) {
+      result = pLinker.addNameSpec(*lib_it);
+      if (Linker::kSuccess != result) {
+        llvm::errs() << "Failed to open the namespec! (detail: " << *lib_it
+                     << ": " << Linker::GetErrorString(result) << ")\n";
+        return false;
+      }
+      ++lib_it;
+    } else {
       break; // we're done with the list
+    }
   }
 
   return true;
 }
 
-static inline
-bool LinkFiles(Linker& pLinker) {
+static inline bool LinkFiles(Linker &pLinker) {
   Linker::ErrorCode result = pLinker.link();
   if (Linker::kSuccess != result) {
     llvm::errs() << "Failed to linking! (detail: "
@@ -285,8 +318,7 @@
   return true;
 }
 
-int main(int argc, char* argv[])
-{
+int main(int argc, char** argv) {
   llvm::cl::SetVersionPrinter(MCLDVersionPrinter);
   llvm::cl::ParseCommandLineOptions(argc, argv);
   init::Initialize();
@@ -308,6 +340,7 @@
   if (!LinkFiles(linker)) {
     return EXIT_FAILURE;
   }
+
   return EXIT_SUCCESS;
 }
 
diff --git a/unittests/MCFragmentRefTest.cpp b/unittests/FragmentRefTest.cpp
similarity index 60%
rename from unittests/MCFragmentRefTest.cpp
rename to unittests/FragmentRefTest.cpp
index 3da3463..d64d52b 100644
--- a/unittests/MCFragmentRefTest.cpp
+++ b/unittests/FragmentRefTest.cpp
@@ -1,4 +1,4 @@
-//===- MCFragmentRefTest --------------------------------------------------===//
+//===- FragmentRefTest ----------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -6,12 +6,13 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include "mcld/MC/MCFragmentRef.h"
-#include "mcld/MC/MCRegionFragment.h"
-#include "mcld/Support/MemoryAreaFactory.h"
-#include "mcld/Support/FileHandle.h"
-#include "mcld/Support/Path.h"
-#include "MCFragmentRefTest.h"
+#include "FragmentRefTest.h"
+
+#include <mcld/LD/FragmentRef.h>
+#include <mcld/LD/RegionFragment.h>
+#include <mcld/Support/MemoryAreaFactory.h>
+#include <mcld/Support/FileHandle.h>
+#include <mcld/Support/Path.h>
 
 using namespace mcld;
 using namespace mcld::sys::fs;
@@ -19,49 +20,48 @@
 using namespace mcldtest;
 
 // Constructor can do set-up work for all test here.
-MCFragmentRefTest::MCFragmentRefTest()
+FragmentRefTest::FragmentRefTest()
 {
 }
 
 // Destructor can do clean-up work that doesn't throw exceptions here.
-MCFragmentRefTest::~MCFragmentRefTest()
+FragmentRefTest::~FragmentRefTest()
 {
 }
 
 // SetUp() will be called immediately before each test.
-void MCFragmentRefTest::SetUp()
+void FragmentRefTest::SetUp()
 {
 }
 
 // TearDown() will be called immediately after each test.
-void MCFragmentRefTest::TearDown()
+void FragmentRefTest::TearDown()
 {
 }
 
 //==========================================================================//
 // Testcases
 //
-TEST_F( MCFragmentRefTest, ) {
+TEST_F( FragmentRefTest, ) {
   Path path(TOPDIR);
   path.append("unittests/test3.txt");
   MemoryAreaFactory* areaFactory = new MemoryAreaFactory(1);
   MemoryArea* area = areaFactory->produce(path, FileHandle::ReadWrite);
 
   MemoryRegion* region = area->request(0, 4096);
-  MCRegionFragment *frag = new MCRegionFragment(*region);
-  MCFragmentRef *ref = new MCFragmentRef(*frag);
+  RegionFragment *frag = new RegionFragment(*region);
+  FragmentRef *ref = new FragmentRef(*frag);
 
   ASSERT_EQ('H', region->getBuffer()[0]);
   ASSERT_EQ(4096, region->size());
   ASSERT_EQ('H', frag->getRegion().getBuffer()[0]);
   ASSERT_EQ(4096, frag->getRegion().size());
   ASSERT_EQ(frag, ref->frag());
-  ASSERT_EQ('H', static_cast<MCRegionFragment*>(ref->frag())->getRegion().getBuffer()[0]);
-  ASSERT_EQ(4096, static_cast<MCRegionFragment*>(ref->frag())->getRegion().size());
+  ASSERT_EQ('H', static_cast<RegionFragment*>(ref->frag())->getRegion().getBuffer()[0]);
+  ASSERT_EQ(4096, static_cast<RegionFragment*>(ref->frag())->getRegion().size());
   ASSERT_EQ('H', ref->deref()[0]);
 
-  ASSERT_FALSE(llvm::MCDataFragment::classof(frag));
-  ASSERT_TRUE(MCRegionFragment::classof(frag));
+  ASSERT_TRUE(RegionFragment::classof(frag));
 
   delete ref;
   delete frag;
diff --git a/unittests/MCFragmentRefTest.h b/unittests/FragmentRefTest.h
similarity index 77%
rename from unittests/MCFragmentRefTest.h
rename to unittests/FragmentRefTest.h
index c0b23f3..340bd77 100644
--- a/unittests/MCFragmentRefTest.h
+++ b/unittests/FragmentRefTest.h
@@ -1,4 +1,4 @@
-//===- MCFragmentRefTest.h ------------------------------------------------===//
+//===- FragmentRefTest.h --------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -14,26 +14,26 @@
 
 namespace mcld
 {
-class MCFragmentRef;
+class FragmentRef;
 
 } // namespace for mcld
 
 namespace mcldtest
 {
 
-/** \class MCFragmentRefTest
+/** \class FragmentRefTest
  *  \brief Reference Test
  *
- *  \see MCFragmentRef 
+ *  \see FragmentRef 
  */
-class MCFragmentRefTest : public ::testing::Test
+class FragmentRefTest : public ::testing::Test
 {
 public:
   // Constructor can do set-up work for all test here.
-  MCFragmentRefTest();
+  FragmentRefTest();
 
   // Destructor can do clean-up work that doesn't throw exceptions here.
-  virtual ~MCFragmentRefTest();
+  virtual ~FragmentRefTest();
 
   // SetUp() will be called immediately before each test.
   virtual void SetUp();
diff --git a/unittests/FragmentTest.cpp b/unittests/FragmentTest.cpp
new file mode 100644
index 0000000..5186ea8
--- /dev/null
+++ b/unittests/FragmentTest.cpp
@@ -0,0 +1,79 @@
+//===- FragmentTest.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "FragmentTest.h"
+
+#include <mcld/LD/Fragment.h>
+#include <mcld/LD/SectionData.h>
+#include <mcld/LD/LDSection.h>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+FragmentTest::FragmentTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+FragmentTest::~FragmentTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void FragmentTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void FragmentTest::TearDown()
+{
+}
+
+//===----------------------------------------------------------------------===//
+// Testcases
+ 
+TEST_F( FragmentTest, Fragment_constructor ) {
+  LDSection test("test", LDFileFormat::Null, 0, 0);
+  SectionData* s = new SectionData(test);
+  Fragment* f1 = new Fragment(Fragment::Alignment, s);
+  EXPECT_TRUE(1 == s->size());
+  Fragment* f2 = new Fragment(Fragment::Alignment, s);
+  Fragment* f3 = new Fragment(Fragment::Region, s);
+  Fragment* f4 = new Fragment(Fragment::Fillment, s);
+  Fragment* f5 = new Fragment(Fragment::Relocation, s);
+  Fragment* f6 = new Fragment(Fragment::Target, s);
+  EXPECT_TRUE(6 == s->size());
+
+  delete s;
+}
+
+TEST_F( FragmentTest, Fragment_trivial_function ) {
+  LDSection test("test", LDFileFormat::Null, 0, 0);
+  SectionData* s = new SectionData(test);
+  Fragment* f = new Fragment(Fragment::Alignment, s);
+  
+  EXPECT_TRUE(Fragment::Alignment == f->getKind());
+
+  EXPECT_TRUE(~uint64_t(0) == f->getOffset());
+  EXPECT_TRUE(~(0U) == f->getLayoutOrder());
+
+  f->setOffset(5566);
+  EXPECT_TRUE(5566 == f->getOffset());
+
+  f->setLayoutOrder(5566);
+  EXPECT_TRUE(5566 == f->getLayoutOrder());
+  
+  //always return true
+  EXPECT_TRUE(f->classof(new Fragment(Fragment::Region, s)) );
+  
+  delete s;
+}
+
+
diff --git a/unittests/MCFragmentRefTest.h b/unittests/FragmentTest.h
similarity index 66%
copy from unittests/MCFragmentRefTest.h
copy to unittests/FragmentTest.h
index c0b23f3..84ac7b7 100644
--- a/unittests/MCFragmentRefTest.h
+++ b/unittests/FragmentTest.h
@@ -1,4 +1,4 @@
-//===- MCFragmentRefTest.h ------------------------------------------------===//
+//===- headerTest.h -------------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -6,40 +6,42 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
-#ifndef MCLD_MCFRAGMENT_REF_TEST_H
-#define MCLD_MCFRAGMENT_REF_TEST_H
+#ifndef MCLD_FRAGMENT_TEST_H
+#define MCLD_FRAGMENT_TEST_H
 
 #include <gtest.h>
 
 namespace mcld
 {
-class MCFragmentRef;
+class Fragment;
 
 } // namespace for mcld
 
 namespace mcldtest
 {
 
-/** \class MCFragmentRefTest
- *  \brief Reference Test
+/** \class FragmentTest
+ *  \brief Unit test for mcld::Fragment.
  *
- *  \see MCFragmentRef 
+ *  \see Fragment 
  */
-class MCFragmentRefTest : public ::testing::Test
+class FragmentTest : public ::testing::Test
 {
 public:
   // Constructor can do set-up work for all test here.
-  MCFragmentRefTest();
+  FragmentTest();
 
   // Destructor can do clean-up work that doesn't throw exceptions here.
-  virtual ~MCFragmentRefTest();
+  virtual ~FragmentTest();
 
   // SetUp() will be called immediately before each test.
   virtual void SetUp();
 
   // TearDown() will be called immediately after each test.
   virtual void TearDown();
+
+protected:
+  mcld::Fragment* m_pTestee;
 };
 
 } // namespace of mcldtest
diff --git a/unittests/Linker/TestLinker.cpp b/unittests/Linker/TestLinker.cpp
index 243be86..ad6e13a 100644
--- a/unittests/Linker/TestLinker.cpp
+++ b/unittests/Linker/TestLinker.cpp
@@ -14,15 +14,18 @@
 
 #include <mcld/LD/TextDiagnosticPrinter.h>
 #include <mcld/MC/InputTree.h>
+#include <mcld/MC/MCLDDirectory.h>
 #include <mcld/Target/TargetLDBackend.h>
 #include <mcld/Support/RegionFactory.h>
 #include <mcld/Support/TargetSelect.h>
 #include <mcld/Support/MsgHandling.h>
 #include <mcld/Support/raw_ostream.h>
 #include <mcld/Support/SystemUtils.h>
+#include <mcld/Support/MemoryAreaFactory.h>
 
 using namespace std;
 using namespace mcld;
+using namespace mcld::sys::fs;
 using namespace mcld::test;
 
 //===----------------------------------------------------------------------===//
@@ -30,7 +33,8 @@
 //===----------------------------------------------------------------------===//
 TestLinker::TestLinker()
   : m_pTarget(NULL), m_pDriver(NULL), m_pInfo(NULL), m_pDiagLineInfo(NULL),
-    m_pDiagPrinter(NULL), m_pBackend(NULL), m_pRegionFactory(NULL) {
+    m_pDiagPrinter(NULL), m_pBackend(NULL), m_pRegionFactory(NULL),
+    m_pMemAreaFactory(NULL) {
 }
 
 TestLinker::~TestLinker()
@@ -49,6 +53,7 @@
   delete m_pDiagPrinter;
   delete m_pBackend;
   delete m_pRegionFactory;
+  delete m_pMemAreaFactory;
 }
 
 bool TestLinker::initialize(const std::string &pTriple)
@@ -99,14 +104,40 @@
     return false;
   }
 
-  m_pDriver = new mcld::MCLDDriver(*m_pInfo, *m_pBackend);
+  m_pMemAreaFactory = new MemoryAreaFactory(32);
 
+  m_pDriver = new mcld::MCLDDriver(*m_pInfo, *m_pBackend, *m_pMemAreaFactory);
   m_pDriver->initMCLinker();
 
   is_initialized = true;
   return true;
 }
 
+void TestLinker::addSearchDir(const std::string &pDirPath)
+{
+  assert(NULL != m_pInfo && "initialize() must be called before addSearchDir");
+  assert(!m_pInfo->options().sysroot().empty() &&
+         "must setSysRoot before addSearchDir");
+
+  mcld::MCLDDirectory* sd = new mcld::MCLDDirectory(pDirPath);
+
+  if (sd->isInSysroot()) {
+    sd->setSysroot(m_pInfo->options().sysroot());
+  }
+
+  if (exists(sd->path()) && is_directory(sd->path())) {
+    m_pInfo->options().directories().add(*sd);
+  } else {
+    mcld::warning(mcld::diag::warn_cannot_open_search_dir) << sd->name();
+  }
+}
+
+void TestLinker::setSysRoot(const mcld::sys::fs::Path &pPath)
+{
+  assert(NULL != m_pInfo && "initialize() must be called before setSysRoot");
+  m_pInfo->options().setSysroot(pPath);
+}
+
 void TestLinker::addObject(const std::string &pPath)
 {
   mcld::Input* input = m_pInfo->inputFactory().produce(pPath, pPath,
@@ -255,6 +286,11 @@
   return true;
 }
 
+bool TestLinker::setOutput(const sys::fs::Path &pPath)
+{
+  return setOutput(pPath.native());
+}
+
 bool TestLinker::setOutput(int pFileHandler)
 {
   if (m_pInfo->output().hasContext())
diff --git a/unittests/Linker/TestLinker.h b/unittests/Linker/TestLinker.h
index 79b3010..f44d2b0 100644
--- a/unittests/Linker/TestLinker.h
+++ b/unittests/Linker/TestLinker.h
@@ -49,6 +49,12 @@
     return m_pInfo;
   }
 
+  // -----  search directories  ----- //
+  void addSearchDir(const std::string &pPath);
+
+  void setSysRoot(const mcld::sys::fs::Path &pPath);
+
+  // -----  input operators  ----- //
   void addObject(const std::string &pPath);
 
   void addObject(const mcld::sys::fs::Path &pPath)
@@ -64,6 +70,8 @@
 
   bool setOutput(int pFileHandler);
 
+  bool setOutput(const sys::fs::Path &pPath);
+
   /// getDriver
   MCLDDriver* getDriver() {
     assert(NULL != m_pDriver);
@@ -100,6 +108,7 @@
   mcld::TargetLDBackend* m_pBackend;
   mcld::InputTree::iterator m_Root;
   mcld::RegionFactory* m_pRegionFactory;
+  mcld::MemoryAreaFactory* m_pMemAreaFactory;
 
   std::list<mcld::FileHandle*> m_FileHandleList;
   std::list<mcld::MemoryArea*> m_MemAreaList;
diff --git a/unittests/PathTest.cpp b/unittests/PathTest.cpp
index 8906d02..2a4de80 100644
--- a/unittests/PathTest.cpp
+++ b/unittests/PathTest.cpp
@@ -138,3 +138,20 @@
   EXPECT_STREQ("/usr/lib/", m_pTestee->generic_string().c_str());
 }
 
+TEST_F( PathTest, parent_path ) {
+  m_pTestee->assign("aa/bb/cc/dd");
+  EXPECT_STREQ("aa/bb/cc", m_pTestee->parent_path().c_str());
+  delete m_pTestee;
+  m_pTestee = new Path("/aa/bb/");
+  EXPECT_STREQ("/aa/bb", m_pTestee->parent_path().c_str());
+  delete m_pTestee;
+  m_pTestee = new Path("/aa/bb");
+  EXPECT_STREQ("/aa", m_pTestee->parent_path().c_str());
+  delete m_pTestee;
+  m_pTestee = new Path("aa/");
+  EXPECT_STREQ("aa", m_pTestee->parent_path().c_str());
+  delete m_pTestee;
+  m_pTestee = new Path("aa");
+  EXPECT_TRUE(m_pTestee->parent_path().empty());
+}
+
diff --git a/unittests/ReadStageTest.cpp b/unittests/ReadStageTest.cpp
new file mode 100644
index 0000000..c687c0b
--- /dev/null
+++ b/unittests/ReadStageTest.cpp
@@ -0,0 +1,147 @@
+//===- ReadStageTest.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "ReadStageTest.h"
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/SectionData.h>
+#include <mcld/LD/Fragment.h>
+#include <mcld/LD/FragmentRef.h>
+#include <mcld/LD/LDSymbol.h>
+#include <mcld/LD/ResolveInfo.h>
+
+#include <sstream>
+#include <iostream>
+
+using namespace std;
+
+using namespace mcld;
+using namespace mcld::test;
+
+
+// Constructor can do set-up work for all test here.
+ReadStageTest::ReadStageTest()
+  : m_pLinker(NULL) {
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+ReadStageTest::~ReadStageTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void ReadStageTest::SetUp()
+{
+  m_pLinker = new mcld::test::TestLinker();
+  m_pLinker->initialize("arm-none-linux-gnueabi");
+
+  // set up target-dependent constraints of attributes
+  m_pLinker->config()->attrFactory().constraint().enableWholeArchive();
+  m_pLinker->config()->attrFactory().constraint().disableAsNeeded();
+  m_pLinker->config()->attrFactory().constraint().setSharedSystem();
+
+  // set up the predefined attributes
+  m_pLinker->config()->attrFactory().predefined().setWholeArchive();
+  m_pLinker->config()->attrFactory().predefined().setDynamic();
+
+  // set up target dependent options
+  mcld::sys::fs::Path path = TOPDIR;
+  path.append("test/libs/ARM/Android/android-14");
+  m_pLinker->setSysRoot(path);
+  m_pLinker->addSearchDir("=/");
+
+  m_pLinker->config()->options().setDyld("/usr/lib/ld.so.1");
+  m_pLinker->config()->options().setBsymbolic(true);
+}
+
+// TearDown() will be called immediately after each test.
+void ReadStageTest::TearDown()
+{
+  delete m_pLinker;
+}
+
+void ReadStageTest::dumpInput(const mcld::Input &pInput, mcld::FileHandle &pFile, size_t pIdent)
+{
+  stringstream sstream;
+  for (int i=0; i < pIdent; ++i)
+    sstream << " ";
+  sstream << "<input name=\"" << pInput.name() << "\">\n";
+
+  LDContext::const_sect_iterator sect, sectEnd = pInput.context()->sectEnd();
+  for (sect = pInput.context()->sectBegin(); sect != sectEnd; ++sect) {
+    for (int i=0; i < (pIdent+1); ++i)
+      sstream << " ";
+    sstream << "<section name=\"" << (*sect)->name() << "\"/>\n";
+  }
+  for (int i=0; i < pIdent; ++i)
+    sstream << " ";
+  sstream << "</input>\n";
+
+  size_t org_size = pFile.size();
+  pFile.truncate(sstream.str().size() + org_size);
+  pFile.write(sstream.str().data(), org_size, sstream.str().size());
+}
+
+void ReadStageTest::dumpOutput(const mcld::Output &pOutput, mcld::FileHandle &pFile, size_t pIdent)
+{
+  stringstream sstream;
+  for (int i=0; i < pIdent; ++i)
+    sstream << " ";
+  sstream << "<output name=\"" << pOutput.name() << "\">\n";
+
+  LDContext::const_sect_iterator sect, sectEnd = pOutput.context()->sectEnd();
+  for (sect = pOutput.context()->sectBegin(); sect != sectEnd; ++sect) {
+    for (int i=0; i < (pIdent+1); ++i)
+      sstream << " ";
+    sstream << "<section name=\"" << (*sect)->name() << "\"/>\n";
+  }
+  for (int i=0; i < pIdent; ++i)
+    sstream << " ";
+  sstream << "</output>\n";
+
+  size_t org_size = pFile.size();
+  pFile.truncate(sstream.str().size() + org_size);
+  pFile.write(sstream.str().data(), org_size, sstream.str().size());
+}
+//===----------------------------------------------------------------------===//
+// Testcases
+//===----------------------------------------------------------------------===//
+TEST_F(ReadStageTest, quake) {
+  mcld::sys::fs::Path top_level = TOPDIR;
+
+  // set up output
+  m_pLinker->config()->output().setType(mcld::Output::DynObj);
+  m_pLinker->setOutput(top_level + "unittests/plasma.so");
+
+
+  // set up input
+  m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtbegin_so.o");
+  m_pLinker->addObject(top_level + "test/Android/Plasma/ARM/plasma.o");
+  m_pLinker->addNameSpec("m");
+  m_pLinker->addNameSpec("log");
+  m_pLinker->addNameSpec("jnigraphics");
+  m_pLinker->addNameSpec("c");
+  m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtend_so.o");
+
+  // dump status
+  m_pLinker->getDriver()->normalize();
+
+  FileHandle file;
+  file.open(top_level + "unittests/read_stage.xml",
+     FileHandle::ReadWrite | FileHandle::Create | FileHandle::Truncate, 0644);
+
+  InputTree::iterator input, inEnd = m_pLinker->config()->inputs().end();
+  for (input = m_pLinker->config()->inputs().begin(); input != inEnd; ++input) {
+    dumpInput(**input, file, 1);
+  }
+
+  dumpOutput(m_pLinker->config()->output(), file, 1);
+  // dump status
+  ASSERT_TRUE(m_pLinker->getDriver()->mergeSections());
+}
+
diff --git a/unittests/ReadStageTest.h b/unittests/ReadStageTest.h
new file mode 100644
index 0000000..5fd4595
--- /dev/null
+++ b/unittests/ReadStageTest.h
@@ -0,0 +1,44 @@
+//===- ReadStageTest.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_UNITTEST_READSTAGE_TEST_H
+#define MCLD_UNITTEST_READSTAGE_TEST_H
+
+#include <gtest.h>
+#include "Linker/TestLinker.h"
+
+namespace mcld {
+namespace test {
+
+class ReadStageTest : public ::testing::Test
+{
+public:
+  // Constructor can do set-up work for all test here.
+  ReadStageTest();
+
+  // Destructor can do clean-up work that doesn't throw exceptions here.
+  virtual ~ReadStageTest();
+
+  // SetUp() will be called immediately before each test.
+  virtual void SetUp();
+
+  // TearDown() will be called immediately after each test.
+  virtual void TearDown();
+
+  void dumpInput(const mcld::Input &pInput, mcld::FileHandle &pFile, size_t pIdent);
+
+  void dumpOutput(const mcld::Output &pOutput, mcld::FileHandle &pFile, size_t pIdent);
+protected:
+  TestLinker* m_pLinker;
+};
+
+} // end of namespace test
+} // end of namespace mcld
+
+#endif
+
diff --git a/unittests/SectionDataTest.cpp b/unittests/SectionDataTest.cpp
new file mode 100644
index 0000000..d100f56
--- /dev/null
+++ b/unittests/SectionDataTest.cpp
@@ -0,0 +1,86 @@
+//===- SectionDataTest.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "SectionDataTest.h"
+
+#include <mcld/LD/SectionData.h>
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/LD/LDSection.h>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+SectionDataTest::SectionDataTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+SectionDataTest::~SectionDataTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void SectionDataTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void SectionDataTest::TearDown()
+{
+}
+
+//===----------------------------------------------------------------------===//
+// Testcases
+//===----------------------------------------------------------------------===//
+ 
+TEST_F( SectionDataTest, constructor_and_trivial_func ) {
+  LDSection test("test", LDFileFormat::Null, 0, 0);
+  
+  SectionData* s = new SectionData(test);
+  EXPECT_TRUE(s->getSection().name() == "test" && \
+              s->getSection().kind() == LDFileFormat::Null);
+  
+  s->setAlignment(5566);
+  EXPECT_TRUE(5566 == s->getAlignment());
+
+  delete s;
+}
+
+TEST_F( SectionDataTest, Fragment_list_and_iterator ) {
+  LDSection test("test", LDFileFormat::Null, 0, 0);
+  SectionData* s = new SectionData(test);
+  EXPECT_TRUE(s->empty());
+
+  Fragment* f1 = new Fragment(Fragment::Alignment, s);
+  Fragment* f2 = new Fragment(Fragment::Alignment, s);
+  Fragment* f3 = new Fragment(Fragment::Region, s);
+  Fragment* f4 = new Fragment(Fragment::Fillment, s);
+  Fragment* f5 = new Fragment(Fragment::Relocation, s);
+  Fragment* f6 = new Fragment(Fragment::Target, s);
+  EXPECT_TRUE(6 == s->size());
+
+  //iterator
+  llvm::iplist<Fragment>::iterator iter=s->begin();
+  EXPECT_TRUE(Fragment::Alignment == iter->getKind());
+  ++iter;
+  EXPECT_TRUE(Fragment::Alignment == iter->getKind());
+  ++iter;
+  EXPECT_TRUE(Fragment::Region == iter->getKind());
+  ++iter;
+  EXPECT_TRUE(Fragment::Fillment == iter->getKind());
+  ++iter;
+  EXPECT_TRUE(Fragment::Relocation == iter->getKind());
+  ++iter;
+  EXPECT_TRUE(Fragment::Target == iter->getKind());
+  ++iter;
+  EXPECT_TRUE(iter == s->end());
+
+  delete s;
+}
diff --git a/unittests/MCFragmentRefTest.h b/unittests/SectionDataTest.h
similarity index 65%
copy from unittests/MCFragmentRefTest.h
copy to unittests/SectionDataTest.h
index c0b23f3..bbc2736 100644
--- a/unittests/MCFragmentRefTest.h
+++ b/unittests/SectionDataTest.h
@@ -1,4 +1,4 @@
-//===- MCFragmentRefTest.h ------------------------------------------------===//
+//===- SectionDataTest.h --------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -6,34 +6,26 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
-#ifndef MCLD_MCFRAGMENT_REF_TEST_H
-#define MCLD_MCFRAGMENT_REF_TEST_H
+#ifndef MCLD_SECTIONDATA_TEST_H
+#define MCLD_SECTIONDATA_TEST_H
 
 #include <gtest.h>
 
-namespace mcld
-{
-class MCFragmentRef;
-
+namespace mcld {
+class SectionData;
 } // namespace for mcld
 
 namespace mcldtest
 {
 
-/** \class MCFragmentRefTest
- *  \brief Reference Test
- *
- *  \see MCFragmentRef 
- */
-class MCFragmentRefTest : public ::testing::Test
+class SectionDataTest : public ::testing::Test
 {
 public:
   // Constructor can do set-up work for all test here.
-  MCFragmentRefTest();
+  SectionDataTest();
 
   // Destructor can do clean-up work that doesn't throw exceptions here.
-  virtual ~MCFragmentRefTest();
+  virtual ~SectionDataTest();
 
   // SetUp() will be called immediately before each test.
   virtual void SetUp();
diff --git a/unittests/StaticResolverTest.cpp b/unittests/StaticResolverTest.cpp
index 5839507..439f21a 100644
--- a/unittests/StaticResolverTest.cpp
+++ b/unittests/StaticResolverTest.cpp
@@ -50,6 +50,7 @@
   delete m_pResolver;
   delete m_pFactory;
   delete m_pLDInfo;
+  delete m_pLineInfo;
 }
 
 // SetUp() will be called immediately before each test.
diff --git a/unittests/SystemUtilsTest.cpp b/unittests/SystemUtilsTest.cpp
new file mode 100644
index 0000000..1222794
--- /dev/null
+++ b/unittests/SystemUtilsTest.cpp
@@ -0,0 +1,42 @@
+//===- SystemUtilsTest.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Support/SystemUtils.h>
+#include "SystemUtilsTest.h"
+
+using namespace mcld;
+using namespace mcld::test;
+
+
+// Constructor can do set-up work for all test here.
+SystemUtilsTest::SystemUtilsTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+SystemUtilsTest::~SystemUtilsTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void SystemUtilsTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void SystemUtilsTest::TearDown()
+{
+}
+
+//===----------------------------------------------------------------------===//
+// Testcases
+//===----------------------------------------------------------------------===//
+TEST_F( SystemUtilsTest, test_strerror) {
+  ASSERT_TRUE(NULL != mcld::sys::strerror(0));
+}
+
diff --git a/unittests/SystemUtilsTest.h b/unittests/SystemUtilsTest.h
new file mode 100644
index 0000000..660d7bb
--- /dev/null
+++ b/unittests/SystemUtilsTest.h
@@ -0,0 +1,37 @@
+//===- SystemUtilsTest.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_UNITTEST_SYSTEM_UTILS_TEST_H
+#define MCLD_UNITTEST_SYSTEM_UTILS_TEST_H
+
+#include <gtest.h>
+
+namespace mcld {
+namespace test {
+
+class SystemUtilsTest : public ::testing::Test
+{
+public:
+  // Constructor can do set-up work for all test here.
+  SystemUtilsTest();
+
+  // Destructor can do clean-up work that doesn't throw exceptions here.
+  virtual ~SystemUtilsTest();
+
+  // SetUp() will be called immediately before each test.
+  virtual void SetUp();
+
+  // TearDown() will be called immediately after each test.
+  virtual void TearDown();
+};
+
+} // namespace of test
+} // namespace of mcld
+
+#endif
+
diff --git a/unittests/TestLinkerTest.cpp b/unittests/TestLinkerTest.cpp
index b6df3cf..272cd89 100644
--- a/unittests/TestLinkerTest.cpp
+++ b/unittests/TestLinkerTest.cpp
@@ -46,9 +46,10 @@
   // set up target dependent options
   mcld::sys::fs::Path path = TOPDIR;
   path.append("test/libs/ARM/Android/android-14");
-  m_pLinker->config()->options().setSysroot(path);
+  m_pLinker->setSysRoot(path);
+  m_pLinker->addSearchDir("=/");
+
   m_pLinker->config()->options().setDyld("/usr/lib/ld.so.1");
-  m_pLinker->config()->options().directories().add("=/");
   m_pLinker->config()->options().setBsymbolic(true);
 }
 
diff --git a/unittests/UniqueGCFactoryBaseTest.cpp b/unittests/UniqueGCFactoryBaseTest.cpp
index 067467b..32447c2 100644
--- a/unittests/UniqueGCFactoryBaseTest.cpp
+++ b/unittests/UniqueGCFactoryBaseTest.cpp
@@ -30,6 +30,8 @@
 // Destructor can do clean-up work that doesn't throw exceptions here.
 UniqueGCFactoryBaseTest::~UniqueGCFactoryBaseTest()
 {
+  delete m_pLDInfo;
+  delete m_pLineInfo;
 }
 
 // SetUp() will be called immediately before each test.
diff --git a/unittests/read_stage.xml b/unittests/read_stage.xml
new file mode 100644
index 0000000..cc061d6
--- /dev/null
+++ b/unittests/read_stage.xml
@@ -0,0 +1,273 @@
+ <input name="/Users/lubatang/Project/MCLinker/build/../src-tree/test/libs/ARM/Android/android-14/crtbegin_so.o">
+  <section name=""/>
+  <section name=".text"/>
+  <section name=".rel.text"/>
+  <section name=".data"/>
+  <section name=".bss"/>
+  <section name=".init_array"/>
+  <section name=".fini_array"/>
+  <section name=".rel.fini_array"/>
+  <section name=".ARM.attributes"/>
+  <section name=".shstrtab"/>
+  <section name=".symtab"/>
+  <section name=".strtab"/>
+ </input>
+ <input name="/Users/lubatang/Project/MCLinker/build/../src-tree/test/Android/Plasma/ARM/plasma.o">
+  <section name=""/>
+  <section name=".text"/>
+  <section name=".rel.text"/>
+  <section name=".text.now_ms"/>
+  <section name=".rel.text.now_ms"/>
+  <section name=".text.init_angles"/>
+  <section name=".rel.text.init_angles"/>
+  <section name=".text.angle_sin"/>
+  <section name=".rel.text.angle_sin"/>
+  <section name=".text.fixed_sin"/>
+  <section name=".rel.text.fixed_sin"/>
+  <section name=".text.make565"/>
+  <section name=".text.init_palette"/>
+  <section name=".rel.text.init_palette"/>
+  <section name=".text.palette_from_fixed"/>
+  <section name=".rel.text.palette_from_fixed"/>
+  <section name=".text.init_tables"/>
+  <section name=".rel.text.init_tables"/>
+  <section name=".text.fill_plasma"/>
+  <section name=".rel.text.fill_plasma"/>
+  <section name=".text.stats_init"/>
+  <section name=".rel.text.stats_init"/>
+  <section name=".text.stats_startFrame"/>
+  <section name=".rel.text.stats_startFrame"/>
+  <section name=".text.stats_endFrame"/>
+  <section name=".rel.text.stats_endFrame"/>
+  <section name=".text.Java_com_example_plasma_PlasmaView_renderPlasma"/>
+  <section name=".rel.text.Java_com_example_plasma_PlasmaView_renderPlasma"/>
+  <section name=".rodata"/>
+  <section name=".ARM.extab.text.now_ms"/>
+  <section name=".ARM.exidx.text.now_ms"/>
+  <section name=".rel.ARM.exidx.text.now_ms"/>
+  <section name=".ARM.extab.text.init_angles"/>
+  <section name=".ARM.exidx.text.init_angles"/>
+  <section name=".rel.ARM.exidx.text.init_angles"/>
+  <section name=".ARM.extab.text.angle_sin"/>
+  <section name=".ARM.exidx.text.angle_sin"/>
+  <section name=".rel.ARM.exidx.text.angle_sin"/>
+  <section name=".ARM.extab.text.fixed_sin"/>
+  <section name=".ARM.exidx.text.fixed_sin"/>
+  <section name=".rel.ARM.exidx.text.fixed_sin"/>
+  <section name=".ARM.extab.text.make565"/>
+  <section name=".ARM.exidx.text.make565"/>
+  <section name=".rel.ARM.exidx.text.make565"/>
+  <section name=".ARM.extab.text.init_palette"/>
+  <section name=".ARM.exidx.text.init_palette"/>
+  <section name=".rel.ARM.exidx.text.init_palette"/>
+  <section name=".ARM.extab.text.palette_from_fixed"/>
+  <section name=".ARM.exidx.text.palette_from_fixed"/>
+  <section name=".rel.ARM.exidx.text.palette_from_fixed"/>
+  <section name=".ARM.extab.text.init_tables"/>
+  <section name=".ARM.exidx.text.init_tables"/>
+  <section name=".rel.ARM.exidx.text.init_tables"/>
+  <section name=".ARM.extab.text.fill_plasma"/>
+  <section name=".ARM.exidx.text.fill_plasma"/>
+  <section name=".rel.ARM.exidx.text.fill_plasma"/>
+  <section name=".ARM.extab.text.stats_init"/>
+  <section name=".ARM.exidx.text.stats_init"/>
+  <section name=".rel.ARM.exidx.text.stats_init"/>
+  <section name=".ARM.extab.text.stats_startFrame"/>
+  <section name=".ARM.exidx.text.stats_startFrame"/>
+  <section name=".rel.ARM.exidx.text.stats_startFrame"/>
+  <section name=".ARM.extab.text.stats_endFrame"/>
+  <section name=".ARM.exidx.text.stats_endFrame"/>
+  <section name=".rel.ARM.exidx.text.stats_endFrame"/>
+  <section name=".ARM.extab.text.Java_com_example_plasma_PlasmaView_renderPlasma"/>
+  <section name=".ARM.exidx.text.Java_com_example_plasma_PlasmaView_renderPlasma"/>
+  <section name=".rel.ARM.exidx.text.Java_com_example_plasma_PlasmaView_renderPlasma"/>
+  <section name=".ARM.extab"/>
+  <section name=".ARM.exidx"/>
+  <section name=".rel.ARM.exidx"/>
+  <section name=".data"/>
+  <section name=".bss"/>
+  <section name=".comment"/>
+  <section name=".debug_aranges"/>
+  <section name=".rel.debug_aranges"/>
+  <section name=".debug_pubnames"/>
+  <section name=".rel.debug_pubnames"/>
+  <section name=".debug_info"/>
+  <section name=".rel.debug_info"/>
+  <section name=".debug_abbrev"/>
+  <section name=".debug_line"/>
+  <section name=".rel.debug_line"/>
+  <section name=".debug_frame"/>
+  <section name=".rel.debug_frame"/>
+  <section name=".debug_str"/>
+  <section name=".debug_loc"/>
+  <section name=".rel.debug_loc"/>
+  <section name=".debug_ranges"/>
+  <section name=".rel.debug_ranges"/>
+  <section name=".note.GNU-stack"/>
+  <section name=".ARM.attributes"/>
+  <section name=".shstrtab"/>
+  <section name=".symtab"/>
+  <section name=".strtab"/>
+ </input>
+ <input name="libm.so">
+  <section name=""/>
+  <section name=".hash"/>
+  <section name=".dynsym"/>
+  <section name=".dynstr"/>
+  <section name=".text"/>
+  <section name=".dynamic"/>
+  <section name=".got"/>
+  <section name=".bss"/>
+  <section name=".ARM.attributes"/>
+  <section name=".comment"/>
+  <section name=".shstrtab"/>
+  <section name=".symtab"/>
+  <section name=".strtab"/>
+ </input>
+ <input name="liblog.so">
+  <section name=""/>
+  <section name=".hash"/>
+  <section name=".dynsym"/>
+  <section name=".dynstr"/>
+  <section name=".text"/>
+  <section name=".dynamic"/>
+  <section name=".got"/>
+  <section name=".ARM.attributes"/>
+  <section name=".comment"/>
+  <section name=".shstrtab"/>
+  <section name=".symtab"/>
+  <section name=".strtab"/>
+ </input>
+ <input name="libjnigraphics.so">
+  <section name=""/>
+  <section name=".hash"/>
+  <section name=".dynsym"/>
+  <section name=".dynstr"/>
+  <section name=".text"/>
+  <section name=".dynamic"/>
+  <section name=".got"/>
+  <section name=".ARM.attributes"/>
+  <section name=".comment"/>
+  <section name=".shstrtab"/>
+  <section name=".symtab"/>
+  <section name=".strtab"/>
+ </input>
+ <input name="libc.so">
+  <section name=""/>
+  <section name=".hash"/>
+  <section name=".dynsym"/>
+  <section name=".dynstr"/>
+  <section name=".text"/>
+  <section name=".dynamic"/>
+  <section name=".got"/>
+  <section name=".bss"/>
+  <section name=".ARM.attributes"/>
+  <section name=".comment"/>
+  <section name=".shstrtab"/>
+  <section name=".symtab"/>
+  <section name=".strtab"/>
+ </input>
+ <input name="/Users/lubatang/Project/MCLinker/build/../src-tree/test/libs/ARM/Android/android-14/crtend_so.o">
+  <section name=""/>
+  <section name=".text"/>
+  <section name=".data"/>
+  <section name=".bss"/>
+  <section name=".init_array"/>
+  <section name=".fini_array"/>
+  <section name=".ARM.attributes"/>
+  <section name=".shstrtab"/>
+  <section name=".symtab"/>
+  <section name=".strtab"/>
+ </input>
+ <output name="">
+  <section name=".text"/>
+  <section name=""/>
+  <section name=".rodata"/>
+  <section name=".bss"/>
+  <section name=".comment"/>
+  <section name=".data"/>
+  <section name=".debug"/>
+  <section name=".init"/>
+  <section name=".init_array"/>
+  <section name=".fini"/>
+  <section name=".fini_array"/>
+  <section name=".line"/>
+  <section name=".preinit_array"/>
+  <section name=".shstrtab"/>
+  <section name=".symtab"/>
+  <section name=".strtab"/>
+  <section name=".tbss"/>
+  <section name=".tdata"/>
+  <section name=".ctor"/>
+  <section name=".data.rel.ro"/>
+  <section name=".dtors"/>
+  <section name=".eh_frame"/>
+  <section name=".gcc_except_table"/>
+  <section name=".gnu.version"/>
+  <section name=".gnu.version_d"/>
+  <section name=".gnu.version_r"/>
+  <section name=".jcr"/>
+  <section name=".stab"/>
+  <section name=".stabstr"/>
+  <section name=".dynsym"/>
+  <section name=".dynstr"/>
+  <section name=".interp"/>
+  <section name=".hash"/>
+  <section name=".dynamic"/>
+  <section name=".rela.dyn"/>
+  <section name=".rela.plt"/>
+  <section name=".rel.dyn"/>
+  <section name=".rel.plt"/>
+  <section name=".got"/>
+  <section name=".plt"/>
+  <section name=".got.plt"/>
+  <section name=".eh_frame_hdr"/>
+  <section name=".ARM.exidx"/>
+  <section name=".ARM.extab"/>
+  <section name=".ARM.attributes"/>
+  <section name=".rel.text"/>
+  <section name=".rel.fini_array"/>
+  <section name=".rel.text.now_ms"/>
+  <section name=".rel.text.init_angles"/>
+  <section name=".rel.text.angle_sin"/>
+  <section name=".rel.text.fixed_sin"/>
+  <section name=".rel.text.init_palette"/>
+  <section name=".rel.text.palette_from_fixed"/>
+  <section name=".rel.text.init_tables"/>
+  <section name=".rel.text.fill_plasma"/>
+  <section name=".rel.text.stats_init"/>
+  <section name=".rel.text.stats_startFrame"/>
+  <section name=".rel.text.stats_endFrame"/>
+  <section name=".rel.text.Java_com_example_plasma_PlasmaView_renderPlasma"/>
+  <section name=".rel.ARM.exidx.text.now_ms"/>
+  <section name=".rel.ARM.exidx.text.init_angles"/>
+  <section name=".rel.ARM.exidx.text.angle_sin"/>
+  <section name=".rel.ARM.exidx.text.fixed_sin"/>
+  <section name=".rel.ARM.exidx.text.make565"/>
+  <section name=".rel.ARM.exidx.text.init_palette"/>
+  <section name=".rel.ARM.exidx.text.palette_from_fixed"/>
+  <section name=".rel.ARM.exidx.text.init_tables"/>
+  <section name=".rel.ARM.exidx.text.fill_plasma"/>
+  <section name=".rel.ARM.exidx.text.stats_init"/>
+  <section name=".rel.ARM.exidx.text.stats_startFrame"/>
+  <section name=".rel.ARM.exidx.text.stats_endFrame"/>
+  <section name=".rel.ARM.exidx.text.Java_com_example_plasma_PlasmaView_renderPlasma"/>
+  <section name=".rel.ARM.exidx"/>
+  <section name=".debug_aranges"/>
+  <section name=".rel.debug_aranges"/>
+  <section name=".debug_pubnames"/>
+  <section name=".rel.debug_pubnames"/>
+  <section name=".debug_info"/>
+  <section name=".rel.debug_info"/>
+  <section name=".debug_abbrev"/>
+  <section name=".debug_line"/>
+  <section name=".rel.debug_line"/>
+  <section name=".debug_frame"/>
+  <section name=".rel.debug_frame"/>
+  <section name=".debug_str"/>
+  <section name=".debug_loc"/>
+  <section name=".rel.debug_loc"/>
+  <section name=".debug_ranges"/>
+  <section name=".rel.debug_ranges"/>
+  <section name=".note.GNU-stack"/>
+ </output>