MCLinker upstream commit 9628cfb76b5a.

Change-Id: I6d12c63bdae94299558dc1cf42b489bb98748851
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;