MCLinker upstream commit c27f2593f4e3.

Change-Id: I41325b6622594ebecd0a494a8d6d298c1c474ac1
diff --git a/include/mcld/ADT/SizeTraits.h b/include/mcld/ADT/SizeTraits.h
index 666d8c0..c8822cf 100644
--- a/include/mcld/ADT/SizeTraits.h
+++ b/include/mcld/ADT/SizeTraits.h
@@ -66,6 +66,16 @@
   return (pAddress + 0x3F) & (~0x3F);
 }
 
+#ifdef bswap16
+#undef bswap16
+#endif
+#ifdef bswap32
+#undef bswap32
+#endif
+#ifdef bswap64
+#undef bswap64
+#endif
+
 /// bswap16 - byte swap 16-bit version
 /// @ref binary utilities - elfcpp_swap
 inline uint16_t bswap16(uint16_t pData)
diff --git a/include/mcld/Config/Config.h b/include/mcld/Config/Config.h
index f604109..8cadee1 100644
--- a/include/mcld/Config/Config.h
+++ b/include/mcld/Config/Config.h
@@ -29,6 +29,7 @@
 #define MCLD_NUM_OF_INPUTS 32
 #define MCLD_SECTIONS_PER_INPUT 16
 #define MCLD_SYMBOLS_PER_INPUT 128
+#define MCLD_RELOCATIONS_PER_INPUT 1024
 
 #endif
 
diff --git a/include/mcld/Config/Config.h.in b/include/mcld/Config/Config.h.in
index f025393..7b55240 100644
--- a/include/mcld/Config/Config.h.in
+++ b/include/mcld/Config/Config.h.in
@@ -15,6 +15,7 @@
 #define MCLD_NUM_OF_INPUTS 32
 #define MCLD_SECTIONS_PER_INPUT 16
 #define MCLD_SYMBOLS_PER_INPUT 128
+#define MCLD_RELOCATIONS_PER_INPUT 1024
 
 #endif
 
diff --git a/include/mcld/Fragment/Fragment.h b/include/mcld/Fragment/Fragment.h
index b3d072d..3501341 100644
--- a/include/mcld/Fragment/Fragment.h
+++ b/include/mcld/Fragment/Fragment.h
@@ -33,7 +33,6 @@
     Alignment,
     Fillment,
     Region,
-    Relocation,
     Target,
     Stub,
     Null
@@ -48,7 +47,8 @@
 
   Type getKind() const { return m_Kind; }
 
-  SectionData *getParent() const { return m_pParent; }
+  const SectionData* getParent() const { return m_pParent; }
+  SectionData*       getParent()       { return m_pParent; }
 
   void setParent(SectionData *pValue) { m_pParent = pValue; }
 
diff --git a/include/mcld/Fragment/FragmentLinker.h b/include/mcld/Fragment/FragmentLinker.h
index 9fd70d0..17e80bd 100644
--- a/include/mcld/Fragment/FragmentLinker.h
+++ b/include/mcld/Fragment/FragmentLinker.h
@@ -65,17 +65,6 @@
   ~FragmentLinker();
 
   // ----- about symbols  ----- //
-  /// addDynSymbol - add a symbol and resolve it immediately
-  template<Input::Type FROM>
-  LDSymbol* addSymbol(const llvm::StringRef& pName,
-                      ResolveInfo::Type pType,
-                      ResolveInfo::Desc pDesc,
-                      ResolveInfo::Binding pBinding,
-                      ResolveInfo::SizeType pSize,
-                      LDSymbol::ValueType pValue,
-                      FragmentRef* pFragmentRef,
-                      ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
-
   /// defineSymbol - add a symbol
   /// defineSymbol define a output symbol
   ///
@@ -108,20 +97,6 @@
 
   bool finalizeSymbols();
 
-  // -----  relocations  ----- //
-  /// addRelocation - add a relocation entry in FragmentLinker (only for object file)
-  /// @param pType - the type of the relocation
-  /// @param pSym  - the symbol should be the symbol in the input file. FragmentLinker
-  ///                  computes the real applied address by the output symbol.
-  /// @param pSection - the input relocation section
-  /// @param pOffset - the offset of target section.
-  /// @param pAddend - the addend value for applying relocation
-  Relocation* addRelocation(Relocation::Type pType,
-                            LDSymbol& pSym,
-                            LDSection& pSection,
-                            uint32_t pOffset,
-                            Relocation::Address pAddend = 0);
-
   /// applyRelocations - apply all relocation enties.
   bool applyRelocations();
 
@@ -182,24 +157,6 @@
 
   bool shouldForceLocal(const ResolveInfo& pInfo) const;
 
-  LDSymbol* addSymbolFromDynObj(const llvm::StringRef& pName,
-                                ResolveInfo::Type pType,
-                                ResolveInfo::Desc pDesc,
-                                ResolveInfo::Binding pBinding,
-                                ResolveInfo::SizeType pSize,
-                                LDSymbol::ValueType pValue,
-                                FragmentRef* pFragmentRef,
-                                ResolveInfo::Visibility pVisibility);
-
-  LDSymbol* addSymbolFromObject(const llvm::StringRef& pName,
-                                ResolveInfo::Type pType,
-                                ResolveInfo::Desc pDesc,
-                                ResolveInfo::Binding pBinding,
-                                ResolveInfo::SizeType pSize,
-                                LDSymbol::ValueType pValue,
-                                FragmentRef* pFragmentRef,
-                                ResolveInfo::Visibility pVisibility);
-
   /// checkIsOutputPIC - return whether the output is position-independent,
   /// called by isOutputPIC()
   bool checkIsOutputPIC() const;
diff --git a/include/mcld/Fragment/FragmentLinker.tcc b/include/mcld/Fragment/FragmentLinker.tcc
index 884a597..cc3fad6 100644
--- a/include/mcld/Fragment/FragmentLinker.tcc
+++ b/include/mcld/Fragment/FragmentLinker.tcc
@@ -6,53 +6,6 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
-/// addSymbol - add a symbol and resolve it immediately
-template<Input::Type FROM>
-LDSymbol* FragmentLinker::addSymbol(const llvm::StringRef& pName,
-                                    ResolveInfo::Type pType,
-                                    ResolveInfo::Desc pDesc,
-                                    ResolveInfo::Binding pBinding,
-                                    ResolveInfo::SizeType pSize,
-                                    LDSymbol::ValueType pValue,
-                                    FragmentRef* pFragmentRef,
-                                    ResolveInfo::Visibility pVisibility)
-{
-  llvm::StringRef symbol_name = pName;
-  if (!getLDInfo().scripts().renameMap().empty() &&
-      ResolveInfo::Undefined == pDesc) {
-    // If the renameMap is not empty, some symbols should be renamed.
-    // --wrap and --portable defines the symbol rename map.
-    ScriptOptions::SymbolRenameMap::const_iterator renameSym
-                                = getLDInfo().scripts().renameMap().find(pName);
-    if (renameSym != getLDInfo().scripts().renameMap().end())
-      symbol_name = renameSym.getEntry()->value();
-  }
-
-  if (FROM == Input::DynObj)
-    return addSymbolFromDynObj(symbol_name,
-                               pType,
-                               pDesc,
-                               pBinding,
-                               pSize,
-                               pValue,
-                               pFragmentRef,
-                               pVisibility);
-
-  if (FROM == Input::Object)
-    return addSymbolFromObject(symbol_name,
-                               pType,
-                               pDesc,
-                               pBinding,
-                               pSize,
-                               pValue,
-                               pFragmentRef,
-                               pVisibility);
-
-  llvm::report_fatal_error("add a symbol from unknown file type.\n");
-  return NULL;
-}
-
 // defineSymbol - define a new symbol
 template<FragmentLinker::DefinePolicy POLICY,
          FragmentLinker::ResolvePolicy RESOLVE>
diff --git a/include/mcld/Fragment/Relocation.h b/include/mcld/Fragment/Relocation.h
index c6584c4..37b32f6 100644
--- a/include/mcld/Fragment/Relocation.h
+++ b/include/mcld/Fragment/Relocation.h
@@ -11,20 +11,24 @@
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
-#include <llvm/Support/DataTypes.h>
-
-#include <mcld/Fragment/Fragment.h>
+#include <mcld/Config/Config.h>
 #include <mcld/Fragment/FragmentRef.h>
+#include <mcld/Support/GCFactoryListTraits.h>
+
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/Support/DataTypes.h>
 
 namespace mcld {
 
 class ResolveInfo;
-class RelocationFactory;
+class Relocator;
 class LinkerConfig;
 
-class Relocation : public Fragment
+class Relocation : public llvm::ilist_node<Relocation>
 {
 friend class RelocationFactory;
+friend class GCFactoryListTraits<Relocation>;
+friend class Chunk<Relocation, MCLD_RELOCATIONS_PER_INPUT>;
 
 public:
   typedef uint64_t Address; // FIXME: use SizeTrait<T>::Address instead
@@ -33,14 +37,35 @@
   typedef uint8_t Type;
 
 private:
+  Relocation();
+
   Relocation(Type pType,
              FragmentRef* pTargetRef,
              Address pAddend,
              DWord pTargetData);
 
-public:
   ~Relocation();
 
+public:
+  /// Initialize - set up the relocation factory
+  static void SetUp(const LinkerConfig& pConfig);
+
+  /// Clear - Clean up the relocation factory
+  static void Clear();
+
+  /// Create - produce an empty relocation entry
+  static Relocation* Create();
+
+  /// Create - produce a relocation entry
+  /// @param pType    [in] the type of the relocation entry
+  /// @param pFragRef [in] the place to apply the relocation
+  /// @param pAddend  [in] the addend of the relocation entry
+  static Relocation* Create(Type pType, FragmentRef& pFragRef,
+                            Address pAddend = 0);
+
+  /// Destroy - destroy a relocation entry
+  static void Destroy(Relocation*& pRelocation);
+
   /// type - relocation type
   Type type() const
   { return m_Type; }
@@ -67,8 +92,7 @@
   const FragmentRef& targetRef() const { return m_TargetAddress; }
   FragmentRef&       targetRef()       { return m_TargetAddress; }
 
-
-  void apply(RelocationFactory& pRelocFactory);
+  void apply(Relocator& pRelocator);
 
   /// updateAddend - A relocation with a section symbol must update addend
   /// before reading its value.
@@ -81,13 +105,6 @@
 
   void setSymInfo(ResolveInfo* pSym);
 
-  // Relocation is a kind of Fragment with type of FT_Reloc
-  static bool classof(const Fragment *F)
-  { return F->getKind() == Fragment::Relocation; }
-
-  static bool classof(const Relocation *)
-  { return true; }
-
   size_t size() const;
 
 private:
diff --git a/include/mcld/GeneralOptions.h b/include/mcld/GeneralOptions.h
index 0b5c7a9..1468704 100644
--- a/include/mcld/GeneralOptions.h
+++ b/include/mcld/GeneralOptions.h
@@ -199,38 +199,56 @@
 
   // -n, --nmagic
   void setNMagic(bool pMagic = true)
-  { m_NMagic = pMagic; }
+  { m_bNMagic = pMagic; }
 
   bool nnagic() const
-  { return m_NMagic; }
+  { return m_bNMagic; }
 
   // -N, --omagic
   void setOMagic(bool pMagic = true)
-  { m_OMagic = pMagic; }
+  { m_bOMagic = pMagic; }
 
   bool omagic() const
-  { return m_OMagic; }
+  { return m_bOMagic; }
 
   // -S, --strip-debug
   void setStripDebug(bool pStripDebug = true)
-  { m_StripDebug = pStripDebug; }
+  { m_bStripDebug = pStripDebug; }
 
   bool stripDebug() const
-  { return m_StripDebug; }
+  { return m_bStripDebug; }
 
   // -E, --export-dynamic
   void setExportDynamic(bool pExportDynamic = true)
-  { m_ExportDynamic = pExportDynamic; }
+  { m_bExportDynamic = pExportDynamic; }
 
   bool exportDynamic() const
-  { return m_ExportDynamic; }
+  { return m_bExportDynamic; }
 
   // --warn-shared-textrel
   void setWarnSharedTextrel(bool pWarnSharedTextrel = true)
-  { m_WarnSharedTextrel = pWarnSharedTextrel; }
+  { m_bWarnSharedTextrel = pWarnSharedTextrel; }
 
   bool warnSharedTextrel() const
-  { return m_WarnSharedTextrel; }
+  { return m_bWarnSharedTextrel; }
+
+  void setBinaryInput(bool pBinaryInput = true)
+  { m_bBinaryInput = pBinaryInput; }
+
+  bool isBinaryInput() const
+  { return m_bBinaryInput; }
+
+  void setDefineCommon(bool pEnable = true)
+  { m_bDefineCommon = pEnable; }
+
+  bool isDefineCommon() const
+  { return m_bDefineCommon; }
+
+  void setFatalWarnings(bool pEnable = true)
+  { m_bFatalWarnings = pEnable; }
+
+  bool isFatalWarnings() const
+  { return m_bFatalWarnings; }
 
 private:
   enum status {
@@ -273,11 +291,14 @@
   bool m_bColor         : 1;   // --color[=true,false,auto]
   bool m_bAllowShlibUndefined : 1; // --[no-]allow-shlib-undefined and
   bool m_bCreateEhFrameHdr : 1;    // --eh-frame-hdr
-  bool m_NMagic; // -n, --nmagic
-  bool m_OMagic; // -N, --omagic
-  bool m_StripDebug; // -S, --strip-debug
-  bool m_ExportDynamic; //-E, --export-dynamic
-  bool m_WarnSharedTextrel; // --warn-shared-textrel
+  bool m_bNMagic : 1; // -n, --nmagic
+  bool m_bOMagic : 1; // -N, --omagic
+  bool m_bStripDebug : 1; // -S, --strip-debug
+  bool m_bExportDynamic :1; //-E, --export-dynamic
+  bool m_bWarnSharedTextrel : 1; // --warn-shared-textrel
+  bool m_bBinaryInput : 1; // -b [input-format], --format=[input-format]
+  bool m_bDefineCommon : 1; // -d, -dc, -dp
+  bool m_bFatalWarnings : 1; // --fatal-warnings
 };
 
 } // namespace of mcld
diff --git a/include/mcld/IRBuilder.h b/include/mcld/IRBuilder.h
index 1ebd153..3de292f 100644
--- a/include/mcld/IRBuilder.h
+++ b/include/mcld/IRBuilder.h
@@ -19,6 +19,7 @@
 
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/EhFrame.h>
+#include <mcld/LD/LDSymbol.h>
 
 #include <mcld/Fragment/Fragment.h>
 #include <mcld/Fragment/Relocation.h>
@@ -360,6 +361,68 @@
   /// @return Total size of the inserted fragments.
   static uint64_t AppendEhFrame(EhFrame::CIE& pCIE, EhFrame& pEhFrame);
 
+  /// AddSymbol - To add a symbol to the input file and module. The symbol is
+  /// resolved immediately.
+  ///
+  /// This is a general method for all kinds of symbol.
+  ///
+  /// @param [in, out] pInput   The input file. Either a relocatable or dynamic
+  ///                           object
+  /// @param [in]      pName    The name of the symbol
+  /// @param [in]      pType    What the symbol refers to
+  /// @param [in]      pDesc    { Undefined, Define, Common, Indirect }
+  /// @param [in]      pBind    { Global, Weak, Local, Absolute }
+  /// @param [in]      pSize    The size of the symbol. Bigger common symbols
+  ///                           overrides the smaller common symbols.
+  /// @param [in]      pValue   Common symbols' value are alignment constraints
+  ///                           Undefined symbols don't have value.
+  ///                           The rest symbols' value are relative section
+  ///                           offset.
+  /// @param [in]      pSection Absolute, undefined, common symbols do not have
+  ///                           pSection. Keep their pSection be NULL.
+  /// @oaram [in]      pVis     The visibility of the symbol
+  LDSymbol* AddSymbol(Input& pInput,
+                      const std::string& pName,
+                      ResolveInfo::Type pType,
+                      ResolveInfo::Desc pDesc,
+                      ResolveInfo::Binding pBind,
+                      ResolveInfo::SizeType pSize,
+                      LDSymbol::ValueType pValue = 0x0,
+                      LDSection* pSection = NULL,
+                      ResolveInfo::Visibility pVis = ResolveInfo::Default);
+
+  /// AddRelocation - To add a relocation entry
+  ///
+  /// @param [in] pSection The relocation section. pSection's link should point to
+  ///                      the target section.
+  /// @param [in] pType    The type of the relocation (target dependent)
+  /// @param [in] pSym     The symbol should be the symbol in the input file.
+  /// @param [in] pOffset  The offset of target section.
+  /// @param [in] pAddend  Tthe addend value for applying relocation
+  static Relocation* AddRelocation(LDSection& pSection,
+                                   Relocation::Type pType,
+                                   LDSymbol& pSym,
+                                   uint32_t pOffset,
+                                   Relocation::Address pAddend = 0);
+
+private:
+  LDSymbol* addSymbolFromObject(const std::string& pName,
+                                ResolveInfo::Type pType,
+                                ResolveInfo::Desc pDesc,
+                                ResolveInfo::Binding pBinding,
+                                ResolveInfo::SizeType pSize,
+                                LDSymbol::ValueType pValue,
+                                FragmentRef* pFragmentRef,
+                                ResolveInfo::Visibility pVisibility);
+
+  LDSymbol* addSymbolFromDynObj(const std::string& pName,
+                                ResolveInfo::Type pType,
+                                ResolveInfo::Desc pDesc,
+                                ResolveInfo::Binding pBinding,
+                                ResolveInfo::SizeType pSize,
+                                LDSymbol::ValueType pValue,
+                                ResolveInfo::Visibility pVisibility);
+
 private:
   Module& m_Module;
   const LinkerConfig& m_Config;
diff --git a/include/mcld/LD/BinaryReader.h b/include/mcld/LD/BinaryReader.h
new file mode 100644
index 0000000..e9c47db
--- /dev/null
+++ b/include/mcld/LD/BinaryReader.h
@@ -0,0 +1,45 @@
+//===- BinaryReader.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_Binary_READER_H
+#define MCLD_Binary_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/LDReader.h"
+#include <llvm/Support/system_error.h>
+
+namespace mcld {
+
+class Module;
+class Input;
+
+/** \class BinaryReader
+ *  \brief BinaryReader provides an common interface for different Binary
+ *  formats.
+ */
+class BinaryReader : public LDReader
+{
+protected:
+  BinaryReader()
+  { }
+
+public:
+  virtual ~BinaryReader()
+  { }
+
+  virtual bool isMyFormat(Input& pInput) const
+  { return true; }
+
+  virtual bool readBinary(Input& pFile) = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/BinaryWriter.h b/include/mcld/LD/BinaryWriter.h
new file mode 100644
index 0000000..d8133c4
--- /dev/null
+++ b/include/mcld/LD/BinaryWriter.h
@@ -0,0 +1,39 @@
+//===- BinaryWriter.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_BINARY_WRITER_INTERFACE_H
+#define MCLD_BINARY_WRITER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Support/system_error.h>
+
+namespace mcld {
+
+class Module;
+class MemoryArea;
+class GNULDBackend;
+
+/** \class BinaryWriter
+ *  \brief BinaryWriter provides a common interface for Binary file writers.
+ */
+class BinaryWriter
+{
+protected:
+  BinaryWriter(GNULDBackend& pBackend);
+
+public:
+  virtual ~BinaryWriter();
+
+  virtual llvm::error_code writeBinary(Module& pModule, MemoryArea& pOutput) = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/DiagRelocations.inc b/include/mcld/LD/DiagRelocations.inc
index 5d52dd8..7ada05f 100644
--- a/include/mcld/LD/DiagRelocations.inc
+++ b/include/mcld/LD/DiagRelocations.inc
@@ -1,3 +1,5 @@
+DIAG(reloc_factory_has_not_config, DiagnosticEngine::Fatal, "Please call mcld::Linker::config before creating relocations", "Please call mcld::Linker::config before creating relocations")
+DIAG(unsupported_bitclass, DiagnosticEngine::Fatal, "Only supports 32 and 64 bits targets. (Target: %0, bitclass:%1)", "Only supports 32 and 64 bits targets. (Target: %0, bitclass:%1)")
 DIAG(undefined_reference, DiagnosticEngine::Fatal, "undefined reference to `%0'", "In %1:%2, variable %0 must be defined")
 DIAG(non_pic_relocation, DiagnosticEngine::Error, "attempt to generate unsupported relocation type `%0' for symbol `%1', recompile with -fPIC", "attempt to generate unsupported relocation type `%0' for symbol `%1, recompile with -fPIC")
 DIAG(base_relocation, DiagnosticEngine::Fatal, "relocation type `%0' is not supported for symbol `%1'\nPlease report to %2", "relocation type `%0' is not supported for symbol `%1'\nPlease report to %2")
diff --git a/include/mcld/LD/ELFBinaryReader.h b/include/mcld/LD/ELFBinaryReader.h
new file mode 100644
index 0000000..fc3a067
--- /dev/null
+++ b/include/mcld/LD/ELFBinaryReader.h
@@ -0,0 +1,48 @@
+//===- ELFBinaryReader.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_Binary_READER_H
+#define MCLD_ELF_Binary_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/BinaryReader.h>
+
+namespace mcld {
+
+class Module;
+class Input;
+class IRBuilder;
+class GNULDBackend;
+class LinkerConfig;
+
+/** \lclass ELFBinaryReader
+ *  \brief ELFBinaryReader reads target-independent parts of Binary file
+ */
+class ELFBinaryReader : public BinaryReader
+{
+public:
+  ELFBinaryReader(GNULDBackend& pBackend,
+                  IRBuilder& pBuilder,
+                  const LinkerConfig& pConfig);
+
+  ~ELFBinaryReader();
+
+  virtual bool readBinary(Input& pInput);
+
+private:
+  GNULDBackend& m_Backend;
+  IRBuilder& m_Builder;
+  const LinkerConfig& m_Config;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFBinaryWriter.h b/include/mcld/LD/ELFBinaryWriter.h
new file mode 100644
index 0000000..593b54b
--- /dev/null
+++ b/include/mcld/LD/ELFBinaryWriter.h
@@ -0,0 +1,46 @@
+//===- ELFBinaryWriter.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_BINARY_WRITER_H
+#define MCLD_ELF_BINARY_WRITER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Support/system_error.h>
+#include <mcld/LD/BinaryWriter.h>
+#include <mcld/LD/ELFWriter.h>
+
+namespace mcld {
+
+class Module;
+class LinkerConfig;
+class MemoryArea;
+class GNULDBackend;
+
+/** \class ELFBinaryWriter
+ *  \brief ELFBinaryWriter writes the target-independent parts of Binary files.
+ *  ELFBinaryWriter reads a MCLDFile and writes into raw_ostream
+ *
+ */
+class ELFBinaryWriter : public BinaryWriter, protected ELFWriter
+{
+public:
+  ELFBinaryWriter(GNULDBackend& pBackend, const LinkerConfig& pConfig);
+
+  ~ELFBinaryWriter();
+
+  llvm::error_code writeBinary(Module& pModule, MemoryArea& pOutput);
+
+private:
+  const LinkerConfig& m_Config;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFDynObjReader.h b/include/mcld/LD/ELFDynObjReader.h
index b5d59a3..f6d2067 100644
--- a/include/mcld/LD/ELFDynObjReader.h
+++ b/include/mcld/LD/ELFDynObjReader.h
@@ -14,11 +14,11 @@
 #include <mcld/LD/DynObjReader.h>
 #include <llvm/Support/system_error.h>
 
-namespace mcld
-{
+namespace mcld {
 
 class Input;
-class FragmentLinker;
+class LinkerConfig;
+class IRBuilder;
 class GNULDBackend;
 class ELFReaderIF;
 
@@ -29,7 +29,9 @@
 class ELFDynObjReader : public DynObjReader
 {
 public:
-  ELFDynObjReader(GNULDBackend& pBackend, FragmentLinker& pLinker);
+  ELFDynObjReader(GNULDBackend& pBackend,
+                  IRBuilder& pBuilder,
+                  const LinkerConfig& pConfig);
   ~ELFDynObjReader();
 
   // -----  observers  ----- //
@@ -42,7 +44,7 @@
 
 private:
   ELFReaderIF *m_pELFReader;
-  FragmentLinker& m_Linker;
+  IRBuilder& m_Builder;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/ELFDynObjWriter.h b/include/mcld/LD/ELFDynObjWriter.h
index b5dd390..774943e 100644
--- a/include/mcld/LD/ELFDynObjWriter.h
+++ b/include/mcld/LD/ELFDynObjWriter.h
@@ -17,9 +17,9 @@
 namespace mcld {
 
 class Module;
+class LinkerConfig;
 class MemoryArea;
 class GNULDBackend;
-class FragmentLinker;
 
 /** \class ELFDynObjWriter
  *  \brief ELFDynObjWriter writes the dynamic sections.
@@ -30,13 +30,15 @@
   typedef ELFWriter::FileOffset FileOffset;
 
 public:
-  ELFDynObjWriter(GNULDBackend& pBackend, FragmentLinker& pLinker);
+  ELFDynObjWriter(GNULDBackend& pBackend,
+                  const LinkerConfig& pConfig);
+
   ~ELFDynObjWriter();
 
   llvm::error_code writeDynObj(Module& pModule, MemoryArea& pOutput);
 
 private:
-  FragmentLinker& m_Linker;
+  const LinkerConfig& m_Config;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/ELFExecWriter.h b/include/mcld/LD/ELFExecWriter.h
index dc731b9..ca69235 100644
--- a/include/mcld/LD/ELFExecWriter.h
+++ b/include/mcld/LD/ELFExecWriter.h
@@ -17,9 +17,9 @@
 namespace mcld {
 
 class Module;
+class LinkerConfig;
 class MemoryArea;
 class GNULDBackend;
-class FragmentLinker;
 
 /** \class ELFDynObjWriter
  *  \brief ELFDynObjWriter writes the dynamic sections.
@@ -30,13 +30,15 @@
   typedef ELFWriter::FileOffset FileOffset;
 
 public:
-  ELFExecWriter(GNULDBackend& pBackend, FragmentLinker& pLinker);
+  ELFExecWriter(GNULDBackend& pBackend,
+                const LinkerConfig& pConfig);
+
   ~ELFExecWriter();
 
   llvm::error_code writeExecutable(Module& pModule, MemoryArea& pOutput);
 
 private:
-  FragmentLinker& m_Linker;
+  const LinkerConfig& m_Config;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/ELFObjectReader.h b/include/mcld/LD/ELFObjectReader.h
index c1463fa..27e4489 100644
--- a/include/mcld/LD/ELFObjectReader.h
+++ b/include/mcld/LD/ELFObjectReader.h
@@ -19,10 +19,11 @@
 
 class Module;
 class Input;
-class FragmentLinker;
+class IRBuilder;
 class GNULDBackend;
 class ELFReaderIF;
 class EhFrameReader;
+class LinkerConfig;
 
 /** \lclass ELFObjectReader
  *  \brief ELFObjectReader reads target-independent parts of ELF object file
@@ -38,7 +39,9 @@
   typedef Flags<ReadFlagType> ReadFlag;
 
 public:
-  ELFObjectReader(GNULDBackend& pBackend, FragmentLinker& pLinker);
+  ELFObjectReader(GNULDBackend& pBackend,
+                  IRBuilder& pBuilder,
+                  const LinkerConfig& pConfig);
 
   ~ELFObjectReader();
 
@@ -60,9 +63,10 @@
 private:
   ELFReaderIF* m_pELFReader;
   EhFrameReader* m_pEhFrameReader;
-  FragmentLinker& m_Linker;
+  IRBuilder& m_Builder;
   ReadFlag m_ReadFlag;
   GNULDBackend& m_Backend;
+  const LinkerConfig& m_Config;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/ELFObjectWriter.h b/include/mcld/LD/ELFObjectWriter.h
index 31f7b12..28bbba8 100644
--- a/include/mcld/LD/ELFObjectWriter.h
+++ b/include/mcld/LD/ELFObjectWriter.h
@@ -11,15 +11,16 @@
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
-#include <llvm/Support/system_error.h>
 #include <mcld/LD/ObjectWriter.h>
 #include <mcld/LD/ELFWriter.h>
 
+#include <llvm/Support/system_error.h>
+
 namespace mcld {
 
 class Module;
+class LinkerConfig;
 class MemoryArea;
-class FragmentLinker;
 class GNULDBackend;
 
 /** \class ELFObjectWriter
@@ -30,14 +31,15 @@
 class ELFObjectWriter : public ObjectWriter, protected ELFWriter
 {
 public:
-  ELFObjectWriter(GNULDBackend& pBackend, FragmentLinker& pLinker);
+  ELFObjectWriter(GNULDBackend& pBackend,
+                  const LinkerConfig& pConfig);
 
   ~ELFObjectWriter();
 
   llvm::error_code writeObject(Module& pModule, MemoryArea& pOutput);
 
 private:
-  FragmentLinker& m_Linker;
+  const LinkerConfig& m_Config;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/ELFReader.h b/include/mcld/LD/ELFReader.h
index 941c8cd..146a00a 100644
--- a/include/mcld/LD/ELFReader.h
+++ b/include/mcld/LD/ELFReader.h
@@ -29,8 +29,8 @@
 namespace mcld {
 
 class Module;
+class IRBuilder;
 class FragmentRef;
-class FragmentLinker;
 class SectionData;
 class LDSection;
 
@@ -74,7 +74,7 @@
 
   /// readSymbols - read ELF symbols and create LDSymbol
   virtual bool readSymbols(Input& pInput,
-                           FragmentLinker& pLinker,
+                           IRBuilder& pBuilder,
                            const MemoryRegion& pRegion,
                            const char* StrTab) const = 0;
 
@@ -86,13 +86,11 @@
 
   /// readRela - read ELF rela and create Relocation
   virtual bool readRela(Input& pInput,
-                        FragmentLinker& pLinker,
                         LDSection& pSection,
                         const MemoryRegion& pRegion) const = 0;
 
   /// readRel - read ELF rel and create Relocation
   virtual bool readRel(Input& pInput,
-                       FragmentLinker& pLinker,
                        LDSection& pSection,
                        const MemoryRegion& pRegion) const = 0;
 
@@ -181,9 +179,9 @@
 
   /// readSymbols - read ELF symbols and create LDSymbol
   bool readSymbols(Input& pInput,
-                          FragmentLinker& pLinker,
-                          const MemoryRegion& pRegion,
-                          const char* StrTab) const;
+                   IRBuilder& pBuilder,
+                   const MemoryRegion& pRegion,
+                   const char* StrTab) const;
 
   /// readSignature - read a symbol from the given Input and index in symtab
   /// This is used to get the signature of a group section.
@@ -193,13 +191,11 @@
 
   /// readRela - read ELF rela and create Relocation
   bool readRela(Input& pInput,
-                FragmentLinker& pLinker,
                 LDSection& pSection,
                 const MemoryRegion& pRegion) const;
 
   /// readRel - read ELF rel and create Relocation
   bool readRel(Input& pInput,
-               FragmentLinker& pLinker,
                LDSection& pSection,
                const MemoryRegion& pRegion) const;
 
diff --git a/include/mcld/LD/Layout.h b/include/mcld/LD/Layout.h
deleted file mode 100644
index 7380b20..0000000
--- a/include/mcld/LD/Layout.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===- Layout.h -----------------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LD_LAYOUT_H
-#define MCLD_LD_LAYOUT_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-
-#include <vector>
-#include <map>
-
-#include <llvm/ADT/ilist.h>
-#include <llvm/ADT/ilist_node.h>
-#include <llvm/ADT/DenseMap.h>
-
-#include <mcld/LD/LDSection.h>
-#include <mcld/LD/SectionData.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/Support/GCFactory.h>
-
-namespace mcld {
-
-class Module;
-class FragmentRef;
-class FragmentLinker;
-class TargetLDBackend;
-
-/** \class Layout
- *  \brief Layout maintains the mapping between sections and fragments.
- *
- *  FragmentLinker is a fragment-based linker. But readers and target backends
- *  still need section information. Layout is used to maintain the mapping
- *  between sections and fragments. Layout helps readers and target backends
- *  get the input or output section information from a fragment.
- */
-class Layout
-{
-public:
-  // -----  modifiers  ----- //
-  bool layout(Module& pModule,
-              const TargetLDBackend& pBackend,
-              const LinkerConfig& pConfig);
-
-private:
-  /// sortSectionOrder - perform sorting on m_SectionOrder to get final layout
-  /// ordering
-  void sortSectionOrder(const TargetLDBackend& pBackend,
-                        const LinkerConfig& pConfig);
-
-private:
-  typedef std::vector<LDSection*> SectionOrder;
-
-private:
-  /// a vector to describe the order of sections
-  SectionOrder m_SectionOrder;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/LD/RelocData.h b/include/mcld/LD/RelocData.h
index 6061544..b53151a 100644
--- a/include/mcld/LD/RelocData.h
+++ b/include/mcld/LD/RelocData.h
@@ -12,81 +12,85 @@
 #include <gtest.h>
 #endif
 
-#include <llvm/ADT/ilist.h>
-#include <llvm/ADT/ilist_node.h>
-#include <llvm/Support/DataTypes.h>
-
 #include <mcld/Config/Config.h>
-#include <mcld/Fragment/Fragment.h>
+#include <mcld/Fragment/Relocation.h>
 #include <mcld/Support/Allocators.h>
 #include <mcld/Support/GCFactoryListTraits.h>
 
+#include <llvm/ADT/ilist.h>
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/Support/DataTypes.h>
 
 namespace mcld {
 
 class LDSection;
 
 /** \class RelocData
- *  \brief RelocData is the special SectionData to store Relocation fragments.
+ *  \brief RelocData stores Relocation.
+ *
  *  Since Relocations are created by GCFactory, we use GCFactoryListTraits for the
- *  FragmentList here to avoid iplist to delete Relocations.
+ *  RelocationList here to avoid iplist to delete Relocations.
  */
 class RelocData
 {
 private:
+  friend class Chunk<RelocData, MCLD_SECTIONS_PER_INPUT>;
+
   RelocData();
-  explicit RelocData(const LDSection &pSection);
+  explicit RelocData(LDSection &pSection);
 
   RelocData(const RelocData &);            // DO NOT IMPLEMENT
   RelocData& operator=(const RelocData &); // DO NOT IMPLEMENT
 
 public:
-  typedef llvm::iplist<Fragment,
-                       GCFactoryListTraits<Fragment> > FragmentListType;
+  typedef llvm::iplist<Relocation,
+                       GCFactoryListTraits<Relocation> > RelocationListType;
 
-  typedef FragmentListType::reference reference;
-  typedef FragmentListType::const_reference const_reference;
+  typedef RelocationListType::reference reference;
+  typedef RelocationListType::const_reference const_reference;
 
-  typedef FragmentListType::iterator iterator;
-  typedef FragmentListType::const_iterator const_iterator;
+  typedef RelocationListType::iterator iterator;
+  typedef RelocationListType::const_iterator const_iterator;
 
-  typedef FragmentListType::reverse_iterator reverse_iterator;
-  typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
+  typedef RelocationListType::reverse_iterator reverse_iterator;
+  typedef RelocationListType::const_reverse_iterator const_reverse_iterator;
 
 public:
-  static RelocData* Create(const LDSection& pSection);
-
-  static RelocData* Create();
+  static RelocData* Create(LDSection& pSection);
 
   static void Destroy(RelocData*& pSection);
 
-  const LDSection &getSection() const
-  { assert(NULL != m_pSection ); return *m_pSection; }
+  static void Clear();
 
-  FragmentListType &getFragmentList() { return m_Fragments; }
-  const FragmentListType &getFragmentList() const { return m_Fragments; }
+  const LDSection& getSection() const { return *m_pSection; }
+  LDSection&       getSection()       { return *m_pSection; }
 
-  size_t size() const { return m_Fragments.size(); }
+  const RelocationListType& getRelocationList() const { return m_Relocations; }
+  RelocationListType&       getRelocationList()       { return m_Relocations; }
 
-  bool empty() const { return m_Fragments.empty(); }
+  size_t size() const { return m_Relocations.size(); }
 
-  reference              front ()       { return m_Fragments.front();  }
-  const_reference        front () const { return m_Fragments.front();  }
-  reference              back  ()       { return m_Fragments.back();   }
-  const_reference        back  () const { return m_Fragments.back();   }
+  bool empty() const { return m_Relocations.empty(); }
 
-  const_iterator         begin () const { return m_Fragments.begin();  }
-  iterator               begin ()       { return m_Fragments.begin();  }
-  const_iterator         end   () const { return m_Fragments.end();    }
-  iterator               end   ()       { return m_Fragments.end();    }
-  const_reverse_iterator rbegin() const { return m_Fragments.rbegin(); }
-  reverse_iterator       rbegin()       { return m_Fragments.rbegin(); }
-  const_reverse_iterator rend  () const { return m_Fragments.rend();   }
-  reverse_iterator       rend  ()       { return m_Fragments.rend();   }
+  RelocData& append(Relocation& pRelocation);
+
+  reference              front ()       { return m_Relocations.front();  }
+  const_reference        front () const { return m_Relocations.front();  }
+  reference              back  ()       { return m_Relocations.back();   }
+  const_reference        back  () const { return m_Relocations.back();   }
+
+  const_iterator         begin () const { return m_Relocations.begin();  }
+  iterator               begin ()       { return m_Relocations.begin();  }
+  const_iterator         end   () const { return m_Relocations.end();    }
+  iterator               end   ()       { return m_Relocations.end();    }
+  const_reverse_iterator rbegin() const { return m_Relocations.rbegin(); }
+  reverse_iterator       rbegin()       { return m_Relocations.rbegin(); }
+  const_reverse_iterator rend  () const { return m_Relocations.rend();   }
+  reverse_iterator       rend  ()       { return m_Relocations.rend();   }
 
 private:
-  FragmentListType m_Fragments;
-  const LDSection* m_pSection;
+  RelocationListType m_Relocations;
+  LDSection* m_pSection;
 
 };
 
diff --git a/include/mcld/LD/RelocationFactory.h b/include/mcld/LD/RelocationFactory.h
index c9f0d64..bd590a5 100644
--- a/include/mcld/LD/RelocationFactory.h
+++ b/include/mcld/LD/RelocationFactory.h
@@ -11,18 +11,13 @@
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
+#include <mcld/Config/Config.h>
 #include <mcld/Support/GCFactory.h>
 #include <mcld/Fragment/Relocation.h>
 
 namespace mcld {
 
-class LDSymbol;
-class ResolveInfo;
 class FragmentRef;
-class FragmentLinker;
-class Layout;
-class GOT;
-class TargetLDBackend;
 class LinkerConfig;
 
 /** \class RelocationFactory
@@ -30,7 +25,7 @@
  *  relocation
  *
  */
-class RelocationFactory : public GCFactory<Relocation, 0>
+class RelocationFactory : public GCFactory<Relocation, MCLD_RELOCATIONS_PER_INPUT>
 {
 public:
   typedef Relocation::Type Type;
@@ -38,21 +33,10 @@
   typedef Relocation::DWord DWord;
   typedef Relocation::SWord SWord;
 
-  enum Result {
-    OK,
-    BadReloc,
-    Overflow,
-    Unsupport,
-    Unknown
-  };
-
 public:
-  explicit RelocationFactory(size_t pNum);
+  explicit RelocationFactory();
 
-  virtual ~RelocationFactory();
-
-  /// apply - general apply function
-  virtual Result applyRelocation(Relocation& pRelocation) = 0;
+  void setConfig(const LinkerConfig& pConfig);
 
   // ----- production ----- //
   /// produce - produce a relocation entry
@@ -69,22 +53,8 @@
 
   void destroy(Relocation* pRelocation);
 
-  void setFragmentLinker(const FragmentLinker& pLinker);
-
-  // ------ observers -----//
-  const FragmentLinker& getFragmentLinker() const;
-
-  bool hasFragmentLinker() const;
-
-  virtual TargetLDBackend& getTarget() = 0;
-
-  virtual const TargetLDBackend& getTarget() const = 0;
-
-  virtual const char* getName(Type pType) const = 0;
-
 private:
-  const FragmentLinker* m_pLinker;
-
+  const LinkerConfig* m_pConfig;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/LD/Relocator.h b/include/mcld/LD/Relocator.h
new file mode 100644
index 0000000..6fd431e
--- /dev/null
+++ b/include/mcld/LD/Relocator.h
@@ -0,0 +1,76 @@
+//===- Relocator.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_RELOCATOR_H
+#define MCLD_RELOCATOR_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Fragment/Relocation.h>
+
+namespace mcld
+{
+
+class FragmentLinker;
+class TargetLDBackend;
+
+/** \class Relocator
+ *  \brief Relocator provides the interface of performing relocations
+ */
+class Relocator
+{
+public:
+  typedef Relocation::Type Type;
+  typedef Relocation::Address Address;
+  typedef Relocation::DWord DWord;
+  typedef Relocation::SWord SWord;
+
+public:
+  enum Result {
+    OK,
+    BadReloc,
+    Overflow,
+    Unsupport,
+    Unknown
+  };
+
+public:
+  virtual ~Relocator() {}
+
+  /// apply - general apply function
+  virtual Result applyRelocation(Relocation& pRelocation) = 0;
+
+  void setFragmentLinker(const FragmentLinker& pLinker)
+  { m_pLinker = &pLinker; }
+
+  // ------ observers -----//
+  const FragmentLinker& getFragmentLinker() const
+  {
+    assert(NULL != m_pLinker);
+    return *m_pLinker;
+  }
+
+  bool hasFragmentLinker() const
+  { return (NULL != m_pLinker); }
+
+  virtual TargetLDBackend& getTarget() = 0;
+
+  virtual const TargetLDBackend& getTarget() const = 0;
+
+  virtual const char* getName(Type pType) const = 0;
+
+private:
+  const FragmentLinker* m_pLinker;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ResolveInfo.h b/include/mcld/LD/ResolveInfo.h
index 2cff57e..aaf74e1 100644
--- a/include/mcld/LD/ResolveInfo.h
+++ b/include/mcld/LD/ResolveInfo.h
@@ -26,7 +26,7 @@
  *  - Desc - Defined, Reference, Common or Indirect
  *  - Binding - Global, Local, Weak
  *  - IsDyn - appear in dynamic objects or regular objects
- *  - Type - what the symbol points to
+ *  - Type - what the symbol refers to
  *  - Size  - the size of the symbol point to
  *  - Value - the pointer to another LDSymbol
  *  In order to save the memory and speed up the performance, FragmentLinker uses
@@ -37,6 +37,7 @@
 class ResolveInfo
 {
 friend class FragmentLinker;
+friend class IRBuilder;
 public:
   typedef uint64_t SizeType;
 
diff --git a/include/mcld/LD/SectionData.h b/include/mcld/LD/SectionData.h
index 316d92f..4f58afa 100644
--- a/include/mcld/LD/SectionData.h
+++ b/include/mcld/LD/SectionData.h
@@ -55,6 +55,8 @@
 
   static void Destroy(SectionData*& pSection);
 
+  static void Clear();
+
   const LDSection& getSection() const { return *m_pSection; }
   LDSection&       getSection()       { return *m_pSection; }
 
diff --git a/include/mcld/LD/StubFactory.h b/include/mcld/LD/StubFactory.h
index 00a65ec..b38a96f 100644
--- a/include/mcld/LD/StubFactory.h
+++ b/include/mcld/LD/StubFactory.h
@@ -6,7 +6,6 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
 #ifndef MCLD_LD_STUB_FACTORY_H
 #define MCLD_LD_STUB_FACTORY_H
 #ifdef ENABLE_UNITTEST
@@ -16,12 +15,10 @@
 #include <llvm/Support/DataTypes.h>
 #include <vector>
 
-namespace mcld
-{
+namespace mcld {
 
 class Stub;
 class Relocation;
-class RelocationFactory;
 class BranchIslandFactory;
 class FragmentLinker;
 
@@ -32,8 +29,6 @@
 class StubFactory
 {
 public:
-  StubFactory();
-
   ~StubFactory();
 
   /// addPrototype - register a stub prototype
@@ -43,7 +38,6 @@
   Stub* create(Relocation& pReloc,
                uint64_t pTargetSymValue,
                FragmentLinker& pLinker,
-               RelocationFactory& pRelocFactory,
                BranchIslandFactory& pBRIslandFactory);
 
 private:
diff --git a/include/mcld/LinkerConfig.h b/include/mcld/LinkerConfig.h
index 7d52819..9e70ecf 100644
--- a/include/mcld/LinkerConfig.h
+++ b/include/mcld/LinkerConfig.h
@@ -16,6 +16,7 @@
 
 #include <mcld/GeneralOptions.h>
 #include <mcld/ScriptOptions.h>
+#include <mcld/TargetOptions.h>
 #include <mcld/BitcodeOption.h>
 #include <mcld/AttributeOption.h>
 #include <mcld/Support/Path.h>
@@ -39,7 +40,8 @@
     Object,
     DynObj,
     Exec,
-    External
+    External,
+    Binary
   };
 
 public:
@@ -55,6 +57,9 @@
   const ScriptOptions&  scripts() const { return m_Scripts; }
   ScriptOptions&        scripts()       { return m_Scripts; }
 
+  const TargetOptions&  targets() const { return m_Targets; }
+  TargetOptions&        targets()       { return m_Targets; }
+
   const BitcodeOption&  bitcode() const { return m_Bitcode; }
   BitcodeOption&        bitcode()       { return m_Bitcode; }
 
@@ -65,22 +70,16 @@
 
   void setCodeGenType(CodeGenType pType) { m_CodeGenType = pType; }
 
-  const llvm::Triple& triple() const { return m_Triple; }
-
-  void setTriple(const std::string& pTriple);
-
-  void setTriple(const llvm::Triple& pTriple);
-
   static const char* version();
 
 private:
   // -----  General Options  ----- //
   GeneralOptions m_Options;
   ScriptOptions m_Scripts;
+  TargetOptions m_Targets;
   BitcodeOption m_Bitcode;
   AttributeOption m_Attribute;
 
-  llvm::Triple m_Triple;
   CodeGenType m_CodeGenType;
 };
 
diff --git a/include/mcld/Object/ObjectLinker.h b/include/mcld/Object/ObjectLinker.h
index 4d9f642..515bc58 100644
--- a/include/mcld/Object/ObjectLinker.h
+++ b/include/mcld/Object/ObjectLinker.h
@@ -22,7 +22,7 @@
 
 class Module;
 class LinkerConfig;
-class InputBuilder;
+class IRBuilder;
 class FragmentLinker;
 class TargetLDBackend;
 class MemoryArea;
@@ -31,9 +31,11 @@
 class DynObjReader;
 class ArchiveReader;
 class GroupReader;
+class BinaryReader;
 class ObjectWriter;
 class DynObjWriter;
 class ExecWriter;
+class BinaryWriter;
 
 /** \class ObjectLinker
  *  \brief ObjectLinker prepares parameters for FragmentLinker.
@@ -43,7 +45,7 @@
 public:
   ObjectLinker(const LinkerConfig& pConfig,
                Module& pModule,
-               InputBuilder& pInputBuilder,
+               IRBuilder& pBuilder,
                TargetLDBackend& pLDBackend);
 
   ~ObjectLinker();
@@ -132,8 +134,11 @@
   const ArchiveReader* getArchiveReader() const { return m_pArchiveReader; }
   ArchiveReader*       getArchiveReader()       { return m_pArchiveReader; }
 
-  const GroupReader* getGroupReader() const { return m_pGroupReader; }
-  GroupReader*       getGroupReader()       { return m_pGroupReader; }
+  const GroupReader*   getGroupReader  () const { return m_pGroupReader;   }
+  GroupReader*         getGroupReader  ()       { return m_pGroupReader;   }
+
+  const BinaryReader*  getBinaryReader () const { return m_pBinaryReader;  }
+  BinaryReader*        getBinaryReader ()       { return m_pBinaryReader;  }
 
   const ObjectWriter*  getObjectWriter () const { return m_pObjectWriter;  }
   ObjectWriter*        getObjectWriter ()       { return m_pObjectWriter;  }
@@ -144,24 +149,28 @@
   const ExecWriter*    getExecWriter   () const { return m_pExecWriter;    }
   ExecWriter*          getExecWriter   ()       { return m_pExecWriter;    }
 
+  const BinaryWriter*  getBinaryWriter () const { return m_pBinaryWriter;  }
+  BinaryWriter*        getBinaryWriter ()       { return m_pBinaryWriter;  }
+
 private:
   const LinkerConfig& m_Config;
   Module& m_Module;
 
-  // we pass in InputBuilder for Archive and GroupReader.
-  InputBuilder& m_InputBuilder; 
+  IRBuilder& m_Builder; 
 
   FragmentLinker* m_pLinker;
   TargetLDBackend &m_LDBackend;
 
   // -----  readers and writers  ----- //
-  ObjectReader* m_pObjectReader;
-  DynObjReader* m_pDynObjReader;
+  ObjectReader*  m_pObjectReader;
+  DynObjReader*  m_pDynObjReader;
   ArchiveReader* m_pArchiveReader;
-  ObjectWriter* m_pObjectWriter;
-  DynObjWriter* m_pDynObjWriter;
-  ExecWriter* m_pExecWriter;
-  GroupReader* m_pGroupReader;
+  GroupReader*   m_pGroupReader;
+  BinaryReader*  m_pBinaryReader;
+  ObjectWriter*  m_pObjectWriter;
+  DynObjWriter*  m_pDynObjWriter;
+  ExecWriter*    m_pExecWriter;
+  BinaryWriter*  m_pBinaryWriter;
 };
 
 } // end namespace mcld
diff --git a/include/mcld/Support/CommandLine.h b/include/mcld/Support/CommandLine.h
index 6a90309..2bb9904 100644
--- a/include/mcld/Support/CommandLine.h
+++ b/include/mcld/Support/CommandLine.h
@@ -11,18 +11,42 @@
 #ifdef ENABLE_UNITTEST
 #include <gtest.h>
 #endif
-#include <llvm/ADT/StringRef.h>
-#include <llvm/Support/CommandLine.h>
 #include <mcld/Support/FileSystem.h>
-#include <mcld/MC/MCLDDirectory.h>
 #include <mcld/MC/ZOption.h>
 
-//--------------------------------------------------
-// parser<mcld::sys::fs::Path>
-//
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/CommandLine.h>
+
+#include <string>
+
 namespace llvm {
 namespace cl {
 
+//===----------------------------------------------------------------------===//
+// SearchDirParser
+//===----------------------------------------------------------------------===//
+class SearchDirParser : public llvm::cl::basic_parser<std::string>
+{
+public:
+  // parse - Return true on error.
+  bool parse(Option &pOption,
+             StringRef pArgName,
+             StringRef pArg,
+             std::string &pValue);
+
+  const char *getValueName() const { return "searchdir"; }
+
+  void printOptionDiff(const Option &pOption,
+                       StringRef pValue,
+                       OptVal pDefault,
+                       size_t pGlobalWidth) const;
+
+  void anchor();
+};
+
+//===----------------------------------------------------------------------===//
+// parser<mcld::sys::fs::Path>
+//===----------------------------------------------------------------------===//
 template<>
 class parser<mcld::sys::fs::Path> : public basic_parser<mcld::sys::fs::Path>
 {
@@ -40,26 +64,9 @@
   virtual void anchor();
 };
 
-//--------------------------------------------------
-// parser<mcld::MCLDDirectory>
-//
-template<>
-class parser<mcld::MCLDDirectory> : public llvm::cl::basic_parser<mcld::MCLDDirectory>
-{
-public:
-  bool parse(Option &O, StringRef ArgName, StringRef Arg, mcld::MCLDDirectory &Val);
-
-  virtual const char *getValueName() const { return "directory"; }
-  void printOptionDiff(const Option &O,
-                       const mcld::MCLDDirectory &V,
-                       OptVal Default,
-                       size_t GlobalWidth) const;
-  virtual void anchor();
-};
-
-//--------------------------------------------------
+//===----------------------------------------------------------------------===//
 // parser<mcld::ZOption>
-//
+//===----------------------------------------------------------------------===//
 template<>
 class parser<mcld::ZOption> : public llvm::cl::basic_parser<mcld::ZOption>
 {
diff --git a/include/mcld/Support/GCFactoryListTraits.h b/include/mcld/Support/GCFactoryListTraits.h
index 8a768c8..986f6f6 100644
--- a/include/mcld/Support/GCFactoryListTraits.h
+++ b/include/mcld/Support/GCFactoryListTraits.h
@@ -17,8 +17,7 @@
 
 #include <assert.h>
 
-namespace mcld
-{
+namespace mcld {
 
 /** \class GCFactoryListTraits
  *  \brief GCFactoryListTraits provides trait class for llvm::iplist when
diff --git a/include/mcld/Target/ELFDynamic.h b/include/mcld/Target/ELFDynamic.h
index 2298bfd..7102226 100644
--- a/include/mcld/Target/ELFDynamic.h
+++ b/include/mcld/Target/ELFDynamic.h
@@ -17,11 +17,10 @@
 #include <vector>
 #include <cstring>
 
-namespace mcld
-{
+namespace mcld {
 
-class GNULDBackend;
 class ELFFileFormat;
+class GNULDBackend;
 class LinkerConfig;
 class MemoryRegion;
 
@@ -105,7 +104,7 @@
   typedef EntryListType::const_iterator const_iterator;
 
 public:
-  ELFDynamic(const GNULDBackend& pParent);
+  ELFDynamic(const GNULDBackend& pBackend, const LinkerConfig& pConfig);
 
   virtual ~ELFDynamic();
 
@@ -116,29 +115,21 @@
   size_t numOfBytes() const;
 
   /// reserveEntries - reserve entries
-  void reserveEntries(const LinkerConfig& pConfig,
-                      const ELFFileFormat& pFormat);
+  void reserveEntries(const ELFFileFormat& pFormat);
 
   /// reserveNeedEntry - reserve on DT_NEED entry.
   void reserveNeedEntry();
 
   /// applyEntries - apply entries
-  void applyEntries(const LinkerConfig& pConfig,
-                    const ELFFileFormat& pFormat);
+  void applyEntries(const ELFFileFormat& pFormat);
 
   void applySoname(uint64_t pStrTabIdx);
 
-  iterator needBegin()
-  { return m_NeedList.begin(); }
+  const_iterator needBegin() const { return m_NeedList.begin(); }
+  iterator       needBegin()       { return m_NeedList.begin(); }
 
-  iterator needEnd()
-  { return m_NeedList.end(); }
-
-  const_iterator needBegin() const
-  { return m_NeedList.begin(); }
-
-  const_iterator needEnd() const
-  { return m_NeedList.end(); }
+  const_iterator needEnd() const { return m_NeedList.end(); }
+  iterator       needEnd()       { return m_NeedList.end(); }
 
   /// emit
   void emit(const LDSection& pSection, MemoryRegion& pRegion) const;
@@ -162,6 +153,7 @@
   EntryListType m_NeedList;
   elf_dynamic::EntryIF* m_pEntryFactory;
   const GNULDBackend& m_Backend;
+  const LinkerConfig& m_Config;
 
   // The entry reserved and the entry being applied are not must matched.
   // For better performance, we use a simple counter and apply entry one-by-one
diff --git a/include/mcld/Target/GNUInfo.h b/include/mcld/Target/GNUInfo.h
new file mode 100644
index 0000000..f918431
--- /dev/null
+++ b/include/mcld/Target/GNUInfo.h
@@ -0,0 +1,48 @@
+//===- GNUInfo.h ----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_GNU_INFO_H
+#define MCLD_TARGET_GNU_INFO_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/Triple.h>
+#include <llvm/Support/ELF.h>
+
+namespace mcld {
+
+/** \class GNUInfo
+ *  \brief GNUInfo records ELF-dependent and target-dependnet data fields
+ */
+class GNUInfo
+{
+public:
+  GNUInfo(const llvm::Triple& pTriple);
+
+  virtual ~GNUInfo() { }
+
+  /// ELFVersion - the value of e_ident[EI_VERSION]
+  virtual uint8_t ELFVersion() const { return llvm::ELF::EV_CURRENT; }
+
+  /// The return value of machine() it the same as e_machine in the ELF header
+  virtual uint32_t machine() const = 0;
+
+  /// OSABI - the value of e_ident[EI_OSABI]
+  uint8_t OSABI() const;
+
+  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
+  uint8_t ABIVersion() const { return 0x0; }
+
+private:
+  const llvm::Triple& m_Triple;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/GNULDBackend.h b/include/mcld/Target/GNULDBackend.h
index 4623e33..d20b8ac 100644
--- a/include/mcld/Target/GNULDBackend.h
+++ b/include/mcld/Target/GNULDBackend.h
@@ -22,12 +22,15 @@
 #include <mcld/LD/GNUArchiveReader.h>
 #include <mcld/LD/ELFObjectReader.h>
 #include <mcld/LD/ELFDynObjReader.h>
+#include <mcld/LD/ELFBinaryReader.h>
 #include <mcld/LD/ELFDynObjWriter.h>
 #include <mcld/LD/ELFExecWriter.h>
 #include <mcld/LD/ELFObjectWriter.h>
+#include <mcld/LD/ELFBinaryWriter.h>
 #include <mcld/LD/ELFSegment.h>
 #include <mcld/LD/ELFSegmentFactory.h>
 #include <mcld/Target/ELFDynamic.h>
+#include <mcld/Target/GNUInfo.h>
 
 #include <mcld/Support/GCFactory.h>
 #include <mcld/Module.h>
@@ -36,11 +39,13 @@
 
 class Module;
 class LinkerConfig;
+class IRBuilder;
 class Layout;
 class EhFrame;
 class EhFrameHdr;
 class BranchIslandFactory;
 class StubFactory;
+class GNUInfo;
 
 /** \class GNULDBackend
  *  \brief GNULDBackend provides a common interface for all GNU Unix-OS
@@ -49,18 +54,20 @@
 class GNULDBackend : public TargetLDBackend
 {
 protected:
-  GNULDBackend(const LinkerConfig& pConfig);
+  GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
 
 public:
   virtual ~GNULDBackend();
 
   // -----  readers/writers  ----- //
   GNUArchiveReader* createArchiveReader(Module& pModule);
-  ELFObjectReader* createObjectReader(FragmentLinker& pLinker);
-  ELFDynObjReader* createDynObjReader(FragmentLinker& pLinker);
-  ELFObjectWriter* createObjectWriter(FragmentLinker& pLinker);
-  ELFDynObjWriter* createDynObjWriter(FragmentLinker& pLinker);
-  ELFExecWriter*   createExecWriter(FragmentLinker& pLinker);
+  ELFObjectReader* createObjectReader(IRBuilder& pBuilder);
+  ELFDynObjReader* createDynObjReader(IRBuilder& pBuilder);
+  ELFBinaryReader* createBinaryReader(IRBuilder& pBuilder);
+  ELFObjectWriter* createObjectWriter();
+  ELFDynObjWriter* createDynObjWriter();
+  ELFExecWriter*   createExecWriter();
+  ELFBinaryWriter* createBinaryWriter();
 
   // -----  output sections  ----- //
   /// initStdSections - initialize standard sections of the output file.
@@ -100,18 +107,8 @@
 
   size_t sectionStartOffset() const;
 
-  /// The return value of machine() it the same as e_machine in the ELF header*/
-  virtual uint32_t machine() const = 0;
-
-  /// ELFVersion - the value of e_ident[EI_VERSION]
-  virtual uint8_t ELFVersion() const
-  { return llvm::ELF::EV_CURRENT; }
-
-  /// OSABI - the value of e_ident[EI_OSABI]
-  virtual uint8_t OSABI() const = 0;
-
-  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
-  virtual uint8_t ABIVersion() const = 0;
+  const GNUInfo& getInfo() const { return *m_pInfo; }
+  GNUInfo&       getInfo()       { return *m_pInfo; }
 
   /// flags - the value of ElfXX_Ehdr::e_flags
   virtual uint64_t flags() const = 0;
@@ -364,6 +361,9 @@
                                Module::iterator pSectBegin,
                                Module::iterator pSectEnd);
 
+  /// layout - layout method
+  void layout(Module& pModule, FragmentLinker& pLinker);
+
   /// preLayout - Backend can do any needed modification before layout
   void preLayout(Module& pModule, FragmentLinker& pLinker);
 
@@ -436,6 +436,14 @@
     SHO_STRTAB               // .strtab
   };
 
+  typedef std::pair<LDSection*, unsigned int> SHOEntry;
+
+  struct SHOCompare
+  {
+    bool operator()(const SHOEntry& X, const SHOEntry& Y) const
+    { return X.second < Y.second; }
+  };
+
   struct SymCompare
   {
     bool operator()(const LDSymbol* X, const LDSymbol* Y) const
@@ -465,6 +473,9 @@
   ELFExecFileFormat*   m_pExecFileFormat;
   ELFObjectFileFormat* m_pObjectFileFormat;
 
+  // GNUInfo
+  GNUInfo* m_pInfo;
+
   // ELF segment factory
   ELFSegmentFactory m_ELFSegmentTable;
 
diff --git a/include/mcld/Target/GOT.h b/include/mcld/Target/GOT.h
index 6dfa9b1..732e98f 100644
--- a/include/mcld/Target/GOT.h
+++ b/include/mcld/Target/GOT.h
@@ -28,41 +28,44 @@
 class GOT
 {
 protected:
-  GOT(LDSection& pSection, size_t pEntrySize);
+  GOT(LDSection& pSection);
 
 public:
   typedef SectionData::iterator iterator;
   typedef SectionData::const_iterator const_iterator;
 
+  template<size_t SIZE>
   class Entry : public TargetFragment
   {
   public:
-    Entry(uint64_t pContent, size_t pEntrySize, SectionData* pParent);
+    enum { EntrySize = SIZE };
 
-    virtual ~Entry();
+  public:
+    Entry(uint64_t pValue, SectionData* pParent)
+      : TargetFragment(Fragment::Target, pParent),
+        f_Value(pValue) {
+    }
 
-    uint64_t getContent() const
-    { return f_Content; }
+    virtual ~Entry() {}
 
-    void setContent(uint64_t pValue)
-    { f_Content = pValue; }
+    uint64_t getValue() const
+    { return f_Value; }
+
+    void setValue(uint64_t pValue)
+    { f_Value = pValue; }
 
     // Override pure virtual function
     size_t size() const
-    { return m_EntrySize; }
+    { return EntrySize; }
 
   protected:
-    uint64_t f_Content;
-    size_t m_EntrySize;
+    uint64_t f_Value;
   };
 
 public:
   virtual ~GOT();
 
   // ----- observers -----//
-  /// entrySize - the number of bytes per entry
-  size_t getEntrySize() const;
-
   uint64_t addr() const { return m_Section.addr(); }
 
   const_iterator begin() const { return m_SectionData->begin(); }
@@ -81,17 +84,11 @@
   /// needed. If an entry is needed, the empty entry is reserved for layout
   /// to adjust the fragment offset. After that, we fill up the entries when
   /// applying relocations.
-  virtual void reserve(size_t pNum = 1);
-
-  /// consume - consume and return an empty entry
-  virtual Entry* consume();
+  virtual void reserve(size_t pNum = 1) = 0;
 
 protected:
   LDSection& m_Section;
   SectionData* m_SectionData;
-  size_t f_EntrySize;
-
-  Entry* m_pLast; ///< the last consumed entry
 };
 
 } // namespace of mcld
diff --git a/include/mcld/Target/OutputRelocSection.h b/include/mcld/Target/OutputRelocSection.h
index ace0c71..b0f8f2d 100644
--- a/include/mcld/Target/OutputRelocSection.h
+++ b/include/mcld/Target/OutputRelocSection.h
@@ -28,18 +28,14 @@
 class OutputRelocSection
 {
 public:
-  OutputRelocSection(Module& pModule,
-                     LDSection& pSection,
-                     unsigned int pEntrySize);
+  OutputRelocSection(Module& pModule, LDSection& pSection);
 
   ~OutputRelocSection();
 
-  void reserveEntry(RelocationFactory& pRelFactory, size_t pNum=1);
+  void reserveEntry(size_t pNum=1);
 
   Relocation* consumeEntry();
 
-  void finalizeSectionSize();
-
   /// addSymbolToDynSym - add local symbol to TLS category so that it'll be
   /// emitted into .dynsym
   bool addSymbolToDynSym(LDSymbol& pSymbol);
@@ -48,27 +44,23 @@
   bool empty()
   { return m_pRelocData->empty(); }
 
+  size_t numOfRelocs();
+
 private:
-  typedef RelocData::iterator FragmentIterator;
+  typedef RelocData::iterator RelocIterator;
 
 private:
   Module& m_Module;
 
-  /// m_pSection - LDSection of this Section
-  LDSection* m_pSection;
-
   /// m_RelocData - the output RelocData which contains the dynamic
   /// relocations
   RelocData* m_pRelocData;
 
-  /// m_EntryBytes - size of a relocation entry
-  unsigned int m_EntryBytes;
-
   /// m_isVisit - First time visit the function getEntry() or not
   bool m_isVisit;
 
   /// m_ValidEntryIterator - point to the first valid entry
-  FragmentIterator m_ValidEntryIterator;
+  RelocIterator m_ValidEntryIterator;
 };
 
 } // namespace of mcld
diff --git a/include/mcld/Target/PLT.h b/include/mcld/Target/PLT.h
index bd5936a..5d91446 100644
--- a/include/mcld/Target/PLT.h
+++ b/include/mcld/Target/PLT.h
@@ -21,6 +21,35 @@
 class LDSection;
 class ResolveInfo;
 
+/** \class PLTEntryDefaultBase
+ *  \brief PLTEntryDefaultBase provides the default interface for PLE Entry
+ */
+class PLTEntryBase : public TargetFragment
+{
+public:
+  PLTEntryBase(SectionData& pParent)
+    : TargetFragment(Fragment::Target, &pParent), m_pValue(NULL)
+  {}
+
+  virtual ~PLTEntryBase()
+  {
+    delete m_pValue;
+  }
+
+  void setValue(unsigned char* pValue)
+  { m_pValue = pValue; }
+
+  const unsigned char* getValue() const
+  { return m_pValue; }
+
+  //Used by llvm::cast<>.
+  static bool classof(const Fragment *O)
+  { return true; }
+
+protected:
+  unsigned char* m_pValue;
+};
+
 /** \class PLT
  *  \brief Procedure linkage table
  */
@@ -30,31 +59,21 @@
   typedef SectionData::iterator iterator;
   typedef SectionData::const_iterator const_iterator;
 
-  class Entry : public TargetFragment
+  template<size_t SIZE, typename EntryBase = PLTEntryBase>
+  class Entry : public EntryBase
   {
   public:
-    Entry(size_t pSize, SectionData& pParent);
-    virtual ~Entry();
+    enum { EntrySize = SIZE };
 
-    size_t getEntrySize() const
-    { return m_EntrySize; }
+  public:
+    Entry(SectionData& pParent)
+      : EntryBase(pParent)
+    {}
 
-    void setContent(unsigned char* pContent)
-    { m_pContent = pContent; }
-
-    const unsigned char* getContent() const
-    { return m_pContent; }
-
-    //Used by llvm::cast<>.
-    static bool classof(const Fragment *O)
-    { return true; }
+    virtual ~Entry() {}
 
     size_t size() const
-    { return m_EntrySize; }
-
-  protected:
-    size_t m_EntrySize;
-    unsigned char* m_pContent;
+    { return EntrySize; }
   };
 
 public:
diff --git a/include/mcld/Target/TargetLDBackend.h b/include/mcld/Target/TargetLDBackend.h
index c18bc79..10cf280 100644
--- a/include/mcld/Target/TargetLDBackend.h
+++ b/include/mcld/Target/TargetLDBackend.h
@@ -15,16 +15,20 @@
 
 class Module;
 class LinkerConfig;
+class IRBuilder;
 class FragmentLinker;
 class Relocation;
 class RelocationFactory;
+class Relocator;
 class Layout;
 class ArchiveReader;
 class ObjectReader;
 class DynObjReader;
+class BinaryReader;
 class ObjectWriter;
 class DynObjWriter;
 class ExecWriter;
+class BinaryWriter;
 class LDFileFormat;
 class LDSymbol;
 class LDSection;
@@ -57,9 +61,10 @@
   virtual void initTargetSymbols(FragmentLinker& pLinker) { }
   virtual void initTargetRelocation(FragmentLinker& pLinker) { }
   virtual bool initStandardSymbols(FragmentLinker& pLinker, Module& pModule) = 0;
-  virtual bool initRelocFactory(const FragmentLinker& pLinker) = 0;
 
-  virtual RelocationFactory* getRelocFactory() = 0;
+  virtual bool initRelocator(const FragmentLinker& pLinker) = 0;
+
+  virtual Relocator* getRelocator() = 0;
 
   /// scanRelocation - When read in relocations, backend can do any modification
   /// to relocation and generate empty entries, such as GOT, dynamic relocation
@@ -86,14 +91,19 @@
 
   // -----  format dependent  ----- //
   virtual ArchiveReader* createArchiveReader(Module&) = 0;
-  virtual ObjectReader*  createObjectReader(FragmentLinker&) = 0;
-  virtual DynObjReader*  createDynObjReader(FragmentLinker&) = 0;
-  virtual ObjectWriter*  createObjectWriter(FragmentLinker&) = 0;
-  virtual DynObjWriter*  createDynObjWriter(FragmentLinker&) = 0;
-  virtual ExecWriter*    createExecWriter(FragmentLinker&) = 0;
+  virtual ObjectReader*  createObjectReader(IRBuilder&) = 0;
+  virtual DynObjReader*  createDynObjReader(IRBuilder&) = 0;
+  virtual BinaryReader*  createBinaryReader(IRBuilder&) = 0;
+  virtual ObjectWriter*  createObjectWriter() = 0;
+  virtual DynObjWriter*  createDynObjWriter() = 0;
+  virtual ExecWriter*    createExecWriter() = 0;
+  virtual BinaryWriter*  createBinaryWriter() = 0;
 
   virtual bool initStdSections(ObjectBuilder& pBuilder) = 0;
 
+  /// layout - layout method
+  virtual void layout(Module& pModule, FragmentLinker& pLinker) = 0;
+
   /// preLayout - Backend can do any needed modification before layout
   virtual void preLayout(Module& pModule, FragmentLinker& pLinker) = 0;
 
@@ -104,12 +114,6 @@
   virtual void postProcessing(FragmentLinker& pLinker,
                               MemoryArea& pOutput) = 0;
 
-  /// Is the target machine little endian? **/
-  virtual bool isLittleEndian() const = 0;
-
-  /// bit class. the bit length of the target machine, 32 or 64 **/
-  virtual unsigned int bitclass() const = 0;
-
   /// the common page size of the target machine
   virtual uint64_t commonPageSize() const = 0;
 
diff --git a/include/mcld/Target/TargetMachine.h b/include/mcld/Target/TargetMachine.h
index 1b167ab..1c2ad99 100644
--- a/include/mcld/Target/TargetMachine.h
+++ b/include/mcld/Target/TargetMachine.h
@@ -39,6 +39,7 @@
   CGFT_DSOFile,
   CGFT_EXEFile,
   CGFT_PARTIAL,
+  CGFT_BINARY,
   CGFT_NULLFile
 };
 
diff --git a/include/mcld/TargetOptions.h b/include/mcld/TargetOptions.h
new file mode 100644
index 0000000..21f65cf
--- /dev/null
+++ b/include/mcld/TargetOptions.h
@@ -0,0 +1,71 @@
+//===- TargetOptions.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_OPTIONS_H
+#define MCLD_TARGET_OPTIONS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/Triple.h>
+
+#include <string>
+
+namespace mcld {
+
+/** \class TargetOptions
+ *  \brief TargetOptions collects the options that dependent on a target
+ *  backend.
+ */
+class TargetOptions
+{
+public:
+  enum Endian {
+    Little,
+    Big,
+    Unknown
+  };
+
+public:
+  TargetOptions();
+
+  TargetOptions(const std::string& pTriple);
+
+  ~TargetOptions();
+
+  const llvm::Triple& triple() const { return m_Triple; }
+
+  void setTriple(const std::string& pTriple);
+
+  void setTriple(const llvm::Triple& pTriple);
+
+  Endian endian() const { return m_Endian; }
+
+  void setEndian(Endian pEndian) { m_Endian = pEndian; }
+
+  bool isLittleEndian() const { return (Little == m_Endian); }
+  bool isBigEndian   () const { return (Big    == m_Endian); }
+
+  unsigned int bitclass() const { return m_BitClass; }
+
+  void setBitClass(unsigned int pBitClass) { m_BitClass = pBitClass; }
+
+  bool is32Bits() const { return (32 == m_BitClass); }
+  bool is64Bits() const { return (64 == m_BitClass); }
+
+private:
+  llvm::Triple m_Triple;
+  Endian m_Endian;
+  unsigned int m_BitClass;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/CodeGen/MCLDTargetMachine.cpp b/lib/CodeGen/MCLDTargetMachine.cpp
index e0eeb63..1a2cfff 100644
--- a/lib/CodeGen/MCLDTargetMachine.cpp
+++ b/lib/CodeGen/MCLDTargetMachine.cpp
@@ -241,6 +241,16 @@
       return true;
     break;
   }
+  case CGFT_BINARY: {
+    pConfig.setCodeGenType(LinkerConfig::Binary);
+    if (addLinkerPasses(pPM,
+                        pConfig,
+                        pModule,
+                        pOutput.memory(),
+                        Context))
+      return true;
+    break;
+  }
   case CGFT_DSOFile: {
     pConfig.setCodeGenType(LinkerConfig::DynObj);
     if (addLinkerPasses(pPM,
diff --git a/lib/Core/Android.mk b/lib/Core/Android.mk
index c30d80c..2fd5781 100644
--- a/lib/Core/Android.mk
+++ b/lib/Core/Android.mk
@@ -10,7 +10,8 @@
   LinkerConfig.cpp  \
   Linker.cpp \
   Module.cpp \
-  ScriptOptions.cpp
+  ScriptOptions.cpp \
+  TargetOptions.cpp
 
 # For the host
 # =====================================================
diff --git a/lib/Core/Environment.cpp b/lib/Core/Environment.cpp
index 5755fe7..0aa7536 100644
--- a/lib/Core/Environment.cpp
+++ b/lib/Core/Environment.cpp
@@ -9,6 +9,8 @@
 #include <mcld/Environment.h>
 #include <mcld/Support/TargetSelect.h>
 
+#include <llvm/Support/TargetSelect.h>
+
 void mcld::Initialize()
 {
   static bool is_initialized = false;
@@ -16,6 +18,7 @@
   if (is_initialized)
     return;
 
+  llvm::InitializeAllTargets();
   mcld::InitializeAllTargets();
   mcld::InitializeAllEmulations();
   mcld::InitializeAllDiagnostics();
diff --git a/lib/Core/GeneralOptions.cpp b/lib/Core/GeneralOptions.cpp
index 902f753..d762237 100644
--- a/lib/Core/GeneralOptions.cpp
+++ b/lib/Core/GeneralOptions.cpp
@@ -43,11 +43,14 @@
     m_bColor(true),
     m_bAllowShlibUndefined(true),
     m_bCreateEhFrameHdr(false),
-    m_NMagic(false),
-    m_OMagic(false),
-    m_StripDebug(false),
-    m_ExportDynamic(false),
-    m_WarnSharedTextrel(false)
+    m_bNMagic(false),
+    m_bOMagic(false),
+    m_bStripDebug(false),
+    m_bExportDynamic(false),
+    m_bWarnSharedTextrel(false),
+    m_bBinaryInput(false),
+    m_bDefineCommon(false),
+    m_bFatalWarnings(false)
 {
 }
 
diff --git a/lib/Core/IRBuilder.cpp b/lib/Core/IRBuilder.cpp
index 58c1360..5472db0 100644
--- a/lib/Core/IRBuilder.cpp
+++ b/lib/Core/IRBuilder.cpp
@@ -13,6 +13,7 @@
 #include <mcld/LD/EhFrame.h>
 #include <mcld/LD/RelocData.h>
 #include <mcld/Support/MsgHandling.h>
+#include <mcld/Fragment/FragmentRef.h>
 
 using namespace mcld;
 
@@ -82,6 +83,22 @@
   return LDFileFormat::MetaData;
 }
 
+bool shouldForceLocal(const ResolveInfo& pInfo, const LinkerConfig& pConfig)
+{
+  // forced local symbol matches all rules:
+  // 1. We are not doing incremental linking.
+  // 2. The symbol is with Hidden or Internal visibility.
+  // 3. The symbol should be global or weak. Otherwise, local symbol is local.
+  // 4. The symbol is defined or common
+  if (LinkerConfig::Object != pConfig.codeGenType() &&
+      (pInfo.visibility() == ResolveInfo::Hidden ||
+         pInfo.visibility() == ResolveInfo::Internal) &&
+      (pInfo.isGlobal() || pInfo.isWeak()) &&
+      (pInfo.isDefine() || pInfo.isCommon()))
+    return true;
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 // IRBuilder
 //===----------------------------------------------------------------------===//
@@ -382,7 +399,7 @@
 /// AppendRelocation - To append an relocation to the given RelocData pRD.
 void IRBuilder::AppendRelocation(Relocation& pRelocation, RelocData& pRD)
 {
-  pRD.getFragmentList().push_back(&pRelocation);
+  pRD.append(pRelocation);
 }
 
 /// AppendEhFrame - To append a fragment to EhFrame.
@@ -411,3 +428,249 @@
   return pCIE.size();
 }
 
+/// AddSymbol - To add a symbol in the input file and resolve the symbol
+/// immediately
+LDSymbol* IRBuilder::AddSymbol(Input& pInput,
+                               const std::string& pName,
+                               ResolveInfo::Type pType,
+                               ResolveInfo::Desc pDesc,
+                               ResolveInfo::Binding pBind,
+                               ResolveInfo::SizeType pSize,
+                               LDSymbol::ValueType pValue,
+                               LDSection* pSection,
+                               ResolveInfo::Visibility pVis)
+{
+  // rename symbols
+  std::string name = pName;
+  if (!m_Config.scripts().renameMap().empty() &&
+      ResolveInfo::Undefined == pDesc) {
+    // If the renameMap is not empty, some symbols should be renamed.
+    // --wrap and --portable defines the symbol rename map.
+    ScriptOptions::SymbolRenameMap::const_iterator renameSym =
+                                    m_Config.scripts().renameMap().find(pName);
+    if (renameSym != m_Config.scripts().renameMap().end())
+      name = renameSym.getEntry()->value();
+  }
+
+  switch (pInput.type()) {
+    case Input::Object: {
+
+      FragmentRef* frag = NULL;
+      if (NULL == pSection ||
+          ResolveInfo::Undefined == pDesc ||
+          ResolveInfo::Common    == pDesc ||
+          ResolveInfo::Absolute  == pBind ||
+          LDFileFormat::Ignore   == pSection->kind() ||
+          LDFileFormat::Group    == pSection->kind())
+        frag = FragmentRef::Null();
+      else
+        frag = FragmentRef::Create(*pSection, pValue);
+
+      LDSymbol* input_sym = addSymbolFromObject(name, pType, pDesc, pBind, pSize, pValue, frag, pVis);
+      pInput.context()->addSymbol(input_sym);
+      return input_sym;
+    }
+    case Input::DynObj: {
+      return addSymbolFromDynObj(name, pType, pDesc, pBind, pSize, pValue, pVis);
+    }
+    default: {
+      return NULL;
+      break;
+    }
+  }
+}
+
+LDSymbol* IRBuilder::addSymbolFromObject(const std::string& pName,
+                                         ResolveInfo::Type pType,
+                                         ResolveInfo::Desc pDesc,
+                                         ResolveInfo::Binding pBinding,
+                                         ResolveInfo::SizeType pSize,
+                                         LDSymbol::ValueType pValue,
+                                         FragmentRef* pFragmentRef,
+                                         ResolveInfo::Visibility pVisibility)
+{
+  // Step 1. calculate a Resolver::Result
+  // resolved_result is a triple <resolved_info, existent, override>
+  Resolver::Result resolved_result;
+  ResolveInfo old_info; // used for arrange output symbols
+
+  if (pBinding == ResolveInfo::Local) {
+    // if the symbol is a local symbol, create a LDSymbol for input, but do not
+    // resolve them.
+    resolved_result.info     = m_Module.getNamePool().createSymbol(pName,
+                                                                   false,
+                                                                   pType,
+                                                                   pDesc,
+                                                                   pBinding,
+                                                                   pSize,
+                                                                   pVisibility);
+
+    // No matter if there is a symbol with the same name, insert the symbol
+    // into output symbol table. So, we let the existent false.
+    resolved_result.existent  = false;
+    resolved_result.overriden = true;
+  }
+  else {
+    // if the symbol is not local, insert and resolve it immediately
+    m_Module.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding,
+                                        pSize, pVisibility,
+                                        &old_info, resolved_result);
+  }
+
+  // the return ResolveInfo should not NULL
+  assert(NULL != resolved_result.info);
+
+  /// Step 2. create an input LDSymbol.
+  // create a LDSymbol for the input file.
+  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
+  input_sym->setFragmentRef(pFragmentRef);
+  input_sym->setValue(pValue);
+
+  // Step 3. Set up corresponding output LDSymbol
+  LDSymbol* output_sym = resolved_result.info->outSymbol();
+  bool has_output_sym = (NULL != output_sym);
+  if (!resolved_result.existent || !has_output_sym) {
+    // it is a new symbol, the output_sym should be NULL.
+    assert(NULL == output_sym);
+
+    if (pType == ResolveInfo::Section) {
+      // if it is a section symbol, its output LDSymbol is the input LDSymbol.
+      output_sym = input_sym;
+    }
+    else {
+      // if it is a new symbol, create a LDSymbol for the output
+      output_sym = LDSymbol::Create(*resolved_result.info);
+    }
+    resolved_result.info->setSymPtr(output_sym);
+  }
+
+  if (resolved_result.overriden || !has_output_sym) {
+    // symbol can be overriden only if it exists.
+    assert(output_sym != NULL);
+
+    // should override output LDSymbol
+    output_sym->setFragmentRef(pFragmentRef);
+    output_sym->setValue(pValue);
+  }
+
+  // Step 4. Adjust the position of output LDSymbol.
+  // After symbol resolution, visibility is changed to the most restrict one.
+  // we need to arrange its position in the output symbol. We arrange the
+  // positions by sorting symbols in SymbolCategory.
+  if (pType != ResolveInfo::Section) {
+    if (!has_output_sym) {
+      // We merge sections when reading them. So we do not need to output symbols
+      // with section type
+
+      // No matter the symbol is already in the output or not, add it if it
+      // should be forcefully set local.
+      if (shouldForceLocal(*resolved_result.info, m_Config))
+        m_Module.getSymbolTable().forceLocal(*output_sym);
+      else {
+        // the symbol should not be forcefully local.
+        m_Module.getSymbolTable().add(*output_sym);
+      }
+    }
+    else if (resolved_result.overriden) {
+      if (!shouldForceLocal(old_info, m_Config) ||
+          !shouldForceLocal(*resolved_result.info, m_Config)) {
+        // If the old info and the new info are both forcefully local, then
+        // we should keep the output_sym in forcefully local category. Else,
+        // we should re-sort the output_sym
+        m_Module.getSymbolTable().arrange(*output_sym, old_info);
+      }
+    }
+  }
+
+  return input_sym;
+}
+
+LDSymbol* IRBuilder::addSymbolFromDynObj(const std::string& pName,
+                                         ResolveInfo::Type pType,
+                                         ResolveInfo::Desc pDesc,
+                                         ResolveInfo::Binding pBinding,
+                                         ResolveInfo::SizeType pSize,
+                                         LDSymbol::ValueType pValue,
+                                         ResolveInfo::Visibility pVisibility)
+{
+  // We don't need sections of dynamic objects. So we ignore section symbols.
+  if (pType == ResolveInfo::Section)
+    return NULL;
+
+  // ignore symbols with local binding or that have internal or hidden
+  // visibility
+  if (pBinding == ResolveInfo::Local ||
+      pVisibility == ResolveInfo::Internal ||
+      pVisibility == ResolveInfo::Hidden)
+    return NULL;
+
+  // A protected symbol in a shared library must be treated as a
+  // normal symbol when viewed from outside the shared library.
+  if (pVisibility == ResolveInfo::Protected)
+    pVisibility = ResolveInfo::Default;
+
+  // insert symbol and resolve it immediately
+  // resolved_result is a triple <resolved_info, existent, override>
+  Resolver::Result resolved_result;
+  m_Module.getNamePool().insertSymbol(pName, true, pType, pDesc,
+                                      pBinding, pSize, pVisibility,
+                                      NULL, resolved_result);
+
+  // the return ResolveInfo should not NULL
+  assert(NULL != resolved_result.info);
+
+  // create a LDSymbol for the input file.
+  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
+  input_sym->setFragmentRef(FragmentRef::Null());
+  input_sym->setValue(pValue);
+
+  LDSymbol* output_sym = NULL;
+  if (!resolved_result.existent) {
+    // we get a new symbol, leave it as NULL
+    resolved_result.info->setSymPtr(NULL);
+  }
+  else {
+    // we saw the symbol before, but the output_sym still may be NULL.
+    output_sym = resolved_result.info->outSymbol();
+  }
+
+  if (output_sym != NULL) {
+    // After symbol resolution, visibility is changed to the most restrict one.
+    // If we are not doing incremental linking, then any symbol with hidden
+    // or internal visibility is forcefully set as a local symbol.
+    if (shouldForceLocal(*resolved_result.info, m_Config)) {
+      m_Module.getSymbolTable().forceLocal(*output_sym);
+    }
+  }
+
+  return input_sym;
+}
+
+/// AddRelocation - add a relocation entry
+///
+/// All symbols should be read and resolved before calling this function.
+Relocation* IRBuilder::AddRelocation(LDSection& pSection,
+                                     Relocation::Type pType,
+                                     LDSymbol& pSym,
+                                     uint32_t pOffset,
+                                     Relocation::Address pAddend)
+{
+  // FIXME: we should dicard sections and symbols first instead
+  // if the symbol is in the discarded input section, then we also need to
+  // discard this relocation.
+  ResolveInfo* resolve_info = pSym.resolveInfo();
+  if (!pSym.hasFragRef() &&
+      ResolveInfo::Section == resolve_info->type() &&
+      ResolveInfo::Undefined == resolve_info->desc())
+    return NULL;
+
+  FragmentRef* frag_ref = FragmentRef::Create(*pSection.getLink(), pOffset);
+
+  Relocation* relocation = Relocation::Create(pType, *frag_ref, pAddend);
+
+  relocation->setSymInfo(resolve_info);
+  pSection.getRelocData()->append(*relocation);
+
+  return relocation;
+}
+
diff --git a/lib/Core/Linker.cpp b/lib/Core/Linker.cpp
index 7262537..9f6449e 100644
--- a/lib/Core/Linker.cpp
+++ b/lib/Core/Linker.cpp
@@ -22,6 +22,9 @@
 #include <mcld/Target/TargetLDBackend.h>
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/LDSymbol.h>
+#include <mcld/LD/SectionData.h>
+#include <mcld/LD/RelocData.h>
+#include <mcld/Fragment/Relocation.h>
 #include <mcld/Fragment/FragmentRef.h>
 
 #include <cassert>
@@ -64,7 +67,7 @@
   m_pIRBuilder = &pBuilder;
   m_pObjLinker = new ObjectLinker(*m_pConfig,
                                   pModule,
-                                  m_pIRBuilder->getInputBuilder(),
+                                  *m_pIRBuilder,
                                   *m_pBackend);
 
   // 2. - initialize FragmentLinker
@@ -203,6 +206,11 @@
   m_pIRBuilder = NULL;
   m_pTarget = NULL;
 
+  // Because llvm::iplist will touch the removed node, we must clear
+  // RelocData before deleting target backend.
+  RelocData::Clear();
+  SectionData::Clear();
+
   delete m_pBackend;
   m_pBackend = NULL;
 
@@ -212,6 +220,7 @@
   LDSection::Clear();
   LDSymbol::Clear();
   FragmentRef::Clear();
+  Relocation::Clear();
   return true;
 }
 
@@ -220,9 +229,9 @@
   assert(NULL != m_pConfig);
 
   std::string error;
-  m_pTarget = TargetRegistry::lookupTarget(m_pConfig->triple().str(), error);
+  m_pTarget = mcld::TargetRegistry::lookupTarget(m_pConfig->targets().triple().str(), error);
   if (NULL == m_pTarget) {
-    fatal(diag::fatal_cannot_init_target) << m_pConfig->triple().str() << error;
+    fatal(diag::fatal_cannot_init_target) << m_pConfig->targets().triple().str() << error;
     return false;
   }
   return true;
@@ -233,7 +242,7 @@
   assert(NULL != m_pTarget);
   m_pBackend = m_pTarget->createLDBackend(*m_pConfig);
   if (NULL == m_pBackend) {
-    fatal(diag::fatal_cannot_init_backend) << m_pConfig->triple().str();
+    fatal(diag::fatal_cannot_init_backend) << m_pConfig->targets().triple().str();
     return false;
   }
   return true;
@@ -242,7 +251,12 @@
 bool Linker::initEmulator()
 {
   assert(NULL != m_pTarget && NULL != m_pConfig);
-  return m_pTarget->emulate(m_pConfig->triple().str(), *m_pConfig);
+  bool result = m_pTarget->emulate(m_pConfig->targets().triple().str(),
+                                   *m_pConfig);
+
+  // Relocation should be set up after emulation.
+  Relocation::SetUp(*m_pConfig);
+  return result;
 }
 
 bool Linker::initOStream()
diff --git a/lib/Core/LinkerConfig.cpp b/lib/Core/LinkerConfig.cpp
index d94bbe2..cbdb7a7 100644
--- a/lib/Core/LinkerConfig.cpp
+++ b/lib/Core/LinkerConfig.cpp
@@ -19,9 +19,9 @@
 LinkerConfig::LinkerConfig()
   : m_Options(),
     m_Scripts(),
+    m_Targets(),
     m_Bitcode(),
     m_Attribute(),
-    m_Triple(),
     m_CodeGenType(Unknown)
 {
   // FIXME: is here the right place to hold this?
@@ -31,9 +31,9 @@
 LinkerConfig::LinkerConfig(const std::string& pTripleString)
   : m_Options(),
     m_Scripts(),
+    m_Targets(pTripleString),
     m_Bitcode(),
     m_Attribute(),
-    m_Triple(pTripleString),
     m_CodeGenType(Unknown)
 {
   // FIXME: is here the right place to hold this?
@@ -46,16 +46,6 @@
   FinalizeDiagnosticEngine();
 }
 
-void LinkerConfig::setTriple(const llvm::Triple& pTriple)
-{
-  m_Triple = pTriple;
-}
-
-void LinkerConfig::setTriple(const std::string& pTriple)
-{
-  m_Triple.setTriple(pTriple);
-}
-
 const char* LinkerConfig::version()
 {
   return MCLD_VERSION;
diff --git a/lib/Core/TargetOptions.cpp b/lib/Core/TargetOptions.cpp
new file mode 100644
index 0000000..db723b6
--- /dev/null
+++ b/lib/Core/TargetOptions.cpp
@@ -0,0 +1,40 @@
+//===- TargetOptions.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/TargetOptions.h>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// TargetOptions
+//===----------------------------------------------------------------------===//
+TargetOptions::TargetOptions()
+  : m_Endian(Unknown),
+    m_BitClass(0) {
+}
+
+TargetOptions::TargetOptions(const std::string& pTriple)
+  : m_Triple(pTriple),
+    m_Endian(Unknown),
+    m_BitClass(0) {
+}
+
+TargetOptions::~TargetOptions()
+{
+}
+
+void TargetOptions::setTriple(const llvm::Triple& pTriple)
+{
+  m_Triple = pTriple;
+}
+
+void TargetOptions::setTriple(const std::string& pTriple)
+{
+  m_Triple.setTriple(pTriple);
+}
+
diff --git a/lib/Fragment/FragmentLinker.cpp b/lib/Fragment/FragmentLinker.cpp
index 4ad3d90..0398834 100644
--- a/lib/Fragment/FragmentLinker.cpp
+++ b/lib/Fragment/FragmentLinker.cpp
@@ -20,7 +20,6 @@
 #include <mcld/Module.h>
 #include <mcld/MC/MCLDInput.h>
 #include <mcld/LD/BranchIslandFactory.h>
-#include <mcld/LD/Layout.h>
 #include <mcld/LD/Resolver.h>
 #include <mcld/LD/LDContext.h>
 #include <mcld/LD/RelocationFactory.h>
@@ -31,9 +30,13 @@
 #include <mcld/Support/FileHandle.h>
 #include <mcld/Support/MsgHandling.h>
 #include <mcld/Target/TargetLDBackend.h>
+#include <mcld/Fragment/Relocation.h>
 
 using namespace mcld;
 
+//===----------------------------------------------------------------------===//
+// FragmentLinker
+//===----------------------------------------------------------------------===//
 /// Constructor
 FragmentLinker::FragmentLinker(const LinkerConfig& pConfig,
                                Module& pModule,
@@ -52,178 +55,6 @@
 //===----------------------------------------------------------------------===//
 // Symbol Operations
 //===----------------------------------------------------------------------===//
-/// addSymbolFromObject - add a symbol from object file and resolve it
-/// immediately
-LDSymbol* FragmentLinker::addSymbolFromObject(const llvm::StringRef& pName,
-                                        ResolveInfo::Type pType,
-                                        ResolveInfo::Desc pDesc,
-                                        ResolveInfo::Binding pBinding,
-                                        ResolveInfo::SizeType pSize,
-                                        LDSymbol::ValueType pValue,
-                                        FragmentRef* pFragmentRef,
-                                        ResolveInfo::Visibility pVisibility)
-{
-
-  // Step 1. calculate a Resolver::Result
-  // resolved_result is a triple <resolved_info, existent, override>
-  Resolver::Result resolved_result;
-  ResolveInfo old_info; // used for arrange output symbols
-
-  if (pBinding == ResolveInfo::Local) {
-    // if the symbol is a local symbol, create a LDSymbol for input, but do not
-    // resolve them.
-    resolved_result.info     = m_Module.getNamePool().createSymbol(pName,
-                                                                   false,
-                                                                   pType,
-                                                                   pDesc,
-                                                                   pBinding,
-                                                                   pSize,
-                                                                   pVisibility);
-
-    // No matter if there is a symbol with the same name, insert the symbol
-    // into output symbol table. So, we let the existent false.
-    resolved_result.existent  = false;
-    resolved_result.overriden = true;
-  }
-  else {
-    // if the symbol is not local, insert and resolve it immediately
-    m_Module.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding,
-                                        pSize, pVisibility,
-                                        &old_info, resolved_result);
-  }
-
-  // the return ResolveInfo should not NULL
-  assert(NULL != resolved_result.info);
-
-  /// Step 2. create an input LDSymbol.
-  // create a LDSymbol for the input file.
-  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
-  input_sym->setFragmentRef(pFragmentRef);
-  input_sym->setValue(pValue);
-
-  // Step 3. Set up corresponding output LDSymbol
-  LDSymbol* output_sym = resolved_result.info->outSymbol();
-  bool has_output_sym = (NULL != output_sym);
-  if (!resolved_result.existent || !has_output_sym) {
-    // it is a new symbol, the output_sym should be NULL.
-    assert(NULL == output_sym);
-
-    if (pType == ResolveInfo::Section) {
-      // if it is a section symbol, its output LDSymbol is the input LDSymbol.
-      output_sym = input_sym;
-    }
-    else {
-      // if it is a new symbol, create a LDSymbol for the output
-      output_sym = LDSymbol::Create(*resolved_result.info);
-    }
-    resolved_result.info->setSymPtr(output_sym);
-  }
-
-  if (resolved_result.overriden || !has_output_sym) {
-    // symbol can be overriden only if it exists.
-    assert(output_sym != NULL);
-
-    // should override output LDSymbol
-    output_sym->setFragmentRef(pFragmentRef);
-    output_sym->setValue(pValue);
-  }
-
-  // Step 4. Adjust the position of output LDSymbol.
-  // After symbol resolution, visibility is changed to the most restrict one.
-  // we need to arrange its position in the output symbol. We arrange the
-  // positions by sorting symbols in SymbolCategory.
-  if (pType != ResolveInfo::Section) {
-    if (!has_output_sym) {
-      // We merge sections when reading them. So we do not need to output symbols
-      // with section type
-
-      // No matter the symbol is already in the output or not, add it if it
-      // should be forcefully set local.
-      if (shouldForceLocal(*resolved_result.info))
-        m_Module.getSymbolTable().forceLocal(*output_sym);
-      else {
-        // the symbol should not be forcefully local.
-        m_Module.getSymbolTable().add(*output_sym);
-      }
-    }
-    else if (resolved_result.overriden) {
-      if (!shouldForceLocal(old_info) ||
-          !shouldForceLocal(*resolved_result.info)) {
-        // If the old info and the new info are both forcefully local, then
-        // we should keep the output_sym in forcefully local category. Else,
-        // we should re-sort the output_sym
-        m_Module.getSymbolTable().arrange(*output_sym, old_info);
-      }
-    }
-  }
-
-  return input_sym;
-}
-
-/// addSymbolFromDynObj - add a symbol from object file and resolve it
-/// immediately
-LDSymbol* FragmentLinker::addSymbolFromDynObj(const llvm::StringRef& pName,
-                                        ResolveInfo::Type pType,
-                                        ResolveInfo::Desc pDesc,
-                                        ResolveInfo::Binding pBinding,
-                                        ResolveInfo::SizeType pSize,
-                                        LDSymbol::ValueType pValue,
-                                        FragmentRef* pFragmentRef,
-                                        ResolveInfo::Visibility pVisibility)
-{
-  // We don't need sections of dynamic objects. So we ignore section symbols.
-  if (pType == ResolveInfo::Section)
-    return NULL;
-
-  // ignore symbols with local binding or that have internal or hidden
-  // visibility
-  if (pBinding == ResolveInfo::Local ||
-      pVisibility == ResolveInfo::Internal ||
-      pVisibility == ResolveInfo::Hidden)
-    return NULL;
-
-  // A protected symbol in a shared library must be treated as a
-  // normal symbol when viewed from outside the shared library.
-  if (pVisibility == ResolveInfo::Protected)
-    pVisibility = ResolveInfo::Default;
-
-  // insert symbol and resolve it immediately
-  // resolved_result is a triple <resolved_info, existent, override>
-  Resolver::Result resolved_result;
-  m_Module.getNamePool().insertSymbol(pName, true, pType, pDesc,
-                                      pBinding, pSize, pVisibility,
-                                      NULL, resolved_result);
-
-  // the return ResolveInfo should not NULL
-  assert(NULL != resolved_result.info);
-
-  // create a LDSymbol for the input file.
-  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
-  input_sym->setFragmentRef(pFragmentRef);
-  input_sym->setValue(pValue);
-
-  LDSymbol* output_sym = NULL;
-  if (!resolved_result.existent) {
-    // we get a new symbol, leave it as NULL
-    resolved_result.info->setSymPtr(NULL);
-  }
-  else {
-    // we saw the symbol before, but the output_sym still may be NULL.
-    output_sym = resolved_result.info->outSymbol();
-  }
-
-  if (output_sym != NULL) {
-    // After symbol resolution, visibility is changed to the most restrict one.
-    // If we are not doing incremental linking, then any symbol with hidden
-    // or internal visibility is forcefully set as a local symbol.
-    if (shouldForceLocal(*resolved_result.info)) {
-      m_Module.getSymbolTable().forceLocal(*output_sym);
-    }
-  }
-
-  return input_sym;
-}
-
 /// defineSymbolForcefully - define an output symbol and override it immediately
 LDSymbol* FragmentLinker::defineSymbolForcefully(const llvm::StringRef& pName,
                                            bool pIsDyn,
@@ -462,36 +293,6 @@
 //===----------------------------------------------------------------------===//
 // Relocation Operations
 //===----------------------------------------------------------------------===//
-/// addRelocation - add a relocation entry in FragmentLinker (only for object file)
-///
-/// All symbols should be read and resolved before calling this function.
-Relocation* FragmentLinker::addRelocation(Relocation::Type pType,
-                                          LDSymbol& pSym,
-                                          LDSection& pSection,
-                                          uint32_t pOffset,
-                                          Relocation::Address pAddend)
-{
-  // FIXME: we should dicard sections and symbols first instead
-  // if the symbol is in the discarded input section, then we also need to
-  // discard this relocation.
-  ResolveInfo* resolve_info = pSym.resolveInfo();
-  if (!pSym.hasFragRef() &&
-      resolve_info->type() == ResolveInfo::Section &&
-      resolve_info->desc() == ResolveInfo::Undefined)
-    return NULL;
-
-  FragmentRef* frag_ref = FragmentRef::Create(*pSection.getLink(), pOffset);
-
-  Relocation* relocation = m_Backend.getRelocFactory()->produce(pType,
-                                                                *frag_ref,
-                                                                pAddend);
-
-  relocation->setSymInfo(resolve_info);
-  pSection.getRelocData()->getFragmentList().push_back(relocation);
-
-  return relocation;
-}
-
 bool FragmentLinker::applyRelocations()
 {
   // when producing relocatables, no need to apply relocation
@@ -513,7 +314,7 @@
       RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
       for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
         Relocation* relocation = llvm::cast<Relocation>(reloc);
-        relocation->apply(*m_Backend.getRelocFactory());
+        relocation->apply(*m_Backend.getRelocator());
       } // for all relocations
     } // for all relocation section
   } // for all inputs
@@ -525,7 +326,7 @@
     BranchIsland& island = *facIter;
     BranchIsland::reloc_iterator iter, iterEnd = island.reloc_end();
     for (iter = island.reloc_begin(); iter != iterEnd; ++iter)
-      (*iter)->apply(*m_Backend.getRelocFactory());
+      (*iter)->apply(*m_Backend.getRelocator());
   }
   return true;
 }
@@ -630,17 +431,17 @@
 
   uint8_t* target_addr = pOutput + out_offset;
   // byte swapping if target and host has different endian, and then write back
-  if(llvm::sys::isLittleEndianHost() != m_Backend.isLittleEndian()) {
+  if(llvm::sys::isLittleEndianHost() != m_Config.targets().isLittleEndian()) {
      uint64_t tmp_data = 0;
 
-     switch(m_Backend.bitclass()) {
+     switch(m_Config.targets().bitclass()) {
        case 32u:
-         tmp_data = bswap32(pReloc.target());
+         tmp_data = mcld::bswap32(pReloc.target());
          std::memcpy(target_addr, &tmp_data, 4);
          break;
 
        case 64u:
-         tmp_data = bswap64(pReloc.target());
+         tmp_data = mcld::bswap64(pReloc.target());
          std::memcpy(target_addr, &tmp_data, 8);
          break;
 
@@ -649,7 +450,7 @@
     }
   }
   else
-    std::memcpy(target_addr, &pReloc.target(), m_Backend.bitclass()/8);
+    std::memcpy(target_addr, &pReloc.target(), m_Config.targets().bitclass()/8);
 }
 
 /// isOutputPIC - return whether the output is position-independent
diff --git a/lib/Fragment/Relocation.cpp b/lib/Fragment/Relocation.cpp
index bae49af..293b1c9 100644
--- a/lib/Fragment/Relocation.cpp
+++ b/lib/Fragment/Relocation.cpp
@@ -7,21 +7,69 @@
 //
 //===----------------------------------------------------------------------===//
 #include <mcld/Fragment/Relocation.h>
-#include <mcld/LD/RelocationFactory.h>
+#include <mcld/LD/Relocator.h>
 #include <mcld/LD/ResolveInfo.h>
 #include <mcld/LD/LDSymbol.h>
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/SectionData.h>
 #include <mcld/Support/MsgHandling.h>
+#include <mcld/LD/RelocationFactory.h>
+
+#include <llvm/Support/ManagedStatic.h>
 
 using namespace mcld;
 
+static llvm::ManagedStatic<RelocationFactory> g_RelocationFactory;
+
+//===----------------------------------------------------------------------===//
+// Relocation Factory Methods
+//===----------------------------------------------------------------------===//
+/// Initialize - set up the relocation factory
+void Relocation::SetUp(const LinkerConfig& pConfig)
+{
+  g_RelocationFactory->setConfig(pConfig);
+}
+
+/// Clear - Clean up the relocation factory
+void Relocation::Clear()
+{
+  g_RelocationFactory->clear();
+}
+
+/// Create - produce an empty relocation entry
+Relocation* Relocation::Create()
+{
+  return g_RelocationFactory->produceEmptyEntry();
+}
+
+/// Create - produce a relocation entry
+/// @param pType    [in] the type of the relocation entry
+/// @param pFragRef [in] the place to apply the relocation
+/// @param pAddend  [in] the addend of the relocation entry
+Relocation* Relocation::Create(Type pType, FragmentRef& pFragRef, Address pAddend)
+{
+  return g_RelocationFactory->produce(pType, pFragRef, pAddend);
+}
+
+/// Destroy - destroy a relocation entry
+void Relocation::Destroy(Relocation*& pRelocation)
+{
+  g_RelocationFactory->destroy(pRelocation);
+  pRelocation = NULL;
+}
+
+//===----------------------------------------------------------------------===//
+// Relocation
+//===----------------------------------------------------------------------===//
+Relocation::Relocation()
+  : m_Type(0x0), m_TargetData(0x0), m_pSymInfo(NULL), m_Addend(0x0) {
+}
+
 Relocation::Relocation(Relocation::Type pType,
                        FragmentRef* pTargetRef,
                        Relocation::Address pAddend,
                        Relocation::DWord pTargetData)
-  : Fragment(Fragment::Relocation),
-    m_Type(pType),
+  : m_Type(pType),
     m_TargetData(pTargetData),
     m_pSymInfo(NULL),
     m_Addend(pAddend)
@@ -49,31 +97,31 @@
   return m_pSymInfo->outSymbol()->value();
 }
 
-void Relocation::apply(RelocationFactory& pRelocFactory)
+void Relocation::apply(Relocator& pRelocator)
 {
-  RelocationFactory::Result result = pRelocFactory.applyRelocation(*this);
+  Relocator::Result result = pRelocator.applyRelocation(*this);
 
   switch (result) {
-    case RelocationFactory::OK: {
+    case Relocator::OK: {
       // do nothing
       return;
     }
-    case RelocationFactory::Overflow: {
-      error(diag::result_overflow) << pRelocFactory.getName(type())
+    case Relocator::Overflow: {
+      error(diag::result_overflow) << pRelocator.getName(type())
                                    << symInfo()->name();
       return;
     }
-    case RelocationFactory::BadReloc: {
-      error(diag::result_badreloc) << pRelocFactory.getName(type())
+    case Relocator::BadReloc: {
+      error(diag::result_badreloc) << pRelocator.getName(type())
                                    << symInfo()->name();
       return;
     }
-    case RelocationFactory::Unsupport: {
+    case Relocator::Unsupport: {
       fatal(diag::unsupported_relocation) << type()
                                           << "mclinker@googlegroups.com";
       return;
     }
-    case RelocationFactory::Unknown: {
+    case Relocator::Unknown: {
       fatal(diag::unknown_relocation) << type() << symInfo()->name();
       return;
     }
diff --git a/lib/LD/Android.mk b/lib/LD/Android.mk
index 21e452e..53c1f10 100644
--- a/lib/LD/Android.mk
+++ b/lib/LD/Android.mk
@@ -7,6 +7,7 @@
 mcld_ld_SRC_FILES := \
   Archive.cpp \
   ArchiveReader.cpp \
+  BinaryWriter.cpp \
   BranchIsland.cpp  \
   BranchIslandFactory.cpp  \
   DWARFLineInfo.cpp \
@@ -17,6 +18,8 @@
   DiagnosticPrinter.cpp \
   DynObjReader.cpp  \
   DynObjWriter.cpp  \
+  ELFBinaryReader.cpp  \
+  ELFBinaryWriter.cpp  \
   ELFSegment.cpp  \
   ELFSegmentFactory.cpp \
   EhFrame.cpp \
@@ -24,7 +27,6 @@
   EhFrameReader.cpp  \
   ExecWriter.cpp  \
   GroupReader.cpp \
-  Layout.cpp  \
   LDContext.cpp \
   LDFileFormat.cpp  \
   LDReader.cpp  \
diff --git a/lib/LD/BinaryWriter.cpp b/lib/LD/BinaryWriter.cpp
new file mode 100644
index 0000000..00dd169
--- /dev/null
+++ b/lib/LD/BinaryWriter.cpp
@@ -0,0 +1,24 @@
+//===- BinaryWriter.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/BinaryWriter.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/Target/GNULDBackend.h>
+
+using namespace mcld;
+
+//==========================
+// BinaryWriter
+BinaryWriter::BinaryWriter(GNULDBackend& pBackend)
+{
+}
+
+BinaryWriter::~BinaryWriter()
+{
+}
+
diff --git a/lib/LD/DiagnosticInfos.cpp b/lib/LD/DiagnosticInfos.cpp
index 6639d0a..130fd9a 100644
--- a/lib/LD/DiagnosticInfos.cpp
+++ b/lib/LD/DiagnosticInfos.cpp
@@ -146,6 +146,14 @@
       break;
   } // end of switch
 
+  // If --fatal-warnings is turned on, then switch warnings and errors to fatal
+  if (m_Config.options().isFatalWarnings()) {
+    if (severity == DiagnosticEngine::Warning ||
+        severity == DiagnosticEngine::Error) {
+      severity = DiagnosticEngine::Fatal;
+    }
+  }
+
   // finally, report it.
   pEngine.getPrinter()->handleDiagnostic(severity, info);
   return true;
diff --git a/lib/LD/DiagnosticPrinter.cpp b/lib/LD/DiagnosticPrinter.cpp
index 245555f..6eee86a 100644
--- a/lib/LD/DiagnosticPrinter.cpp
+++ b/lib/LD/DiagnosticPrinter.cpp
@@ -10,8 +10,9 @@
 
 using namespace mcld;
 
-//==========================
+//===----------------------------------------------------------------------===//
 // DiagnosticPrinter
+//===----------------------------------------------------------------------===//
 DiagnosticPrinter::DiagnosticPrinter()
   : m_NumErrors(0), m_NumWarnings(0) {
 }
diff --git a/lib/LD/ELFBinaryReader.cpp b/lib/LD/ELFBinaryReader.cpp
new file mode 100644
index 0000000..c291544
--- /dev/null
+++ b/lib/LD/ELFBinaryReader.cpp
@@ -0,0 +1,124 @@
+//===- ELFBinaryReader.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/ELFBinaryReader.h>
+
+#include <mcld/IRBuilder.h>
+#include <mcld/LinkerConfig.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/Support/MemoryArea.h>
+#include <mcld/Target/GNULDBackend.h>
+
+#include <llvm/Support/ELF.h>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// ELFBinaryReader
+//===----------------------------------------------------------------------===//
+/// constructor
+ELFBinaryReader::ELFBinaryReader(GNULDBackend& pBackend,
+                                 IRBuilder& pBuilder,
+                                 const LinkerConfig& pConfig)
+  : BinaryReader(),
+    m_Backend(pBackend),
+    m_Builder(pBuilder),
+    m_Config(pConfig) {
+}
+
+/// destructor
+ELFBinaryReader::~ELFBinaryReader()
+{
+}
+
+bool ELFBinaryReader::readBinary(Input& pInput)
+{
+  // section: NULL
+  m_Builder.CreateELFHeader(pInput,
+                            "",
+                            LDFileFormat::Null,
+                            llvm::ELF::SHT_NULL,
+                            0x0);
+
+  // section: .data
+  LDSection* data_sect =
+    m_Builder.CreateELFHeader(pInput,
+                              ".data",
+                              LDFileFormat::Regular,
+                              llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC,
+                              0x1);
+
+
+  SectionData* data = m_Builder.CreateSectionData(*data_sect);
+  size_t data_size = pInput.memArea()->handler()->size();
+  Fragment* frag = m_Builder.CreateRegion(pInput, 0x0, data_size);
+  m_Builder.AppendFragment(*frag, *data);
+
+  // section: .shstrtab
+  m_Builder.CreateELFHeader(pInput,
+                            ".shstrtab",
+                            LDFileFormat::NamePool,
+                            llvm::ELF::SHT_STRTAB,
+                            0x1);
+
+  // section: .symtab
+  m_Builder.CreateELFHeader(pInput,
+                            ".symtab",
+                            LDFileFormat::NamePool,
+                            llvm::ELF::SHT_SYMTAB,
+                            m_Config.targets().bitclass() / 8);
+
+  // symbol: .data
+  m_Builder.AddSymbol(pInput,
+                      ".data",
+                      ResolveInfo::Section,
+                      ResolveInfo::Define,
+                      ResolveInfo::Local,
+                      0x0,
+                      0x0,
+                      data_sect);
+
+  // symbol: _start
+  m_Builder.AddSymbol(pInput,
+                      "_binary_" + pInput.path().filename().string() + "_start",
+                      ResolveInfo::NoType,
+                      ResolveInfo::Define,
+                      ResolveInfo::Global,
+                      0x0,
+                      0x0,
+                      data_sect);
+
+  // symbol: _end
+  m_Builder.AddSymbol(pInput,
+                      "_binary_" + pInput.path().filename().string() + "_end",
+                      ResolveInfo::NoType,
+                      ResolveInfo::Define,
+                      ResolveInfo::Global,
+                      0x0,
+                      data_size,
+                      data_sect);
+
+  // symbol: _size
+  m_Builder.AddSymbol(pInput,
+                      "_binary_" + pInput.path().filename().string() + "_size",
+                      ResolveInfo::NoType,
+                      ResolveInfo::Define,
+                      ResolveInfo::Global,
+                      0x0,
+                      data_size,
+                      data_sect);
+
+  // section: .strtab
+  m_Builder.CreateELFHeader(pInput,
+                            ".strtab",
+                            LDFileFormat::NamePool,
+                            llvm::ELF::SHT_STRTAB,
+                            0x1);
+
+  return true;
+}
diff --git a/lib/LD/ELFBinaryWriter.cpp b/lib/LD/ELFBinaryWriter.cpp
new file mode 100644
index 0000000..28ef553
--- /dev/null
+++ b/lib/LD/ELFBinaryWriter.cpp
@@ -0,0 +1,110 @@
+//===- ELFBinaryWriter.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/ELFBinaryWriter.h>
+
+#include <mcld/Module.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/Fragment/FragmentLinker.h>
+#include <mcld/Support/MemoryArea.h>
+#include <mcld/LD/ELFSegmentFactory.h>
+#include <mcld/LD/ELFSegment.h>
+
+#include <llvm/Support/system_error.h>
+using namespace llvm;
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// ELFBinaryWriter
+//===----------------------------------------------------------------------===//
+ELFBinaryWriter::ELFBinaryWriter(GNULDBackend& pBackend,
+                                 const LinkerConfig& pConfig)
+  : BinaryWriter(pBackend), ELFWriter(pBackend), m_Config(pConfig) {
+}
+
+ELFBinaryWriter::~ELFBinaryWriter()
+{
+}
+
+llvm::error_code ELFBinaryWriter::writeBinary(Module& pModule,
+                                              MemoryArea& pOutput)
+{
+  // Write out regular ELF sections
+  for (ELFSegmentFactory::iterator seg = target().elfSegmentTable().begin(),
+         segEnd = target().elfSegmentTable().end(); seg != segEnd; ++seg) {
+    if (llvm::ELF::PT_LOAD != (*seg).type())
+      continue;
+
+    for (ELFSegment::sect_iterator sect = (*seg).begin(),
+           sectEnd = (*seg).end(); sect != sectEnd; ++sect) {
+      MemoryRegion* region = NULL;
+      // request output region
+      switch((*sect)->kind()) {
+        case LDFileFormat::Note:
+          if ((*sect)->getSectionData() == NULL)
+            continue;
+          // Fall through
+        case LDFileFormat::Regular:
+        case LDFileFormat::Relocation:
+        case LDFileFormat::Target:
+        case LDFileFormat::Debug:
+        case LDFileFormat::GCCExceptTable:
+        case LDFileFormat::EhFrame: {
+          region = pOutput.request((*sect)->offset(), (*sect)->size());
+          if (NULL == region) {
+            llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") +
+                                     llvm::Twine((*sect)->name()) +
+                                     llvm::Twine("'.\n"));
+          }
+          break;
+        }
+        case LDFileFormat::Null:
+        case LDFileFormat::NamePool:
+        case LDFileFormat::BSS:
+        case LDFileFormat::MetaData:
+        case LDFileFormat::Version:
+        case LDFileFormat::EhFrameHdr:
+        case LDFileFormat::StackNote:
+          // ignore these sections
+          continue;
+        default: {
+          llvm::errs() << "WARNING: unsupported section kind: "
+                       << (*sect)->kind()
+                       << " of section "
+                       << (*sect)->name()
+                       << ".\n";
+          continue;
+        }
+      }
+
+      // write out sections with data
+      switch((*sect)->kind()) {
+        case LDFileFormat::Regular:
+        case LDFileFormat::Debug:
+        case LDFileFormat::GCCExceptTable:
+        case LDFileFormat::Note:
+        case LDFileFormat::EhFrame: {
+          // FIXME: if optimization of exception handling sections is enabled,
+          // then we should emit these sections by the other way.
+          emitSectionData(**sect, *region);
+          break;
+        }
+        case LDFileFormat::Relocation:
+          emitRelocation(m_Config, **sect, *region);
+          break;
+        case LDFileFormat::Target:
+          target().emitSectionData(**sect, *region);
+          break;
+        default:
+          continue;
+      }
+    } // end of section for loop
+  } // end of segment for loop
+  return llvm::make_error_code(llvm::errc::success);
+}
+
diff --git a/lib/LD/ELFDynObjReader.cpp b/lib/LD/ELFDynObjReader.cpp
index 740577c..e52e863 100644
--- a/lib/LD/ELFDynObjReader.cpp
+++ b/lib/LD/ELFDynObjReader.cpp
@@ -6,17 +6,19 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+#include <mcld/LD/ELFDynObjReader.h>
+
+#include <mcld/LinkerConfig.h>
+#include <mcld/IRBuilder.h>
+#include <mcld/LD/ELFReader.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/Target/GNULDBackend.h>
+
 #include <llvm/ADT/Twine.h>
 #include <llvm/ADT/OwningPtr.h>
 #include <llvm/Support/ErrorHandling.h>
 
-#include <mcld/LD/ELFDynObjReader.h>
-#include <mcld/LD/ELFReader.h>
-#include <mcld/MC/MCLDInput.h>
-#include <mcld/Fragment/FragmentLinker.h>
-#include <mcld/Target/GNULDBackend.h>
-#include <mcld/Support/MemoryRegion.h>
-
 #include <string>
 
 using namespace mcld;
@@ -24,11 +26,13 @@
 //===----------------------------------------------------------------------===//
 // ELFDynObjReader
 //===----------------------------------------------------------------------===//
-ELFDynObjReader::ELFDynObjReader(GNULDBackend& pBackend, FragmentLinker& pLinker)
+ELFDynObjReader::ELFDynObjReader(GNULDBackend& pBackend,
+                                 IRBuilder& pBuilder,
+                                 const LinkerConfig& pConfig)
   : DynObjReader(),
     m_pELFReader(0),
-    m_Linker(pLinker) {
-  if (32 == pBackend.bitclass() && pBackend.isLittleEndian())
+    m_Builder(pBuilder) {
+  if (pConfig.targets().is32Bits() && pConfig.targets().isLittleEndian())
     m_pELFReader = new ELFReader<32, true>(pBackend);
 }
 
@@ -108,8 +112,8 @@
   MemoryRegion* strtab_region = pInput.memArea()->request(
               pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size());
   char* strtab = reinterpret_cast<char*>(strtab_region->start());
-  bool result = m_pELFReader->readSymbols(pInput, m_Linker, *symtab_region,
-                                            strtab);
+  bool result = m_pELFReader->readSymbols(pInput, m_Builder,
+                                          *symtab_region, strtab);
   pInput.memArea()->release(symtab_region);
   pInput.memArea()->release(strtab_region);
 
diff --git a/lib/LD/ELFDynObjWriter.cpp b/lib/LD/ELFDynObjWriter.cpp
index 48ce0a3..2e903ce 100644
--- a/lib/LD/ELFDynObjWriter.cpp
+++ b/lib/LD/ELFDynObjWriter.cpp
@@ -13,7 +13,6 @@
 #include <mcld/LD/LDSymbol.h>
 #include <mcld/Target/GNULDBackend.h>
 #include <mcld/MC/MCLDInput.h>
-#include <mcld/Fragment/FragmentLinker.h>
 #include <mcld/Support/MemoryArea.h>
 
 #include <llvm/Support/ELF.h>
@@ -26,10 +25,10 @@
 //===----------------------------------------------------------------------===//
 // ELFDynObjWriter
 //===----------------------------------------------------------------------===//
-ELFDynObjWriter::ELFDynObjWriter(GNULDBackend& pBackend, FragmentLinker& pLinker)
-  : DynObjWriter(pBackend),
-    ELFWriter(pBackend),
-    m_Linker(pLinker) {
+ELFDynObjWriter::ELFDynObjWriter(GNULDBackend& pBackend,
+                                 const LinkerConfig& pConfig)
+  : DynObjWriter(pBackend), ELFWriter(pBackend),
+    m_Config(pConfig) {
 
 }
 
@@ -54,6 +53,10 @@
     MemoryRegion* region = NULL;
     // request output region
     switch((*sect)->kind()) {
+      case LDFileFormat::Note:
+        if ((*sect)->getSectionData() == NULL)
+          continue;
+        // Fall through
       case LDFileFormat::Regular:
       case LDFileFormat::Relocation:
       case LDFileFormat::Target:
@@ -71,7 +74,6 @@
       case LDFileFormat::Null:
       case LDFileFormat::NamePool:
       case LDFileFormat::BSS:
-      case LDFileFormat::Note:
       case LDFileFormat::MetaData:
       case LDFileFormat::Version:
       case LDFileFormat::EhFrameHdr:
@@ -93,6 +95,7 @@
       case LDFileFormat::Regular:
       case LDFileFormat::Debug:
       case LDFileFormat::GCCExceptTable:
+      case LDFileFormat::Note:
       case LDFileFormat::EhFrame: {
         // FIXME: if optimization of exception handling sections is enabled,
         // then we should emit these sections by the other way.
@@ -100,7 +103,7 @@
         break;
       }
       case LDFileFormat::Relocation:
-        emitRelocation(m_Linker.getLDInfo(), **sect, *region);
+        emitRelocation(m_Config, **sect, *region);
         break;
       case LDFileFormat::Target:
         target().emitSectionData(**sect, *region);
@@ -115,27 +118,23 @@
                   pModule,
                   pOutput);
 
-  if (32 == target().bitclass()) {
+  if (m_Config.targets().is32Bits()) {
     // Write out ELF header
     // Write out section header table
-    writeELF32Header(m_Linker.getLDInfo(),
-                     pModule,
-                     pOutput);
+    writeELF32Header(m_Config, pModule, pOutput);
 
     emitELF32ProgramHeader(pOutput);
 
-    emitELF32SectionHeader(pModule, m_Linker.getLDInfo(), pOutput);
+    emitELF32SectionHeader(pModule, m_Config, pOutput);
   }
-  else if (64 == target().bitclass()) {
+  else if (m_Config.targets().is64Bits()) {
     // Write out ELF header
     // Write out section header table
-    writeELF64Header(m_Linker.getLDInfo(),
-                     pModule,
-                     pOutput);
+    writeELF64Header(m_Config, pModule, pOutput);
 
     emitELF64ProgramHeader(pOutput);
 
-    emitELF64SectionHeader(pModule, m_Linker.getLDInfo(), pOutput);
+    emitELF64SectionHeader(pModule, m_Config, pOutput);
   }
   else
     return make_error_code(errc::not_supported);
diff --git a/lib/LD/ELFExecWriter.cpp b/lib/LD/ELFExecWriter.cpp
index dec5e26..a9af584 100644
--- a/lib/LD/ELFExecWriter.cpp
+++ b/lib/LD/ELFExecWriter.cpp
@@ -12,7 +12,6 @@
 #include <mcld/LinkerConfig.h>
 #include <mcld/LD/LDSymbol.h>
 #include <mcld/Target/GNULDBackend.h>
-#include <mcld/Fragment/FragmentLinker.h>
 #include <mcld/Support/MemoryArea.h>
 
 #include <llvm/Support/ELF.h>
@@ -25,10 +24,10 @@
 //===----------------------------------------------------------------------===//
 // ELFExecWriter
 //===----------------------------------------------------------------------===//
-ELFExecWriter::ELFExecWriter(GNULDBackend& pBackend, FragmentLinker& pLinker)
-  : ExecWriter(pBackend),
-    ELFWriter(pBackend),
-    m_Linker(pLinker) {
+ELFExecWriter::ELFExecWriter(GNULDBackend& pBackend,
+                             const LinkerConfig& pConfig)
+  : ExecWriter(pBackend), ELFWriter(pBackend),
+    m_Config(pConfig) {
 
 }
 
@@ -54,6 +53,10 @@
     MemoryRegion* region = NULL;
     // request output region
     switch((*sect)->kind()) {
+      case LDFileFormat::Note:
+        if ((*sect)->getSectionData() == NULL)
+          continue;
+        // Fall through
       case LDFileFormat::Regular:
       case LDFileFormat::Relocation:
       case LDFileFormat::Target:
@@ -71,7 +74,6 @@
       case LDFileFormat::Null:
       case LDFileFormat::NamePool:
       case LDFileFormat::BSS:
-      case LDFileFormat::Note:
       case LDFileFormat::MetaData:
       case LDFileFormat::Version:
       case LDFileFormat::EhFrameHdr:
@@ -93,6 +95,7 @@
       case LDFileFormat::Regular:
       case LDFileFormat::Debug:
       case LDFileFormat::GCCExceptTable:
+      case LDFileFormat::Note:
       case LDFileFormat::EhFrame: {
         // FIXME: if optimization of exception handling sections is enabled,
         // then we should emit these sections by the other way.
@@ -100,7 +103,7 @@
         break;
       }
       case LDFileFormat::Relocation:
-        emitRelocation(m_Linker.getLDInfo(), **sect, *region);
+        emitRelocation(m_Config, **sect, *region);
         break;
       case LDFileFormat::Target:
         target().emitSectionData(**sect, *region);
@@ -114,27 +117,23 @@
                   pModule,
                   pOutput);
 
-  if (32 == target().bitclass()) {
+  if (m_Config.targets().is32Bits()) {
     // Write out ELF header
     // Write out section header table
-    writeELF32Header(m_Linker.getLDInfo(),
-                     pModule,
-                     pOutput);
+    writeELF32Header(m_Config, pModule, pOutput);
 
     emitELF32ProgramHeader(pOutput);
 
-    emitELF32SectionHeader(pModule, m_Linker.getLDInfo(), pOutput);
+    emitELF32SectionHeader(pModule, m_Config, pOutput);
   }
-  else if (64 == target().bitclass()) {
+  else if (m_Config.targets().is64Bits()) {
     // Write out ELF header
     // Write out section header table
-    writeELF64Header(m_Linker.getLDInfo(),
-                     pModule,
-                     pOutput);
+    writeELF64Header(m_Config, pModule, pOutput);
 
     emitELF64ProgramHeader(pOutput);
 
-    emitELF64SectionHeader(pModule, m_Linker.getLDInfo(), pOutput);
+    emitELF64SectionHeader(pModule, m_Config, pOutput);
   }
   else
     return make_error_code(errc::not_supported);
diff --git a/lib/LD/ELFFileFormat.cpp b/lib/LD/ELFFileFormat.cpp
index 7512e38..b4792b5 100644
--- a/lib/LD/ELFFileFormat.cpp
+++ b/lib/LD/ELFFileFormat.cpp
@@ -155,6 +155,7 @@
                                               llvm::ELF::SHT_SYMTAB,
                                               0x0,
                                               pBitClass / 8);
+
   f_pStrTab          = pBuilder.CreateSection(".strtab",
                                               LDFileFormat::NamePool,
                                               llvm::ELF::SHT_STRTAB,
diff --git a/lib/LD/ELFObjectReader.cpp b/lib/LD/ELFObjectReader.cpp
index 4124098..a87b5b8 100644
--- a/lib/LD/ELFObjectReader.cpp
+++ b/lib/LD/ELFObjectReader.cpp
@@ -16,7 +16,6 @@
 
 #include <mcld/IRBuilder.h>
 #include <mcld/MC/MCLDInput.h>
-#include <mcld/Fragment/FragmentLinker.h>
 #include <mcld/LD/ELFReader.h>
 #include <mcld/LD/EhFrameReader.h>
 #include <mcld/LD/EhFrame.h>
@@ -30,14 +29,17 @@
 // ELFObjectReader
 //===----------------------------------------------------------------------===//
 /// constructor
-ELFObjectReader::ELFObjectReader(GNULDBackend& pBackend, FragmentLinker& pLinker)
+ELFObjectReader::ELFObjectReader(GNULDBackend& pBackend,
+                                 IRBuilder& pBuilder,
+                                 const LinkerConfig& pConfig)
   : ObjectReader(),
     m_pELFReader(NULL),
     m_pEhFrameReader(NULL),
-    m_Linker(pLinker),
+    m_Builder(pBuilder),
     m_ReadFlag(ParseEhFrame),
-    m_Backend(pBackend) {
-  if (32 == pBackend.bitclass() && pBackend.isLittleEndian()) {
+    m_Backend(pBackend),
+    m_Config(pConfig) {
+  if (pConfig.targets().is32Bits() && pConfig.targets().isLittleEndian()) {
     m_pELFReader = new ELFReader<32, true>(pBackend);
   }
 
@@ -166,7 +168,7 @@
         break;
       }
       case LDFileFormat::Debug: {
-        if (m_Linker.getLDInfo().options().stripDebug()) {
+        if (m_Config.options().stripDebug()) {
           (*section)->setKind(LDFileFormat::Ignore);
         }
         else {
@@ -180,7 +182,7 @@
       case LDFileFormat::EhFrame: {
         EhFrame* eh_frame = IRBuilder::CreateEhFrame(**section);
 
-        if (m_Linker.getLDInfo().options().hasEhFrameHdr() &&
+        if (m_Config.options().hasEhFrameHdr() &&
             (m_ReadFlag & ParseEhFrame)) {
 
           // if --eh-frame-hdr option is given, parse .eh_frame.
@@ -231,7 +233,7 @@
   return true;
 }
 
-/// readSymbols - read symbols into FragmentLinker from the input relocatable object.
+/// readSymbols - read symbols from the input relocatable object.
 bool ELFObjectReader::readSymbols(Input& pInput)
 {
   assert(pInput.hasMemArea());
@@ -258,7 +260,7 @@
              pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size());
   char* strtab = reinterpret_cast<char*>(strtab_region->start());
   bool result = m_pELFReader->readSymbols(pInput,
-                                          m_Linker,
+                                          m_Builder,
                                           *symtab_region,
                                           strtab);
   pInput.memArea()->release(symtab_region);
@@ -282,14 +284,14 @@
     IRBuilder::CreateRelocData(**rs); ///< create relocation data for the header
     switch ((*rs)->type()) {
       case llvm::ELF::SHT_RELA: {
-        if (!m_pELFReader->readRela(pInput, m_Linker, **rs, *region)) {
+        if (!m_pELFReader->readRela(pInput, **rs, *region)) {
           mem->release(region);
           return false;
         }
         break;
       }
       case llvm::ELF::SHT_REL: {
-        if (!m_pELFReader->readRel(pInput, m_Linker, **rs, *region)) {
+        if (!m_pELFReader->readRel(pInput, **rs, *region)) {
           mem->release(region);
           return false;
         }
diff --git a/lib/LD/ELFObjectWriter.cpp b/lib/LD/ELFObjectWriter.cpp
index ee9a7ac..e9b7b99 100644
--- a/lib/LD/ELFObjectWriter.cpp
+++ b/lib/LD/ELFObjectWriter.cpp
@@ -9,11 +9,12 @@
 #include <mcld/LD/ELFObjectWriter.h>
 
 #include <mcld/Module.h>
+#include <mcld/LinkerConfig.h>
 #include <mcld/Target/GNULDBackend.h>
-#include <mcld/Fragment/FragmentLinker.h>
 #include <mcld/Support/MemoryArea.h>
 
 #include <llvm/Support/system_error.h>
+
 using namespace llvm;
 using namespace mcld;
 
@@ -21,8 +22,9 @@
 // ELFObjectWriter
 //===----------------------------------------------------------------------===//
 ELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend,
-                                 FragmentLinker& pLinker)
-  : ObjectWriter(pBackend), ELFWriter(pBackend), m_Linker(pLinker) {
+                                 const LinkerConfig& pConfig)
+  : ObjectWriter(pBackend), ELFWriter(pBackend),
+    m_Config(pConfig) {
 }
 
 ELFObjectWriter::~ELFObjectWriter()
@@ -41,6 +43,10 @@
     MemoryRegion* region = NULL;
     // request output region
     switch((*sect)->kind()) {
+      case LDFileFormat::Note:
+        if ((*sect)->getSectionData() == NULL)
+          continue;
+        // Fall through
       case LDFileFormat::Regular:
       case LDFileFormat::Relocation:
       case LDFileFormat::Target:
@@ -58,7 +64,6 @@
       case LDFileFormat::Null:
       case LDFileFormat::NamePool:
       case LDFileFormat::BSS:
-      case LDFileFormat::Note:
       case LDFileFormat::MetaData:
       case LDFileFormat::Version:
       case LDFileFormat::EhFrameHdr:
@@ -80,6 +85,7 @@
       case LDFileFormat::Regular:
       case LDFileFormat::Debug:
       case LDFileFormat::GCCExceptTable:
+      case LDFileFormat::Note:
       case LDFileFormat::EhFrame: {
         // FIXME: if optimization of exception handling sections is enabled,
         // then we should emit these sections by the other way.
@@ -87,7 +93,7 @@
         break;
       }
       case LDFileFormat::Relocation:
-        emitRelocation(m_Linker.getLDInfo(), **sect, *region);
+        emitRelocation(m_Config, **sect, *region);
         break;
       case LDFileFormat::Target:
         target().emitSectionData(**sect, *region);
@@ -101,23 +107,23 @@
                   pModule,
                   pOutput);
 
-  if (32 == target().bitclass()) {
+  if (m_Config.targets().is32Bits()) {
     // Write out ELF header
     // Write out section header table
-    writeELF32Header(m_Linker.getLDInfo(),
+    writeELF32Header(m_Config,
                      pModule,
                      pOutput);
 
-    emitELF32SectionHeader(pModule, m_Linker.getLDInfo(), pOutput);
+    emitELF32SectionHeader(pModule, m_Config, pOutput);
   }
-  else if (64 == target().bitclass()) {
+  else if (m_Config.targets().is64Bits()) {
     // Write out ELF header
     // Write out section header table
-    writeELF64Header(m_Linker.getLDInfo(),
+    writeELF64Header(m_Config,
                      pModule,
                      pOutput);
 
-    emitELF64SectionHeader(pModule, m_Linker.getLDInfo(), pOutput);
+    emitELF64SectionHeader(pModule, m_Config, pOutput);
   }
   else
     return make_error_code(errc::not_supported);
diff --git a/lib/LD/ELFReader.cpp b/lib/LD/ELFReader.cpp
index 7f105b3..84ad17b 100644
--- a/lib/LD/ELFReader.cpp
+++ b/lib/LD/ELFReader.cpp
@@ -9,7 +9,6 @@
 #include <mcld/LD/ELFReader.h>
 
 #include <mcld/IRBuilder.h>
-#include <mcld/Fragment/FragmentLinker.h>
 #include <mcld/Fragment/FillFragment.h>
 #include <mcld/LD/EhFrame.h>
 #include <mcld/LD/SectionData.h>
@@ -105,7 +104,10 @@
   if (Input::DynObj == pInput.type())
     return FragmentRef::Null();
 
-  if (pShndx == llvm::ELF::SHN_UNDEF || pShndx >= llvm::ELF::SHN_LORESERVE)
+  if (pShndx == llvm::ELF::SHN_UNDEF)
+    return FragmentRef::Null();
+
+  if (pShndx >= llvm::ELF::SHN_LORESERVE) // including ABS and COMMON
     return FragmentRef::Null();
 
   LDSection* sect_hdr = pInput.context()->getSection(pShndx);
@@ -193,7 +195,7 @@
 
 /// readSymbols - read ELF symbols and create LDSymbol
 bool ELFReader<32, true>::readSymbols(Input& pInput,
-                                      FragmentLinker& pLinker,
+                                      IRBuilder& pBuilder,
                                       const MemoryRegion& pRegion,
                                       const char* pStrTab) const
 {
@@ -223,10 +225,10 @@
       st_shndx = symtab[idx].st_shndx;
     }
     else {
-      st_name  = bswap32(symtab[idx].st_name);
-      st_value = bswap32(symtab[idx].st_value);
-      st_size  = bswap32(symtab[idx].st_size);
-      st_shndx = bswap16(symtab[idx].st_shndx);
+      st_name  = mcld::bswap32(symtab[idx].st_name);
+      st_value = mcld::bswap32(symtab[idx].st_value);
+      st_size  = mcld::bswap32(symtab[idx].st_size);
+      st_shndx = mcld::bswap16(symtab[idx].st_shndx);
     }
 
     // If the section should not be included, set the st_shndx SHN_UNDEF
@@ -250,55 +252,33 @@
     // get ld_value - ld_value must be section relative.
     uint64_t ld_value = getSymValue(st_value, st_shndx, pInput);
 
-    // get the input fragment
-    FragmentRef* ld_frag_ref = getSymFragmentRef(pInput,
-                                                 st_shndx,
-                                                 ld_value);
-
     // get ld_vis
     ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);
 
+    // get section
+    LDSection* section = NULL;
+    if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON
+      section = pInput.context()->getSection(st_shndx);
+
     // get ld_name
-    llvm::StringRef ld_name;
+    std::string ld_name;
     if (ResolveInfo::Section == ld_type) {
       // Section symbol's st_name is the section index.
-      LDSection* section = pInput.context()->getSection(st_shndx);
       assert(NULL != section && "get a invalid section");
-      ld_name = llvm::StringRef(section->name());
+      ld_name = section->name();
     }
     else {
-      ld_name = llvm::StringRef(pStrTab + st_name);
+      ld_name = std::string(pStrTab + st_name);
     }
 
-
-    // push into FragmentLinker
-    LDSymbol* input_sym = NULL;
-
-    if (pInput.type() == Input::Object) {
-      input_sym = pLinker.addSymbol<Input::Object>(ld_name,
-                                                   ld_type,
-                                                   ld_desc,
-                                                   ld_binding,
-                                                   st_size,
-                                                   ld_value,
-                                                   ld_frag_ref,
-                                                   ld_vis);
-      // push into the input file
-      pInput.context()->addSymbol(input_sym);
-      continue;
-    }
-    else if (pInput.type() == Input::DynObj) {
-      input_sym = pLinker.addSymbol<Input::DynObj>(ld_name,
-                                                   ld_type,
-                                                   ld_desc,
-                                                   ld_binding,
-                                                   st_size,
-                                                   ld_value,
-                                                   ld_frag_ref,
-                                                   ld_vis);
-      continue;
-    }
-
+    pBuilder.AddSymbol(pInput,
+                       ld_name,
+                       ld_type,
+                       ld_desc,
+                       ld_binding,
+                       st_size,
+                       ld_value,
+                       section, ld_vis);
   } // end of for loop
   return true;
 }
@@ -308,7 +288,6 @@
 //===----------------------------------------------------------------------===//
 /// ELFReader::readRela - read ELF rela and create Relocation
 bool ELFReader<32, true>::readRela(Input& pInput,
-                                   FragmentLinker& pLinker,
                                    LDSection& pSection,
                                    const MemoryRegion& pRegion) const
 {
@@ -327,9 +306,9 @@
       r_addend = relaTab[idx].r_addend;
     }
     else {
-      r_offset = bswap32(relaTab[idx].r_offset);
-      r_info   = bswap32(relaTab[idx].r_info);
-      r_addend = bswap32(relaTab[idx].r_addend);
+      r_offset = mcld::bswap32(relaTab[idx].r_offset);
+      r_info   = mcld::bswap32(relaTab[idx].r_info);
+      r_addend = mcld::bswap32(relaTab[idx].r_addend);
     }
 
     uint8_t  r_type = static_cast<unsigned char>(r_info);
@@ -339,14 +318,13 @@
       fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path();
     }
 
-    pLinker.addRelocation(r_type, *symbol, pSection, r_offset, r_addend);
+    IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend);
   } // end of for
   return true;
 }
 
 /// readRel - read ELF rel and create Relocation
 bool ELFReader<32, true>::readRel(Input& pInput,
-                                  FragmentLinker& pLinker,
                                   LDSection& pSection,
                                   const MemoryRegion& pRegion) const
 {
@@ -363,8 +341,8 @@
       r_info   = relTab[idx].r_info;
     }
     else {
-      r_offset = bswap32(relTab[idx].r_offset);
-      r_info   = bswap32(relTab[idx].r_info);
+      r_offset = mcld::bswap32(relTab[idx].r_offset);
+      r_info   = mcld::bswap32(relTab[idx].r_info);
     }
 
     uint8_t  r_type = static_cast<unsigned char>(r_info);
@@ -375,7 +353,7 @@
       fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path();
     }
 
-    pLinker.addRelocation(r_type, *symbol, pSection, r_offset);
+    IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset);
   } // end of for
   return true;
 }
@@ -396,8 +374,8 @@
                           reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
 
   if (llvm::sys::isLittleEndianHost())
-    return (hdr->e_machine == target().machine());
-  return (bswap16(hdr->e_machine) == target().machine());
+    return (hdr->e_machine == target().getInfo().machine());
+  return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine());
 }
 
 /// fileType - return the file type
@@ -409,7 +387,7 @@
   if (llvm::sys::isLittleEndianHost())
     type = hdr->e_type;
   else
-    type = bswap16(hdr->e_type);
+    type = mcld::bswap16(hdr->e_type);
 
   switch(type) {
   case llvm::ELF::ET_REL:
@@ -445,10 +423,10 @@
     shstrtab  = ehdr->e_shstrndx;
   }
   else {
-    shoff     = bswap32(ehdr->e_shoff);
-    shentsize = bswap16(ehdr->e_shentsize);
-    shnum     = bswap16(ehdr->e_shnum);
-    shstrtab  = bswap16(ehdr->e_shstrndx);
+    shoff     = mcld::bswap32(ehdr->e_shoff);
+    shentsize = mcld::bswap16(ehdr->e_shentsize);
+    shnum     = mcld::bswap16(ehdr->e_shnum);
+    shstrtab  = mcld::bswap16(ehdr->e_shstrndx);
   }
 
   // If the file has no section header table, e_shoff holds zero.
@@ -476,8 +454,8 @@
     sh_size   = shdr->sh_size;
   }
   else {
-    sh_offset = bswap32(shdr->sh_offset);
-    sh_size   = bswap32(shdr->sh_size);
+    sh_offset = mcld::bswap32(shdr->sh_offset);
+    sh_size   = mcld::bswap32(shdr->sh_size);
   }
 
   MemoryRegion* sect_name_region = pInput.memArea()->request(
@@ -500,14 +478,14 @@
       sh_addralign = shdrTab[idx].sh_addralign;
     }
     else {
-      sh_name      = bswap32(shdrTab[idx].sh_name);
-      sh_type      = bswap32(shdrTab[idx].sh_type);
-      sh_flags     = bswap32(shdrTab[idx].sh_flags);
-      sh_offset    = bswap32(shdrTab[idx].sh_offset);
-      sh_size      = bswap32(shdrTab[idx].sh_size);
-      sh_link      = bswap32(shdrTab[idx].sh_link);
-      sh_info      = bswap32(shdrTab[idx].sh_info);
-      sh_addralign = bswap32(shdrTab[idx].sh_addralign);
+      sh_name      = mcld::bswap32(shdrTab[idx].sh_name);
+      sh_type      = mcld::bswap32(shdrTab[idx].sh_type);
+      sh_flags     = mcld::bswap32(shdrTab[idx].sh_flags);
+      sh_offset    = mcld::bswap32(shdrTab[idx].sh_offset);
+      sh_size      = mcld::bswap32(shdrTab[idx].sh_size);
+      sh_link      = mcld::bswap32(shdrTab[idx].sh_link);
+      sh_info      = mcld::bswap32(shdrTab[idx].sh_info);
+      sh_addralign = mcld::bswap32(shdrTab[idx].sh_addralign);
     }
 
     LDSection* section = IRBuilder::CreateELFHeader(pInput,
@@ -574,8 +552,8 @@
     st_shndx = entry->st_shndx;
   }
   else {
-    st_name  = bswap32(entry->st_name);
-    st_shndx = bswap16(entry->st_shndx);
+    st_name  = mcld::bswap32(entry->st_name);
+    st_shndx = mcld::bswap16(entry->st_shndx);
   }
 
   MemoryRegion* strtab_region = pInput.memArea()->request(
@@ -635,8 +613,8 @@
       d_tag = dynamic[idx].d_tag;
       d_val = dynamic[idx].d_un.d_val;
     } else {
-      d_tag = bswap32(dynamic[idx].d_tag);
-      d_val = bswap32(dynamic[idx].d_un.d_val);
+      d_tag = mcld::bswap32(dynamic[idx].d_tag);
+      d_val = mcld::bswap32(dynamic[idx].d_un.d_val);
     }
 
     switch (d_tag) {
diff --git a/lib/LD/ELFWriter.cpp b/lib/LD/ELFWriter.cpp
index 93fc4b9..a37e654 100644
--- a/lib/LD/ELFWriter.cpp
+++ b/lib/LD/ELFWriter.cpp
@@ -49,11 +49,11 @@
   memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
 
   header->e_ident[EI_CLASS]      = ELFCLASS32;
-  header->e_ident[EI_DATA]       = target().isLittleEndian()?
+  header->e_ident[EI_DATA]       = pConfig.targets().isLittleEndian()?
                                        ELFDATA2LSB : ELFDATA2MSB;
-  header->e_ident[EI_VERSION]    = target().ELFVersion();
-  header->e_ident[EI_OSABI]      = target().OSABI();
-  header->e_ident[EI_ABIVERSION] = target().ABIVersion();
+  header->e_ident[EI_VERSION]    = target().getInfo().ELFVersion();
+  header->e_ident[EI_OSABI]      = target().getInfo().OSABI();
+  header->e_ident[EI_ABIVERSION] = target().getInfo().ABIVersion();
 
   // FIXME: add processor-specific and core file types.
   switch(pConfig.codeGenType()) {
@@ -70,7 +70,7 @@
       llvm::errs() << "unspported output file type: " << pConfig.codeGenType() << ".\n";
       header->e_type = ET_NONE;
   }
-  header->e_machine   = target().machine();
+  header->e_machine   = target().getInfo().machine();
   header->e_version   = header->e_ident[EI_VERSION];
   header->e_entry     = getEntryPoint(pConfig, pModule);
 
@@ -101,11 +101,11 @@
   memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
 
   header->e_ident[EI_CLASS]      = ELFCLASS64;
-  header->e_ident[EI_DATA]       = target().isLittleEndian()?
+  header->e_ident[EI_DATA]       = pConfig.targets().isLittleEndian()?
                                        ELFDATA2LSB : ELFDATA2MSB;
-  header->e_ident[EI_VERSION]    = target().ELFVersion();
-  header->e_ident[EI_OSABI]      = target().OSABI();
-  header->e_ident[EI_ABIVERSION] = target().ABIVersion();
+  header->e_ident[EI_VERSION]    = target().getInfo().ELFVersion();
+  header->e_ident[EI_OSABI]      = target().getInfo().OSABI();
+  header->e_ident[EI_ABIVERSION] = target().getInfo().ABIVersion();
 
   // FIXME: add processor-specific and core file types.
   switch(pConfig.codeGenType()) {
@@ -122,7 +122,7 @@
       llvm::errs() << "unspported output file type: " << pConfig.codeGenType() << ".\n";
       header->e_type = ET_NONE;
   }
-  header->e_machine   = target().machine();
+  header->e_machine   = target().getInfo().machine();
   header->e_version   = header->e_ident[EI_VERSION];
   header->e_entry     = getEntryPoint(pConfig, pModule);
 
@@ -500,10 +500,18 @@
 /// getSectInfo - compute ElfXX_Shdr::sh_info
 uint64_t ELFWriter::getSectInfo(const LDSection& pSection) const
 {
-  const LDSection* info_link = pSection.getLink();
-  if (NULL == info_link)
-    return 0x0;
-  return info_link->index();
+  if (llvm::ELF::SHT_SYMTAB == pSection.type() ||
+      llvm::ELF::SHT_DYNSYM == pSection.type())
+    return pSection.getInfo();
+
+  if (llvm::ELF::SHT_REL == pSection.type() ||
+      llvm::ELF::SHT_RELA == pSection.type()) {
+    const LDSection* info_link = pSection.getLink();
+    if (NULL != info_link)
+      return info_link->index();
+  }
+
+  return 0x0;
 }
 
 /// getELF32LastStartOffset
@@ -579,9 +587,6 @@
         assert(0x0 == size);
         break;
       }
-      case Fragment::Relocation:
-        llvm::report_fatal_error("relocation fragment should not be in a regular section.\n");
-        break;
       case Fragment::Target:
         llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
         break;
diff --git a/lib/LD/GNUArchiveReader.cpp b/lib/LD/GNUArchiveReader.cpp
index 9aeaa6b..82e4fec 100644
--- a/lib/LD/GNUArchiveReader.cpp
+++ b/lib/LD/GNUArchiveReader.cpp
@@ -262,7 +262,7 @@
     // read the number of symbols
     uint32_t number = 0;
     if (llvm::sys::isLittleEndianHost())
-      number = bswap32(*data);
+      number = mcld::bswap32(*data);
     else
       number = *data;
 
@@ -273,7 +273,7 @@
     // add the archive symbols
     for (uint32_t i = 0; i < number; ++i) {
       if (llvm::sys::isLittleEndianHost())
-        pArchive.addSymbol(name, bswap32(*data));
+        pArchive.addSymbol(name, mcld::bswap32(*data));
       else
         pArchive.addSymbol(name, *data);
       name += strlen(name) + 1;
diff --git a/lib/LD/GroupReader.cpp b/lib/LD/GroupReader.cpp
index 91e79c0..a407c3d 100644
--- a/lib/LD/GroupReader.cpp
+++ b/lib/LD/GroupReader.cpp
@@ -94,7 +94,7 @@
     }
     else {
       fatal(diag::err_unrecognized_input_file) << (*input)->path()
-                                               << pConfig.triple().str();
+                                               << pConfig.targets().triple().str();
     }
     ++input;
   }
diff --git a/lib/LD/Layout.cpp b/lib/LD/Layout.cpp
deleted file mode 100644
index a2a1028..0000000
--- a/lib/LD/Layout.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-//===- Layout.cpp ---------------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/LD/Layout.h>
-
-#include <mcld/Module.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/ADT/SizeTraits.h>
-#include <mcld/LD/LDFileFormat.h>
-#include <mcld/LD/LDSection.h>
-#include <mcld/Support/MsgHandling.h>
-#include <mcld/Target/TargetLDBackend.h>
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// Layout
-//===----------------------------------------------------------------------===//
-void Layout::sortSectionOrder(const TargetLDBackend& pBackend,
-                              const LinkerConfig& pConfig)
-{
-  typedef std::pair<LDSection*, unsigned int> SectOrder;
-  typedef std::vector<SectOrder > SectListTy;
-  SectListTy sect_list;
-  // get section order from backend
-  for (size_t index = 0; index < m_SectionOrder.size(); ++index) {
-    sect_list.push_back(
-            std::make_pair(
-                    m_SectionOrder[index],
-                    pBackend.getSectionOrder(*m_SectionOrder[index])
-            ));
-  }
-
-  // simple insertion sort should be fine for general cases such as so and exec
-  for (unsigned int i = 1; i < sect_list.size(); ++i) {
-    SectOrder order = sect_list[i];
-    int j = i - 1;
-    while (j >= 0 && sect_list[j].second > order.second) {
-      sect_list[j + 1] = sect_list[j];
-      --j;
-    }
-    sect_list[j + 1] = order;
-  }
-
-  // update the sorted ordering to m_SectionOrder
-  m_SectionOrder.clear();
-  for (size_t index = 0; index < sect_list.size(); ++index) {
-    m_SectionOrder.push_back(sect_list[index].first);
-  }
-}
-
-/// layout - layout the sections
-///   1. finalize fragment offset
-///   2. compute section order
-///   3. finalize section offset
-bool Layout::layout(Module& pModule,
-                    const TargetLDBackend& pBackend,
-                    const LinkerConfig& pConfig)
-{
-  // determine what sections in output context will go into final output, and
-  // push the needed sections into m_SectionOrder for later processing
-  Module::iterator it, itEnd = pModule.end();
-  for (it = pModule.begin(); it != itEnd; ++it) {
-    // calculate 1. all fragment offset, and 2. the section order
-    LDSection* sect = *it;
-
-    switch (sect->kind()) {
-      // take NULL and StackNote directly
-      case LDFileFormat::Null:
-      case LDFileFormat::StackNote:
-        m_SectionOrder.push_back(sect);
-        break;
-      // ignore if section size is 0
-      case LDFileFormat::Regular:
-      case LDFileFormat::Target:
-      case LDFileFormat::MetaData:
-      case LDFileFormat::BSS:
-      case LDFileFormat::Debug:
-      case LDFileFormat::EhFrame:
-      case LDFileFormat::GCCExceptTable:
-      case LDFileFormat::NamePool:
-      case LDFileFormat::Relocation:
-      case LDFileFormat::Note:
-      case LDFileFormat::EhFrameHdr:
-        if (0 != sect->size()) {
-          m_SectionOrder.push_back(sect);
-        }
-        break;
-      case LDFileFormat::Group:
-        if (LinkerConfig::Object == pConfig.codeGenType()) {
-          //TODO: support incremental linking
-          ;
-        }
-        break;
-      case LDFileFormat::Version:
-        if (0 != sect->size()) {
-          m_SectionOrder.push_back(sect);
-          warning(diag::warn_unsupported_symbolic_versioning) << sect->name();
-        }
-        break;
-      default:
-        if (0 != sect->size()) {
-          error(diag::err_unsupported_section) << sect->name() << sect->kind();
-        }
-        break;
-    }
-  } // end of for
-
-  // perform sorting on m_SectionOrder to get a ordering for final layout
-  sortSectionOrder(pBackend, pConfig);
-
-  // 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.
-  // always set NULL section's offset to 0
-  m_SectionOrder[0]->setOffset(0);
-  for (size_t index = 1; index < m_SectionOrder.size(); ++index) {
-
-    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);
-  }
-
-  // FIXME: Currently Writer bases on the section table in output context to
-  // write out sections, so we have to update its content..
-  pModule.getSectionTable().clear();
-  for (size_t index = 0; index < m_SectionOrder.size(); ++index) {
-    pModule.getSectionTable().push_back(m_SectionOrder[index]);
-    // after sorting, update the correct output section indices
-    m_SectionOrder[index]->setIndex(index);
-  }
-  return true;
-}
-
diff --git a/lib/LD/NamePool.cpp b/lib/LD/NamePool.cpp
index 9e4755d..6af1f7d 100644
--- a/lib/LD/NamePool.cpp
+++ b/lib/LD/NamePool.cpp
@@ -93,7 +93,7 @@
     pOldInfo->override(*old_symbol);
   }
 
-  // exit and is a symbol
+  // exist and is a symbol
   // symbol resolution
   bool override = false;
   unsigned int action = Resolver::LastAction;
diff --git a/lib/LD/RelocData.cpp b/lib/LD/RelocData.cpp
index 92192e6..1c9411d 100644
--- a/lib/LD/RelocData.cpp
+++ b/lib/LD/RelocData.cpp
@@ -7,9 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 #include <mcld/LD/RelocData.h>
+#include <mcld/Support/GCFactory.h>
+
+#include <llvm/Support/ManagedStatic.h>
 
 using namespace mcld;
 
+typedef GCFactory<RelocData, MCLD_SECTIONS_PER_INPUT> RelocDataFactory;
+
+static llvm::ManagedStatic<RelocDataFactory> g_RelocDataFactory;
+
 //===----------------------------------------------------------------------===//
 // RelocData
 //===----------------------------------------------------------------------===//
@@ -17,23 +24,32 @@
   : m_pSection(NULL) {
 }
 
-RelocData::RelocData(const LDSection &pSection)
+RelocData::RelocData(LDSection &pSection)
   : m_pSection(&pSection) {
 }
 
-RelocData* RelocData::Create(const LDSection& pSection)
+RelocData* RelocData::Create(LDSection& pSection)
 {
-  return new RelocData(pSection);
-}
-
-RelocData* RelocData::Create()
-{
-  return new RelocData();
+  RelocData* result = g_RelocDataFactory->allocate();
+  new (result) RelocData(pSection);
+  return result;
 }
 
 void RelocData::Destroy(RelocData*& pSection)
 {
-  delete pSection;
+  pSection->~RelocData();
+  g_RelocDataFactory->deallocate(pSection);
   pSection = NULL;
 }
 
+void RelocData::Clear()
+{
+  g_RelocDataFactory->clear();
+}
+
+RelocData& RelocData::append(Relocation& pRelocation)
+{
+  m_Relocations.push_back(&pRelocation);
+  return *this;
+}
+
diff --git a/lib/LD/RelocationFactory.cpp b/lib/LD/RelocationFactory.cpp
index 6fb6cb2..52bf45c 100644
--- a/lib/LD/RelocationFactory.cpp
+++ b/lib/LD/RelocationFactory.cpp
@@ -6,62 +6,69 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
 #include <mcld/LD/RelocationFactory.h>
-
-#include <cstring>
-#include <cassert>
+#include <mcld/LinkerConfig.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <mcld/Support/MsgHandling.h>
 
 #include <llvm/Support/Host.h>
 
-#include <mcld/Target/GOT.h>
-#include <mcld/Target/TargetLDBackend.h>
+#include <cstring>
+#include <cassert>
 
 using namespace mcld;
 
 //===----------------------------------------------------------------------===//
 // RelocationFactory
 //===----------------------------------------------------------------------===//
-RelocationFactory::RelocationFactory(size_t pNum)
-  : GCFactory<Relocation, 0>(pNum),
-    m_pLinker(NULL) {
+RelocationFactory::RelocationFactory()
+  : GCFactory<Relocation, MCLD_RELOCATIONS_PER_INPUT>(), m_pConfig(NULL) {
 }
 
-RelocationFactory::~RelocationFactory()
+void RelocationFactory::setConfig(const LinkerConfig& pConfig)
 {
+  m_pConfig = &pConfig;
 }
 
 Relocation* RelocationFactory::produce(RelocationFactory::Type pType,
                                        FragmentRef& pFragRef,
                                        Address pAddend)
 {
+  if (NULL == m_pConfig) {
+    fatal(diag::reloc_factory_has_not_config);
+    return NULL;
+  }
+
   // target_data is the place where the relocation applys to.
   // Use TargetDataFactory to generate temporary data, and copy the
   // content of the fragment into this data.
   DWord target_data = 0;
 
   // byte swapping if the host and target have different endian
-  if(llvm::sys::isLittleEndianHost() != getTarget().isLittleEndian()) {
+  if(llvm::sys::isLittleEndianHost() != m_pConfig->targets().isLittleEndian()) {
      uint32_t tmp_data;
 
-     switch(getTarget().bitclass()) {
-      case 32u:
-        pFragRef.memcpy(&tmp_data, 4);
-        tmp_data = bswap32(tmp_data);
-        target_data = tmp_data;
-        break;
-
-      case 64u:
-        pFragRef.memcpy(&target_data, 8);
-        target_data = bswap64(target_data);
-        break;
-
-      default:
-        break;
-    }
+     switch (m_pConfig->targets().bitclass()) {
+       case 32: {
+         pFragRef.memcpy(&tmp_data, 4);
+         tmp_data = mcld::bswap32(tmp_data);
+         target_data = tmp_data;
+         break;
+       }
+       case 64: {
+         pFragRef.memcpy(&target_data, 8);
+         target_data = mcld::bswap64(target_data);
+         break;
+       }
+       default: {
+         fatal(diag::unsupported_bitclass) << m_pConfig->targets().triple().str()
+                                         << m_pConfig->targets().bitclass();
+         return NULL;
+       }
+     } // end of switch
   }
   else {
-    pFragRef.memcpy(&target_data, (getTarget().bitclass()/8));
+    pFragRef.memcpy(&target_data, (m_pConfig->targets().bitclass()/8));
   }
 
   Relocation *result = allocate();
@@ -83,19 +90,3 @@
    /** GCFactory will recycle the relocation **/
 }
 
-void RelocationFactory::setFragmentLinker(const FragmentLinker& pLinker)
-{
-  m_pLinker = &pLinker;
-}
-
-const FragmentLinker& RelocationFactory::getFragmentLinker() const
-{
-  assert(NULL != m_pLinker);
-  return *m_pLinker;
-}
-
-bool RelocationFactory::hasFragmentLinker() const
-{
-  return (NULL != m_pLinker);
-}
-
diff --git a/lib/LD/SectionData.cpp b/lib/LD/SectionData.cpp
index 43800ff..bb73724 100644
--- a/lib/LD/SectionData.cpp
+++ b/lib/LD/SectionData.cpp
@@ -44,3 +44,8 @@
   pSection = NULL;
 }
 
+void SectionData::Clear()
+{
+  g_SectDataFactory->clear();
+}
+
diff --git a/lib/LD/SectionSymbolSet.cpp b/lib/LD/SectionSymbolSet.cpp
index 79f4d78..e369412 100644
--- a/lib/LD/SectionSymbolSet.cpp
+++ b/lib/LD/SectionSymbolSet.cpp
@@ -64,13 +64,16 @@
 bool SectionSymbolSet::finalize(LDSection& pOutSect,
                                 SymbolTable& pSymTab)
 {
+  if (0x0 == pOutSect.size())
+    return true;
+
   LDSymbol* sym = get(pOutSect);
   assert(NULL != sym);
   FragmentRef* frag_ref = NULL;
   switch (pOutSect.kind()) {
     case LDFileFormat::Relocation:
-      frag_ref = FragmentRef::Create(pOutSect.getRelocData()->front(), 0x0);
-      break;
+      // Relocation section should not have section symbol.
+      return true;
 
     case LDFileFormat::EhFrame:
       frag_ref = FragmentRef::Create(
diff --git a/lib/LD/StubFactory.cpp b/lib/LD/StubFactory.cpp
index 1fc43dd..cbe14b2 100644
--- a/lib/LD/StubFactory.cpp
+++ b/lib/LD/StubFactory.cpp
@@ -6,25 +6,23 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
 #include <mcld/LD/StubFactory.h>
 #include <mcld/LD/BranchIslandFactory.h>
 #include <mcld/LD/BranchIsland.h>
 #include <mcld/LD/LDSymbol.h>
 #include <mcld/LD/ResolveInfo.h>
-#include <mcld/LD/RelocationFactory.h>
 #include <mcld/Fragment/Stub.h>
 #include <mcld/Fragment/Relocation.h>
 #include <mcld/Fragment/FragmentLinker.h>
 #include <mcld/Fragment/FragmentRef.h>
 
 #include <string>
+
 using namespace mcld;
 
-StubFactory::StubFactory()
-{
-}
-
+//===----------------------------------------------------------------------===//
+// StubFactory
+//===----------------------------------------------------------------------===//
 StubFactory::~StubFactory()
 {
   for (StubPoolType::iterator it = m_StubPool.begin(), ie = m_StubPool.end();
@@ -42,7 +40,6 @@
 Stub* StubFactory::create(Relocation& pReloc,
                           uint64_t pTargetSymValue,
                           FragmentLinker& pLinker,
-                          RelocationFactory& pRelocFactory,
                           BranchIslandFactory& pBRIslandFactory)
 {
   // find if there is a prototype stub for the input relocation
@@ -93,8 +90,7 @@
       for (Stub::fixup_iterator it = stub->fixup_begin(),
              ie = stub->fixup_end(); it != ie; ++it) {
 
-        Relocation* reloc = pRelocFactory.produce(
-                                 (*it)->type(),
+        Relocation* reloc = Relocation::Create((*it)->type(),
                                  *(FragmentRef::Create(*stub, (*it)->offset())),
                                  (*it)->addend());
         reloc->setSymInfo(pReloc.symInfo());
diff --git a/lib/Object/ObjectLinker.cpp b/lib/Object/ObjectLinker.cpp
index 93fdb20..1e2ccb4 100644
--- a/lib/Object/ObjectLinker.cpp
+++ b/lib/Object/ObjectLinker.cpp
@@ -11,7 +11,7 @@
 #include <mcld/LinkerConfig.h>
 #include <mcld/Module.h>
 #include <mcld/InputTree.h>
-#include <mcld/MC/InputBuilder.h>
+#include <mcld/IRBuilder.h>
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/LDContext.h>
 #include <mcld/LD/Archive.h>
@@ -19,11 +19,12 @@
 #include <mcld/LD/ObjectReader.h>
 #include <mcld/LD/DynObjReader.h>
 #include <mcld/LD/GroupReader.h>
+#include <mcld/LD/BinaryReader.h>
 #include <mcld/LD/ObjectWriter.h>
 #include <mcld/LD/DynObjWriter.h>
 #include <mcld/LD/ExecWriter.h>
+#include <mcld/LD/BinaryWriter.h>
 #include <mcld/LD/ResolveInfo.h>
-#include <mcld/LD/Layout.h>
 #include <mcld/LD/RelocData.h>
 #include <mcld/Support/RealPath.h>
 #include <mcld/Support/MemoryArea.h>
@@ -39,20 +40,22 @@
 
 ObjectLinker::ObjectLinker(const LinkerConfig& pConfig,
                            Module& pModule,
-                           InputBuilder& pInputBuilder,
+                           IRBuilder& pBuilder,
                            TargetLDBackend& pLDBackend)
   : m_Config(pConfig),
     m_Module(pModule),
-    m_InputBuilder(pInputBuilder),
+    m_Builder(pBuilder),
     m_pLinker(NULL),
     m_LDBackend(pLDBackend),
     m_pObjectReader(NULL),
     m_pDynObjReader(NULL),
     m_pArchiveReader(NULL),
+    m_pGroupReader(NULL),
+    m_pBinaryReader(NULL),
     m_pObjectWriter(NULL),
     m_pDynObjWriter(NULL),
     m_pExecWriter(NULL),
-    m_pGroupReader(NULL)
+    m_pBinaryWriter(NULL)
 {
   // set up soname
   if (!m_Config.options().soname().empty()) {
@@ -66,10 +69,12 @@
   delete m_pObjectReader;
   delete m_pDynObjReader;
   delete m_pArchiveReader;
+  delete m_pGroupReader;
+  delete m_pBinaryReader;
   delete m_pObjectWriter;
   delete m_pDynObjWriter;
   delete m_pExecWriter;
-  delete m_pGroupReader;
+  delete m_pBinaryWriter;
 }
 
 /// initFragmentLinker - initialize FragmentLinker
@@ -85,17 +90,19 @@
   // initialize the readers and writers
   // Because constructor can not be failed, we initalize all readers and
   // writers outside the FragmentLinker constructors.
-  m_pObjectReader  = m_LDBackend.createObjectReader(*m_pLinker);
+  m_pObjectReader  = m_LDBackend.createObjectReader(m_Builder);
   m_pArchiveReader = m_LDBackend.createArchiveReader(m_Module);
-  m_pDynObjReader  = m_LDBackend.createDynObjReader(*m_pLinker);
-  m_pObjectWriter  = m_LDBackend.createObjectWriter(*m_pLinker);
-  m_pDynObjWriter  = m_LDBackend.createDynObjWriter(*m_pLinker);
-  m_pExecWriter    = m_LDBackend.createExecWriter(*m_pLinker);
+  m_pDynObjReader  = m_LDBackend.createDynObjReader(m_Builder);
   m_pGroupReader   = new GroupReader(m_Module, *m_pObjectReader,
                                      *m_pDynObjReader, *m_pArchiveReader);
+  m_pBinaryReader  = m_LDBackend.createBinaryReader(m_Builder);
+  m_pObjectWriter  = m_LDBackend.createObjectWriter();
+  m_pDynObjWriter  = m_LDBackend.createDynObjWriter();
+  m_pExecWriter    = m_LDBackend.createExecWriter();
+  m_pBinaryWriter  = m_LDBackend.createBinaryWriter();
 
-  // initialize RelocationFactory
-  m_LDBackend.initRelocFactory(*m_pLinker);
+  // initialize Relocator
+  m_LDBackend.initRelocator(*m_pLinker);
 
   // initialize BranchIslandFactory
   m_LDBackend.initBRIslandFactory();
@@ -130,7 +137,7 @@
   for (input = m_Module.input_begin(); input!=inEnd; ++input) {
     // is a group node
     if (isGroup(input)) {
-      getGroupReader()->readGroup(input, m_InputBuilder, m_Config);
+      getGroupReader()->readGroup(input, m_Builder.getInputBuilder(), m_Config);
       continue;
     }
 
@@ -151,8 +158,14 @@
       continue;
     }
 
+    // read input as a binary file
+    if (m_Config.options().isBinaryInput()) {
+      (*input)->setType(Input::Object);
+      getBinaryReader()->readBinary(**input);
+      m_Module.getObjectList().push_back(*input);
+    }
     // is a relocatable object file
-    if (getObjectReader()->isMyFormat(**input)) {
+    else if (getObjectReader()->isMyFormat(**input)) {
       (*input)->setType(Input::Object);
       getObjectReader()->readHeader(**input);
       getObjectReader()->readSections(**input);
@@ -169,7 +182,7 @@
     // is an archive
     else if (getArchiveReader()->isMyFormat(**input)) {
       (*input)->setType(Input::Archive);
-      Archive archive(**input, m_InputBuilder);
+      Archive archive(**input, m_Builder.getInputBuilder());
       getArchiveReader()->readArchive(archive);
       if(archive.numOfObjectMember() > 0) {
         m_Module.getInputTree().merge<InputTree::Inclusive>(input,
@@ -178,7 +191,7 @@
     }
     else {
       fatal(diag::err_unrecognized_input_file) << (*input)->path()
-                                               << m_Config.triple().str();
+                                          << m_Config.targets().triple().str();
     }
   } // end of for
 }
@@ -342,18 +355,16 @@
 {
   // finalize the section symbols, set their fragment reference and push them
   // into output symbol table
-  Module::iterator iter, iterEnd = m_Module.end();
-  for (iter = m_Module.begin(); iter != iterEnd; ++iter) {
-    LDSection* section = *iter;
-    if (0x0 == section->size() || LDFileFormat::Relocation == section->kind())
-      continue;
-    m_Module.getSectionSymbolSet().finalize(
-                                           *section, m_Module.getSymbolTable());
+  Module::iterator sect, sEnd = m_Module.end();
+  for (sect = m_Module.begin(); sect != sEnd; ++sect) {
+    m_Module.getSectionSymbolSet().finalize(**sect, m_Module.getSymbolTable());
   }
 
   m_LDBackend.preLayout(m_Module, *m_pLinker);
 
-  m_LDBackend.allocateCommonSymbols(m_Module);
+  if (LinkerConfig::Object != m_Config.codeGenType() ||
+      m_Config.options().isDefineCommon())
+    m_LDBackend.allocateCommonSymbols(m_Module);
 
   /// check program interpreter - computer the name size of the runtime dyld
   if (!m_pLinker->isStaticLink() &&
@@ -380,8 +391,8 @@
 ///   directly
 bool ObjectLinker::layout()
 {
-  Layout layout;
-  return layout.layout(m_Module, m_LDBackend, m_Config);
+  m_LDBackend.layout(m_Module, *m_pLinker);
+  return true;
 }
 
 /// prelayout - help backend to do some modification after layout
@@ -422,6 +433,9 @@
     case LinkerConfig::Exec:
       getExecWriter()->writeExecutable(m_Module, pOutput);
       return true;
+    case LinkerConfig::Binary:
+      getBinaryWriter()->writeBinary(m_Module, pOutput);
+      return true;
     default:
       fatal(diag::unrecognized_output_file) << m_Config.codeGenType();
   }
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 891b2bb..15cd816 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -16,6 +16,45 @@
 
 using namespace mcld;
 
+static const size_t MaxOptWidth = 8;  // arbitrary spacing for printOptionDiff
+
+//===----------------------------------------------------------------------===//
+// SearchDirParser
+//===----------------------------------------------------------------------===//
+// parse - Return true on error.
+bool SearchDirParser::parse(Option &pOption,
+                            StringRef pArgName,
+                            StringRef pArg,
+                            std::string &pValue)
+{
+  char separator = *(pArgName.data() + 1);
+  if ('=' == separator)
+    pValue = '=';
+  pValue += pArg.str();
+  return false;
+}
+
+void SearchDirParser::printOptionDiff(const Option &pOption,
+                                      StringRef pValue,
+                                      OptVal pDefault,
+                                      size_t pGlobalWidth) const
+{
+  printOptionName(pOption, pGlobalWidth);
+  outs() << "= " << pValue;
+  size_t NumSpaces = MaxOptWidth > pValue.size()?MaxOptWidth - pValue.size():0;
+  outs().indent(NumSpaces) << " (default: ";
+  if (pDefault.hasValue())
+    outs() << pDefault.getValue();
+  else
+    outs() << "*no default*";
+  outs() << ")\n";
+}
+
+void SearchDirParser::anchor()
+{
+  // do nothing
+}
+
 //===----------------------------------------------------------------------===//
 // parser<mcld::sys::fs::Path>
 //===----------------------------------------------------------------------===//
@@ -28,8 +67,6 @@
   return false;
 }
 
-static const size_t MaxOptWidth = 8;  // arbitrary spacing for printOptionDiff
-
 void parser<mcld::sys::fs::Path>::printOptionDiff(const llvm::cl::Option &O,
                                                   const mcld::sys::fs::Path &V,
                                                   parser<mcld::sys::fs::Path>::OptVal Default,
@@ -53,40 +90,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// parser<mcld::MCLDDirectory>
-//===----------------------------------------------------------------------===//
-bool parser<mcld::MCLDDirectory>::parse(llvm::cl::Option &O,
-                                llvm::StringRef ArgName,
-                                llvm::StringRef Arg,
-                                mcld::MCLDDirectory &Val)
-{
-  Val.assign(Arg);
-  return false;
-}
-
-void parser<mcld::MCLDDirectory>::printOptionDiff(const llvm::cl::Option &O,
-                                                  const mcld::MCLDDirectory &V,
-                                                  parser<mcld::MCLDDirectory>::OptVal Default,
-                                                  size_t GlobalWidth) const
-{
-  printOptionName(O, GlobalWidth);
-  outs() << "= " << V.name();
-  size_t VSize = V.name().size();
-  size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;
-  outs().indent(NumSpaces) << " (default: ";
-  if (Default.hasValue())
-    outs() << Default.getValue().name();
-  else
-    outs() << "*no default*";
-  outs() << ")\n";
-}
-
-void parser<mcld::MCLDDirectory>::anchor()
-{
-  // do nothing
-}
-
-//===----------------------------------------------------------------------===//
 // parser<mcld::ZOption>
 //===----------------------------------------------------------------------===//
 bool parser<mcld::ZOption>::parse(llvm::cl::Option &O,
diff --git a/lib/Support/RegionFactory.cpp b/lib/Support/RegionFactory.cpp
index 7ed87f1..a52921b 100644
--- a/lib/Support/RegionFactory.cpp
+++ b/lib/Support/RegionFactory.cpp
@@ -9,6 +9,8 @@
 #include <mcld/Support/RegionFactory.h>
 #include <mcld/Support/Space.h>
 
+#include <new>
+
 using namespace mcld;
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp
index 8bfa235..38074d5 100644
--- a/lib/Support/TargetRegistry.cpp
+++ b/lib/Support/TargetRegistry.cpp
@@ -16,7 +16,8 @@
   s_TargetList.push_back(&T);
 }
 
-const mcld::Target* mcld::TargetRegistry::lookupTarget(const llvm::Target &pTarget)
+const mcld::Target*
+mcld::TargetRegistry::lookupTarget(const llvm::Target &pTarget)
 {
   mcld::Target *result = 0;
   TargetListTy::const_iterator TIter, TEnd = s_TargetList.end();
@@ -29,12 +30,14 @@
   return result;
 }
 
-const mcld::Target *mcld::TargetRegistry::lookupTarget(const std::string &pTriple,
-                                                       std::string &pError) 
+const mcld::Target*
+mcld::TargetRegistry::lookupTarget(const std::string &pTriple,
+                                   std::string &pError)
 {
   const llvm::Target* target = llvm::TargetRegistry::lookupTarget(pTriple, pError);
   if (!target)
-    return 0;
+    return NULL;
+
   return lookupTarget( *target );
 }
 
diff --git a/lib/Target/ARM/ARMELFDynamic.cpp b/lib/Target/ARM/ARMELFDynamic.cpp
index c81a6f3..cbec6e8 100644
--- a/lib/Target/ARM/ARMELFDynamic.cpp
+++ b/lib/Target/ARM/ARMELFDynamic.cpp
@@ -6,14 +6,15 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+#include "ARMELFDynamic.h"
 
 #include <mcld/LD/ELFFileFormat.h>
-#include "ARMELFDynamic.h"
 
 using namespace mcld;
 
-ARMELFDynamic::ARMELFDynamic(const GNULDBackend& pParent)
-  : ELFDynamic(pParent)
+ARMELFDynamic::ARMELFDynamic(const GNULDBackend& pParent,
+                             const LinkerConfig& pConfig)
+  : ELFDynamic(pParent, pConfig)
 {
 }
 
diff --git a/lib/Target/ARM/ARMELFDynamic.h b/lib/Target/ARM/ARMELFDynamic.h
index 914dcc4..826070b 100644
--- a/lib/Target/ARM/ARMELFDynamic.h
+++ b/lib/Target/ARM/ARMELFDynamic.h
@@ -18,7 +18,7 @@
 
 class ARMELFDynamic : public ELFDynamic {
 public:
-  ARMELFDynamic(const GNULDBackend& pParent);
+  ARMELFDynamic(const GNULDBackend& pParent, const LinkerConfig& pConfig);
   ~ARMELFDynamic();
 
 private:
diff --git a/lib/Target/ARM/ARMEmulation.cpp b/lib/Target/ARM/ARMEmulation.cpp
index 875d229..3995618 100644
--- a/lib/Target/ARM/ARMEmulation.cpp
+++ b/lib/Target/ARM/ARMEmulation.cpp
@@ -18,6 +18,10 @@
   if (!MCLDEmulateELF(pConfig))
     return false;
 
+  // set up bitclass and endian
+  pConfig.targets().setEndian(TargetOptions::Little);
+  pConfig.targets().setBitClass(32);
+
   // set up target-dependent constraints of attributes
   pConfig.attribute().constraint().enableWholeArchive();
   pConfig.attribute().constraint().enableAsNeeded();
diff --git a/lib/Target/ARM/ARMGNUInfo.h b/lib/Target/ARM/ARMGNUInfo.h
new file mode 100644
index 0000000..9091dce
--- /dev/null
+++ b/lib/Target/ARM/ARMGNUInfo.h
@@ -0,0 +1,29 @@
+//===- ARMGNUInfo.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_ARM_GNU_INFO_H
+#define MCLD_TARGET_ARM_GNU_INFO_H
+#include <mcld/Target/GNUInfo.h>
+
+#include <llvm/Support/ELF.h>
+
+namespace mcld {
+
+class ARMGNUInfo : public GNUInfo
+{
+public:
+  ARMGNUInfo(const llvm::Triple& pTriple) : GNUInfo(pTriple) { }
+
+  uint32_t machine() const { return llvm::ELF::EM_ARM; }
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/ARMGOT.cpp b/lib/Target/ARM/ARMGOT.cpp
index 3d2d07a..1796635 100644
--- a/lib/Target/ARM/ARMGOT.cpp
+++ b/lib/Target/ARM/ARMGOT.cpp
@@ -8,8 +8,6 @@
 //===----------------------------------------------------------------------===//
 #include "ARMGOT.h"
 
-#include <new>
-
 #include <llvm/Support/Casting.h>
 
 #include <mcld/LD/LDSection.h>
@@ -18,7 +16,6 @@
 #include <mcld/Support/MsgHandling.h>
 
 namespace {
-  const size_t ARMGOTEntrySize = 4;
   const unsigned int ARMGOT0Num = 3;
 } // end of anonymous namespace
 
@@ -27,7 +24,7 @@
 //===----------------------------------------------------------------------===//
 // ARMGOT
 ARMGOT::ARMGOT(LDSection& pSection)
-  : GOT(pSection, ARMGOTEntrySize)
+  : GOT(pSection), m_pLast(NULL)
 {
   // Create GOT0 entries.
   reserve(ARMGOT0Num);
@@ -47,9 +44,28 @@
   return (m_SectionData->size() > ARMGOT0Num);
 }
 
+void ARMGOT::reserve(size_t pNum)
+{
+  for (size_t i = 0; i < pNum; i++) {
+    new ARMGOTEntry(0, m_SectionData);
+  }
+}
+
+ARMGOTEntry* ARMGOT::consume()
+{
+  if (NULL == m_pLast) {
+    assert(!empty() && "Consume empty GOT entry!");
+    m_pLast = llvm::cast<ARMGOTEntry>(&m_SectionData->front());
+    return m_pLast;
+  }
+
+  m_pLast = llvm::cast<ARMGOTEntry>(m_pLast->getNextNode());
+  return m_pLast;
+}
+
 void ARMGOT::reserveGOTPLT()
 {
-  Entry* entry = new Entry(0, getEntrySize(), m_SectionData);
+  ARMGOTEntry* entry = new ARMGOTEntry(0, m_SectionData);
   if (NULL == m_GOTPLT.front) {
     // GOTPLT is empty
     if (NULL == m_GOT.front) {
@@ -60,26 +76,26 @@
     else {
       // GOTn is not empty. Shift GOTn backward by one entry.
       m_GOTPLT.front = m_GOT.front;
-      m_GOT.front = llvm::cast<GOT::Entry>(m_GOT.front->getNextNode());
+      m_GOT.front = llvm::cast<ARMGOTEntry>(m_GOT.front->getNextNode());
     }
   }
   else {
     // GOTPLT is not empty
     if (NULL != m_GOT.front)
-      m_GOT.front = llvm::cast<GOT::Entry>(m_GOT.front->getNextNode());
+      m_GOT.front = llvm::cast<ARMGOTEntry>(m_GOT.front->getNextNode());
   }
 }
 
 void ARMGOT::reserveGOT()
 {
-  Entry* entry = new Entry(0, getEntrySize(), m_SectionData);
+  ARMGOTEntry* entry = new ARMGOTEntry(0, m_SectionData);
   if (NULL == m_GOT.front) {
     // Entry must be the last entry. We can directly assign it to GOT part.
     m_GOT.front = entry;
   }
 }
 
-GOT::Entry* ARMGOT::consumeGOTPLT()
+ARMGOTEntry* ARMGOT::consumeGOTPLT()
 {
   assert(NULL != m_GOTPLT.front && "Consuming empty GOTPLT section!");
 
@@ -87,13 +103,13 @@
     m_GOTPLT.last_used = m_GOTPLT.front;
   }
   else {
-    m_GOTPLT.last_used = llvm::cast<GOT::Entry>(m_GOTPLT.last_used->getNextNode());
+    m_GOTPLT.last_used = llvm::cast<ARMGOTEntry>(m_GOTPLT.last_used->getNextNode());
     assert(m_GOTPLT.last_used != m_GOT.front && "No GOT/PLT entry to consume!");
   }
   return m_GOTPLT.last_used;
 }
 
-GOT::Entry* ARMGOT::consumeGOT()
+ARMGOTEntry* ARMGOT::consumeGOT()
 {
   assert(NULL != m_GOT.front && "Consuming empty GOT section!");
 
@@ -101,7 +117,7 @@
     m_GOT.last_used = m_GOT.front;
   }
   else {
-    m_GOT.last_used = llvm::cast<GOT::Entry>(m_GOT.last_used->getNextNode());
+    m_GOT.last_used = llvm::cast<ARMGOTEntry>(m_GOT.last_used->getNextNode());
     assert(m_GOT.last_used != NULL && "No GOTn entry to consume!");
   }
   return m_GOT.last_used;
@@ -109,8 +125,8 @@
 
 void ARMGOT::applyGOT0(uint64_t pAddress)
 {
-  llvm::cast<Entry>
-    (*(m_SectionData->getFragmentList().begin())).setContent(pAddress);
+  llvm::cast<ARMGOTEntry>
+    (*(m_SectionData->getFragmentList().begin())).setValue(pAddress);
 }
 
 void ARMGOT::applyGOTPLT(uint64_t pPLTBase)
@@ -126,7 +142,7 @@
     e_end = SectionData::iterator(m_GOT.front);
 
   while (entry != e_end) {
-    llvm::cast<GOT::Entry>(entry)->setContent(pPLTBase);
+    llvm::cast<ARMGOTEntry>(entry)->setValue(pPLTBase);
     ++entry;
   }
 }
@@ -135,13 +151,12 @@
 {
   uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
 
-  Entry* got = 0;
-  unsigned int entry_size = getEntrySize();
+  ARMGOTEntry* got = NULL;
   uint64_t result = 0x0;
   for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) {
-      got = &(llvm::cast<Entry>((*it)));
-      *buffer = static_cast<uint32_t>(got->getContent());
-      result += entry_size;
+      got = &(llvm::cast<ARMGOTEntry>((*it)));
+      *buffer = static_cast<uint32_t>(got->getValue());
+      result += ARMGOTEntry::EntrySize;
   }
   return result;
 }
diff --git a/lib/Target/ARM/ARMGOT.h b/lib/Target/ARM/ARMGOT.h
index 1e8f383..be22c67 100644
--- a/lib/Target/ARM/ARMGOT.h
+++ b/lib/Target/ARM/ARMGOT.h
@@ -21,6 +21,17 @@
 class LDSection;
 class MemoryRegion;
 
+/** \class ARMGOTEntry
+ *  \brief GOT Entry with size of 4 bytes
+ */
+class ARMGOTEntry : public GOT::Entry<4>
+{
+public:
+  ARMGOTEntry(uint64_t pContent, SectionData* pParent)
+   : GOT::Entry<4>(pContent, pParent)
+  {}
+};
+
 /** \class ARMGOT
  *  \brief ARM Global Offset Table.
  *
@@ -45,13 +56,17 @@
 
   ~ARMGOT();
 
+  void reserve(size_t pNum = 1);
+
   void reserveGOTPLT();
 
   void reserveGOT();
 
-  GOT::Entry* consumeGOT();
+  ARMGOTEntry* consume();
 
-  GOT::Entry* consumeGOTPLT();
+  ARMGOTEntry* consumeGOT();
+
+  ARMGOTEntry* consumeGOTPLT();
 
   uint64_t emit(MemoryRegion& pRegion);
 
@@ -67,14 +82,15 @@
     Part() : front(NULL), last_used(NULL) { }
 
   public:
-    GOT::Entry* front;
-    GOT::Entry* last_used;
+    ARMGOTEntry* front;
+    ARMGOTEntry* last_used;
   };
 
 private:
   Part m_GOTPLT;
   Part m_GOT;
 
+  ARMGOTEntry* m_pLast; ///< the last consumed entry
 };
 
 } // namespace of mcld
diff --git a/lib/Target/ARM/ARMLDBackend.cpp b/lib/Target/ARM/ARMLDBackend.cpp
index a90ae63..2fd7e64 100644
--- a/lib/Target/ARM/ARMLDBackend.cpp
+++ b/lib/Target/ARM/ARMLDBackend.cpp
@@ -7,9 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 #include "ARM.h"
+#include "ARMGNUInfo.h"
 #include "ARMELFDynamic.h"
 #include "ARMLDBackend.h"
-#include "ARMRelocationFactory.h"
+#include "ARMRelocator.h"
 #include "ARMToARMStub.h"
 #include "ARMToTHMStub.h"
 #include "THMToTHMStub.h"
@@ -38,15 +39,16 @@
 #include <mcld/Object/ObjectBuilder.h>
 #include <mcld/Fragment/NullFragment.h>
 #include <mcld/LD/LDContext.h>
+#include <mcld/Target/GNUInfo.h>
 
 using namespace mcld;
 
 //===----------------------------------------------------------------------===//
 // ARMGNULDBackend
 //===----------------------------------------------------------------------===//
-ARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig)
-  : GNULDBackend(pConfig),
-    m_pRelocFactory(NULL),
+ARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
+  : GNULDBackend(pConfig, pInfo),
+    m_pRelocator(NULL),
     m_pGOT(NULL),
     m_pPLT(NULL),
     m_pRelDyn(NULL),
@@ -62,7 +64,7 @@
 
 ARMGNULDBackend::~ARMGNULDBackend()
 {
-  delete m_pRelocFactory;
+  delete m_pRelocator;
   delete m_pGOT;
   delete m_pPLT;
   delete m_pRelDyn;
@@ -70,21 +72,6 @@
   delete m_pDynamic;
 }
 
-bool ARMGNULDBackend::initRelocFactory(const FragmentLinker& pLinker)
-{
-  if (NULL == m_pRelocFactory) {
-    m_pRelocFactory = new ARMRelocationFactory(1024, *this);
-    m_pRelocFactory->setFragmentLinker(pLinker);
-  }
-  return true;
-}
-
-RelocationFactory* ARMGNULDBackend::getRelocFactory()
-{
-  assert(NULL != m_pRelocFactory);
-  return m_pRelocFactory;
-}
-
 void ARMGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder)
 {
  // FIXME: Currently we set exidx and extab to "Exception" and directly emit
@@ -93,7 +80,7 @@
                                            LDFileFormat::Target,
                                            llvm::ELF::SHT_ARM_EXIDX,
                                            llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER,
-                                           bitclass() / 8);
+                                           config().targets().bitclass() / 8);
   m_pEXTAB        = pBuilder.CreateSection(".ARM.extab",
                                            LDFileFormat::Target,
                                            llvm::ELF::SHT_PROGBITS,
@@ -120,15 +107,11 @@
     LDSection& relplt = file_format->getRelPlt();
     relplt.setLink(&plt);
     // create SectionData and ARMRelDynSection
-    m_pRelPLT = new OutputRelocSection(pModule,
-                                       relplt,
-                                       getRelEntrySize());
+    m_pRelPLT = new OutputRelocSection(pModule, relplt);
 
     // initialize .rel.dyn
     LDSection& reldyn = file_format->getRelDyn();
-    m_pRelDyn = new OutputRelocSection(pModule,
-                                       reldyn,
-                                       getRelEntrySize());
+    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
   }
 }
 
@@ -184,6 +167,21 @@
                                                   ResolveInfo::Hidden);
 }
 
+bool ARMGNULDBackend::initRelocator(const FragmentLinker& pLinker)
+{
+  if (NULL == m_pRelocator) {
+    m_pRelocator = new ARMRelocator(*this);
+    m_pRelocator->setFragmentLinker(pLinker);
+  }
+  return true;
+}
+
+Relocator* ARMGNULDBackend::getRelocator()
+{
+  assert(NULL != m_pRelocator);
+  return m_pRelocator;
+}
+
 void ARMGNULDBackend::doPreLayout(FragmentLinker& pLinker)
 {
   // set .got size
@@ -200,13 +198,16 @@
     if (m_pPLT->hasPLT1())
       m_pPLT->finalizeSectionSize();
 
+    ELFFileFormat* file_format = getOutputFormat();
     // set .rel.dyn size
     if (!m_pRelDyn->empty())
-      m_pRelDyn->finalizeSectionSize();
+      file_format->getRelDyn().setSize(
+                                  m_pRelDyn->numOfRelocs() * getRelEntrySize());
 
     // set .rel.plt size
     if (!m_pRelPLT->empty())
-      m_pRelPLT->finalizeSectionSize();
+      file_format->getRelPlt().setSize(
+                                  m_pRelPLT->numOfRelocs() * getRelEntrySize());
   }
 }
 
@@ -242,7 +243,7 @@
 ARMELFDynamic& ARMGNULDBackend::dynamic()
 {
   if (NULL == m_pDynamic)
-    m_pDynamic = new ARMELFDynamic(*this);
+    m_pDynamic = new ARMELFDynamic(*this, config());
 
   return *m_pDynamic;
 }
@@ -320,7 +321,7 @@
 
   // Determine the alignment by the symbol value
   // FIXME: here we use the largest alignment
-  uint32_t addralign = bitclass() / 8;
+  uint32_t addralign = config().targets().bitclass() / 8;
 
   // allocate space in BSS for the copy symbol
   Fragment* frag = new FillFragment(0x0, 1, pSym.size());
@@ -398,7 +399,7 @@
       // a dynamic relocations with RELATIVE type to this location is needed.
       // Reserve an entry in .rel.dyn
       if (pLinker.isOutputPIC()) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         // set Rel bit
         rsym->setReserved(rsym->reserved() | ReserveRel);
         }
@@ -444,7 +445,7 @@
       // Reserve an entry in .rel.dyn
       if (pLinker.isOutputPIC()) {
         // create .rel.dyn section if not exist
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         // set GOTRel bit
         rsym->setReserved(rsym->reserved() | 0x4u);
         return;
@@ -512,7 +513,7 @@
           // in .got and .rel.plt. (GOT entry will be reserved simultaneously
           // when calling ARMPLT->reserveEntry())
           m_pPLT->reserveEntry();
-          m_pRelPLT->reserveEntry(*m_pRelocFactory);
+          m_pRelPLT->reserveEntry();
           // set PLT bit
           rsym->setReserved(rsym->reserved() | ReservePLT);
         }
@@ -521,7 +522,7 @@
       if (symbolNeedsDynRel(
                       pLinker, *rsym, (rsym->reserved() & ReservePLT), true)) {
         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) {
           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
           addCopyReloc(*cpy_sym.resolveInfo());
@@ -596,7 +597,7 @@
       if (symbolNeedsDynRel(
                      pLinker, *rsym, (rsym->reserved() & ReservePLT), false)) {
         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) {
           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
           addCopyReloc(*cpy_sym.resolveInfo());
@@ -644,7 +645,7 @@
       // in .got and .rel.plt. (GOT entry will be reserved simultaneously
       // when calling ARMPLT->reserveEntry())
       m_pPLT->reserveEntry();
-      m_pRelPLT->reserveEntry(*m_pRelocFactory);
+      m_pRelPLT->reserveEntry();
       // set PLT bit
       rsym->setReserved(rsym->reserved() | ReservePLT);
       return;
@@ -666,7 +667,7 @@
       // if the symbol cannot be fully resolved at link time, then we need a
       // dynamic relocation
       if (!symbolFinalValueIsKnown(pLinker, *rsym)) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         // set GOTRel bit
         rsym->setReserved(rsym->reserved() | GOTRel);
         return;
@@ -718,7 +719,7 @@
 
   // check if we shoule issue undefined reference for the relocation target
   // symbol
-  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak())
+  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
     fatal(diag::undefined_reference) << rsym->name();
 
   if ((rsym->reserved() & ReserveRel) != 0x0) {
@@ -984,14 +985,13 @@
             Stub* stub = getStubFactory()->create(*relocation, // relocation
                                                   sym_value, // symbol value
                                                   pLinker,
-                                                  *getRelocFactory(),
                                                   *getBRIslandFactory());
             if (NULL != stub) {
               assert(NULL != stub->symInfo());
               // increase the size of .symtab and .strtab
               LDSection& symtab = file_format->getSymTab();
               LDSection& strtab = file_format->getStrTab();
-              if (32 == bitclass())
+              if (config().targets().is32Bits())
                 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
               else
                 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf64_Sym));
@@ -1079,7 +1079,7 @@
 TargetLDBackend* createARMLDBackend(const llvm::Target& pTarget,
                                     const LinkerConfig& pConfig)
 {
-  if (pConfig.triple().isOSDarwin()) {
+  if (pConfig.targets().triple().isOSDarwin()) {
     assert(0 && "MachO linker is not supported yet");
     /**
     return new ARMMachOLDBackend(createARMMachOArchiveReader,
@@ -1087,7 +1087,7 @@
                                createARMMachOObjectWriter);
     **/
   }
-  if (pConfig.triple().isOSWindows()) {
+  if (pConfig.targets().triple().isOSWindows()) {
     assert(0 && "COFF linker is not supported yet");
     /**
     return new ARMCOFFLDBackend(createARMCOFFArchiveReader,
@@ -1095,7 +1095,7 @@
                                createARMCOFFObjectWriter);
     **/
   }
-  return new ARMGNULDBackend(pConfig);
+  return new ARMGNULDBackend(pConfig, new ARMGNUInfo(pConfig.targets().triple()));
 }
 
 } // namespace of mcld
diff --git a/lib/Target/ARM/ARMLDBackend.h b/lib/Target/ARM/ARMLDBackend.h
index 6cf531b..6110b1c 100644
--- a/lib/Target/ARM/ARMLDBackend.h
+++ b/lib/Target/ARM/ARMLDBackend.h
@@ -19,6 +19,7 @@
 namespace mcld {
 
 class LinkerConfig;
+class GNUInfo;
 class FragmentLinker;
 class SectionMap;
 
@@ -38,7 +39,7 @@
   static const int32_t THM2_MAX_BWD_BRANCH_OFFSET = (-(1 << 24) + 4);
 
 public:
-  ARMGNULDBackend(const LinkerConfig& pConfig);
+  ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
   ~ARMGNULDBackend();
 
 public:
@@ -94,11 +95,11 @@
   /// initTargetSymbols - initialize target dependent symbols in output.
   void initTargetSymbols(FragmentLinker& pLinker);
 
-  /// initRelocFactory - create and initialize RelocationFactory
-  bool initRelocFactory(const FragmentLinker& pLinker);
+  /// initRelocator - create and initialize Relocator.
+  bool initRelocator(const FragmentLinker& pLinker);
 
-  /// getRelocFactory
-  RelocationFactory* getRelocFactory();
+  /// getRelocator - return relocator.
+  Relocator* getRelocator();
 
   /// scanRelocation - determine the empty entries are needed or not and create
   /// the empty entries if needed.
@@ -111,27 +112,10 @@
                       Module& pModule,
                       const LDSection& pSection);
 
-  uint32_t machine() const
-  { return llvm::ELF::EM_ARM; }
-
-  /// OSABI - the value of e_ident[EI_OSABI]
-  virtual uint8_t OSABI() const
-  { return llvm::ELF::ELFOSABI_NONE; }
-
-  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
-  virtual uint8_t ABIVersion() const
-  { return 0x0; }
-
   /// flags - the value of ElfXX_Ehdr::e_flags
   virtual uint64_t flags() const
   { return (llvm::ELF::EF_ARM_EABIMASK & 0x05000000); }
 
-  bool isLittleEndian() const
-  { return true; }
-
-  unsigned int bitclass() const
-  { return 32; }
-
   uint64_t defaultTextSegmentAddr() const
   { return 0x8000; }
 
@@ -246,7 +230,8 @@
                                    const FragmentLinker& pLinker);
 
 private:
-  RelocationFactory* m_pRelocFactory;
+  Relocator* m_pRelocator;
+
   ARMGOT* m_pGOT;
   ARMPLT* m_pPLT;
   /// m_RelDyn - dynamic relocation table of .rel.dyn
diff --git a/lib/Target/ARM/ARMPLT.cpp b/lib/Target/ARM/ARMPLT.cpp
index a5f4733..d7342ab 100644
--- a/lib/Target/ARM/ARMPLT.cpp
+++ b/lib/Target/ARM/ARMPLT.cpp
@@ -17,31 +17,13 @@
 #include <mcld/Support/MemoryRegion.h>
 #include <mcld/Support/MsgHandling.h>
 
-namespace {
-
-const uint32_t arm_plt0[] = {
-  0xe52de004, // str   lr, [sp, #-4]!
-  0xe59fe004, // ldr   lr, [pc, #4]
-  0xe08fe00e, // add   lr, pc, lr
-  0xe5bef008, // ldr   pc, [lr, #8]!
-  0x00000000, // &GOT[0] - .
-};
-
-const uint32_t arm_plt1[] = {
-  0xe28fc600, // add   ip, pc, #0xNN00000
-  0xe28cca00, // add   ip, ip, #0xNN000
-  0xe5bcf000, // ldr   pc, [ip, #0xNNN]!
-};
-
-} // anonymous namespace
-
 using namespace mcld;
 
 ARMPLT0::ARMPLT0(SectionData& pParent)
-  : PLT::Entry(sizeof(arm_plt0), pParent) {}
+  : PLT::Entry<sizeof(arm_plt0)>(pParent) {}
 
 ARMPLT1::ARMPLT1(SectionData& pParent)
-  : PLT::Entry(sizeof(arm_plt1), pParent) {}
+  : PLT::Entry<sizeof(arm_plt1)>(pParent) {}
 
 //===----------------------------------------------------------------------===//
 // ARMPLT
@@ -134,15 +116,15 @@
   ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first));
 
   uint32_t* data = 0;
-  data = static_cast<uint32_t*>(malloc(plt0->getEntrySize()));
+  data = static_cast<uint32_t*>(malloc(ARMPLT0::EntrySize));
 
   if (!data)
     fatal(diag::fail_allocate_memory_plt);
 
-  memcpy(data, arm_plt0, plt0->getEntrySize());
+  memcpy(data, arm_plt0, ARMPLT0::EntrySize);
   data[4] = offset;
 
-  plt0->setContent(reinterpret_cast<unsigned char*>(data));
+  plt0->setValue(reinterpret_cast<unsigned char*>(data));
 }
 
 void ARMPLT::applyPLT1() {
@@ -157,21 +139,21 @@
   ARMPLT::iterator ie = m_SectionData->end();
   assert(it != ie && "FragmentList is empty, applyPLT1 failed!");
 
-  uint32_t GOTEntrySize = m_GOT.getEntrySize();
+  uint32_t GOTEntrySize = ARMGOTEntry::EntrySize;
   uint32_t GOTEntryAddress =
     got_base +  GOTEntrySize * 3;
 
   uint64_t PLTEntryAddress =
-    plt_base + llvm::cast<ARMPLT0>((*it)).getEntrySize(); //Offset of PLT0
+    plt_base + ARMPLT0::EntrySize; //Offset of PLT0
 
   ++it; //skip PLT0
-  uint64_t PLT1EntrySize = llvm::cast<ARMPLT1>((*it)).getEntrySize();
+  uint64_t PLT1EntrySize = ARMPLT1::EntrySize;
   ARMPLT1* plt1 = NULL;
 
   uint32_t* Out = NULL;
   while (it != ie) {
     plt1 = &(llvm::cast<ARMPLT1>(*it));
-    Out = static_cast<uint32_t*>(malloc(plt1->getEntrySize()));
+    Out = static_cast<uint32_t*>(malloc(ARMPLT1::EntrySize));
 
     if (!Out)
       fatal(diag::fail_allocate_memory_plt);
@@ -184,7 +166,7 @@
     Out[1] = arm_plt1[1] | ((Offset >> 12) & 0xFF);
     Out[2] = arm_plt1[2] | (Offset & 0xFFF);
 
-    plt1->setContent(reinterpret_cast<unsigned char*>(Out));
+    plt1->setValue(reinterpret_cast<unsigned char*>(Out));
     ++it;
 
     GOTEntryAddress += GOTEntrySize;
@@ -198,21 +180,18 @@
 {
   uint64_t result = 0x0;
   iterator it = begin();
-  unsigned int plt0_size = llvm::cast<ARMPLT0>((*it)).getEntrySize();
 
   unsigned char* buffer = pRegion.getBuffer();
-  memcpy(buffer, llvm::cast<ARMPLT0>((*it)).getContent(), plt0_size);
-  result += plt0_size;
+  memcpy(buffer, llvm::cast<ARMPLT0>((*it)).getValue(), ARMPLT0::EntrySize);
+  result += ARMPLT0::EntrySize;
   ++it;
 
   ARMPLT1* plt1 = 0;
   ARMPLT::iterator ie = end();
-  unsigned int entry_size = 0;
   while (it != ie) {
     plt1 = &(llvm::cast<ARMPLT1>(*it));
-    entry_size = plt1->getEntrySize();
-    memcpy(buffer + result, plt1->getContent(), entry_size);
-    result += entry_size;
+    memcpy(buffer + result, plt1->getValue(), ARMPLT1::EntrySize);
+    result += ARMPLT1::EntrySize;
     ++it;
   }
   return result;
diff --git a/lib/Target/ARM/ARMPLT.h b/lib/Target/ARM/ARMPLT.h
index 67b6f4e..9554f0c 100644
--- a/lib/Target/ARM/ARMPLT.h
+++ b/lib/Target/ARM/ARMPLT.h
@@ -12,17 +12,37 @@
 #include <mcld/Target/GOT.h>
 #include <mcld/Target/PLT.h>
 
+namespace {
+
+const uint32_t arm_plt0[] = {
+  0xe52de004, // str   lr, [sp, #-4]!
+  0xe59fe004, // ldr   lr, [pc, #4]
+  0xe08fe00e, // add   lr, pc, lr
+  0xe5bef008, // ldr   pc, [lr, #8]!
+  0x00000000, // &GOT[0] - .
+};
+
+const uint32_t arm_plt1[] = {
+  0xe28fc600, // add   ip, pc, #0xNN00000
+  0xe28cca00, // add   ip, ip, #0xNN000
+  0xe5bcf000, // ldr   pc, [ip, #0xNNN]!
+};
+
+} // anonymous namespace
+
 namespace mcld {
 
 class ARMGOT;
 class MemoryRegion;
 
-class ARMPLT0 : public PLT::Entry {
+class ARMPLT0 : public PLT::Entry<sizeof(arm_plt0)>
+{
 public:
   ARMPLT0(SectionData& pParent);
 };
 
-class ARMPLT1 : public PLT::Entry {
+class ARMPLT1 : public PLT::Entry<sizeof(arm_plt1)>
+{
 public:
   ARMPLT1(SectionData& pParent);
 };
diff --git a/lib/Target/ARM/ARMRelocationFunctions.h b/lib/Target/ARM/ARMRelocationFunctions.h
index 3f8b90e..cd25e2c 100644
--- a/lib/Target/ARM/ARMRelocationFunctions.h
+++ b/lib/Target/ARM/ARMRelocationFunctions.h
@@ -8,8 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #define DECL_ARM_APPLY_RELOC_FUNC(Name) \
-static ARMRelocationFactory::Result Name    (Relocation& pEntry, \
-                                             ARMRelocationFactory& pParent);
+static ARMRelocator::Result Name    (Relocation& pEntry, \
+                                     ARMRelocator& pParent);
 
 #define DECL_ARM_APPLY_RELOC_FUNCS \
 DECL_ARM_APPLY_RELOC_FUNC(none)             \
diff --git a/lib/Target/ARM/ARMRelocationFactory.cpp b/lib/Target/ARM/ARMRelocator.cpp
similarity index 63%
rename from lib/Target/ARM/ARMRelocationFactory.cpp
rename to lib/Target/ARM/ARMRelocator.cpp
index d668fc5..d613d66 100644
--- a/lib/Target/ARM/ARMRelocationFactory.cpp
+++ b/lib/Target/ARM/ARMRelocator.cpp
@@ -1,4 +1,4 @@
-//===- ARMRelocationFactory.cpp  ----------------------------------------===//
+//===- ARMRelocator.cpp  ----------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -12,9 +12,8 @@
 #include <llvm/Support/ELF.h>
 #include <llvm/Support/Host.h>
 #include <mcld/Fragment/FragmentLinker.h>
-#include <mcld/LinkerConfig.h>
 #include <mcld/Support/MsgHandling.h>
-#include "ARMRelocationFactory.h"
+#include "ARMRelocator.h"
 #include "ARMRelocationFunctions.h"
 
 using namespace mcld;
@@ -25,9 +24,8 @@
 DECL_ARM_APPLY_RELOC_FUNCS
 
 /// the prototype of applying function
-typedef RelocationFactory::Result (*ApplyFunctionType)(
-                                               Relocation& pReloc,
-                                               ARMRelocationFactory& pParent);
+typedef Relocator::Result (*ApplyFunctionType)(Relocation& pReloc,
+                                               ARMRelocator& pParent);
 
 // the table entry of applying functions
 struct ApplyFunctionTriple
@@ -43,41 +41,40 @@
 };
 
 //===--------------------------------------------------------------------===//
-// ARMRelocationFactory
+// ARMRelocator
 //===--------------------------------------------------------------------===//
-ARMRelocationFactory::ARMRelocationFactory(size_t pNum,
-                                           ARMGNULDBackend& pParent)
-  : RelocationFactory(pNum),
+ARMRelocator::ARMRelocator(ARMGNULDBackend& pParent)
+  : Relocator(),
     m_Target(pParent) {
 }
 
-ARMRelocationFactory::~ARMRelocationFactory()
+ARMRelocator::~ARMRelocator()
 {
 }
 
-RelocationFactory::Result
-ARMRelocationFactory::applyRelocation(Relocation& pRelocation)
+Relocator::Result
+ARMRelocator::applyRelocation(Relocation& pRelocation)
 {
   Relocation::Type type = pRelocation.type();
   if (type > 130) { // 131-255 doesn't noted in ARM spec
-    return RelocationFactory::Unknown;
+    return Relocator::Unknown;
   }
 
   return ApplyFunctions[type].func(pRelocation, *this);
 }
 
-const char* ARMRelocationFactory::getName(RelocationFactory::Type pType) const
+const char* ARMRelocator::getName(Relocator::Type pType) const
 {
   return ApplyFunctions[pType].name;
 }
 
 //===--------------------------------------------------------------------===//
 // non-member functions
-static RelocationFactory::DWord getThumbBit(const Relocation& pReloc)
+static Relocator::DWord getThumbBit(const Relocation& pReloc)
 {
   // Set thumb bit if
   // - symbol has type of STT_FUNC, is defined and with bit 0 of its value set
-  RelocationFactory::DWord thumbBit =
+  Relocator::DWord thumbBit =
        ((!pReloc.symInfo()->isUndef() || pReloc.symInfo()->isDyn()) &&
         (pReloc.symInfo()->type() == ResolveInfo::Function) &&
         ((pReloc.symValue() & 0x1) != 0))?
@@ -112,7 +109,7 @@
 // Check if symbol can use relocation R_ARM_RELATIVE
 static bool
 helper_use_relative_reloc(const ResolveInfo& pSym,
-                          const ARMRelocationFactory& pFactory)
+                          const ARMRelocator& pFactory)
 {
   // if symbol is dynamic or undefine or preemptible
   if (pSym.isDyn() ||
@@ -123,21 +120,21 @@
 }
 
 static
-GOT::Entry& helper_get_GOT_and_init(Relocation& pReloc,
-                                    ARMRelocationFactory& pParent)
+ARMGOTEntry& helper_get_GOT_and_init(Relocation& pReloc,
+                                     ARMRelocator& pParent)
 {
   // rsym - The relocation target symbol
   ResolveInfo* rsym = pReloc.symInfo();
   ARMGNULDBackend& ld_backend = pParent.getTarget();
 
-  GOT::Entry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
+  ARMGOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
   if (NULL == got_entry) {
     got_entry = ld_backend.getGOT().consumeGOT();
     pParent.getSymGOTMap().record(*rsym, *got_entry);
     // If we first get this GOT entry, we should initialize it.
     if (rsym->reserved() & ARMGNULDBackend::ReserveGOT) {
       // No corresponding dynamic relocation, initialize to the symbol value.
-      got_entry->setContent(pReloc.symValue());
+      got_entry->setValue(pReloc.symValue());
     }
     else if (rsym->reserved() & ARMGNULDBackend::GOTRel) {
 
@@ -146,13 +143,13 @@
       if ( rsym->isLocal() ||
           helper_use_relative_reloc(*rsym, pParent)) {
         // Initialize got entry to target symbol address
-        got_entry->setContent(pReloc.symValue());
+        got_entry->setValue(pReloc.symValue());
         rel_entry.setType(llvm::ELF::R_ARM_RELATIVE);
         rel_entry.setSymInfo(0);
       }
       else {
         // Initialize got entry to 0 for corresponding dynamic relocation.
-        got_entry->setContent(0);
+        got_entry->setValue(0);
         rel_entry.setType(llvm::ELF::R_ARM_GLOB_DAT);
         rel_entry.setSymInfo(rsym);
       }
@@ -166,30 +163,28 @@
 }
 
 static
-ARMRelocationFactory::Address helper_GOT_ORG(ARMRelocationFactory& pParent)
+ARMRelocator::Address helper_GOT_ORG(ARMRelocator& pParent)
 {
   return pParent.getTarget().getGOT().addr();
 }
 
 
 static
-ARMRelocationFactory::Address helper_GOT(Relocation& pReloc,
-                                         ARMRelocationFactory& pParent)
+ARMRelocator::Address helper_GOT(Relocation& pReloc, ARMRelocator& pParent)
 {
-  GOT::Entry& got_entry = helper_get_GOT_and_init(pReloc, pParent);
+  ARMGOTEntry& got_entry = helper_get_GOT_and_init(pReloc, pParent);
   return helper_GOT_ORG(pParent) + got_entry.getOffset();
 }
 
 
 static
-PLT::Entry& helper_get_PLT_and_init(Relocation& pReloc,
-                                    ARMRelocationFactory& pParent)
+ARMPLT1& helper_get_PLT_and_init(Relocation& pReloc, ARMRelocator& pParent)
 {
   // rsym - The relocation target symbol
   ResolveInfo* rsym = pReloc.symInfo();
   ARMGNULDBackend& ld_backend = pParent.getTarget();
 
-  PLT::Entry* plt_entry = pParent.getSymPLTMap().lookUp(*rsym);
+  ARMPLT1* plt_entry = pParent.getSymPLTMap().lookUp(*rsym);
   if (NULL != plt_entry)
     return *plt_entry;
 
@@ -198,7 +193,7 @@
 
   // If we first get this PLT entry, we should initialize it.
   if (rsym->reserved() & ARMGNULDBackend::ReservePLT) {
-    GOT::Entry* gotplt_entry = pParent.getSymGOTPLTMap().lookUp(*rsym);
+    ARMGOTEntry* gotplt_entry = pParent.getSymGOTPLTMap().lookUp(*rsym);
     assert(NULL == gotplt_entry && "PLT entry not exist, but DynRel entry exist!");
     gotplt_entry = ld_backend.getGOT().consumeGOTPLT();
     pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry);
@@ -217,26 +212,26 @@
 }
 
 static
-ARMRelocationFactory::Address helper_PLT_ORG(ARMRelocationFactory& pParent)
+ARMRelocator::Address helper_PLT_ORG(ARMRelocator& pParent)
 {
   return pParent.getTarget().getPLT().addr();
 }
 
 
 static
-ARMRelocationFactory::Address helper_PLT(Relocation& pReloc,
-                                         ARMRelocationFactory& pParent)
+ARMRelocator::Address helper_PLT(Relocation& pReloc, ARMRelocator& pParent)
 {
-  PLT::Entry& plt_entry = helper_get_PLT_and_init(pReloc, pParent);
+  ARMPLT1& plt_entry = helper_get_PLT_and_init(pReloc, pParent);
   return helper_PLT_ORG(pParent) + plt_entry.getOffset();
 }
 
 // Get an relocation entry in .rel.dyn and set its type to pType,
-// its FragmentRef to pReloc->targetFrag() and its ResolveInfo to pReloc->symInfo()
+// its FragmentRef to pReloc->targetFrag() and its ResolveInfo to
+// pReloc->symInfo()
 static
 void helper_DynRel(Relocation& pReloc,
-                   ARMRelocationFactory::Type pType,
-                   ARMRelocationFactory& pParent)
+                   ARMRelocator::Type pType,
+                   ARMRelocator& pParent)
 {
   // rsym - The relocation target symbol
   ResolveInfo* rsym = pReloc.symInfo();
@@ -252,17 +247,17 @@
     rel_entry.setSymInfo(rsym);
 }
 
-static ARMRelocationFactory::DWord
-helper_extract_movw_movt_addend(ARMRelocationFactory::DWord pTarget)
+static ARMRelocator::DWord
+helper_extract_movw_movt_addend(ARMRelocator::DWord pTarget)
 {
   // imm16: [19-16][11-0]
   return helper_sign_extend((((pTarget >> 4)) & 0xf000U) | (pTarget & 0xfffU),
                             16);
 }
 
-static ARMRelocationFactory::DWord
-helper_insert_val_movw_movt_inst(ARMRelocationFactory::DWord pTarget,
-                                 ARMRelocationFactory::DWord pImm)
+static ARMRelocator::DWord
+helper_insert_val_movw_movt_inst(ARMRelocator::DWord pTarget,
+                                 ARMRelocator::DWord pImm)
 {
   // imm16: [19-16][11-0]
   pTarget &= 0xfff0f000U;
@@ -271,8 +266,8 @@
   return pTarget;
 }
 
-static ARMRelocationFactory::DWord
-helper_extract_thumb_movw_movt_addend(ARMRelocationFactory::DWord pValue)
+static ARMRelocator::DWord
+helper_extract_thumb_movw_movt_addend(ARMRelocator::DWord pValue)
 {
   // imm16: [19-16][26][14-12][7-0]
   return helper_sign_extend((((pValue >> 4) & 0xf000U) |
@@ -282,9 +277,9 @@
                             16);
 }
 
-static ARMRelocationFactory::DWord
-helper_insert_val_thumb_movw_movt_inst(ARMRelocationFactory::DWord pValue,
-                                       ARMRelocationFactory::DWord pImm)
+static ARMRelocator::DWord
+helper_insert_val_thumb_movw_movt_inst(ARMRelocator::DWord pValue,
+                                       ARMRelocator::DWord pImm)
 {
   // imm16: [19-16][26][14-12][7-0]
   pValue &= 0xfbf08f00U;
@@ -295,16 +290,16 @@
   return pValue;
 }
 
-static ARMRelocationFactory::DWord
-helper_thumb32_branch_offset(ARMRelocationFactory::DWord pUpper16,
-                             ARMRelocationFactory::DWord pLower16)
+static ARMRelocator::DWord
+helper_thumb32_branch_offset(ARMRelocator::DWord pUpper16,
+                             ARMRelocator::DWord pLower16)
 {
-  ARMRelocationFactory::DWord s = (pUpper16 & (1U << 10)) >> 10,  // 26 bit
-                              u = pUpper16 & 0x3ffU,              // 25-16
-                              l = pLower16 & 0x7ffU,              // 10-0
-                             j1 = (pLower16 & (1U << 13)) >> 13,  // 13
-                             j2 = (pLower16 & (1U << 11)) >> 11;  // 11
-  ARMRelocationFactory::DWord i1 = j1 ^ s? 0: 1,
+  ARMRelocator::DWord s = (pUpper16 & (1U << 10)) >> 10,        // 26 bit
+                           u  = pUpper16 & 0x3ffU,              // 25-16
+                           l  = pLower16 & 0x7ffU,              // 10-0
+                           j1 = (pLower16 & (1U << 13)) >> 13,  // 13
+                           j2 = (pLower16 & (1U << 11)) >> 11;  // 11
+  ARMRelocator::DWord i1 = j1 ^ s? 0: 1,
                               i2 = j2 ^ s? 0: 1;
 
   // [31-25][24][23][22][21-12][11-1][0]
@@ -314,17 +309,17 @@
                             25);
 }
 
-static ARMRelocationFactory::DWord
-helper_thumb32_branch_upper(ARMRelocationFactory::DWord pUpper16,
-                            ARMRelocationFactory::DWord pOffset)
+static ARMRelocator::DWord
+helper_thumb32_branch_upper(ARMRelocator::DWord pUpper16,
+                            ARMRelocator::DWord pOffset)
 {
   uint32_t sign = ((pOffset & 0x80000000U) >> 31);
   return (pUpper16 & ~0x7ffU) | ((pOffset >> 12) & 0x3ffU) | (sign << 10);
 }
 
-static ARMRelocationFactory::DWord
-helper_thumb32_branch_lower(ARMRelocationFactory::DWord pLower16,
-                            ARMRelocationFactory::DWord pOffset)
+static ARMRelocator::DWord
+helper_thumb32_branch_lower(ARMRelocator::DWord pLower16,
+                            ARMRelocator::DWord pOffset)
 {
   uint32_t sign = ((pOffset & 0x80000000U) >> 31);
   return ((pLower16 & ~0x2fffU) |
@@ -335,7 +330,7 @@
 
 // Return true if overflow
 static bool
-helper_check_signed_overflow(ARMRelocationFactory::DWord pValue,
+helper_check_signed_overflow(ARMRelocator::DWord pValue,
                              unsigned bits)
 {
   int32_t signed_val = static_cast<int32_t>(pValue);
@@ -354,20 +349,18 @@
 //=========================================//
 
 // R_ARM_NONE
-ARMRelocationFactory::Result none(Relocation& pReloc,
-                                  ARMRelocationFactory& pParent)
+ARMRelocator::Result none(Relocation& pReloc, ARMRelocator& pParent)
 {
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_ABS32: (S + A) | T
-ARMRelocationFactory::Result abs32(Relocation& pReloc,
-                                   ARMRelocationFactory& pParent)
+ARMRelocator::Result abs32(Relocation& pReloc, ARMRelocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
-  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend();
-  ARMRelocationFactory::DWord S = pReloc.symValue();
+  ARMRelocator::DWord T = getThumbBit(pReloc);
+  ARMRelocator::DWord A = pReloc.target() + pReloc.addend();
+  ARMRelocator::DWord S = pReloc.symValue();
 
   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
 
@@ -375,14 +368,14 @@
   // but perform static relocation. (e.g., applying .debug section)
   if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
     pReloc.target() = (S + A) | T;
-    return ARMRelocationFactory::OK;
+    return ARMRelocator::OK;
   }
 
   // A local symbol may need REL Type dynamic relocation
   if (rsym->isLocal() && (rsym->reserved() & ARMGNULDBackend::ReserveRel)) {
     helper_DynRel(pReloc, llvm::ELF::R_ARM_RELATIVE, pParent);
     pReloc.target() = (S + A) | T ;
-    return ARMRelocationFactory::OK;
+    return ARMRelocator::OK;
   }
 
   // An external symbol may need PLT and dynamic relocation
@@ -400,7 +393,7 @@
       }
       else {
         helper_DynRel(pReloc, pReloc.type(), pParent);
-        return ARMRelocationFactory::OK;
+        return ARMRelocator::OK;
       }
     }
   }
@@ -408,17 +401,16 @@
 
   // perform static relocation
   pReloc.target() = (S + A) | T;
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_REL32: ((S + A) | T) - P
-ARMRelocationFactory::Result rel32(Relocation& pReloc,
-                                   ARMRelocationFactory& pParent)
+ARMRelocator::Result rel32(Relocation& pReloc, ARMRelocator& pParent)
 {
   // perform static relocation
-  ARMRelocationFactory::Address S = pReloc.symValue();
-  ARMRelocationFactory::DWord   T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord   A = pReloc.target() + pReloc.addend();
+  ARMRelocator::Address S = pReloc.symValue();
+  ARMRelocator::DWord   T = getThumbBit(pReloc);
+  ARMRelocator::DWord   A = pReloc.target() + pReloc.addend();
 
   // An external symbol may need PLT (this reloc is from stub)
   if (!pReloc.symInfo()->isLocal()) {
@@ -431,70 +423,65 @@
   // perform relocation
   pReloc.target() = ((S + A) | T) - pReloc.place();
 
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_BASE_PREL: B(S) + A - P
-ARMRelocationFactory::Result base_prel(Relocation& pReloc,
-                                       ARMRelocationFactory& pParent)
+ARMRelocator::Result base_prel(Relocation& pReloc, ARMRelocator& pParent)
 {
   // perform static relocation
-  ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  ARMRelocator::DWord A = pReloc.target() + pReloc.addend();
   pReloc.target() = pReloc.symValue() + A - pReloc.place();
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_GOTOFF32: ((S + A) | T) - GOT_ORG
-ARMRelocationFactory::Result gotoff32(Relocation& pReloc,
-                                      ARMRelocationFactory& pParent)
+ARMRelocator::Result gotoff32(Relocation& pReloc, ARMRelocator& pParent)
 {
-  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend();
-  ARMRelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
-  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocator::DWord T = getThumbBit(pReloc);
+  ARMRelocator::DWord A = pReloc.target() + pReloc.addend();
+  ARMRelocator::Address GOT_ORG = helper_GOT_ORG(pParent);
+  ARMRelocator::Address S = pReloc.symValue();
 
   pReloc.target() = ((S + A) | T) - GOT_ORG;
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_GOT_BREL: GOT(S) + A - GOT_ORG
-ARMRelocationFactory::Result got_brel(Relocation& pReloc,
-                                      ARMRelocationFactory& pParent)
+ARMRelocator::Result got_brel(Relocation& pReloc, ARMRelocator& pParent)
 {
   if (!(pReloc.symInfo()->reserved() &
       (ARMGNULDBackend::ReserveGOT | ARMGNULDBackend::GOTRel))) {
-    return ARMRelocationFactory::BadReloc;
+    return ARMRelocator::BadReloc;
   }
-  ARMRelocationFactory::Address GOT_S   = helper_GOT(pReloc, pParent);
-  ARMRelocationFactory::DWord   A       = pReloc.target() + pReloc.addend();
-  ARMRelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
+  ARMRelocator::Address GOT_S   = helper_GOT(pReloc, pParent);
+  ARMRelocator::DWord   A       = pReloc.target() + pReloc.addend();
+  ARMRelocator::Address GOT_ORG = helper_GOT_ORG(pParent);
   // Apply relocation.
   pReloc.target() = GOT_S + A - GOT_ORG;
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_GOT_PREL: GOT(S) + A - P
-ARMRelocationFactory::Result got_prel(Relocation& pReloc,
-                                      ARMRelocationFactory& pParent)
+ARMRelocator::Result got_prel(Relocation& pReloc, ARMRelocator& pParent)
 {
   if (!(pReloc.symInfo()->reserved() &
       (ARMGNULDBackend::ReserveGOT | ARMGNULDBackend::GOTRel))) {
-    return ARMRelocationFactory::BadReloc;
+    return ARMRelocator::BadReloc;
   }
-  ARMRelocationFactory::Address GOT_S   = helper_GOT(pReloc, pParent);
-  ARMRelocationFactory::DWord   A       = pReloc.target() + pReloc.addend();
-  ARMRelocationFactory::Address P = pReloc.place();
+  ARMRelocator::Address GOT_S   = helper_GOT(pReloc, pParent);
+  ARMRelocator::DWord   A       = pReloc.target() + pReloc.addend();
+  ARMRelocator::Address P = pReloc.place();
 
   // Apply relocation.
   pReloc.target() = GOT_S + A - P;
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_PLT32: ((S + A) | T) - P
 // R_ARM_JUMP24: ((S + A) | T) - P
 // R_ARM_CALL: ((S + A) | T) - P
-ARMRelocationFactory::Result call(Relocation& pReloc,
-                                  ARMRelocationFactory& pParent)
+ARMRelocator::Result call(Relocation& pReloc, ARMRelocator& pParent)
 {
   // If target is undefined weak symbol, we only need to jump to the
   // next instruction unless it has PLT entry. Rewrite instruction
@@ -505,15 +492,15 @@
       !(pReloc.symInfo()->reserved() & ARMGNULDBackend::ReservePLT)) {
     // change target to NOP : mov r0, r0
     pReloc.target() = (pReloc.target() & 0xf0000000U) | 0x01a00000;
-    return ARMRelocationFactory::OK;
+    return ARMRelocator::OK;
   }
 
-  ARMRelocationFactory::Address S; // S depends on PLT exists or not.
-  ARMRelocationFactory::DWord   T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord   A =
+  ARMRelocator::Address S; // S depends on PLT exists or not.
+  ARMRelocator::DWord   T = getThumbBit(pReloc);
+  ARMRelocator::DWord   A =
     helper_sign_extend((pReloc.target() & 0x00FFFFFFu) << 2, 26)
     + pReloc.addend();
-  ARMRelocationFactory::Address P = pReloc.place();
+  ARMRelocator::Address P = pReloc.place();
 
   S = pReloc.symValue();
   if (pReloc.symInfo()->reserved() & ARMGNULDBackend::ReservePLT) {
@@ -528,26 +515,25 @@
   if (T != 0) {
     // cannot rewrite to blx for R_ARM_JUMP24
     if (pReloc.type() == llvm::ELF::R_ARM_JUMP24)
-      return ARMRelocationFactory::BadReloc;
+      return ARMRelocator::BadReloc;
 
     pReloc.target() = (pReloc.target() & 0xffffff) |
                       0xfa000000 |
                       (((S + A - P) & 2) << 23);
   }
 
-  ARMRelocationFactory::DWord X = ((S + A) | T) - P;
+  ARMRelocator::DWord X = ((S + A) | T) - P;
   // Check X is 24bit sign int. If not, we should use stub or PLT before apply.
   if (helper_check_signed_overflow(X, 26))
-    return ARMRelocationFactory::Overflow;
+    return ARMRelocator::Overflow;
   //                    Make sure the Imm is 0.          Result Mask.
   pReloc.target() = (pReloc.target() & 0xFF000000u) | ((X & 0x03FFFFFEu) >> 2);
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_THM_CALL: ((S + A) | T) - P
 // R_ARM_THM_JUMP24: (((S + A) | T) - P)
-ARMRelocationFactory::Result thm_call(Relocation& pReloc,
-                                      ARMRelocationFactory& pParent)
+ARMRelocator::Result thm_call(Relocation& pReloc, ARMRelocator& pParent)
 {
   // If target is undefined weak symbol, we only need to jump to the
   // next instruction unless it has PLT entry. Rewrite instruction
@@ -557,18 +543,18 @@
       !pReloc.symInfo()->isDyn() &&
       !(pReloc.symInfo()->reserved() & ARMGNULDBackend::ReservePLT)) {
     pReloc.target() = (0xe000U << 16) | 0xbf00U;
-    return ARMRelocationFactory::OK;
+    return ARMRelocator::OK;
   }
 
   // get lower and upper 16 bit instructions from relocation targetData
   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
 
-  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord A = helper_thumb32_branch_offset(upper_inst,
+  ARMRelocator::DWord T = getThumbBit(pReloc);
+  ARMRelocator::DWord A = helper_thumb32_branch_offset(upper_inst,
                                                                lower_inst);
-  ARMRelocationFactory::Address P = pReloc.place();
-  ARMRelocationFactory::Address S;
+  ARMRelocator::Address P = pReloc.place();
+  ARMRelocator::Address S;
 
   // if symbol has plt
   if (pReloc.symInfo()->reserved() & ARMGNULDBackend::ReservePLT) {
@@ -588,7 +574,7 @@
   if (T == 0) {
     // cannot rewrite to blx for R_ARM_THM_JUMP24
     if (pReloc.type() == llvm::ELF::R_ARM_THM_JUMP24)
-      return ARMRelocationFactory::BadReloc;
+      return ARMRelocator::BadReloc;
 
     // for BLX, select bit 1 from relocation base address to jump target
     // address
@@ -601,11 +587,11 @@
     lower_inst |= 0x1000U;
   }
 
-  ARMRelocationFactory::DWord X = (S | T) - P;
+  ARMRelocator::DWord X = (S | T) - P;
 
   // FIXME: Check bit size is 24(thumb2) or 22?
   if (helper_check_signed_overflow(X, 25)) {
-    return ARMRelocationFactory::Overflow;
+    return ARMRelocator::Overflow;
   }
 
   upper_inst = helper_thumb32_branch_upper(upper_inst, X);
@@ -614,19 +600,18 @@
   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst;
   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst;
 
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_MOVW_ABS_NC: (S + A) | T
-ARMRelocationFactory::Result movw_abs_nc(Relocation& pReloc,
-                                         ARMRelocationFactory& pParent)
+ARMRelocator::Result movw_abs_nc(Relocation& pReloc, ARMRelocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
-  ARMRelocationFactory::Address S = pReloc.symValue();
-  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord A =
+  ARMRelocator::Address S = pReloc.symValue();
+  ARMRelocator::DWord T = getThumbBit(pReloc);
+  ARMRelocator::DWord A =
       helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
-  ARMRelocationFactory::DWord X;
+  ARMRelocator::DWord X;
 
   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
 
@@ -644,39 +629,37 @@
   X = (S + A) | T;
   pReloc.target() = helper_insert_val_movw_movt_inst(
                                          pReloc.target() + pReloc.addend(), X);
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_MOVW_PREL_NC: ((S + A) | T) - P
-ARMRelocationFactory::Result movw_prel_nc(Relocation& pReloc,
-                                          ARMRelocationFactory& pParent)
+ARMRelocator::Result movw_prel_nc(Relocation& pReloc, ARMRelocator& pParent)
 {
-  ARMRelocationFactory::Address S = pReloc.symValue();
-  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord P = pReloc.place();
-  ARMRelocationFactory::DWord A =
+  ARMRelocator::Address S = pReloc.symValue();
+  ARMRelocator::DWord T = getThumbBit(pReloc);
+  ARMRelocator::DWord P = pReloc.place();
+  ARMRelocator::DWord A =
       helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
-  ARMRelocationFactory::DWord X;
+  ARMRelocator::DWord X;
 
   X = ((S + A) | T) - P;
 
   if (helper_check_signed_overflow(X, 16)) {
-    return ARMRelocationFactory::Overflow;
+    return ARMRelocator::Overflow;
   } else {
     pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
-    return ARMRelocationFactory::OK;
+    return ARMRelocator::OK;
   }
 }
 
 // R_ARM_MOVT_ABS: S + A
-ARMRelocationFactory::Result movt_abs(Relocation& pReloc,
-                                      ARMRelocationFactory& pParent)
+ARMRelocator::Result movt_abs(Relocation& pReloc, ARMRelocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
-  ARMRelocationFactory::Address S = pReloc.symValue();
-  ARMRelocationFactory::DWord A =
+  ARMRelocator::Address S = pReloc.symValue();
+  ARMRelocator::DWord A =
     helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
-  ARMRelocationFactory::DWord X;
+  ARMRelocator::DWord X;
 
   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
 
@@ -693,41 +676,39 @@
   X >>= 16;
   // perform static relocation
   pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_MOVT_PREL: S + A - P
-ARMRelocationFactory::Result movt_prel(Relocation& pReloc,
-                                       ARMRelocationFactory& pParent)
+ARMRelocator::Result movt_prel(Relocation& pReloc, ARMRelocator& pParent)
 {
-  ARMRelocationFactory::Address S = pReloc.symValue();
-  ARMRelocationFactory::DWord P = pReloc.place();
-  ARMRelocationFactory::DWord A =
+  ARMRelocator::Address S = pReloc.symValue();
+  ARMRelocator::DWord P = pReloc.place();
+  ARMRelocator::DWord A =
             helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
-  ARMRelocationFactory::DWord X;
+  ARMRelocator::DWord X;
 
   X = S + A - P;
   X >>= 16;
 
   pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_THM_MOVW_ABS_NC: (S + A) | T
-ARMRelocationFactory::Result thm_movw_abs_nc(Relocation& pReloc,
-                                             ARMRelocationFactory& pParent)
+ARMRelocator::Result thm_movw_abs_nc(Relocation& pReloc, ARMRelocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
-  ARMRelocationFactory::Address S = pReloc.symValue();
-  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocator::Address S = pReloc.symValue();
+  ARMRelocator::DWord T = getThumbBit(pReloc);
 
   // get lower and upper 16 bit instructions from relocation targetData
   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
-  ARMRelocationFactory::DWord val = ((upper_inst) << 16) | (lower_inst);
-  ARMRelocationFactory::DWord A =
+  ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst);
+  ARMRelocator::DWord A =
       helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
-  ARMRelocationFactory::DWord X;
+  ARMRelocator::DWord X;
 
   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   // If the flag of target section is not ALLOC, we will not scan this relocation
@@ -745,24 +726,23 @@
   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst;
   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst;
 
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_THM_MOVW_PREL_NC: ((S + A) | T) - P
-ARMRelocationFactory::Result thm_movw_prel_nc(Relocation& pReloc,
-                                              ARMRelocationFactory& pParent)
+ARMRelocator::Result thm_movw_prel_nc(Relocation& pReloc, ARMRelocator& pParent)
 {
-  ARMRelocationFactory::Address S = pReloc.symValue();
-  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord P = pReloc.place();
+  ARMRelocator::Address S = pReloc.symValue();
+  ARMRelocator::DWord T = getThumbBit(pReloc);
+  ARMRelocator::DWord P = pReloc.place();
 
   // get lower and upper 16 bit instructions from relocation targetData
   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
-  ARMRelocationFactory::DWord val = ((upper_inst) << 16) | (lower_inst);
-  ARMRelocationFactory::DWord A =
+  ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst);
+  ARMRelocator::DWord A =
       helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
-  ARMRelocationFactory::DWord X;
+  ARMRelocator::DWord X;
 
   X = ((S + A) | T) - P;
 
@@ -770,25 +750,24 @@
   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst;
   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst;
 
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_THM_MOVW_BREL_NC: ((S + A) | T) - B(S)
 // R_ARM_THM_MOVW_BREL: ((S + A) | T) - B(S)
-ARMRelocationFactory::Result thm_movw_brel(Relocation& pReloc,
-                                              ARMRelocationFactory& pParent)
+ARMRelocator::Result thm_movw_brel(Relocation& pReloc, ARMRelocator& pParent)
 {
-  ARMRelocationFactory::Address S = pReloc.symValue();
-  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord P = pReloc.place();
+  ARMRelocator::Address S = pReloc.symValue();
+  ARMRelocator::DWord T = getThumbBit(pReloc);
+  ARMRelocator::DWord P = pReloc.place();
 
   // get lower and upper 16 bit instructions from relocation targetData
   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
-  ARMRelocationFactory::DWord val = ((upper_inst) << 16) | (lower_inst);
-  ARMRelocationFactory::DWord A =
+  ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst);
+  ARMRelocator::DWord A =
       helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
-  ARMRelocationFactory::DWord X;
+  ARMRelocator::DWord X;
 
   X = ((S + A) | T) - P;
 
@@ -796,23 +775,22 @@
   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst;
   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst;
 
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_THM_MOVT_ABS: S + A
-ARMRelocationFactory::Result thm_movt_abs(Relocation& pReloc,
-                                          ARMRelocationFactory& pParent)
+ARMRelocator::Result thm_movt_abs(Relocation& pReloc, ARMRelocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
-  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocator::Address S = pReloc.symValue();
 
   // get lower and upper 16 bit instructions from relocation targetData
   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
-  ARMRelocationFactory::DWord val = ((upper_inst) << 16) | (lower_inst);
-  ARMRelocationFactory::DWord A =
+  ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst);
+  ARMRelocator::DWord A =
       helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
-  ARMRelocationFactory::DWord X;
+  ARMRelocator::DWord X;
 
   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   // If the flag of target section is not ALLOC, we will not scan this relocation
@@ -829,30 +807,29 @@
 
   // check 16-bit overflow
   if (helper_check_signed_overflow(X, 16)) {
-    return ARMRelocationFactory::Overflow;
+    return ARMRelocator::Overflow;
   } else {
     val = helper_insert_val_thumb_movw_movt_inst(val, X);
     *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst;
     *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst;
-    return ARMRelocationFactory::OK;
+    return ARMRelocator::OK;
   }
 }
 
 // R_ARM_THM_MOVT_PREL: S + A - P
 // R_ARM_THM_MOVT_BREL: S + A - B(S)
-ARMRelocationFactory::Result thm_movt_prel(Relocation& pReloc,
-                                           ARMRelocationFactory& pParent)
+ARMRelocator::Result thm_movt_prel(Relocation& pReloc, ARMRelocator& pParent)
 {
-  ARMRelocationFactory::Address S = pReloc.symValue();
-  ARMRelocationFactory::DWord P = pReloc.place();
+  ARMRelocator::Address S = pReloc.symValue();
+  ARMRelocator::DWord P = pReloc.place();
 
   // get lower and upper 16 bit instructions from relocation targetData
   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
-  ARMRelocationFactory::DWord val = ((upper_inst) << 16) | (lower_inst);
-  ARMRelocationFactory::DWord A =
+  ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst);
+  ARMRelocator::DWord A =
       helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
-  ARMRelocationFactory::DWord X;
+  ARMRelocator::DWord X;
 
   X = S + A - P;
   X >>= 16;
@@ -861,19 +838,18 @@
   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst;
   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst;
 
-  return ARMRelocationFactory::OK;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_PREL31: ((S + A) | T) - P
-ARMRelocationFactory::Result prel31(Relocation& pReloc,
-                                    ARMRelocationFactory& pParent)
+ARMRelocator::Result prel31(Relocation& pReloc, ARMRelocator& pParent)
 {
-  ARMRelocationFactory::DWord target = pReloc.target();
-  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
-  ARMRelocationFactory::DWord A = helper_sign_extend(target, 31) +
+  ARMRelocator::DWord target = pReloc.target();
+  ARMRelocator::DWord T = getThumbBit(pReloc);
+  ARMRelocator::DWord A = helper_sign_extend(target, 31) +
                                   pReloc.addend();
-  ARMRelocationFactory::DWord P = pReloc.place();
-  ARMRelocationFactory::Address S;
+  ARMRelocator::DWord P = pReloc.place();
+  ARMRelocator::Address S;
 
   S = pReloc.symValue();
   // if symbol has plt
@@ -882,24 +858,22 @@
     T = 0;  // PLT is not thumb.
   }
 
-  ARMRelocationFactory::DWord X = ((S + A) | T) - P;
+  ARMRelocator::DWord X = ((S + A) | T) - P;
   pReloc.target() = helper_bit_select(target, X, 0x7fffffffU);
   if (helper_check_signed_overflow(X, 31))
-    return ARMRelocationFactory::Overflow;
-  return ARMRelocationFactory::OK;
+    return ARMRelocator::Overflow;
+  return ARMRelocator::OK;
 }
 
 // R_ARM_TLS_GD32: GOT(S) + A - P
 // R_ARM_TLS_IE32: GOT(S) + A - P
 // R_ARM_TLS_LE32: S + A - tp
-ARMRelocationFactory::Result tls(Relocation& pReloc,
-                                 ARMRelocationFactory& pParent)
+ARMRelocator::Result tls(Relocation& pReloc, ARMRelocator& pParent)
 {
-  return ARMRelocationFactory::Unsupport;
+  return ARMRelocator::Unsupport;
 }
 
-ARMRelocationFactory::Result unsupport(Relocation& pReloc,
-                                       ARMRelocationFactory& pParent)
+ARMRelocator::Result unsupport(Relocation& pReloc, ARMRelocator& pParent)
 {
-  return ARMRelocationFactory::Unsupport;
+  return ARMRelocator::Unsupport;
 }
diff --git a/lib/Target/ARM/ARMRelocationFactory.h b/lib/Target/ARM/ARMRelocator.h
similarity index 74%
rename from lib/Target/ARM/ARMRelocationFactory.h
rename to lib/Target/ARM/ARMRelocator.h
index 25135ed..0bf3653 100644
--- a/lib/Target/ARM/ARMRelocationFactory.h
+++ b/lib/Target/ARM/ARMRelocator.h
@@ -1,4 +1,4 @@
-//===-  ARMRelocationFactory.h --------------------------------------------===//
+//===-  ARMRelocator.h ----------------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -12,26 +12,26 @@
 #include <gtest.h>
 #endif
 
-#include <mcld/LD/RelocationFactory.h>
+#include <mcld/LD/Relocator.h>
 #include <mcld/Target/GOT.h>
 #include <mcld/Target/SymbolEntryMap.h>
 #include "ARMLDBackend.h"
 
 namespace mcld {
 
-/** \class ARMRelocationFactory
- *  \brief ARMRelocationFactory creates and destroys the ARM relocations.
+/** \class ARMRelocator
+ *  \brief ARMRelocator creates and destroys the ARM relocations.
  *
  */
-class ARMRelocationFactory : public RelocationFactory
+class ARMRelocator : public Relocator
 {
 public:
-  typedef SymbolEntryMap<GOT::Entry> SymGOTMap;
-  typedef SymbolEntryMap<PLT::Entry> SymPLTMap;
+  typedef SymbolEntryMap<ARMGOTEntry> SymGOTMap;
+  typedef SymbolEntryMap<ARMPLT1> SymPLTMap;
 
 public:
-  ARMRelocationFactory(size_t pNum, ARMGNULDBackend& pParent);
-  ~ARMRelocationFactory();
+  ARMRelocator(ARMGNULDBackend& pParent);
+  ~ARMRelocator();
 
   Result applyRelocation(Relocation& pRelocation);
 
diff --git a/lib/Target/ARM/Android.mk b/lib/Target/ARM/Android.mk
index f9cb356..525ac4e 100644
--- a/lib/Target/ARM/Android.mk
+++ b/lib/Target/ARM/Android.mk
@@ -9,7 +9,7 @@
   ARMLDBackend.cpp  \
   ARMMCLinker.cpp  \
   ARMPLT.cpp  \
-  ARMRelocationFactory.cpp  \
+  ARMRelocator.cpp  \
   ARMTargetMachine.cpp \
   ARMToARMStub.cpp \
   ARMToTHMStub.cpp \
diff --git a/lib/Target/ARM/README b/lib/Target/ARM/README
deleted file mode 100644
index ea88bfe..0000000
--- a/lib/Target/ARM/README
+++ /dev/null
@@ -1,2 +0,0 @@
-ARMLDBackend stands like ARMAsmBackend. It's a backend of linker, 
-and all target-dependent behavior and data are here.
diff --git a/lib/Target/Android.mk b/lib/Target/Android.mk
index e70b467..77ab932 100644
--- a/lib/Target/Android.mk
+++ b/lib/Target/Android.mk
@@ -4,6 +4,7 @@
   ELFDynamic.cpp  \
   ELFEmulation.cpp  \
   ELFMCLinker.cpp  \
+  GNUInfo.cpp \
   GNULDBackend.cpp  \
   GOT.cpp \
   OutputRelocSection.cpp  \
diff --git a/lib/Target/ELFDynamic.cpp b/lib/Target/ELFDynamic.cpp
index 25b21f0..89917cc 100644
--- a/lib/Target/ELFDynamic.cpp
+++ b/lib/Target/ELFDynamic.cpp
@@ -20,6 +20,7 @@
 
 //===----------------------------------------------------------------------===//
 // elf_dynamic::EntryIF
+//===----------------------------------------------------------------------===//
 EntryIF::EntryIF()
 {
 }
@@ -30,9 +31,11 @@
 
 //===----------------------------------------------------------------------===//
 // ELFDynamic
-ELFDynamic::ELFDynamic(const GNULDBackend& pParent)
-  : m_pEntryFactory(NULL), m_Backend(pParent), m_Idx(0) {
-  if (32 == pParent.bitclass() && pParent.isLittleEndian()) {
+//===----------------------------------------------------------------------===//
+ELFDynamic::ELFDynamic(const GNULDBackend& pParent,
+                       const LinkerConfig& pConfig)
+  : m_pEntryFactory(NULL), m_Backend(pParent), m_Config(pConfig), m_Idx(0) {
+  if (m_Config.targets().is32Bits() && m_Config.targets().isLittleEndian()) {
     m_pEntryFactory = new Entry<32, true>();
   }
   // FIXME: support big-endian and 64-bit machine.
@@ -86,13 +89,12 @@
 }
 
 /// reserveEntries - reserve entries
-void ELFDynamic::reserveEntries(const LinkerConfig& pConfig,
-                                const ELFFileFormat& pFormat)
+void ELFDynamic::reserveEntries(const ELFFileFormat& pFormat)
 {
-  if (LinkerConfig::DynObj == pConfig.codeGenType()) {
+  if (LinkerConfig::DynObj == m_Config.codeGenType()) {
     reserveOne(llvm::ELF::DT_SONAME); // DT_SONAME
 
-    if (pConfig.options().Bsymbolic())
+    if (m_Config.options().Bsymbolic())
       reserveOne(llvm::ELF::DT_SYMBOLIC); // DT_SYMBOLIC
   }
 
@@ -147,29 +149,29 @@
     reserveOne(llvm::ELF::DT_RELAENT); // DT_RELAENT
   }
 
-  if (pConfig.options().hasOrigin() ||
-      pConfig.options().Bsymbolic() ||
-      pConfig.options().hasNow()    ||
+  if (m_Config.options().hasOrigin() ||
+      m_Config.options().Bsymbolic() ||
+      m_Config.options().hasNow()    ||
       m_Backend.hasTextRel()        ||
       (m_Backend.hasStaticTLS() &&
-        (LinkerConfig::DynObj == pConfig.codeGenType()))) {
+        (LinkerConfig::DynObj == m_Config.codeGenType()))) {
     reserveOne(llvm::ELF::DT_FLAGS); // DT_FLAGS
   }
 
   if (m_Backend.hasTextRel())
     reserveOne(llvm::ELF::DT_TEXTREL); // DT_TEXTREL
 
-  if (pConfig.options().hasNow()          ||
-      pConfig.options().hasLoadFltr()     ||
-      pConfig.options().hasOrigin()       ||
-      pConfig.options().hasInterPose()    ||
-      pConfig.options().hasNoDefaultLib() ||
-      pConfig.options().hasNoDump()       ||
-      pConfig.options().Bgroup()          ||
-      ((LinkerConfig::DynObj == pConfig.codeGenType()) &&
-       (pConfig.options().hasNoDelete()  ||
-        pConfig.options().hasInitFirst() ||
-        pConfig.options().hasNoDLOpen()))) {
+  if (m_Config.options().hasNow()          ||
+      m_Config.options().hasLoadFltr()     ||
+      m_Config.options().hasOrigin()       ||
+      m_Config.options().hasInterPose()    ||
+      m_Config.options().hasNoDefaultLib() ||
+      m_Config.options().hasNoDump()       ||
+      m_Config.options().Bgroup()          ||
+      ((LinkerConfig::DynObj == m_Config.codeGenType()) &&
+       (m_Config.options().hasNoDelete()  ||
+        m_Config.options().hasInitFirst() ||
+        m_Config.options().hasNoDLOpen()))) {
     reserveOne(llvm::ELF::DT_FLAGS_1); // DT_FLAGS_1
   }
 
@@ -177,11 +179,10 @@
 }
 
 /// applyEntries - apply entries
-void ELFDynamic::applyEntries(const LinkerConfig& pConfig,
-                              const ELFFileFormat& pFormat)
+void ELFDynamic::applyEntries(const ELFFileFormat& pFormat)
 {
-  if (LinkerConfig::DynObj == pConfig.codeGenType() &&
-      pConfig.options().Bsymbolic()) {
+  if (LinkerConfig::DynObj == m_Config.codeGenType() &&
+      m_Config.options().Bsymbolic()) {
       applyOne(llvm::ELF::DT_SYMBOLIC, 0x0); // DT_SYMBOLIC
   }
 
@@ -247,48 +248,48 @@
   if (m_Backend.hasTextRel()) {
     applyOne(llvm::ELF::DT_TEXTREL, 0x0); // DT_TEXTREL
 
-    if (pConfig.options().warnSharedTextrel() &&
-        LinkerConfig::DynObj == pConfig.codeGenType())
+    if (m_Config.options().warnSharedTextrel() &&
+        LinkerConfig::DynObj == m_Config.codeGenType())
       mcld::warning(mcld::diag::warn_shared_textrel);
   }
 
   uint64_t dt_flags = 0x0;
-  if (pConfig.options().hasOrigin())
+  if (m_Config.options().hasOrigin())
     dt_flags |= llvm::ELF::DF_ORIGIN;
-  if (pConfig.options().Bsymbolic())
+  if (m_Config.options().Bsymbolic())
     dt_flags |= llvm::ELF::DF_SYMBOLIC;
-  if (pConfig.options().hasNow())
+  if (m_Config.options().hasNow())
     dt_flags |= llvm::ELF::DF_BIND_NOW;
   if (m_Backend.hasTextRel())
     dt_flags |= llvm::ELF::DF_TEXTREL;
   if (m_Backend.hasStaticTLS() &&
-      (LinkerConfig::DynObj == pConfig.codeGenType()))
+      (LinkerConfig::DynObj == m_Config.codeGenType()))
     dt_flags |= llvm::ELF::DF_STATIC_TLS;
   if (0x0 != dt_flags) {
     applyOne(llvm::ELF::DT_FLAGS, dt_flags); // DT_FLAGS
   }
 
   uint64_t dt_flags_1 = 0x0;
-  if (pConfig.options().hasNow())
+  if (m_Config.options().hasNow())
     dt_flags_1 |= llvm::ELF::DF_1_NOW;
-  if (pConfig.options().hasLoadFltr())
+  if (m_Config.options().hasLoadFltr())
     dt_flags_1 |= llvm::ELF::DF_1_LOADFLTR;
-  if (pConfig.options().hasOrigin())
+  if (m_Config.options().hasOrigin())
     dt_flags_1 |= llvm::ELF::DF_1_ORIGIN;
-  if (pConfig.options().hasInterPose())
+  if (m_Config.options().hasInterPose())
     dt_flags_1 |= llvm::ELF::DF_1_INTERPOSE;
-  if (pConfig.options().hasNoDefaultLib())
+  if (m_Config.options().hasNoDefaultLib())
     dt_flags_1 |= llvm::ELF::DF_1_NODEFLIB;
-  if (pConfig.options().hasNoDump())
+  if (m_Config.options().hasNoDump())
     dt_flags_1 |= llvm::ELF::DF_1_NODUMP;
-  if (pConfig.options().Bgroup())
+  if (m_Config.options().Bgroup())
     dt_flags_1 |= llvm::ELF::DF_1_GROUP;
-  if (LinkerConfig::DynObj == pConfig.codeGenType()) {
-    if (pConfig.options().hasNoDelete())
+  if (LinkerConfig::DynObj == m_Config.codeGenType()) {
+    if (m_Config.options().hasNoDelete())
       dt_flags_1 |= llvm::ELF::DF_1_NODELETE;
-    if (pConfig.options().hasInitFirst())
+    if (m_Config.options().hasInitFirst())
       dt_flags_1 |= llvm::ELF::DF_1_INITFIRST;
-    if (pConfig.options().hasNoDLOpen())
+    if (m_Config.options().hasNoDLOpen())
       dt_flags_1 |= llvm::ELF::DF_1_NOOPEN;
   }
   if (0x0 != dt_flags_1)
diff --git a/lib/Target/GNUInfo.cpp b/lib/Target/GNUInfo.cpp
new file mode 100644
index 0000000..75234b0
--- /dev/null
+++ b/lib/Target/GNUInfo.cpp
@@ -0,0 +1,31 @@
+//===- GNUInfo.cpp --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Target/GNUInfo.h>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// GNUInfo
+//===----------------------------------------------------------------------===//
+GNUInfo::GNUInfo(const llvm::Triple& pTriple)
+  : m_Triple(pTriple) {
+}
+
+uint8_t GNUInfo::OSABI() const
+{
+  switch (m_Triple.getOS()) {
+    case llvm::Triple::FreeBSD:
+      return llvm::ELF::ELFOSABI_FREEBSD;
+    case llvm::Triple::Linux:
+      return llvm::ELF::ELFOSABI_LINUX;
+    default:
+      return llvm::ELF::ELFOSABI_NONE;
+  }
+}
+
diff --git a/lib/Target/GNULDBackend.cpp b/lib/Target/GNULDBackend.cpp
index 950ac43..590c14f 100644
--- a/lib/Target/GNULDBackend.cpp
+++ b/lib/Target/GNULDBackend.cpp
@@ -11,11 +11,14 @@
 #include <string>
 #include <cstring>
 #include <cassert>
+#include <vector>
+#include <algorithm>
 
 #include <mcld/Module.h>
 #include <mcld/LinkerConfig.h>
 #include <mcld/IRBuilder.h>
 #include <mcld/InputTree.h>
+#include <mcld/Config/Config.h>
 #include <mcld/ADT/SizeTraits.h>
 #include <mcld/LD/LDSymbol.h>
 #include <mcld/LD/LDContext.h>
@@ -23,6 +26,7 @@
 #include <mcld/LD/EhFrame.h>
 #include <mcld/LD/EhFrameHdr.h>
 #include <mcld/LD/RelocData.h>
+#include <mcld/LD/RelocationFactory.h>
 #include <mcld/MC/Attribute.h>
 #include <mcld/Fragment/FragmentLinker.h>
 #include <mcld/Support/MemoryArea.h>
@@ -52,12 +56,13 @@
 //===----------------------------------------------------------------------===//
 // GNULDBackend
 //===----------------------------------------------------------------------===//
-GNULDBackend::GNULDBackend(const LinkerConfig& pConfig)
+GNULDBackend::GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
   : TargetLDBackend(pConfig),
     m_pObjectReader(NULL),
     m_pDynObjFileFormat(NULL),
     m_pExecFileFormat(NULL),
     m_pObjectFileFormat(NULL),
+    m_pInfo(pInfo),
     m_ELFSegmentTable(9), // magic number
     m_pBRIslandFactory(NULL),
     m_pStubFactory(NULL),
@@ -89,6 +94,7 @@
 
 GNULDBackend::~GNULDBackend()
 {
+  delete m_pInfo;
   delete m_pDynObjFileFormat;
   delete m_pExecFileFormat;
   delete m_pSymIndexMap;
@@ -103,8 +109,21 @@
 
 size_t GNULDBackend::sectionStartOffset() const
 {
-  // FIXME: use fixed offset, we need 10 segments by default
-  return sizeof(llvm::ELF::Elf64_Ehdr)+10*sizeof(llvm::ELF::Elf64_Phdr);
+  if (LinkerConfig::Binary == config().codeGenType())
+    return 0x0;
+
+  switch (config().targets().bitclass()) {
+    case 32u:
+      return sizeof(llvm::ELF::Elf32_Ehdr) +
+             numOfSegments() * sizeof(llvm::ELF::Elf32_Phdr);
+    case 64u:
+      return sizeof(llvm::ELF::Elf64_Ehdr) +
+             numOfSegments() * sizeof(llvm::ELF::Elf64_Phdr);
+    default:
+      fatal(diag::unsupported_bitclass) << config().targets().triple().str()
+                                        << config().targets().bitclass();
+      return 0;
+  }
 }
 
 uint64_t GNULDBackend::segmentStartAddr(const FragmentLinker& pLinker) const
@@ -126,30 +145,40 @@
   return new GNUArchiveReader(pModule, *m_pObjectReader);
 }
 
-ELFObjectReader* GNULDBackend::createObjectReader(FragmentLinker& pLinker)
+ELFObjectReader* GNULDBackend::createObjectReader(IRBuilder& pBuilder)
 {
-  m_pObjectReader = new ELFObjectReader(*this, pLinker);
+  m_pObjectReader = new ELFObjectReader(*this, pBuilder, config());
   return m_pObjectReader;
 }
 
-ELFDynObjReader* GNULDBackend::createDynObjReader(FragmentLinker& pLinker)
+ELFDynObjReader* GNULDBackend::createDynObjReader(IRBuilder& pBuilder)
 {
-  return new ELFDynObjReader(*this, pLinker);
+  return new ELFDynObjReader(*this, pBuilder, config());
 }
 
-ELFObjectWriter* GNULDBackend::createObjectWriter(FragmentLinker& pLinker)
+ELFBinaryReader* GNULDBackend::createBinaryReader(IRBuilder& pBuilder)
 {
-  return new ELFObjectWriter(*this, pLinker);
+  return new ELFBinaryReader(*this, pBuilder, config());
 }
 
-ELFDynObjWriter* GNULDBackend::createDynObjWriter(FragmentLinker& pLinker)
+ELFObjectWriter* GNULDBackend::createObjectWriter()
 {
-  return new ELFDynObjWriter(*this, pLinker);
+  return new ELFObjectWriter(*this, config());
 }
 
-ELFExecWriter* GNULDBackend::createExecWriter(FragmentLinker& pLinker)
+ELFDynObjWriter* GNULDBackend::createDynObjWriter()
 {
-  return new ELFExecWriter(*this, pLinker);
+  return new ELFDynObjWriter(*this, config());
+}
+
+ELFExecWriter* GNULDBackend::createExecWriter()
+{
+  return new ELFExecWriter(*this, config());
+}
+
+ELFBinaryWriter* GNULDBackend::createBinaryWriter()
+{
+  return new ELFBinaryWriter(*this, config());
 }
 
 bool GNULDBackend::initStdSections(ObjectBuilder& pBuilder)
@@ -158,19 +187,23 @@
     case LinkerConfig::DynObj: {
       if (NULL == m_pDynObjFileFormat)
         m_pDynObjFileFormat = new ELFDynObjFileFormat();
-      m_pDynObjFileFormat->initStdSections(pBuilder, bitclass());
+      m_pDynObjFileFormat->initStdSections(pBuilder,
+                                           config().targets().bitclass());
       return true;
     }
-    case LinkerConfig::Exec: {
+    case LinkerConfig::Exec:
+    case LinkerConfig::Binary: {
       if (NULL == m_pExecFileFormat)
         m_pExecFileFormat = new ELFExecFileFormat();
-      m_pExecFileFormat->initStdSections(pBuilder, bitclass());
+      m_pExecFileFormat->initStdSections(pBuilder,
+                                         config().targets().bitclass());
       return true;
     }
     case LinkerConfig::Object: {
       if (NULL == m_pObjectFileFormat)
         m_pObjectFileFormat = new ELFObjectFileFormat();
-      m_pObjectFileFormat->initStdSections(pBuilder, bitclass());
+      m_pObjectFileFormat->initStdSections(pBuilder,
+                                           config().targets().bitclass());
       return true;
     }
     default:
@@ -687,6 +720,7 @@
       assert(NULL != m_pDynObjFileFormat);
       return m_pDynObjFileFormat;
     case LinkerConfig::Exec:
+    case LinkerConfig::Binary:
       assert(NULL != m_pExecFileFormat);
       return m_pExecFileFormat;
     case LinkerConfig::Object:
@@ -705,6 +739,7 @@
       assert(NULL != m_pDynObjFileFormat);
       return m_pDynObjFileFormat;
     case LinkerConfig::Exec:
+    case LinkerConfig::Binary:
       assert(NULL != m_pExecFileFormat);
       return m_pExecFileFormat;
     case LinkerConfig::Object:
@@ -758,6 +793,9 @@
   size_t shstrtab = 1;
   size_t hash   = 0;
 
+  // number of local symbol in the .dynsym
+  size_t dynsym_local_cnt = 0;
+
   /// compute the size of .symtab, .dynsym and .strtab
   /// @{
   Module::const_sym_iterator symbol;
@@ -789,6 +827,7 @@
     if (ResolveInfo::Section != (*symbol)->type())
       strtab += str_size;
   }
+  dynsym_local_cnt = dynsym;
   // compute the size of the reset of symbols
   symEnd = pModule.sym_end();
   for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
@@ -813,7 +852,8 @@
         dynstr += pModule.name().size() + 1;
     }
     /** fall through **/
-    case LinkerConfig::Exec: {
+    case LinkerConfig::Exec:
+    case LinkerConfig::Binary: {
       // add DT_NEED strings into .dynstr and .dynamic
       // Rules:
       //   1. ignore --no-add-needed
@@ -844,21 +884,28 @@
       }
 
       // set size
-      if (32 == bitclass())
+      if (config().targets().is32Bits())
         file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym));
       else
         file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym));
       file_format->getDynStrTab().setSize(dynstr);
       file_format->getHashTab().setSize(hash);
 
+      // set .dynsym sh_info to one greater than the symbol table
+      // index of the last local symbol
+      file_format->getDynSymTab().setInfo(dynsym_local_cnt);
     }
     /* fall through */
     case LinkerConfig::Object: {
-      if (32 == bitclass())
+      if (config().targets().is32Bits())
         file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
       else
         file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
       file_format->getStrTab().setSize(strtab);
+
+      // set .symtab sh_info to one greater than the symbol table
+      // index of the last local symbol
+      file_format->getSymTab().setInfo(symbols.numOfLocals() + 1);
       break;
     }
     default:
@@ -870,12 +917,13 @@
   /// reserve fixed entries in the .dynamic section.
   /// @{
   if (LinkerConfig::DynObj == config().codeGenType() ||
-      LinkerConfig::Exec == config().codeGenType()) {
+      LinkerConfig::Exec   == config().codeGenType() ||
+      LinkerConfig::Binary == config().codeGenType()) {
     // Because some entries in .dynamic section need information of .dynsym,
     // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
     // entries until we get the size of the sections mentioned above
     if (!pIsStaticLink)
-      dynamic().reserveEntries(config(), *file_format);
+      dynamic().reserveEntries(*file_format);
     file_format->getDynamic().setSize(dynamic().numOfBytes());
   }
   /// @}
@@ -956,20 +1004,21 @@
   // set up symtab_region
   llvm::ELF::Elf32_Sym* symtab32 = NULL;
   llvm::ELF::Elf64_Sym* symtab64 = NULL;
-  if (32 == bitclass())
+  if (config().targets().is32Bits())
     symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
-  else if (64 == bitclass())
+  else if (config().targets().is64Bits())
     symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
-  else
-    llvm::report_fatal_error(llvm::Twine("unsupported bitclass ") +
-                             llvm::Twine(bitclass()) +
-                             llvm::Twine(".\n"));
+  else {
+    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
+                                      << config().targets().bitclass();
+  }
+
   // set up strtab_region
   char* strtab = (char*)strtab_region->start();
   strtab[0] = '\0';
 
   // initialize the first ELF symbol
-  if (32 == bitclass()) {
+  if (config().targets().is32Bits()) {
     symtab32[0].st_name  = 0;
     symtab32[0].st_value = 0;
     symtab32[0].st_size  = 0;
@@ -1005,7 +1054,7 @@
       entry->setValue(symtabIdx);
     }
 
-    if (32 == bitclass())
+    if (config().targets().is32Bits())
       emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
                    symtabIdx);
     else
@@ -1052,17 +1101,17 @@
   // set up symtab_region
   llvm::ELF::Elf32_Sym* symtab32 = NULL;
   llvm::ELF::Elf64_Sym* symtab64 = NULL;
-  if (32 == bitclass())
+  if (config().targets().is32Bits())
     symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
-  else if (64 == bitclass())
+  else if (config().targets().is64Bits())
     symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
-  else
-    llvm::report_fatal_error(llvm::Twine("unsupported bitclass ") +
-                             llvm::Twine(bitclass()) +
-                             llvm::Twine(".\n"));
+  else {
+    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
+                                      << config().targets().bitclass();
+  }
 
   // initialize the first ELF symbol
-  if (32 == bitclass()) {
+  if (config().targets().is32Bits()) {
     symtab32[0].st_name  = 0;
     symtab32[0].st_value = 0;
     symtab32[0].st_size  = 0;
@@ -1098,7 +1147,7 @@
     if (!isDynamicSymbol(**symbol))
       continue;
 
-    if (32 == bitclass())
+    if (config().targets().is32Bits())
       emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
                    symtabIdx);
     else
@@ -1117,7 +1166,7 @@
   // emit symbols in TLS category, all symbols in TLS category shold be emitited
   symEnd = symbols.tlsEnd();
   for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) {
-    if (32 == bitclass())
+    if (config().targets().is32Bits())
       emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
                    symtabIdx);
     else
@@ -1139,7 +1188,7 @@
     if (!isDynamicSymbol(**symbol))
       continue;
 
-    if (32 == bitclass())
+    if (config().targets().is32Bits())
       emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
                    symtabIdx);
     else
@@ -1188,7 +1237,7 @@
     // set pointer to SONAME entry in dynamic string table.
     dynamic().applySoname(strtabsize);
   }
-  dynamic().applyEntries(config(), *file_format);
+  dynamic().applyEntries(*file_format);
   dynamic().emit(dyn_sect, *dyn_region);
 
   // emit soname
@@ -1217,7 +1266,7 @@
 
   StringHash<ELF> hash_func;
 
-  if (32 == bitclass()) {
+  if (config().targets().is32Bits()) {
     for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
       llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
       size_t bucket_pos = hash_func(name) % nbucket;
@@ -1225,7 +1274,7 @@
       bucket[bucket_pos] = sym_idx;
     }
   }
-  else if (64 == bitclass()) {
+  else if (config().targets().is64Bits()) {
     for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
       llvm::StringRef name(strtab + symtab64[sym_idx].st_name);
       size_t bucket_pos = hash_func(name) % nbucket;
@@ -1301,9 +1350,9 @@
               &pSectHdr == &file_format->getCtors() ||
               &pSectHdr == &file_format->getDtors() ||
               &pSectHdr == &file_format->getJCR() ||
-              0 == pSectHdr.name().compare(".data.rel.ro"))
+              &pSectHdr == &file_format->getDataRelRo())
             return SHO_RELRO;
-          if (0 == pSectHdr.name().compare(".data.rel.ro.local"))
+          if (&pSectHdr == &file_format->getDataRelRoLocal())
             return SHO_RELRO_LOCAL;
         }
         if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) {
@@ -1374,8 +1423,9 @@
     bind = llvm::ELF::STB_GLOBAL;
   }
 
-  if (pSymbol.visibility() == llvm::ELF::STV_INTERNAL ||
-      pSymbol.visibility() == llvm::ELF::STV_HIDDEN)
+  if (config().codeGenType() != LinkerConfig::Object &&
+      (pSymbol.visibility() == llvm::ELF::STV_INTERNAL ||
+      pSymbol.visibility() == llvm::ELF::STV_HIDDEN))
     bind = llvm::ELF::STB_LOCAL;
 
   uint32_t type = pSymbol.resolveInfo()->type();
@@ -1660,7 +1710,7 @@
     // update PT_PHDR
     if (llvm::ELF::PT_PHDR == segment.type()) {
       uint64_t offset, phdr_size;
-      if (32 == bitclass()) {
+      if (config().targets().is32Bits()) {
         offset = sizeof(llvm::ELF::Elf32_Ehdr);
         phdr_size = sizeof(llvm::ELF::Elf32_Phdr);
       }
@@ -1673,7 +1723,7 @@
       segment.setPaddr(segment.vaddr());
       segment.setFilesz(numOfSegments() * phdr_size);
       segment.setMemsz(numOfSegments() * phdr_size);
-      segment.setAlign(bitclass() / 8);
+      segment.setAlign(config().targets().bitclass() / 8);
       continue;
     }
 
@@ -1859,16 +1909,18 @@
     if (mapping != config().scripts().addressMap().end()) {
       // check address mapping
       start_addr = mapping.getEntry()->value();
-      const uint64_t remainder = start_addr % abiPageSize();
-      if (remainder != (*seg).front()->offset() % abiPageSize()) {
-        uint64_t padding = abiPageSize() + remainder -
-                           (*seg).front()->offset() % abiPageSize();
-        setOutputSectionOffset(pModule,
-                               pModule.begin() + (*seg).front()->index(),
-                               pModule.end(),
-                               (*seg).front()->offset() + padding);
-        if (config().options().hasRelro())
-          setupRelro(pModule);
+      if ((*seg).front()->kind() != LDFileFormat::Null) {
+        const uint64_t remainder = start_addr % abiPageSize();
+        if (remainder != (*seg).front()->offset() % abiPageSize()) {
+          uint64_t padding = abiPageSize() + remainder -
+                             (*seg).front()->offset() % abiPageSize();
+          setOutputSectionOffset(pModule,
+                                 pModule.begin() + (*seg).front()->index(),
+                                 pModule.end(),
+                                 (*seg).front()->offset() + padding);
+          if (config().options().hasRelro())
+            setupRelro(pModule);
+        }
       }
     }
     else {
@@ -1910,6 +1962,75 @@
   }
 }
 
+/// layout - layout method
+void GNULDBackend::layout(Module& pModule, FragmentLinker& pLinker)
+{
+  std::vector<SHOEntry> output_list;
+  // 1. determine what sections will go into final output, and push the needed
+  // sections into output_list for later processing
+  for (Module::iterator it = pModule.begin(), ie = pModule.end(); it != ie;
+       ++it) {
+    switch ((*it)->kind()) {
+      // take NULL and StackNote directly
+      case LDFileFormat::Null:
+      case LDFileFormat::StackNote:
+        output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
+        break;
+      // ignore if section size is 0
+      case LDFileFormat::Regular:
+      case LDFileFormat::Target:
+      case LDFileFormat::MetaData:
+      case LDFileFormat::BSS:
+      case LDFileFormat::Debug:
+      case LDFileFormat::EhFrame:
+      case LDFileFormat::GCCExceptTable:
+      case LDFileFormat::NamePool:
+      case LDFileFormat::Relocation:
+      case LDFileFormat::Note:
+      case LDFileFormat::EhFrameHdr:
+        if (0 != (*it)->size()) {
+          output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
+        }
+        break;
+      case LDFileFormat::Group:
+        if (LinkerConfig::Object == config().codeGenType()) {
+          //TODO: support incremental linking
+          ;
+        }
+        break;
+      case LDFileFormat::Version:
+        if (0 != (*it)->size()) {
+          output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
+          warning(diag::warn_unsupported_symbolic_versioning) << (*it)->name();
+        }
+        break;
+      default:
+        if (0 != (*it)->size()) {
+          error(diag::err_unsupported_section) << (*it)->name() << (*it)->kind();
+        }
+        break;
+    }
+  } // end of for
+
+  // 2. sort output section orders
+  std::stable_sort(output_list.begin(), output_list.end(), SHOCompare());
+
+  // 3. update output sections in Module
+  pModule.getSectionTable().clear();
+  for(size_t index = 0; index < output_list.size(); ++index) {
+    (output_list[index].first)->setIndex(index);
+    pModule.getSectionTable().push_back(output_list[index].first);
+  }
+
+  // 4. create program headers
+  if (LinkerConfig::Object != config().codeGenType()) {
+    createProgramHdrs(pModule, pLinker);
+  }
+
+  // 5. set output section offset
+  setOutputSectionOffset(pModule, pModule.begin(), pModule.end(), 0x0);
+}
+
 /// preLayout - Backend can do any needed modification before layout
 void GNULDBackend::preLayout(Module& pModule, FragmentLinker& pLinker)
 {
@@ -1970,10 +2091,10 @@
         RelocData* out_reloc_data = output_sect->getRelocData();
 
         // move relocations from input's to output's RelcoationData
-        RelocData::FragmentListType& out_list =
-                                             out_reloc_data->getFragmentList();
-        RelocData::FragmentListType& in_list =
-                                      (*rs)->getRelocData()->getFragmentList();
+        RelocData::RelocationListType& out_list =
+                                             out_reloc_data->getRelocationList();
+        RelocData::RelocationListType& in_list =
+                                      (*rs)->getRelocData()->getRelocationList();
         out_list.splice(out_list.end(), in_list);
 
         // size output
@@ -1997,25 +2118,20 @@
 void GNULDBackend::postLayout(Module& pModule,
                               FragmentLinker& pLinker)
 {
-  // 1. emit program headers
-  if (LinkerConfig::Object != config().codeGenType()) {
-    // 1.1 create program headers
-    createProgramHdrs(pModule, pLinker);
-  }
-
+  // 1. set up section address and segment attributes
   if (LinkerConfig::Object != config().codeGenType()) {
     if (config().options().hasRelro()) {
-      // 1.2 set up the offset constraint of PT_RELRO
+      // 1.1 set up the offset constraint of PT_RELRO
       setupRelro(pModule);
     }
 
-    // 1.3 set up the output sections' address
+    // 1.2 set up the output sections' address
     setOutputSectionAddress(pLinker, pModule, pModule.begin(), pModule.end());
 
-    // 1.4 do relaxation
+    // 1.3 do relaxation
     relax(pModule, pLinker);
 
-    // 1.5 set up the attributes of program headers
+    // 1.4 set up the attributes of program headers
     setupProgramHdrs(pLinker);
   }
 
@@ -2027,7 +2143,7 @@
 {
   if (config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) {
     // emit eh_frame_hdr
-    if (bitclass() == 32)
+    if (config().targets().is32Bits())
       m_pEhFrameHdr->emitOutput<32>(pOutput);
   }
 }
@@ -2070,9 +2186,11 @@
   // If we are building shared object, and the visibility is external, we
   // need to add it.
   if (LinkerConfig::DynObj == config().codeGenType() ||
-      LinkerConfig::Exec == config().codeGenType()) {
+      LinkerConfig::Exec   == config().codeGenType() ||
+      LinkerConfig::Binary == config().codeGenType()) {
     if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default ||
-        pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected) {
+        pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected ||
+        pSymbol.resolveInfo()->type() == ResolveInfo::ThreadLocal) {
       return true;
     }
   }
@@ -2091,9 +2209,11 @@
   // If we are building shared object, and the visibility is external, we
   // need to add it.
   if (LinkerConfig::DynObj == config().codeGenType() ||
-      LinkerConfig::Exec == config().codeGenType()) {
+      LinkerConfig::Exec   == config().codeGenType() ||
+      LinkerConfig::Binary == config().codeGenType()) {
     if (pResolveInfo.visibility() == ResolveInfo::Default ||
-        pResolveInfo.visibility() == ResolveInfo::Protected) {
+        pResolveInfo.visibility() == ResolveInfo::Protected ||
+        pResolveInfo.type() == ResolveInfo::ThreadLocal) {
       return true;
     }
   }
@@ -2160,7 +2280,8 @@
   // resolved to 0 and no need a dynamic relocation
   if (pSym.isUndef() &&
       !pSym.isDyn() &&
-      LinkerConfig::Exec == config().codeGenType())
+      (LinkerConfig::Exec   == config().codeGenType() ||
+       LinkerConfig::Binary == config().codeGenType()))
     return false;
 
   if (pSym.isAbsolute())
@@ -2214,7 +2335,9 @@
 {
   // if the output is pic code or if not executables, symbols' value may change
   // at runtime
-  if (pLinker.isOutputPIC() || LinkerConfig::Exec != config().codeGenType())
+  if (pLinker.isOutputPIC() ||
+      (LinkerConfig::Exec != config().codeGenType() &&
+       LinkerConfig::Binary != config().codeGenType()))
     return false;
 
   // if the symbol is from dynamic object, then its value is unknown
diff --git a/lib/Target/GOT.cpp b/lib/Target/GOT.cpp
index 32afdff..a441775 100644
--- a/lib/Target/GOT.cpp
+++ b/lib/Target/GOT.cpp
@@ -19,25 +19,10 @@
 using namespace mcld;
 
 //===----------------------------------------------------------------------===//
-// GOT::Entry
-//===----------------------------------------------------------------------===//
-GOT::Entry::Entry(uint64_t pContent, size_t pEntrySize, SectionData* pParent)
-  : TargetFragment(Fragment::Target, pParent),
-    f_Content(pContent),
-    m_EntrySize(pEntrySize) {
-}
-
-GOT::Entry::~Entry()
-{
-}
-
-//===----------------------------------------------------------------------===//
 // GOT
 //===----------------------------------------------------------------------===//
-GOT::GOT(LDSection& pSection, size_t pEntrySize)
-  : m_Section(pSection),
-    f_EntrySize(pEntrySize),
-    m_pLast(NULL) {
+GOT::GOT(LDSection& pSection)
+  : m_Section(pSection) {
   m_SectionData = IRBuilder::CreateSectionData(pSection);
 }
 
@@ -45,39 +30,15 @@
 {
 }
 
-size_t GOT::getEntrySize() const
-{
-  return f_EntrySize;
-}
-
-void GOT::reserve(size_t pNum)
-{
-  for (size_t i = 0; i < pNum; i++) {
-    new Entry(0, f_EntrySize, m_SectionData);
-  }
-}
-
-GOT::Entry* GOT::consume()
-{
-  if (NULL == m_pLast) {
-    assert(!empty() && "Consume empty GOT entry!");
-    m_pLast = llvm::cast<Entry>(&m_SectionData->front());
-    return m_pLast;
-  }
-
-  m_pLast = llvm::cast<Entry>(m_pLast->getNextNode());
-  return m_pLast;
-}
-
 void GOT::finalizeSectionSize()
 {
-  m_Section.setSize(m_SectionData->size() * f_EntrySize);
-
   uint32_t offset = 0;
   SectionData::iterator frag, fragEnd = m_SectionData->end();
   for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) {
     frag->setOffset(offset);
     offset += frag->size();
   }
+
+  m_Section.setSize(offset);
 }
 
diff --git a/lib/Target/Mips/Android.mk b/lib/Target/Mips/Android.mk
index dd3905d..2410f6f 100644
--- a/lib/Target/Mips/Android.mk
+++ b/lib/Target/Mips/Android.mk
@@ -8,7 +8,7 @@
   MipsGOT.cpp \
   MipsLDBackend.cpp \
   MipsMCLinker.cpp \
-  MipsRelocationFactory.cpp \
+  MipsRelocator.cpp \
   MipsTargetMachine.cpp
 
 # For the host
diff --git a/lib/Target/Mips/MipsELFDynamic.cpp b/lib/Target/Mips/MipsELFDynamic.cpp
index fd779f3..58ed7a5 100644
--- a/lib/Target/Mips/MipsELFDynamic.cpp
+++ b/lib/Target/Mips/MipsELFDynamic.cpp
@@ -6,11 +6,11 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+#include "MipsELFDynamic.h"
 
+#include "MipsLDBackend.h"
 #include <mcld/LD/ELFFileFormat.h>
 #include <mcld/Target/GNULDBackend.h>
-#include "MipsELFDynamic.h"
-#include "MipsLDBackend.h"
 
 using namespace mcld;
 
@@ -24,8 +24,9 @@
   MIPS_GOTSYM       = 0x70000013
 };
 
-MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent)
-  : ELFDynamic(pParent),
+MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent,
+                               const LinkerConfig& pConfig)
+  : ELFDynamic(pParent, pConfig),
     m_pParent(pParent)
 {
 }
diff --git a/lib/Target/Mips/MipsELFDynamic.h b/lib/Target/Mips/MipsELFDynamic.h
index 118e4f9..6efbf71 100644
--- a/lib/Target/Mips/MipsELFDynamic.h
+++ b/lib/Target/Mips/MipsELFDynamic.h
@@ -21,7 +21,7 @@
 class MipsELFDynamic : public ELFDynamic
 {
 public:
-  MipsELFDynamic(const MipsGNULDBackend& pParent);
+  MipsELFDynamic(const MipsGNULDBackend& pParent, const LinkerConfig& pConfig);
   ~MipsELFDynamic();
 
 private:
diff --git a/lib/Target/Mips/MipsEmulation.cpp b/lib/Target/Mips/MipsEmulation.cpp
index 74f2637..845e1a5 100644
--- a/lib/Target/Mips/MipsEmulation.cpp
+++ b/lib/Target/Mips/MipsEmulation.cpp
@@ -18,6 +18,10 @@
   if (!MCLDEmulateELF(pConfig))
     return false;
 
+  // set up bitclass and endian
+  pConfig.targets().setEndian(TargetOptions::Little);
+  pConfig.targets().setBitClass(32);
+
   // set up target-dependent constraints of attributes
   pConfig.attribute().constraint().enableWholeArchive();
   pConfig.attribute().constraint().enableAsNeeded();
diff --git a/lib/Target/Mips/MipsGNUInfo.h b/lib/Target/Mips/MipsGNUInfo.h
new file mode 100644
index 0000000..9bbc548
--- /dev/null
+++ b/lib/Target/Mips/MipsGNUInfo.h
@@ -0,0 +1,29 @@
+//===- MipsGNUInfo.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_MIPS_GNU_INFO_H
+#define MCLD_TARGET_MIPS_GNU_INFO_H
+#include <mcld/Target/GNUInfo.h>
+
+#include <llvm/Support/ELF.h>
+
+namespace mcld {
+
+class MipsGNUInfo : public GNUInfo
+{
+public:
+  MipsGNUInfo(const llvm::Triple& pTriple) : GNUInfo(pTriple) { }
+
+  uint32_t machine() const { return llvm::ELF::EM_MIPS; }
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/Mips/MipsGOT.cpp b/lib/Target/Mips/MipsGOT.cpp
index b4eb1cd..d18eebf 100644
--- a/lib/Target/Mips/MipsGOT.cpp
+++ b/lib/Target/Mips/MipsGOT.cpp
@@ -16,7 +16,6 @@
 #include <mcld/Support/MsgHandling.h>
 
 namespace {
-  const size_t MipsGOTEntrySize = 4;
   const size_t MipsGOT0Num = 1;
 }
 
@@ -26,8 +25,9 @@
 // MipsGOT
 //===----------------------------------------------------------------------===//
 MipsGOT::MipsGOT(LDSection& pSection)
-  : GOT(pSection, MipsGOTEntrySize),
-    m_pLocalNum(0)
+  : GOT(pSection),
+    m_pLocalNum(0),
+    m_pLast(NULL)
 {
   // Create GOT0 entries.
   reserve(MipsGOT0Num);
@@ -47,6 +47,25 @@
   m_pLocalNum = MipsGOT0Num;
 }
 
+void MipsGOT::reserve(size_t pNum)
+{
+  for (size_t i = 0; i < pNum; i++) {
+    new MipsGOTEntry(0, m_SectionData);
+  }
+}
+
+MipsGOTEntry* MipsGOT::consume()
+{
+  if (NULL == m_pLast) {
+    assert(!empty() && "Consume empty GOT entry!");
+    m_pLast = llvm::cast<MipsGOTEntry>(&m_SectionData->front());
+    return m_pLast;
+  }
+
+  m_pLast = llvm::cast<MipsGOTEntry>(m_pLast->getNextNode());
+  return m_pLast;
+}
+
 bool MipsGOT::hasGOT1() const
 {
   return (m_SectionData->size() > MipsGOT0Num);
@@ -56,14 +75,12 @@
 {
   uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
 
-  size_t entry_size = getEntrySize();
-
   uint64_t result = 0;
   for (iterator it = begin(), ie = end();
        it != ie; ++it, ++buffer) {
-    GOT::Entry* got = &(llvm::cast<GOT::Entry>((*it)));
-    *buffer = static_cast<uint32_t>(got->getContent());
-    result += entry_size;
+    MipsGOTEntry* got = &(llvm::cast<MipsGOTEntry>((*it)));
+    *buffer = static_cast<uint32_t>(got->getValue());
+    result += got->size();
   }
   return result;
 }
@@ -83,22 +100,22 @@
   reserve(1);
 }
 
-GOT::Entry* MipsGOT::consumeLocal()
+MipsGOTEntry* MipsGOT::consumeLocal()
 {
   iterator& it = m_LocalGOTIterator;
   ++it;
   assert(it != m_SectionData->getFragmentList().end() &&
          "The number of GOT Entries and ResolveInfo doesn't match");
-  return llvm::cast<GOT::Entry>(&(*it));
+  return llvm::cast<MipsGOTEntry>(&(*it));
 }
 
-GOT::Entry* MipsGOT::consumeGlobal()
+MipsGOTEntry* MipsGOT::consumeGlobal()
 {
   iterator& it = m_GlobalGOTIterator;
   ++it;
   assert(it != m_SectionData->getFragmentList().end() &&
          "The number of GOT Entries and ResolveInfo doesn't match");
-  return llvm::cast<GOT::Entry>(&(*it));
+  return llvm::cast<MipsGOTEntry>(&(*it));
 }
 
 size_t MipsGOT::getTotalNum() const
diff --git a/lib/Target/Mips/MipsGOT.h b/lib/Target/Mips/MipsGOT.h
index 6ec4926..fa46e91 100644
--- a/lib/Target/Mips/MipsGOT.h
+++ b/lib/Target/Mips/MipsGOT.h
@@ -21,6 +21,17 @@
 class LDSection;
 class MemoryRegion;
 
+/** \class MipsGOTEntry
+ *  \brief GOT Entry with size of 4 bytes
+ */
+class MipsGOTEntry : public GOT::Entry<4>
+{
+public:
+  MipsGOTEntry(uint64_t pContent, SectionData* pParent)
+   : GOT::Entry<4>(pContent, pParent)
+  {}
+};
+
 /** \class MipsGOT
  *  \brief Mips Global Offset Table.
  */
@@ -31,14 +42,16 @@
 
   uint64_t emit(MemoryRegion& pRegion);
 
+  void reserve(size_t pNum = 1);
   void reserveLocalEntry();
   void reserveGlobalEntry();
 
   size_t getTotalNum() const;
   size_t getLocalNum() const;
 
-  GOT::Entry* consumeLocal();
-  GOT::Entry* consumeGlobal();
+  MipsGOTEntry* consume();
+  MipsGOTEntry* consumeLocal();
+  MipsGOTEntry* consumeGlobal();
 
   void setLocal(const ResolveInfo* pInfo) {
     m_GOTTypeMap[pInfo] = false;
@@ -68,6 +81,8 @@
   iterator m_LocalGOTIterator;  // last local GOT entries
   iterator m_GlobalGOTIterator; // last global GOT entries
   size_t m_pLocalNum;
+
+  MipsGOTEntry* m_pLast; ///< the last consumed entry
 };
 
 } // namespace of mcld
diff --git a/lib/Target/Mips/MipsLDBackend.cpp b/lib/Target/Mips/MipsLDBackend.cpp
index da2399e..59b8d18 100644
--- a/lib/Target/Mips/MipsLDBackend.cpp
+++ b/lib/Target/Mips/MipsLDBackend.cpp
@@ -7,9 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 #include "Mips.h"
+#include "MipsGNUInfo.h"
 #include "MipsELFDynamic.h"
 #include "MipsLDBackend.h"
-#include "MipsRelocationFactory.h"
+#include "MipsRelocator.h"
 
 #include <llvm/ADT/Triple.h>
 #include <llvm/Support/ELF.h>
@@ -43,9 +44,10 @@
 //===----------------------------------------------------------------------===//
 // MipsGNULDBackend
 //===----------------------------------------------------------------------===//
-MipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig)
-  : GNULDBackend(pConfig),
-    m_pRelocFactory(NULL),
+MipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig,
+                                   MipsGNUInfo* pInfo)
+  : GNULDBackend(pConfig, pInfo),
+    m_pRelocator(NULL),
     m_pGOT(NULL),
     m_pRelDyn(NULL),
     m_pDynamic(NULL),
@@ -56,7 +58,7 @@
 
 MipsGNULDBackend::~MipsGNULDBackend()
 {
-  delete m_pRelocFactory;
+  delete m_pRelocator;
   delete m_pGOT;
   delete m_pRelDyn;
   delete m_pDynamic;
@@ -73,9 +75,7 @@
 
     // initialize .rel.dyn
     LDSection& reldyn = file_format->getRelDyn();
-    m_pRelDyn = new OutputRelocSection(pModule,
-                                       reldyn,
-                                       getRelEntrySize());
+    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
   }
 }
 
@@ -110,19 +110,19 @@
   }
 }
 
-bool MipsGNULDBackend::initRelocFactory(const FragmentLinker& pLinker)
+bool MipsGNULDBackend::initRelocator(const FragmentLinker& pLinker)
 {
-  if (NULL == m_pRelocFactory) {
-    m_pRelocFactory = new MipsRelocationFactory(1024, *this);
-    m_pRelocFactory->setFragmentLinker(pLinker);
+  if (NULL == m_pRelocator) {
+    m_pRelocator = new MipsRelocator(*this);
+    m_pRelocator->setFragmentLinker(pLinker);
   }
   return true;
 }
 
-RelocationFactory* MipsGNULDBackend::getRelocFactory()
+Relocator* MipsGNULDBackend::getRelocator()
 {
-  assert(NULL != m_pRelocFactory);
-  return m_pRelocFactory;
+  assert(NULL != m_pRelocator);
+  return m_pRelocator;
 }
 
 void MipsGNULDBackend::scanRelocation(Relocation& pReloc,
@@ -156,7 +156,7 @@
 
   // check if we shoule issue undefined reference for the relocation target
   // symbol
-  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak())
+  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
     fatal(diag::undefined_reference) << rsym->name();
 
   if ((rsym->reserved() & ReserveRel) != 0x0) {
@@ -165,21 +165,6 @@
   }
 }
 
-uint32_t MipsGNULDBackend::machine() const
-{
-  return llvm::ELF::EM_MIPS;
-}
-
-uint8_t MipsGNULDBackend::OSABI() const
-{
-  return llvm::ELF::ELFOSABI_NONE;
-}
-
-uint8_t MipsGNULDBackend::ABIVersion() const
-{
-  return 0;
-}
-
 uint64_t MipsGNULDBackend::flags() const
 {
   // TODO: (simon) The correct flag's set depend on command line
@@ -191,17 +176,6 @@
          E_MIPS_ABI_O32;
 }
 
-bool MipsGNULDBackend::isLittleEndian() const
-{
-  // Now we support little endian (mipsel) target only.
-  return true;
-}
-
-unsigned int MipsGNULDBackend::bitclass() const
-{
-  return 32;
-}
-
 uint64_t MipsGNULDBackend::defaultTextSegmentAddr() const
 {
   return 0x80000;
@@ -227,9 +201,11 @@
       defineGOTSymbol(pLinker);
     }
 
+    ELFFileFormat* file_format = getOutputFormat();
     // set .rel.dyn size
     if (!m_pRelDyn->empty())
-      m_pRelDyn->finalizeSectionSize();
+      file_format->getRelDyn().setSize(
+                                  m_pRelDyn->numOfRelocs() * getRelEntrySize());
   }
 }
 void MipsGNULDBackend::doPostLayout(Module& pModule,
@@ -242,7 +218,7 @@
 MipsELFDynamic& MipsGNULDBackend::dynamic()
 {
   if (NULL == m_pDynamic)
-    m_pDynamic = new MipsELFDynamic(*this);
+    m_pDynamic = new MipsELFDynamic(*this, config());
 
   return *m_pDynamic;
 }
@@ -298,6 +274,9 @@
   size_t shstrtab = 1;
   size_t hash   = 0;
 
+  // number of local symbol in the .dynsym
+  size_t dynsym_local_cnt = 0;
+
   /// compute the size of .symtab, .dynsym and .strtab
   /// @{
   Module::const_sym_iterator symbol;
@@ -329,6 +308,7 @@
     if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
       strtab += str_size;
   }
+  dynsym_local_cnt = dynsym;
   // compute the size of the reset of symbols
   symEnd = pModule.sym_end();
   for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
@@ -384,21 +364,28 @@
       }
 
       // set size
-      if (32 == bitclass())
+      if (config().targets().is32Bits())
         file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym));
       else
         file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym));
       file_format->getDynStrTab().setSize(dynstr);
       file_format->getHashTab().setSize(hash);
 
+      // set .dynsym sh_info to one greater than the symbol table
+      // index of the last local symbol
+      file_format->getDynSymTab().setInfo(dynsym_local_cnt);
     }
     /* fall through */
     case LinkerConfig::Object: {
-      if (32 == bitclass())
+      if (config().targets().is32Bits())
         file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
       else
         file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
       file_format->getStrTab().setSize(strtab);
+
+      // set .symtab sh_info to one greater than the symbol table
+      // index of the last local symbol
+      file_format->getSymTab().setInfo(symbols.numOfLocals() + 1);
       break;
     }
     default: {
@@ -415,7 +402,7 @@
     // Because some entries in .dynamic section need information of .dynsym,
     // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
     // entries until we get the size of the sections mentioned above
-    dynamic().reserveEntries(config(), *file_format);
+    dynamic().reserveEntries(*file_format);
     file_format->getDynamic().setSize(dynamic().numOfBytes());
   }
   /// @}
@@ -630,7 +617,7 @@
   // initialize value of ELF .dynamic section
   if (LinkerConfig::DynObj == config().codeGenType())
     dynamic().applySoname(strtabsize);
-  dynamic().applyEntries(config(), *file_format);
+  dynamic().applyEntries(*file_format);
   dynamic().emit(dyn_sect, *dyn_region);
 
   strcpy((strtab + strtabsize), pModule.name().c_str());
@@ -823,7 +810,7 @@
         // section if the symbol section flags contains SHF_EXECINSTR.
         // 1. Find the reason of this condition.
         // 2. Check this condition here.
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         rsym->setReserved(rsym->reserved() | ReserveRel);
 
         // Remeber this rsym is a local GOT entry (as if it needs an entry).
@@ -927,7 +914,7 @@
     case llvm::ELF::R_MIPS_HI16:
     case llvm::ELF::R_MIPS_LO16:
       if (symbolNeedsDynRel(pLinker, *rsym, false, true)) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         rsym->setReserved(rsym->reserved() | ReserveRel);
 
         // Remeber this rsym is a global GOT entry (as if it needs an entry).
@@ -1038,13 +1025,13 @@
 static TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget,
                                             const LinkerConfig& pConfig)
 {
-  if (pConfig.triple().isOSDarwin()) {
+  if (pConfig.targets().triple().isOSDarwin()) {
     assert(0 && "MachO linker is not supported yet");
   }
-  if (pConfig.triple().isOSWindows()) {
+  if (pConfig.targets().triple().isOSWindows()) {
     assert(0 && "COFF linker is not supported yet");
   }
-  return new MipsGNULDBackend(pConfig);
+  return new MipsGNULDBackend(pConfig, new MipsGNUInfo(pConfig.targets().triple()));
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Target/Mips/MipsLDBackend.h b/lib/Target/Mips/MipsLDBackend.h
index b6adb93..b9db410 100644
--- a/lib/Target/Mips/MipsLDBackend.h
+++ b/lib/Target/Mips/MipsLDBackend.h
@@ -19,6 +19,7 @@
 class OutputRelocSection;
 class SectionMap;
 class MemoryArea;
+class MipsGNUInfo;
 
 //===----------------------------------------------------------------------===//
 /// MipsGNULDBackend - linker backend of Mips target of GNU ELF format
@@ -34,7 +35,7 @@
   };
 
 public:
-  MipsGNULDBackend(const LinkerConfig& pConfig);
+  MipsGNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo);
   ~MipsGNULDBackend();
 
 public:
@@ -44,11 +45,11 @@
   /// initTargetSymbols - initialize target dependent symbols in output.
   void initTargetSymbols(FragmentLinker& pLinker);
 
-  /// initRelocFactory - create and initialize RelocationFactory.
-  bool initRelocFactory(const FragmentLinker& pLinker);
+  /// initRelocator - create and initialize Relocator.
+  bool initRelocator(const FragmentLinker& pLinker);
 
-  /// getRelocFactory - return relocation factory.
-  RelocationFactory* getRelocFactory();
+  /// getRelocator - return relocator.
+  Relocator* getRelocator();
 
   /// scanRelocation - determine the empty entries are needed or not and
   /// create the empty entries if needed.
@@ -58,21 +59,9 @@
                       Module& pModule,
                       const LDSection& pSection);
 
-  uint32_t machine() const;
-
-  /// OSABI - the value of e_ident[EI_OSABI]
-  uint8_t OSABI() const;
-
-  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
-  uint8_t ABIVersion() const;
-
   /// flags - the value of ElfXX_Ehdr::e_flags
   uint64_t flags() const;
 
-  bool isLittleEndian() const;
-
-  unsigned int bitclass() const;
-
   uint64_t defaultTextSegmentAddr() const;
 
   /// abiPageSize - the abi page size of the target machine
@@ -159,7 +148,7 @@
                                    const FragmentLinker& pLinker);
 
 private:
-  RelocationFactory* m_pRelocFactory;
+  Relocator* m_pRelocator;
 
   MipsGOT* m_pGOT;                      // .got
   OutputRelocSection* m_pRelDyn;        // .rel.dyn
diff --git a/lib/Target/Mips/MipsRelocationFunctions.h b/lib/Target/Mips/MipsRelocationFunctions.h
index adff43f..aad708e 100644
--- a/lib/Target/Mips/MipsRelocationFunctions.h
+++ b/lib/Target/Mips/MipsRelocationFunctions.h
@@ -8,8 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #define DECL_MIPS_APPLY_RELOC_FUNC(Name) \
-static MipsRelocationFactory::Result Name(Relocation& pEntry, \
-                                          MipsRelocationFactory& pParent);
+static MipsRelocator::Result Name(Relocation& pEntry, \
+                                  MipsRelocator& pParent);
 
 #define DECL_MIPS_APPLY_RELOC_FUNCS \
 DECL_MIPS_APPLY_RELOC_FUNC(none) \
@@ -18,7 +18,9 @@
 DECL_MIPS_APPLY_RELOC_FUNC(lo16) \
 DECL_MIPS_APPLY_RELOC_FUNC(got16) \
 DECL_MIPS_APPLY_RELOC_FUNC(call16) \
-DECL_MIPS_APPLY_RELOC_FUNC(gprel32)
+DECL_MIPS_APPLY_RELOC_FUNC(gprel32) \
+DECL_MIPS_APPLY_RELOC_FUNC(gothi16) \
+DECL_MIPS_APPLY_RELOC_FUNC(gotlo16)
 
 #define DECL_MIPS_APPLY_RELOC_FUNC_PTRS \
   { &none,     0, "R_MIPS_NONE"            }, \
@@ -43,16 +45,16 @@
   { &none,    19, "R_MIPS_GOT_DISP"        }, \
   { &none,    20, "R_MIPS_GOT_PAGE"        }, \
   { &none,    21, "R_MIPS_GOT_OFST"        }, \
-  { &none,    22, "R_MIPS_GOT_HI16"        }, \
-  { &none,    23, "R_MIPS_GOT_LO16"        }, \
+  { &gothi16, 22, "R_MIPS_GOT_HI16"        }, \
+  { &gotlo16, 23, "R_MIPS_GOT_LO16"        }, \
   { &none,    24, "R_MIPS_SUB"             }, \
   { &none,    25, "R_MIPS_INSERT_A"        }, \
   { &none,    26, "R_MIPS_INSERT_B"        }, \
   { &none,    27, "R_MIPS_DELETE"          }, \
   { &none,    28, "R_MIPS_HIGHER"          }, \
   { &none,    29, "R_MIPS_HIGHEST"         }, \
-  { &none,    30, "R_MIPS_CALL_HI16"       }, \
-  { &none,    31, "R_MIPS_CALL_LO16"       }, \
+  { &gothi16, 30, "R_MIPS_CALL_HI16"       }, \
+  { &gotlo16, 31, "R_MIPS_CALL_LO16"       }, \
   { &none,    32, "R_MIPS_SCN_DISP"        }, \
   { &none,    33, "R_MIPS_REL16"           }, \
   { &none,    34, "R_MIPS_ADD_IMMEDIATE"   }, \
diff --git a/lib/Target/Mips/MipsRelocationFactory.cpp b/lib/Target/Mips/MipsRelocator.cpp
similarity index 72%
rename from lib/Target/Mips/MipsRelocationFactory.cpp
rename to lib/Target/Mips/MipsRelocator.cpp
index 09041be..ad5de22 100644
--- a/lib/Target/Mips/MipsRelocationFactory.cpp
+++ b/lib/Target/Mips/MipsRelocator.cpp
@@ -1,4 +1,4 @@
-//===- MipsRelocationFactory.cpp  -----------------------------------------===//
+//===- MipsRelocator.cpp  -----------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -13,7 +13,7 @@
 #include <mcld/Support/MsgHandling.h>
 #include <mcld/Target/OutputRelocSection.h>
 
-#include "MipsRelocationFactory.h"
+#include "MipsRelocator.h"
 #include "MipsRelocationFunctions.h"
 
 using namespace mcld;
@@ -24,8 +24,7 @@
 DECL_MIPS_APPLY_RELOC_FUNCS
 
 /// the prototype of applying function
-typedef RelocationFactory::Result (*ApplyFunctionType)(Relocation&,
-                                                       MipsRelocationFactory&);
+typedef Relocator::Result (*ApplyFunctionType)(Relocation&, MipsRelocator&);
 
 // the table entry of applying functions
 struct ApplyFunctionTriple
@@ -41,18 +40,17 @@
 };
 
 //===----------------------------------------------------------------------===//
-// MipsRelocationFactory
+// MipsRelocator
 //===----------------------------------------------------------------------===//
-MipsRelocationFactory::MipsRelocationFactory(size_t pNum,
-                                             MipsGNULDBackend& pParent)
-  : RelocationFactory(pNum),
+MipsRelocator::MipsRelocator(MipsGNULDBackend& pParent)
+  : Relocator(),
     m_Target(pParent),
     m_AHL(0)
 {
 }
 
-RelocationFactory::Result
-MipsRelocationFactory::applyRelocation(Relocation& pRelocation)
+Relocator::Result
+MipsRelocator::applyRelocation(Relocation& pRelocation)
 
 {
   Relocation::Type type = pRelocation.type();
@@ -65,7 +63,7 @@
   return ApplyFunctions[type].func(pRelocation, *this);
 }
 
-const char* MipsRelocationFactory::getName(Relocation::Type pType) const
+const char* MipsRelocator::getName(Relocation::Type pType) const
 {
   return ApplyFunctions[pType].name;
 }
@@ -101,15 +99,15 @@
 }
 
 static
-RelocationFactory::Address helper_GetGP(MipsRelocationFactory& pParent)
+Relocator::Address helper_GetGP(MipsRelocator& pParent)
 {
   return pParent.getTarget().getGOT().addr() + 0x7FF0;
 }
 
 static
-GOT::Entry& helper_GetGOTEntry(Relocation& pReloc,
-                             MipsRelocationFactory& pParent,
-                             bool& pExist, int32_t value)
+MipsGOTEntry& helper_GetGOTEntry(Relocation& pReloc,
+                                 MipsRelocator& pParent,
+                                 bool& pExist, int32_t value)
 {
   // rsym - The relocation target symbol
   ResolveInfo* rsym = pReloc.symInfo();
@@ -121,7 +119,7 @@
     return *got.consumeLocal();
   }
 
-  GOT::Entry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
+  MipsGOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
   if (NULL != got_entry) {
     // found a mapping, then return the mapped entry immediately
     return *got_entry;
@@ -137,7 +135,7 @@
 
   // If we first get this GOT entry, we should initialize it.
   if (rsym->reserved() & MipsGNULDBackend::ReserveGot) {
-    got_entry->setContent(pReloc.symValue());
+    got_entry->setValue(pReloc.symValue());
   }
   else {
     fatal(diag::reserve_entry_number_mismatch_got);
@@ -147,11 +145,11 @@
 }
 
 static
-RelocationFactory::Address helper_GetGOTOffset(Relocation& pReloc,
-                                               MipsRelocationFactory& pParent)
+Relocator::Address helper_GetGOTOffset(Relocation& pReloc,
+                                       MipsRelocator& pParent)
 {
   bool exist;
-  GOT::Entry& got_entry = helper_GetGOTEntry(pReloc, pParent, exist, 0);
+  MipsGOTEntry& got_entry = helper_GetGOTEntry(pReloc, pParent, exist, 0);
   return got_entry.getOffset() - 0x7FF0;
 }
 
@@ -174,8 +172,7 @@
 }
 
 static
-void helper_DynRel(Relocation& pReloc,
-                   MipsRelocationFactory& pParent)
+void helper_DynRel(Relocation& pReloc, MipsRelocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
   MipsGNULDBackend& ld_backend = pParent.getTarget();
@@ -186,8 +183,8 @@
   rel_entry.setType(llvm::ELF::R_MIPS_REL32);
   rel_entry.targetRef() = pReloc.targetRef();
 
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
-  RelocationFactory::DWord S = pReloc.symValue();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
+  Relocator::DWord S = pReloc.symValue();
 
   if (got.isLocal(rsym)) {
     rel_entry.setSymInfo(NULL);
@@ -206,47 +203,44 @@
 
 // R_MIPS_NONE and those unsupported/deprecated relocation type
 static
-MipsRelocationFactory::Result none(Relocation& pReloc,
-                                   MipsRelocationFactory& pParent)
+MipsRelocator::Result none(Relocation& pReloc, MipsRelocator& pParent)
 {
-  return MipsRelocationFactory::OK;
+  return MipsRelocator::OK;
 }
 
 // R_MIPS_32: S + A
 static
-MipsRelocationFactory::Result abs32(Relocation& pReloc,
-                                    MipsRelocationFactory& pParent)
+MipsRelocator::Result abs32(Relocation& pReloc, MipsRelocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
 
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
-  RelocationFactory::DWord S = pReloc.symValue();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
+  Relocator::DWord S = pReloc.symValue();
 
   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   // If the flag of target section is not ALLOC, we will not scan this relocation
   // but perform static relocation. (e.g., applying .debug section)
   if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
     pReloc.target() = S + A;
-    return MipsRelocationFactory::OK;
+    return MipsRelocator::OK;
   }
 
   if (rsym->reserved() & MipsGNULDBackend::ReserveRel) {
     helper_DynRel(pReloc, pParent);
 
-    return MipsRelocationFactory::OK;
+    return MipsRelocator::OK;
   }
 
   pReloc.target() = (S + A);
 
-  return MipsRelocationFactory::OK;
+  return MipsRelocator::OK;
 }
 
 // R_MIPS_HI16:
 //   local/external: ((AHL + S) - (short)(AHL + S)) >> 16
 //   _gp_disp      : ((AHL + GP - P) - (short)(AHL + GP - P)) >> 16
 static
-MipsRelocationFactory::Result hi16(Relocation& pReloc,
-                                   MipsRelocationFactory& pParent)
+MipsRelocator::Result hi16(Relocation& pReloc, MipsRelocator& pParent)
 {
   Relocation* lo_reloc = helper_FindLo16Reloc(pReloc);
   assert(NULL != lo_reloc && "There is no paired R_MIPS_LO16 for R_MIPS_HI16");
@@ -269,15 +263,14 @@
   pReloc.target() &= 0xFFFF0000;
   pReloc.target() |= (res & 0xFFFF);
 
-  return MipsRelocationFactory::OK;
+  return MipsRelocator::OK;
 }
 
 // R_MIPS_LO16:
 //   local/external: AHL + S
 //   _gp_disp      : AHL + GP - P + 4
 static
-MipsRelocationFactory::Result lo16(Relocation& pReloc,
-                                   MipsRelocationFactory& pParent)
+MipsRelocator::Result lo16(Relocation& pReloc, MipsRelocator& pParent)
 {
   int32_t res = 0;
 
@@ -299,18 +292,17 @@
   pReloc.target() &= 0xFFFF0000;
   pReloc.target() |= (res & 0xFFFF);
 
-  return MipsRelocationFactory::OK;
+  return MipsRelocator::OK;
 }
 
 // R_MIPS_GOT16:
 //   local   : G (calculate AHL and put high 16 bit to GOT)
 //   external: G
 static
-MipsRelocationFactory::Result got16(Relocation& pReloc,
-                                    MipsRelocationFactory& pParent)
+MipsRelocator::Result got16(Relocation& pReloc, MipsRelocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
-  RelocationFactory::Address G = 0;
+  Relocator::Address G = 0;
 
   if (rsym->isLocal()) {
     Relocation* lo_reloc = helper_FindLo16Reloc(pReloc);
@@ -323,9 +315,9 @@
 
     int32_t res = (AHL + S + 0x8000) & 0xFFFF0000;
     bool exist;
-    GOT::Entry& got_entry = helper_GetGOTEntry(pReloc, pParent, exist, res);
+    MipsGOTEntry& got_entry = helper_GetGOTEntry(pReloc, pParent, exist, res);
 
-    got_entry.setContent(res);
+    got_entry.setValue(res);
     G = got_entry.getOffset() - 0x7FF0;
   }
   else {
@@ -335,26 +327,55 @@
   pReloc.target() &= 0xFFFF0000;
   pReloc.target() |= (G & 0xFFFF);
 
-  return MipsRelocationFactory::OK;
+  return MipsRelocator::OK;
 }
 
-// R_MIPS_CALL16: G
+// R_MIPS_GOTHI16:
+//   external: (G - (short)G) >> 16 + A
 static
-MipsRelocationFactory::Result call16(Relocation& pReloc,
-                                     MipsRelocationFactory& pParent)
+MipsRelocator::Result gothi16(Relocation& pReloc, MipsRelocator& pParent)
 {
-  RelocationFactory::Address G = helper_GetGOTOffset(pReloc, pParent);
+  int32_t res = 0;
+
+  Relocator::Address G = helper_GetGOTOffset(pReloc, pParent);
+  int32_t A = pReloc.target() + pReloc.addend();
+
+  res = (G - (int16_t)G) >> (16 + A);
+
+  pReloc.target() &= 0xFFFF0000;
+  pReloc.target() |= (res & 0xFFFF);
+
+  return MipsRelocator::OK;
+}
+
+// R_MIPS_GOTLO16:
+//   external: G & 0xffff
+static
+MipsRelocator::Result gotlo16(Relocation& pReloc, MipsRelocator& pParent)
+{
+  Relocator::Address G = helper_GetGOTOffset(pReloc, pParent);
 
   pReloc.target() &= 0xFFFF0000;
   pReloc.target() |= (G & 0xFFFF);
 
-  return MipsRelocationFactory::OK;
+  return MipsRelocator::OK;
+}
+
+// R_MIPS_CALL16: G
+static
+MipsRelocator::Result call16(Relocation& pReloc, MipsRelocator& pParent)
+{
+  Relocator::Address G = helper_GetGOTOffset(pReloc, pParent);
+
+  pReloc.target() &= 0xFFFF0000;
+  pReloc.target() |= (G & 0xFFFF);
+
+  return MipsRelocator::OK;
 }
 
 // R_MIPS_GPREL32: A + S + GP0 - GP
 static
-MipsRelocationFactory::Result gprel32(Relocation& pReloc,
-                                      MipsRelocationFactory& pParent)
+MipsRelocator::Result gprel32(Relocation& pReloc, MipsRelocator& pParent)
 {
   // Remember to add the section offset to A.
   int32_t A = pReloc.target() + pReloc.addend();
@@ -365,5 +386,6 @@
   // Assume that GP0 is zero.
   pReloc.target() = (A + S - GP) & 0xFFFFFFFF;
 
-  return MipsRelocationFactory::OK;
+  return MipsRelocator::OK;
 }
+
diff --git a/lib/Target/Mips/MipsRelocationFactory.h b/lib/Target/Mips/MipsRelocator.h
similarity index 73%
rename from lib/Target/Mips/MipsRelocationFactory.h
rename to lib/Target/Mips/MipsRelocator.h
index 6076416..836b7d2 100644
--- a/lib/Target/Mips/MipsRelocationFactory.h
+++ b/lib/Target/Mips/MipsRelocator.h
@@ -1,4 +1,4 @@
-//===- MipsRelocationFactory.h --------------------------------------------===//
+//===- MipsRelocator.h --------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -12,23 +12,23 @@
 #include <gtest.h>
 #endif
 
-#include <mcld/LD/RelocationFactory.h>
+#include <mcld/LD/Relocator.h>
 #include <mcld/Support/GCFactory.h>
 #include <mcld/Target/SymbolEntryMap.h>
 #include "MipsLDBackend.h"
 
 namespace mcld {
 
-/** \class MipsRelocationFactory
- *  \brief MipsRelocationFactory creates and destroys the Mips relocations.
+/** \class MipsRelocator
+ *  \brief MipsRelocator creates and destroys the Mips relocations.
  */
-class MipsRelocationFactory : public RelocationFactory
+class MipsRelocator : public Relocator
 {
 public:
-  typedef SymbolEntryMap<GOT::Entry> SymGOTMap;
+  typedef SymbolEntryMap<MipsGOTEntry> SymGOTMap;
 
 public:
-  MipsRelocationFactory(size_t pNum, MipsGNULDBackend& pParent);
+  MipsRelocator(MipsGNULDBackend& pParent);
 
   Result applyRelocation(Relocation& pRelocation);
 
diff --git a/lib/Target/OutputRelocSection.cpp b/lib/Target/OutputRelocSection.cpp
index 593bdb9..3c1a0ce 100644
--- a/lib/Target/OutputRelocSection.cpp
+++ b/lib/Target/OutputRelocSection.cpp
@@ -6,28 +6,24 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
-#include <llvm/Support/Casting.h>
+#include <mcld/Target/OutputRelocSection.h>
 
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/RelocationFactory.h>
 #include <mcld/Module.h>
 #include <mcld/Support/MsgHandling.h>
-#include <mcld/Target/OutputRelocSection.h>
 #include <mcld/IRBuilder.h>
 
+#include <llvm/Support/Casting.h>
+
 using namespace mcld;
 
 //===----------------------------------------------------------------------===//
 // OutputRelocSection
 //===----------------------------------------------------------------------===//
-OutputRelocSection::OutputRelocSection(Module& pModule,
-                                       LDSection& pSection,
-                                       unsigned int pEntrySize)
+OutputRelocSection::OutputRelocSection(Module& pModule, LDSection& pSection)
   : m_Module(pModule),
-    m_pSection(&pSection),
     m_pRelocData(NULL),
-    m_EntryBytes(pEntrySize),
     m_isVisit(false),
     m_ValidEntryIterator(){
   assert(!pSection.hasRelocData() && "Given section is not a relocation section");
@@ -38,15 +34,10 @@
 {
 }
 
-void OutputRelocSection::reserveEntry(RelocationFactory& pRelFactory,
-                                      size_t pNum)
+void OutputRelocSection::reserveEntry(size_t pNum)
 {
-  for(size_t i=0; i<pNum; i++) {
-    m_pRelocData->getFragmentList().push_back(
-                                              pRelFactory.produceEmptyEntry());
-    // update section size
-    m_pSection->setSize(m_pSection->size() + m_EntryBytes);
-  }
+  for(size_t i=0; i<pNum; i++)
+    m_pRelocData->append(*Relocation::Create());
 }
 
 Relocation* OutputRelocSection::consumeEntry()
@@ -54,9 +45,9 @@
   // first time visit this function, set m_ValidEntryIterator to
   // Fragments.begin()
   if(!m_isVisit) {
-    assert(!m_pRelocData->getFragmentList().empty() &&
+    assert(!m_pRelocData->getRelocationList().empty() &&
              "DynRelSection contains no entries.");
-    m_ValidEntryIterator = m_pRelocData->getFragmentList().begin();
+    m_ValidEntryIterator = m_pRelocData->begin();
     m_isVisit = true;
   }
   else {
@@ -70,13 +61,12 @@
   assert(m_ValidEntryIterator != m_pRelocData->end() &&
          "No empty relocation entry for the incoming symbol.");
 
-  Relocation* result = &llvm::cast<Relocation>(*m_ValidEntryIterator);
-  return result;
+  return &(*m_ValidEntryIterator);
 }
 
-void OutputRelocSection::finalizeSectionSize()
+size_t OutputRelocSection::numOfRelocs()
 {
-  m_pSection->setSize(m_pRelocData->size() * m_EntryBytes);
+  return m_pRelocData->size();
 }
 
 bool OutputRelocSection::addSymbolToDynSym(LDSymbol& pSymbol)
@@ -84,3 +74,4 @@
   m_Module.getSymbolTable().changeLocalToTLS(pSymbol);
   return true;
 }
+
diff --git a/lib/Target/PLT.cpp b/lib/Target/PLT.cpp
index a8b515c..60e219e 100644
--- a/lib/Target/PLT.cpp
+++ b/lib/Target/PLT.cpp
@@ -15,23 +15,6 @@
 class GOT;
 
 //===----------------------------------------------------------------------===//
-// PLT::Entry
-//===----------------------------------------------------------------------===//
-PLT::Entry::Entry(size_t pSize, SectionData& pParent)
-  : TargetFragment(Fragment::Target, &pParent),
-    m_EntrySize(pSize), m_pContent(NULL)
-{
-}
-
-PLT::Entry::~Entry()
-{
-  if (m_pContent) {
-    free(m_pContent);
-    m_pContent = NULL;
-  }
-}
-
-//===----------------------------------------------------------------------===//
 // PLT
 //===----------------------------------------------------------------------===//
 PLT::PLT(LDSection& pSection)
diff --git a/lib/Target/X86/Android.mk b/lib/Target/X86/Android.mk
index cf7ea17..94b2f0f 100644
--- a/lib/Target/X86/Android.mk
+++ b/lib/Target/X86/Android.mk
@@ -10,7 +10,7 @@
   X86LDBackend.cpp  \
   X86MCLinker.cpp  \
   X86PLT.cpp  \
-  X86RelocationFactory.cpp  \
+  X86Relocator.cpp  \
   X86TargetMachine.cpp
 
 # For the host
diff --git a/lib/Target/X86/X86ELFDynamic.cpp b/lib/Target/X86/X86ELFDynamic.cpp
index af86b2c..c74cc13 100644
--- a/lib/Target/X86/X86ELFDynamic.cpp
+++ b/lib/Target/X86/X86ELFDynamic.cpp
@@ -6,14 +6,15 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+#include "X86ELFDynamic.h"
 
 #include <mcld/LD/ELFFileFormat.h>
-#include "X86ELFDynamic.h"
 
 using namespace mcld;
 
-X86ELFDynamic::X86ELFDynamic(const GNULDBackend& pParent)
-  : ELFDynamic(pParent)
+X86ELFDynamic::X86ELFDynamic(const GNULDBackend& pParent,
+                             const LinkerConfig& pConfig)
+  : ELFDynamic(pParent, pConfig)
 {
 }
 
diff --git a/lib/Target/X86/X86ELFDynamic.h b/lib/Target/X86/X86ELFDynamic.h
index 7053a0b..e3d5338 100644
--- a/lib/Target/X86/X86ELFDynamic.h
+++ b/lib/Target/X86/X86ELFDynamic.h
@@ -19,7 +19,7 @@
 class X86ELFDynamic : public ELFDynamic
 {
 public:
-  X86ELFDynamic(const GNULDBackend& pParent);
+  X86ELFDynamic(const GNULDBackend& pParent, const LinkerConfig& pConfig);
   ~X86ELFDynamic();
 
 private:
diff --git a/lib/Target/X86/X86Emulation.cpp b/lib/Target/X86/X86Emulation.cpp
index 74b7e47..9343583 100644
--- a/lib/Target/X86/X86Emulation.cpp
+++ b/lib/Target/X86/X86Emulation.cpp
@@ -18,6 +18,10 @@
   if (!MCLDEmulateELF(pConfig))
     return false;
 
+  // set up bitclass and endian
+  pConfig.targets().setEndian(TargetOptions::Little);
+  pConfig.targets().setBitClass(32);
+
   // set up target-dependent constraints of attributes
   pConfig.attribute().constraint().enableWholeArchive();
   pConfig.attribute().constraint().enableAsNeeded();
diff --git a/lib/Target/X86/X86GNUInfo.h b/lib/Target/X86/X86GNUInfo.h
new file mode 100644
index 0000000..af548f0
--- /dev/null
+++ b/lib/Target/X86/X86GNUInfo.h
@@ -0,0 +1,29 @@
+//===- X86GNUInfo.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_X86_GNU_INFO_H
+#define MCLD_TARGET_X86_GNU_INFO_H
+#include <mcld/Target/GNUInfo.h>
+
+#include <llvm/Support/ELF.h>
+
+namespace mcld {
+
+class X86GNUInfo : public GNUInfo
+{
+public:
+  X86GNUInfo(const llvm::Triple& pTriple) : GNUInfo(pTriple) { }
+
+  uint32_t machine() const { return llvm::ELF::EM_386; }
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/X86/X86GOT.cpp b/lib/Target/X86/X86GOT.cpp
index ae28ea7..e734bb3 100644
--- a/lib/Target/X86/X86GOT.cpp
+++ b/lib/Target/X86/X86GOT.cpp
@@ -11,9 +11,7 @@
 #include <mcld/LD/LDFileFormat.h>
 #include <mcld/LD/SectionData.h>
 
-namespace {
-  const size_t X86GOTEntrySize = 4;
-}
+#include <llvm/Support/Casting.h>
 
 using namespace mcld;
 
@@ -21,7 +19,7 @@
 // X86GOT
 //===----------------------------------------------------------------------===//
 X86GOT::X86GOT(LDSection& pSection)
-             : GOT(pSection, X86GOTEntrySize)
+  : GOT(pSection), m_pLast(NULL)
 {
 }
 
@@ -29,3 +27,22 @@
 {
 }
 
+void X86GOT::reserve(size_t pNum)
+{
+  for (size_t i = 0; i < pNum; i++) {
+    new X86GOTEntry(0, m_SectionData);
+  }
+}
+
+X86GOTEntry* X86GOT::consume()
+{
+  if (NULL == m_pLast) {
+    assert(!empty() && "Consume empty GOT entry!");
+    m_pLast = llvm::cast<X86GOTEntry>(&m_SectionData->front());
+    return m_pLast;
+  }
+
+  m_pLast = llvm::cast<X86GOTEntry>(m_pLast->getNextNode());
+  return m_pLast;
+}
+
diff --git a/lib/Target/X86/X86GOT.h b/lib/Target/X86/X86GOT.h
index a027dc7..66967e1 100644
--- a/lib/Target/X86/X86GOT.h
+++ b/lib/Target/X86/X86GOT.h
@@ -19,6 +19,17 @@
 class LDSection;
 class SectionData;
 
+/** \class X86GOTEntry
+ *  \brief GOT Entry with size of 4 bytes
+ */
+class X86GOTEntry : public GOT::Entry<4>
+{
+public:
+  X86GOTEntry(uint64_t pContent, SectionData* pParent)
+   : GOT::Entry<4>(pContent, pParent)
+  {}
+};
+
 /** \class X86GOT
  *  \brief X86 Global Offset Table.
  */
@@ -29,6 +40,13 @@
   X86GOT(LDSection& pSection);
 
   ~X86GOT();
+
+  void reserve(size_t pNum = 1);
+
+  X86GOTEntry* consume();
+
+private:
+  X86GOTEntry* m_pLast; ///< the last consumed entry
 };
 
 } // namespace of mcld
diff --git a/lib/Target/X86/X86GOTPLT.cpp b/lib/Target/X86/X86GOTPLT.cpp
index b4e0ffe..b72487e 100644
--- a/lib/Target/X86/X86GOTPLT.cpp
+++ b/lib/Target/X86/X86GOTPLT.cpp
@@ -9,25 +9,19 @@
 #include "X86GOTPLT.h"
 #include "X86PLT.h"
 
-#include <new>
-
 #include <llvm/Support/Casting.h>
 
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/LDFileFormat.h>
 #include <mcld/Support/MsgHandling.h>
 
-namespace {
-  const uint64_t X86GOTPLTEntrySize = 4;
-}
-
 namespace mcld {
 
 //===----------------------------------------------------------------------===//
 // X86GOTPLT
 //===----------------------------------------------------------------------===//
 X86GOTPLT::X86GOTPLT(LDSection& pSection)
-  : GOT(pSection, X86GOTPLTEntrySize)
+  : GOT(pSection), m_pLast(NULL)
 {
   // Create GOT0 entries
   reserve(X86GOTPLT0Num);
@@ -42,6 +36,25 @@
 {
 }
 
+void X86GOTPLT::reserve(size_t pNum)
+{
+  for (size_t i = 0; i < pNum; i++) {
+    new X86GOTPLTEntry(0, m_SectionData);
+  }
+}
+
+X86GOTPLTEntry* X86GOTPLT::consume()
+{
+  if (NULL == m_pLast) {
+    assert(!empty() && "Consume empty GOT entry!");
+    m_pLast = llvm::cast<X86GOTPLTEntry>(&m_SectionData->front());
+    return m_pLast;
+  }
+
+  m_pLast = llvm::cast<X86GOTPLTEntry>(m_pLast->getNextNode());
+  return m_pLast;
+}
+
 bool X86GOTPLT::hasGOT1() const
 {
   return (m_SectionData->size() > X86GOTPLT0Num);
@@ -49,8 +62,8 @@
 
 void X86GOTPLT::applyGOT0(uint64_t pAddress)
 {
-  llvm::cast<Entry>
-    (*(m_SectionData->getFragmentList().begin())).setContent(pAddress);
+  llvm::cast<X86GOTPLTEntry>
+    (*(m_SectionData->getFragmentList().begin())).setValue(pAddress);
 }
 
 void X86GOTPLT::applyAllGOTPLT(const X86PLT& pPLT)
@@ -62,7 +75,7 @@
   // address of corresponding plt entry
   uint64_t plt_addr = pPLT.addr() + pPLT.getPLT0Size();
   for (; it != end() ; ++it) {
-    llvm::cast<Entry>(*it).setContent(plt_addr + 6);
+    llvm::cast<X86GOTPLTEntry>(*it).setValue(plt_addr + 6);
     plt_addr += pPLT.getPLT1Size();
   }
 }
diff --git a/lib/Target/X86/X86GOTPLT.h b/lib/Target/X86/X86GOTPLT.h
index b2fa65a..f288fa4 100644
--- a/lib/Target/X86/X86GOTPLT.h
+++ b/lib/Target/X86/X86GOTPLT.h
@@ -23,6 +23,14 @@
 
 const unsigned int X86GOTPLT0Num = 3;
 
+class X86GOTPLTEntry : public GOT::Entry<4>
+{
+public:
+  X86GOTPLTEntry(uint64_t pContent, SectionData* pParent)
+   : GOT::Entry<4>(pContent, pParent)
+  {}
+};
+
 /** \class X86GOTPLT
  *  \brief X86 .got.plt section.
  */
@@ -33,12 +41,19 @@
 
   ~X86GOTPLT();
 
+  void reserve(size_t pNum = 1);
+
+  X86GOTPLTEntry* consume();
+
   // hasGOT1 - return if this section has any GOT1 entry
   bool hasGOT1() const;
 
   void applyGOT0(uint64_t pAddress);
 
   void applyAllGOTPLT(const X86PLT& pPLT);
+
+private:
+  X86GOTPLTEntry* m_pLast; ///< the last consumed entry
 };
 
 } // namespace of mcld
diff --git a/lib/Target/X86/X86LDBackend.cpp b/lib/Target/X86/X86LDBackend.cpp
index 987daec..a18fedb 100644
--- a/lib/Target/X86/X86LDBackend.cpp
+++ b/lib/Target/X86/X86LDBackend.cpp
@@ -9,7 +9,8 @@
 #include "X86.h"
 #include "X86ELFDynamic.h"
 #include "X86LDBackend.h"
-#include "X86RelocationFactory.h"
+#include "X86Relocator.h"
+#include "X86GNUInfo.h"
 
 #include <llvm/ADT/Triple.h>
 #include <llvm/Support/Casting.h>
@@ -31,9 +32,9 @@
 //===----------------------------------------------------------------------===//
 // X86GNULDBackend
 //===----------------------------------------------------------------------===//
-X86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig)
-  : GNULDBackend(pConfig),
-    m_pRelocFactory(NULL),
+X86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig, X86GNUInfo* pInfo)
+  : GNULDBackend(pConfig, pInfo),
+    m_pRelocator(NULL),
     m_pGOT(NULL),
     m_pPLT(NULL),
     m_pGOTPLT(NULL),
@@ -45,7 +46,7 @@
 
 X86GNULDBackend::~X86GNULDBackend()
 {
-  delete m_pRelocFactory;
+  delete m_pRelocator;
   delete m_pGOT;
   delete m_pPLT;
   delete m_pGOTPLT;
@@ -54,21 +55,21 @@
   delete m_pDynamic;
 }
 
-RelocationFactory* X86GNULDBackend::getRelocFactory()
+bool X86GNULDBackend::initRelocator(const FragmentLinker& pLinker)
 {
-  assert(NULL != m_pRelocFactory);
-  return m_pRelocFactory;
-}
-
-bool X86GNULDBackend::initRelocFactory(const FragmentLinker& pLinker)
-{
-  if (NULL == m_pRelocFactory) {
-    m_pRelocFactory = new X86RelocationFactory(1024, *this);
-    m_pRelocFactory->setFragmentLinker(pLinker);
+  if (NULL == m_pRelocator) {
+    m_pRelocator = new X86Relocator(*this);
+    m_pRelocator->setFragmentLinker(pLinker);
   }
   return true;
 }
 
+Relocator* X86GNULDBackend::getRelocator()
+{
+  assert(NULL != m_pRelocator);
+  return m_pRelocator;
+}
+
 void X86GNULDBackend::doPreLayout(FragmentLinker& pLinker)
 {
   // set .got.plt size
@@ -89,13 +90,16 @@
     if (m_pPLT->hasPLT1())
       m_pPLT->finalizeSectionSize();
 
+    ELFFileFormat* file_format = getOutputFormat();
     // set .rel.dyn size
     if (!m_pRelDyn->empty())
-      m_pRelDyn->finalizeSectionSize();
+      file_format->getRelDyn().setSize(
+                                  m_pRelDyn->numOfRelocs() * getRelEntrySize());
 
     // set .rel.plt size
     if (!m_pRelPLT->empty())
-      m_pRelPLT->finalizeSectionSize();
+      file_format->getRelPlt().setSize(
+                                  m_pRelPLT->numOfRelocs() * getRelEntrySize());
   }
 }
 
@@ -109,7 +113,7 @@
 X86ELFDynamic& X86GNULDBackend::dynamic()
 {
   if (NULL == m_pDynamic)
-    m_pDynamic = new X86ELFDynamic(*this);
+    m_pDynamic = new X86ELFDynamic(*this, config());
 
   return *m_pDynamic;
 }
@@ -186,7 +190,7 @@
 
   // Determine the alignment by the symbol value
   // FIXME: here we use the largest alignment
-  uint32_t addralign = bitclass() / 8;
+  uint32_t addralign = config().targets().bitclass() / 8;
 
   // allocate space in BSS for the copy symbol
   Fragment* frag = new FillFragment(0x0, 1, pSym.size());
@@ -233,7 +237,7 @@
       // a dynamic relocations with RELATIVE type to this location is needed.
       // Reserve an entry in .rel.dyn
       if (pLinker.isOutputPIC()) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         // set Rel bit
         rsym->setReserved(rsym->reserved() | ReserveRel);
       }
@@ -256,7 +260,7 @@
       // entry in .rel.dyn
       if (LinkerConfig::DynObj ==
                    config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         // set GOTRel bit
         rsym->setReserved(rsym->reserved() | GOTRel);
         return;
@@ -276,7 +280,7 @@
         return;
       m_pGOT->reserve(2);
       // reserve an rel entry
-      m_pRelDyn->reserveEntry(*m_pRelocFactory);
+      m_pRelDyn->reserveEntry();
       // set GOTRel bit
       rsym->setReserved(rsym->reserved() | GOTRel);
       // define the section symbol for .tdata or .tbss
@@ -310,14 +314,14 @@
       setHasStaticTLS();
       // if buildint shared object, a RELATIVE dynamic relocation is needed
       if (LinkerConfig::DynObj == config().codeGenType()) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         rsym->setReserved(rsym->reserved() | ReserveRel);
       }
       if (rsym->reserved() & GOTRel)
         return;
       // reserve got and dyn relocation entries for tp-relative offset
       m_pGOT->reserve();
-      m_pRelDyn->reserveEntry(*m_pRelocFactory);
+      m_pRelDyn->reserveEntry();
       // set GOTRel bit
       rsym->setReserved(rsym->reserved() | GOTRel);
       m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
@@ -329,7 +333,7 @@
         return;
       // reserve got and dyn relocation entries for tp-relative offset
       m_pGOT->reserve();
-      m_pRelDyn->reserveEntry(*m_pRelocFactory);
+      m_pRelDyn->reserveEntry();
       // set GOTRel bit
       rsym->setReserved(rsym->reserved() | GOTRel);
       m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
@@ -340,7 +344,7 @@
       setHasStaticTLS();
       // if buildint shared object, a dynamic relocation is needed
       if (LinkerConfig::DynObj == config().codeGenType()) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         rsym->setReserved(rsym->reserved() | ReserveRel);
         // the target symbol of the dynamic relocation is rsym, so we need to
         // emit it into .dynsym
@@ -379,7 +383,7 @@
           // when calling X86PLT->reserveEntry())
           m_pPLT->reserveEntry();
           m_pGOTPLT->reserve();
-          m_pRelPLT->reserveEntry(*m_pRelocFactory);
+          m_pRelPLT->reserveEntry();
           // set PLT bit
           rsym->setReserved(rsym->reserved() | ReservePLT);
         }
@@ -388,7 +392,7 @@
       if (symbolNeedsDynRel(pLinker, *rsym, (rsym->reserved() & ReservePLT),
                                                                        true)) {
         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) {
           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
           addCopyReloc(*cpy_sym.resolveInfo());
@@ -430,7 +434,7 @@
       // when calling X86PLT->reserveEntry())
       m_pPLT->reserveEntry();
       m_pGOTPLT->reserve();
-      m_pRelPLT->reserveEntry(*m_pRelocFactory);
+      m_pRelPLT->reserveEntry();
       // set PLT bit
       rsym->setReserved(rsym->reserved() | ReservePLT);
       return;
@@ -446,7 +450,7 @@
       // entry in .rel.dyn
       if (LinkerConfig::DynObj ==
                    config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         // set GOTRel bit
         rsym->setReserved(rsym->reserved() | GOTRel);
         return;
@@ -469,7 +473,7 @@
           // when calling X86PLT->reserveEntry())
           m_pPLT->reserveEntry();
           m_pGOTPLT->reserve();
-          m_pRelPLT->reserveEntry(*m_pRelocFactory);
+          m_pRelPLT->reserveEntry();
           // set PLT bit
           rsym->setReserved(rsym->reserved() | ReservePLT);
         }
@@ -478,7 +482,7 @@
       if (symbolNeedsDynRel(pLinker, *rsym, (rsym->reserved() & ReservePLT),
                                                                       false)) {
         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) {
           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym);
           addCopyReloc(*cpy_sym.resolveInfo());
@@ -496,7 +500,7 @@
         return;
       // reserve two pairs of got entry and dynamic relocation
       m_pGOT->reserve(2);
-      m_pRelDyn->reserveEntry(*m_pRelocFactory, 2);
+      m_pRelDyn->reserveEntry(2);
       // set GOTRel bit
       rsym->setReserved(rsym->reserved() | GOTRel);
       return;
@@ -513,14 +517,14 @@
       setHasStaticTLS();
       // if buildint shared object, a RELATIVE dynamic relocation is needed
       if (LinkerConfig::DynObj == config().codeGenType()) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         rsym->setReserved(rsym->reserved() | ReserveRel);
       }
       if (rsym->reserved() & GOTRel)
         return;
       // reserve got and dyn relocation entries for tp-relative offset
       m_pGOT->reserve();
-      m_pRelDyn->reserveEntry(*m_pRelocFactory);
+      m_pRelDyn->reserveEntry();
       // set GOTRel bit
       rsym->setReserved(rsym->reserved() | GOTRel);
       return;
@@ -531,7 +535,7 @@
         return;
       // reserve got and dyn relocation entries for tp-relative offset
       m_pGOT->reserve();
-      m_pRelDyn->reserveEntry(*m_pRelocFactory);
+      m_pRelDyn->reserveEntry();
       // set GOTRel bit
       rsym->setReserved(rsym->reserved() | GOTRel);
       return;
@@ -541,7 +545,7 @@
       setHasStaticTLS();
       // if buildint shared object, a dynamic relocation is needed
       if (LinkerConfig::DynObj == config().codeGenType()) {
-        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        m_pRelDyn->reserveEntry();
         rsym->setReserved(rsym->reserved() | ReserveRel);
       }
       return;
@@ -579,7 +583,7 @@
 
   // check if we shoule issue undefined reference for the relocation target
   // symbol
-  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak())
+  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
     fatal(diag::undefined_reference) << rsym->name();
 
   if ((rsym->reserved() & ReserveRel) != 0x0) {
@@ -608,18 +612,18 @@
     m_pPLT->applyPLT0();
     m_pPLT->applyPLT1();
     X86PLT::iterator it = m_pPLT->begin();
-    unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize();
+    unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();
 
-    memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size);
+    memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
     RegionSize += plt0_size;
     ++it;
 
-    X86PLT1* plt1 = 0;
+    PLTEntryBase* plt1 = 0;
     X86PLT::iterator ie = m_pPLT->end();
     while (it != ie) {
-      plt1 = &(llvm::cast<X86PLT1>(*it));
-      EntrySize = plt1->getEntrySize();
-      memcpy(buffer + RegionSize, plt1->getContent(), EntrySize);
+      plt1 = &(llvm::cast<PLTEntryBase>(*it));
+      EntrySize = plt1->size();
+      memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
       RegionSize += EntrySize;
       ++it;
     }
@@ -630,13 +634,13 @@
 
     uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
 
-    GOT::Entry* got = 0;
-    EntrySize = m_pGOT->getEntrySize();
+    X86GOTEntry* got = 0;
+    EntrySize = X86GOTEntry::EntrySize;
 
     for (X86GOT::iterator it = m_pGOT->begin(),
          ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
-      got = &(llvm::cast<GOT::Entry>((*it)));
-      *buffer = static_cast<uint32_t>(got->getContent());
+      got = &(llvm::cast<X86GOTEntry>((*it)));
+      *buffer = static_cast<uint32_t>(got->getValue());
       RegionSize += EntrySize;
     }
   }
@@ -648,13 +652,13 @@
 
     uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
 
-    GOT::Entry* got = 0;
-    EntrySize = m_pGOTPLT->getEntrySize();
+    X86GOTEntry* got = 0;
+    EntrySize = X86GOTPLTEntry::EntrySize;
 
     for (X86GOTPLT::iterator it = m_pGOTPLT->begin(),
          ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
-      got = &(llvm::cast<GOT::Entry>((*it)));
-      *buffer = static_cast<uint32_t>(got->getContent());
+      got = &(llvm::cast<X86GOTEntry>((*it)));
+      *buffer = static_cast<uint32_t>(got->getValue());
       RegionSize += EntrySize;
     }
   }
@@ -667,11 +671,6 @@
   return RegionSize;
 }
 
-uint32_t X86GNULDBackend::machine() const
-{
-  return llvm::ELF::EM_386;
-}
-
 X86GOT& X86GNULDBackend::getGOT()
 {
   assert(NULL != m_pGOT);
@@ -721,18 +720,18 @@
 }
 
 // Create a GOT entry for the TLS module index
-GOT::Entry& X86GNULDBackend::getTLSModuleID()
+X86GOTEntry& X86GNULDBackend::getTLSModuleID()
 {
-  static GOT::Entry* got_entry = NULL;
+  static X86GOTEntry* got_entry = NULL;
   if (NULL != got_entry)
     return *got_entry;
 
   // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
   m_pGOT->reserve(2);
   got_entry = m_pGOT->consume();
-  m_pGOT->consume()->setContent(0x0);
+  m_pGOT->consume()->setValue(0x0);
 
-  m_pRelDyn->reserveEntry(*m_pRelocFactory);
+  m_pRelDyn->reserveEntry();
   Relocation* rel_entry = m_pRelDyn->consumeEntry();
   rel_entry->setType(llvm::ELF::R_386_TLS_DTPMOD32);
   rel_entry->targetRef().assign(*got_entry, 0x0);
@@ -776,11 +775,6 @@
   return SHO_UNDEFINED;
 }
 
-unsigned int X86GNULDBackend::bitclass() const
-{
-  return 32;
-}
-
 void X86GNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder)
 {
   if (LinkerConfig::Object != config().codeGenType()) {
@@ -802,14 +796,12 @@
     // initialize .rel.plt
     LDSection& relplt = file_format->getRelPlt();
     relplt.setLink(&plt);
-    m_pRelPLT = new OutputRelocSection(pModule,
-                                       relplt,
-                                       getRelEntrySize());
+    m_pRelPLT = new OutputRelocSection(pModule, relplt);
+
     // initialize .rel.dyn
     LDSection& reldyn = file_format->getRelDyn();
-    m_pRelDyn = new OutputRelocSection(pModule,
-                                       reldyn,
-                                       getRelEntrySize());
+    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
+
   }
 }
 
@@ -854,7 +846,7 @@
 TargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
                                     const LinkerConfig& pConfig)
 {
-  if (pConfig.triple().isOSDarwin()) {
+  if (pConfig.targets().triple().isOSDarwin()) {
     assert(0 && "MachO linker is not supported yet");
     /**
     return new X86MachOLDBackend(createX86MachOArchiveReader,
@@ -862,7 +854,7 @@
                                createX86MachOObjectWriter);
     **/
   }
-  if (pConfig.triple().isOSWindows()) {
+  if (pConfig.targets().triple().isOSWindows()) {
     assert(0 && "COFF linker is not supported yet");
     /**
     return new X86COFFLDBackend(createX86COFFArchiveReader,
@@ -870,7 +862,7 @@
                                createX86COFFObjectWriter);
     **/
   }
-  return new X86GNULDBackend(pConfig);
+  return new X86GNULDBackend(pConfig, new X86GNUInfo(pConfig.targets().triple()));
 }
 
 } // namespace of mcld
diff --git a/lib/Target/X86/X86LDBackend.h b/lib/Target/X86/X86LDBackend.h
index fb3aa6b..3f8a626 100644
--- a/lib/Target/X86/X86LDBackend.h
+++ b/lib/Target/X86/X86LDBackend.h
@@ -20,6 +20,7 @@
 namespace mcld {
 
 class LinkerConfig;
+class X86GNUInfo;
 
 //===----------------------------------------------------------------------===//
 /// X86GNULDBackend - linker backend of X86 target of GNU ELF format
@@ -71,17 +72,12 @@
   };
 
 public:
-  X86GNULDBackend(const LinkerConfig& pConfig);
+  X86GNULDBackend(const LinkerConfig& pConfig, X86GNUInfo* pInfo);
 
   ~X86GNULDBackend();
 
-  RelocationFactory* getRelocFactory();
-
   uint32_t machine() const;
 
-  bool isLittleEndian() const
-  { return true; }
-
   X86GOT& getGOT();
 
   const X86GOT& getGOT() const;
@@ -94,9 +90,7 @@
 
   const X86PLT& getPLT() const;
 
-  GOT::Entry& getTLSModuleID();
-
-  unsigned int bitclass() const;
+  X86GOTEntry& getTLSModuleID();
 
   /// preLayout - Backend can do any needed modification before layout
   void doPreLayout(FragmentLinker& pLinker);
@@ -130,16 +124,6 @@
   uint64_t emitSectionData(const LDSection& pSection,
                            MemoryRegion& pRegion) const;
 
-  /// OSABI - the value of e_ident[EI_OSABI]
-  /// FIXME
-  uint8_t OSABI() const
-  { return llvm::ELF::ELFOSABI_NONE; }
-
-  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
-  /// FIXME
-  uint8_t ABIVersion() const
-  { return 0x0; }
-
   /// flags - the value of ElfXX_Ehdr::e_flags
   /// FIXME
   uint64_t flags() const
@@ -148,8 +132,11 @@
   uint64_t defaultTextSegmentAddr() const
   { return 0x08048000; }
 
-  // initRelocFactory - create and initialize RelocationFactory
-  bool initRelocFactory(const FragmentLinker& pLinker);
+  /// initRelocator - create and initialize Relocator.
+  bool initRelocator(const FragmentLinker& pLinker);
+
+  /// getRelocator - return relocator.
+  Relocator* getRelocator();
 
   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
 
@@ -217,7 +204,7 @@
                                    const FragmentLinker& pLinker);
 
 private:
-  RelocationFactory* m_pRelocFactory;
+  Relocator* m_pRelocator;
   X86GOT* m_pGOT;
   X86PLT* m_pPLT;
   X86GOTPLT* m_pGOTPLT;
diff --git a/lib/Target/X86/X86PLT.cpp b/lib/Target/X86/X86PLT.cpp
index 5b5ac58..25eaab9 100644
--- a/lib/Target/X86/X86PLT.cpp
+++ b/lib/Target/X86/X86PLT.cpp
@@ -16,44 +16,30 @@
 #include <mcld/LinkerConfig.h>
 #include <mcld/Support/MsgHandling.h>
 
+using namespace mcld;
+
 //===----------------------------------------------------------------------===//
 // PLT entry data
 //===----------------------------------------------------------------------===//
-namespace {
-
-const uint8_t x86_dyn_plt0[] = {
-  0xff, 0xb3, 0x04, 0, 0, 0, // pushl  0x4(%ebx)
-  0xff, 0xa3, 0x08, 0, 0, 0, // jmp    *0x8(%ebx)
-  0x0f, 0x1f, 0x4,  0        // nopl   0(%eax)
-};
-
-const uint8_t x86_dyn_plt1[] = {
-  0xff, 0xa3, 0, 0, 0, 0,    // jmp    *sym@GOT(%ebx)
-  0x68, 0, 0, 0, 0,          // pushl  $offset
-  0xe9, 0, 0, 0, 0           // jmp    plt0
-};
-
-const uint8_t x86_exec_plt0[] = {
-  0xff, 0x35, 0, 0, 0, 0,    // pushl  .got + 4
-  0xff, 0x25, 0, 0, 0, 0,    // jmp    *(.got + 8)
-  0x0f, 0x1f, 0x4, 0         // nopl   0(%eax)
-};
-
-const uint8_t x86_exec_plt1[] = {
-  0xff, 0x25, 0, 0, 0, 0,    // jmp    *(sym in .got)
-  0x68, 0, 0, 0, 0,          // pushl  $offset
-  0xe9, 0, 0, 0, 0           // jmp    plt0
-};
-
+X86DynPLT0::X86DynPLT0(SectionData& pParent)
+  : PLT::Entry<sizeof(x86_dyn_plt0)>(pParent)
+{
 }
 
-namespace mcld {
+X86DynPLT1::X86DynPLT1(SectionData& pParent)
+  : PLT::Entry<sizeof(x86_dyn_plt1)>(pParent)
+{
+}
 
-X86PLT0::X86PLT0(SectionData& pParent, unsigned int pSize)
-  : PLT::Entry(pSize, pParent) { }
+X86ExecPLT0::X86ExecPLT0(SectionData& pParent)
+  : PLT::Entry<sizeof(x86_exec_plt0)>(pParent)
+{
+}
 
-X86PLT1::X86PLT1(SectionData& pParent, unsigned int pSize)
-  : PLT::Entry(pSize, pParent) { }
+X86ExecPLT1::X86ExecPLT1(SectionData& pParent)
+  : PLT::Entry<sizeof(x86_exec_plt1)>(pParent)
+{
+}
 
 //===----------------------------------------------------------------------===//
 // X86PLT
@@ -66,22 +52,25 @@
     m_Config(pConfig)
 {
   assert(LinkerConfig::DynObj == m_Config.codeGenType() ||
-         LinkerConfig::Exec == m_Config.codeGenType());
+         LinkerConfig::Exec   == m_Config.codeGenType() ||
+         LinkerConfig::Binary == m_Config.codeGenType());
 
   if (LinkerConfig::DynObj == m_Config.codeGenType()) {
-      m_PLT0 = x86_dyn_plt0;
-      m_PLT1 = x86_dyn_plt1;
-      m_PLT0Size = sizeof (x86_dyn_plt0);
-      m_PLT1Size = sizeof (x86_dyn_plt1);
+    m_PLT0 = x86_dyn_plt0;
+    m_PLT1 = x86_dyn_plt1;
+    m_PLT0Size = sizeof (x86_dyn_plt0);
+    m_PLT1Size = sizeof (x86_dyn_plt1);
+    // create PLT0
+    new X86DynPLT0(*m_SectionData);
   }
   else {
-      m_PLT0 = x86_exec_plt0;
-      m_PLT1 = x86_exec_plt1;
-      m_PLT0Size = sizeof (x86_exec_plt0);
-      m_PLT1Size = sizeof (x86_exec_plt1);
+    m_PLT0 = x86_exec_plt0;
+    m_PLT1 = x86_exec_plt1;
+    m_PLT0Size = sizeof (x86_exec_plt0);
+    m_PLT1Size = sizeof (x86_exec_plt1);
+    // create PLT0
+    new X86ExecPLT0(*m_SectionData);
   }
-  new X86PLT0(*m_SectionData, m_PLT0Size);
-
   m_Last = m_SectionData->begin();
 }
 
@@ -93,15 +82,15 @@
 {
   uint64_t size = 0;
   // plt0 size
-  size = getPLT0()->getEntrySize();
+  size = getPLT0()->size();
 
   // get first plt1 entry
   X86PLT::iterator it = begin();
   ++it;
   if (end() != it) {
     // plt1 size
-    X86PLT1* plt1 = &(llvm::cast<X86PLT1>(*it));
-    size += (m_SectionData->size() - 1) * plt1->getEntrySize();
+    PLTEntryBase* plt1 = &(llvm::cast<PLTEntryBase>(*it));
+    size += (m_SectionData->size() - 1) * plt1->size();
   }
   m_Section.setSize(size);
 
@@ -120,34 +109,37 @@
 
 void X86PLT::reserveEntry(size_t pNum)
 {
-  X86PLT1* plt1_entry = 0;
+  PLTEntryBase* plt1_entry = NULL;
 
   for (size_t i = 0; i < pNum; ++i) {
-    plt1_entry = new (std::nothrow) X86PLT1(*m_SectionData, m_PLT1Size);
 
-    if (!plt1_entry)
+    if (LinkerConfig::DynObj == m_Config.codeGenType())
+      plt1_entry = new X86DynPLT1(*m_SectionData);
+    else
+      plt1_entry = new X86ExecPLT1(*m_SectionData);
+
+    if (NULL == plt1_entry)
       fatal(diag::fail_allocate_memory_plt);
   }
 }
 
-PLT::Entry* X86PLT::consume()
+PLTEntryBase* X86PLT::consume()
 {
   // This will skip PLT0.
   ++m_Last;
   assert(m_Last != m_SectionData->end() &&
          "The number of PLT Entries and ResolveInfo doesn't match");
-  return llvm::cast<X86PLT1>(&(*m_Last));
+  return llvm::cast<PLTEntryBase>(&(*m_Last));
 }
 
-X86PLT0* X86PLT::getPLT0() const
+PLTEntryBase* X86PLT::getPLT0() const
 {
-
   iterator first = m_SectionData->getFragmentList().begin();
 
   assert(first != m_SectionData->getFragmentList().end() &&
          "FragmentList is empty, getPLT0 failed!");
 
-  X86PLT0* plt0 = &(llvm::cast<X86PLT0>(*first));
+  PLTEntryBase* plt0 = &(llvm::cast<PLTEntryBase>(*first));
 
   return plt0;
 }
@@ -155,15 +147,15 @@
 // FIXME: It only works on little endian machine.
 void X86PLT::applyPLT0()
 {
-  X86PLT0* plt0 = getPLT0();
+  PLTEntryBase* plt0 = getPLT0();
 
   unsigned char* data = 0;
-  data = static_cast<unsigned char*>(malloc(plt0->getEntrySize()));
+  data = static_cast<unsigned char*>(malloc(plt0->size()));
 
   if (!data)
     fatal(diag::fail_allocate_memory_plt);
 
-  memcpy(data, m_PLT0, plt0->getEntrySize());
+  memcpy(data, m_PLT0, plt0->size());
 
   if (m_PLT0 == x86_exec_plt0) {
     uint32_t *offset = reinterpret_cast<uint32_t*>(data + 2);
@@ -172,7 +164,7 @@
     *offset = m_GOTPLT.addr() + 8;
   }
 
-  plt0->setContent(data);
+  plt0->setValue(data);
 }
 
 // FIXME: It only works on little endian machine.
@@ -184,7 +176,7 @@
   X86PLT::iterator ie = m_SectionData->end();
   assert(it != ie && "FragmentList is empty, applyPLT1 failed!");
 
-  uint64_t GOTEntrySize = m_GOTPLT.getEntrySize();
+  uint64_t GOTEntrySize = X86GOTPLTEntry::EntrySize;
 
   // Skip GOT0
   uint64_t GOTEntryOffset = GOTEntrySize * X86GOTPLT0Num;
@@ -195,19 +187,19 @@
   uint64_t PLTEntryOffset = m_PLT0Size;
   ++it;
 
-  X86PLT1* plt1 = 0;
+  PLTEntryBase* plt1 = 0;
 
   uint64_t PLTRelOffset = 0;
 
   while (it != ie) {
-    plt1 = &(llvm::cast<X86PLT1>(*it));
+    plt1 = &(llvm::cast<PLTEntryBase>(*it));
     unsigned char *data;
-    data = static_cast<unsigned char*>(malloc(plt1->getEntrySize()));
+    data = static_cast<unsigned char*>(malloc(plt1->size()));
 
     if (!data)
       fatal(diag::fail_allocate_memory_plt);
 
-    memcpy(data, m_PLT1, plt1->getEntrySize());
+    memcpy(data, m_PLT1, plt1->size());
 
     uint32_t* offset;
 
@@ -223,10 +215,8 @@
     *offset = -(PLTEntryOffset + 12 + 4);
     PLTEntryOffset += m_PLT1Size;
 
-    plt1->setContent(data);
+    plt1->setValue(data);
     ++it;
   }
 }
 
-} // end namespace mcld
-
diff --git a/lib/Target/X86/X86PLT.h b/lib/Target/X86/X86PLT.h
index 5e8b45f..75a72e6 100644
--- a/lib/Target/X86/X86PLT.h
+++ b/lib/Target/X86/X86PLT.h
@@ -11,24 +11,70 @@
 
 #include <mcld/Target/PLT.h>
 
+namespace {
+
+const uint8_t x86_dyn_plt0[] = {
+  0xff, 0xb3, 0x04, 0, 0, 0, // pushl  0x4(%ebx)
+  0xff, 0xa3, 0x08, 0, 0, 0, // jmp    *0x8(%ebx)
+  0x0f, 0x1f, 0x4,  0        // nopl   0(%eax)
+};
+
+const uint8_t x86_dyn_plt1[] = {
+  0xff, 0xa3, 0, 0, 0, 0,    // jmp    *sym@GOT(%ebx)
+  0x68, 0, 0, 0, 0,          // pushl  $offset
+  0xe9, 0, 0, 0, 0           // jmp    plt0
+};
+
+const uint8_t x86_exec_plt0[] = {
+  0xff, 0x35, 0, 0, 0, 0,    // pushl  .got + 4
+  0xff, 0x25, 0, 0, 0, 0,    // jmp    *(.got + 8)
+  0x0f, 0x1f, 0x4, 0         // nopl   0(%eax)
+};
+
+const uint8_t x86_exec_plt1[] = {
+  0xff, 0x25, 0, 0, 0, 0,    // jmp    *(sym in .got)
+  0x68, 0, 0, 0, 0,          // pushl  $offset
+  0xe9, 0, 0, 0, 0           // jmp    plt0
+};
+
+} // anonymous namespace
+
 namespace mcld {
 
 class X86GOTPLT;
 class GOTEntry;
 class LinkerConfig;
 
-class X86PLT0 : public PLT::Entry
+//===----------------------------------------------------------------------===//
+// X86PLT Entry
+//===----------------------------------------------------------------------===//
+class X86DynPLT0 : public PLT::Entry<sizeof(x86_dyn_plt0)>
 {
 public:
-  X86PLT0(SectionData& pParent, unsigned int pSize);
+  X86DynPLT0(SectionData& pParent);
 };
 
-class X86PLT1 : public PLT::Entry
+class X86DynPLT1 : public PLT::Entry<sizeof(x86_dyn_plt1)>
 {
 public:
-  X86PLT1(SectionData& pParent, unsigned int pSize);
+  X86DynPLT1(SectionData& pParent);
 };
 
+class X86ExecPLT0 : public PLT::Entry<sizeof(x86_exec_plt0)>
+{
+public:
+  X86ExecPLT0(SectionData& pParent);
+};
+
+class X86ExecPLT1 : public PLT::Entry<sizeof(x86_exec_plt1)>
+{
+public:
+  X86ExecPLT1(SectionData& pParent);
+};
+
+//===----------------------------------------------------------------------===//
+// X86PLT
+//===----------------------------------------------------------------------===//
 /** \class X86PLT
  *  \brief X86 Procedure Linkage Table
  */
@@ -48,7 +94,7 @@
 
   void reserveEntry(size_t pNum = 1) ;
 
-  PLT::Entry* consume();
+  PLTEntryBase* consume();
 
   void applyPLT0();
 
@@ -58,7 +104,7 @@
   unsigned int getPLT1Size() const { return m_PLT1Size; }
 
 private:
-  X86PLT0* getPLT0() const;
+  PLTEntryBase* getPLT0() const;
 
 private:
   X86GOTPLT& m_GOTPLT;
@@ -77,3 +123,4 @@
 } // namespace of mcld
 
 #endif
+
diff --git a/lib/Target/X86/X86RelocationFunctions.h b/lib/Target/X86/X86RelocationFunctions.h
index 9b82739..df2e70c 100644
--- a/lib/Target/X86/X86RelocationFunctions.h
+++ b/lib/Target/X86/X86RelocationFunctions.h
@@ -8,8 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #define DECL_X86_APPLY_RELOC_FUNC(Name) \
-static X86RelocationFactory::Result Name    (Relocation& pEntry, \
-					     X86RelocationFactory& pParent);
+static X86Relocator::Result Name    (Relocation& pEntry, \
+					                          X86Relocator& pParent);
 
 #define DECL_X86_APPLY_RELOC_FUNCS \
 DECL_X86_APPLY_RELOC_FUNC(none)             \
diff --git a/lib/Target/X86/X86RelocationFactory.cpp b/lib/Target/X86/X86Relocator.cpp
similarity index 67%
rename from lib/Target/X86/X86RelocationFactory.cpp
rename to lib/Target/X86/X86Relocator.cpp
index d7cfe09..3b4d389 100644
--- a/lib/Target/X86/X86RelocationFactory.cpp
+++ b/lib/Target/X86/X86Relocator.cpp
@@ -1,4 +1,4 @@
-//===- X86RelocationFactory.cpp -------------------------------------------===//
+//===- X86Relocator.cpp -------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -11,10 +11,9 @@
 #include <llvm/Support/DataTypes.h>
 #include <llvm/Support/ELF.h>
 #include <mcld/Fragment/FragmentLinker.h>
-#include <mcld/LinkerConfig.h>
 #include <mcld/Support/MsgHandling.h>
 
-#include "X86RelocationFactory.h"
+#include "X86Relocator.h"
 #include "X86RelocationFunctions.h"
 
 using namespace mcld;
@@ -25,9 +24,8 @@
 DECL_X86_APPLY_RELOC_FUNCS
 
 /// the prototype of applying function
-typedef RelocationFactory::Result
-                          (*ApplyFunctionType)(Relocation& pReloc,
-                                               X86RelocationFactory& pParent);
+typedef Relocator::Result (*ApplyFunctionType)(Relocation& pReloc,
+                                               X86Relocator& pParent);
 
 // the table entry of applying functions
 struct ApplyFunctionTriple
@@ -43,20 +41,19 @@
 };
 
 //===--------------------------------------------------------------------===//
-// X86RelocationFactory
+// X86Relocator
 //===--------------------------------------------------------------------===//
-X86RelocationFactory::X86RelocationFactory(size_t pNum,
-                                           X86GNULDBackend& pParent)
-  : RelocationFactory(pNum),
+X86Relocator::X86Relocator(X86GNULDBackend& pParent)
+  : Relocator(),
     m_Target(pParent) {
 }
 
-X86RelocationFactory::~X86RelocationFactory()
+X86Relocator::~X86Relocator()
 {
 }
 
-RelocationFactory::Result
-X86RelocationFactory::applyRelocation(Relocation& pRelocation)
+Relocator::Result
+X86Relocator::applyRelocation(Relocation& pRelocation)
 {
   Relocation::Type type = pRelocation.type();
 
@@ -68,7 +65,7 @@
   return ApplyFunctions[type].func(pRelocation, *this);
 }
 
-const char* X86RelocationFactory::getName(Relocation::Type pType) const
+const char* X86Relocator::getName(Relocation::Type pType) const
 {
   return ApplyFunctions[pType].name;
 }
@@ -82,8 +79,8 @@
 Relocation& helper_DynRel(ResolveInfo* pSym,
                           Fragment& pFrag,
                           uint64_t pOffset,
-                          X86RelocationFactory::Type pType,
-                          X86RelocationFactory& pParent)
+                          X86Relocator::Type pType,
+                          X86Relocator& pParent)
 {
   X86GNULDBackend& ld_backend = pParent.getTarget();
   Relocation& rel_entry = *ld_backend.getRelDyn().consumeEntry();
@@ -102,7 +99,7 @@
 /// R_386_RELATIVE
 static bool
 helper_use_relative_reloc(const ResolveInfo& pSym,
-                          const X86RelocationFactory& pFactory)
+                          const X86Relocator& pFactory)
 
 {
   // if symbol is dynamic or undefine or preemptible
@@ -114,14 +111,14 @@
 }
 
 static
-GOT::Entry& helper_get_GOT_and_init(Relocation& pReloc,
-                                    X86RelocationFactory& pParent)
+X86GOTEntry& helper_get_GOT_and_init(Relocation& pReloc,
+                                     X86Relocator& pParent)
 {
   // rsym - The relocation target symbol
   ResolveInfo* rsym = pReloc.symInfo();
   X86GNULDBackend& ld_backend = pParent.getTarget();
 
-  GOT::Entry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
+  X86GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
   if (NULL != got_entry)
     return *got_entry;
 
@@ -132,17 +129,17 @@
   // If we first get this GOT entry, we should initialize it.
   if (rsym->reserved() & X86GNULDBackend::ReserveGOT) {
     // No corresponding dynamic relocation, initialize to the symbol value.
-    got_entry->setContent(pReloc.symValue());
+    got_entry->setValue(pReloc.symValue());
   }
   else if (rsym->reserved() & X86GNULDBackend::GOTRel) {
     // Initialize got_entry content and the corresponding dynamic relocation.
     if (helper_use_relative_reloc(*rsym, pParent)) {
       helper_DynRel(rsym, *got_entry, 0x0, llvm::ELF::R_386_RELATIVE, pParent);
-      got_entry->setContent(pReloc.symValue());
+      got_entry->setValue(pReloc.symValue());
     }
     else {
       helper_DynRel(rsym, *got_entry, 0x0, llvm::ELF::R_386_GLOB_DAT, pParent);
-      got_entry->setContent(0);
+      got_entry->setValue(0);
     }
   }
   else {
@@ -153,31 +150,29 @@
 
 
 static
-X86RelocationFactory::Address helper_GOT_ORG(X86RelocationFactory& pParent)
+X86Relocator::Address helper_GOT_ORG(X86Relocator& pParent)
 {
   return pParent.getTarget().getGOTPLT().addr();
 }
 
 
 static
-X86RelocationFactory::Address helper_GOT(Relocation& pReloc,
-                                         X86RelocationFactory& pParent)
+X86Relocator::Address helper_GOT(Relocation& pReloc, X86Relocator& pParent)
 {
-  GOT::Entry& got_entry = helper_get_GOT_and_init(pReloc, pParent);
-  X86RelocationFactory::Address got_addr = pParent.getTarget().getGOT().addr();
+  X86GOTEntry& got_entry = helper_get_GOT_and_init(pReloc, pParent);
+  X86Relocator::Address got_addr = pParent.getTarget().getGOT().addr();
   return got_addr + got_entry.getOffset();
 }
 
 
 static
-PLT::Entry& helper_get_PLT_and_init(Relocation& pReloc,
-                                    X86RelocationFactory& pParent)
+PLTEntryBase& helper_get_PLT_and_init(Relocation& pReloc, X86Relocator& pParent)
 {
   // rsym - The relocation target symbol
   ResolveInfo* rsym = pReloc.symInfo();
   X86GNULDBackend& ld_backend = pParent.getTarget();
 
-  PLT::Entry* plt_entry = pParent.getSymPLTMap().lookUp(*rsym);
+  PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(*rsym);
   if (NULL != plt_entry)
     return *plt_entry;
 
@@ -186,7 +181,7 @@
   pParent.getSymPLTMap().record(*rsym, *plt_entry);
   // If we first get this PLT entry, we should initialize it.
   if (rsym->reserved() & X86GNULDBackend::ReservePLT) {
-    GOT::Entry* gotplt_entry = pParent.getSymGOTPLTMap().lookUp(*rsym);
+    X86GOTPLTEntry* gotplt_entry = pParent.getSymGOTPLTMap().lookUp(*rsym);
     assert(NULL == gotplt_entry && "PLT entry not exist, but DynRel entry exist!");
     gotplt_entry = ld_backend.getGOTPLT().consume();
     pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry);
@@ -205,17 +200,16 @@
 
 
 static
-X86RelocationFactory::Address helper_PLT_ORG(X86RelocationFactory& pParent)
+X86Relocator::Address helper_PLT_ORG(X86Relocator& pParent)
 {
   return pParent.getTarget().getPLT().addr();
 }
 
 
 static
-X86RelocationFactory::Address helper_PLT(Relocation& pReloc,
-                                         X86RelocationFactory& pParent)
+X86Relocator::Address helper_PLT(Relocation& pReloc, X86Relocator& pParent)
 {
-  PLT::Entry& plt_entry = helper_get_PLT_and_init(pReloc, pParent);
+  PLTEntryBase& plt_entry = helper_get_PLT_and_init(pReloc, pParent);
   return helper_PLT_ORG(pParent) + plt_entry.getOffset();
 }
 
@@ -225,21 +219,19 @@
 //=========================================//
 
 // R_386_NONE
-X86RelocationFactory::Result none(Relocation& pReloc,
-                                  X86RelocationFactory& pParent)
+X86Relocator::Result none(Relocation& pReloc, X86Relocator& pParent)
 {
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_32: S + A
 // R_386_16
 // R_386_8
-X86RelocationFactory::Result abs(Relocation& pReloc,
-                                 X86RelocationFactory& pParent)
+X86Relocator::Result abs(Relocation& pReloc, X86Relocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
-  RelocationFactory::DWord S = pReloc.symValue();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
+  Relocator::DWord S = pReloc.symValue();
   bool has_dyn_rel = pParent.getTarget().symbolNeedsDynRel(
                               pParent.getFragmentLinker(),
                               *rsym,
@@ -251,7 +243,7 @@
   // but perform static relocation. (e.g., applying .debug section)
   if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
     pReloc.target() = S + A;
-    return X86RelocationFactory::OK;
+    return X86Relocator::OK;
   }
 
   // A local symbol may need REL Type dynamic relocation
@@ -267,7 +259,7 @@
                     pReloc.targetRef().offset(), pReloc.type(), pParent);
     }
     pReloc.target() = S + A;
-    return X86RelocationFactory::OK;
+    return X86Relocator::OK;
   }
 
   // An external symbol may need PLT and dynamic relocation
@@ -287,33 +279,32 @@
       else {
         helper_DynRel(rsym, *pReloc.targetRef().frag(),
                           pReloc.targetRef().offset(), pReloc.type(), pParent);
-        return X86RelocationFactory::OK;
+        return X86Relocator::OK;
       }
     }
   }
 
   // perform static relocation
   pReloc.target() = S + A;
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_PC32: S + A - P
 // R_386_PC16
 // R_386_PC8
-X86RelocationFactory::Result rel(Relocation& pReloc,
-                                 X86RelocationFactory& pParent)
+X86Relocator::Result rel(Relocation& pReloc, X86Relocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
-  RelocationFactory::DWord S = pReloc.symValue();
-  RelocationFactory::DWord P = pReloc.place();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
+  Relocator::DWord S = pReloc.symValue();
+  Relocator::DWord P = pReloc.place();
 
   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   // If the flag of target section is not ALLOC, we will not scan this relocation
   // but perform static relocation. (e.g., applying .debug section)
   if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
     pReloc.target() = S + A - P;
-    return X86RelocationFactory::OK;
+    return X86Relocator::OK;
   }
 
   // An external symbol may need PLT and dynamic relocation
@@ -334,80 +325,75 @@
       else {
         helper_DynRel(rsym, *pReloc.targetRef().frag(),
                           pReloc.targetRef().offset(), pReloc.type(), pParent);
-          return X86RelocationFactory::OK;
+          return X86Relocator::OK;
       }
     }
   }
 
    // perform static relocation
   pReloc.target() = S + A - P;
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_GOTOFF: S + A - GOT_ORG
-X86RelocationFactory::Result gotoff32(Relocation& pReloc,
-                                      X86RelocationFactory& pParent)
+X86Relocator::Result gotoff32(Relocation& pReloc, X86Relocator& pParent)
 {
-  RelocationFactory::DWord      A = pReloc.target() + pReloc.addend();
-  X86RelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
-  X86RelocationFactory::Address S = pReloc.symValue();
+  Relocator::DWord      A = pReloc.target() + pReloc.addend();
+  X86Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
+  X86Relocator::Address S = pReloc.symValue();
 
   pReloc.target() = S + A - GOT_ORG;
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_GOTPC: GOT_ORG + A - P
-X86RelocationFactory::Result gotpc32(Relocation& pReloc,
-                                     X86RelocationFactory& pParent)
+X86Relocator::Result gotpc32(Relocation& pReloc, X86Relocator& pParent)
 {
-  RelocationFactory::DWord      A       = pReloc.target() + pReloc.addend();
-  X86RelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
+  Relocator::DWord      A       = pReloc.target() + pReloc.addend();
+  X86Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
   // Apply relocation.
   pReloc.target() = GOT_ORG + A - pReloc.place();
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_GOT32: GOT(S) + A - GOT_ORG
-X86RelocationFactory::Result got32(Relocation& pReloc,
-                                   X86RelocationFactory& pParent)
+X86Relocator::Result got32(Relocation& pReloc, X86Relocator& pParent)
 {
   if (!(pReloc.symInfo()->reserved()
        & (X86GNULDBackend::ReserveGOT |X86GNULDBackend::GOTRel))) {
-    return X86RelocationFactory::BadReloc;
+    return X86Relocator::BadReloc;
   }
-  X86RelocationFactory::Address GOT_S   = helper_GOT(pReloc, pParent);
-  RelocationFactory::DWord      A       = pReloc.target() + pReloc.addend();
-  X86RelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
+  X86Relocator::Address GOT_S   = helper_GOT(pReloc, pParent);
+  Relocator::DWord      A       = pReloc.target() + pReloc.addend();
+  X86Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
   // Apply relocation.
   pReloc.target() = GOT_S + A - GOT_ORG;
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_PLT32: PLT(S) + A - P
-X86RelocationFactory::Result plt32(Relocation& pReloc,
-                                   X86RelocationFactory& pParent)
+X86Relocator::Result plt32(Relocation& pReloc, X86Relocator& pParent)
 {
   // PLT_S depends on if there is a PLT entry.
-  X86RelocationFactory::Address PLT_S;
+  X86Relocator::Address PLT_S;
   if ((pReloc.symInfo()->reserved() & X86GNULDBackend::ReservePLT))
     PLT_S = helper_PLT(pReloc, pParent);
   else
     PLT_S = pReloc.symValue();
-  RelocationFactory::DWord      A = pReloc.target() + pReloc.addend();
-  X86RelocationFactory::Address P = pReloc.place();
+  Relocator::DWord      A = pReloc.target() + pReloc.addend();
+  X86Relocator::Address P = pReloc.place();
   pReloc.target() = PLT_S + A - P;
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_TLS_GD:
-X86RelocationFactory::Result tls_gd(Relocation& pReloc,
-                                    X86RelocationFactory& pParent)
+X86Relocator::Result tls_gd(Relocation& pReloc, X86Relocator& pParent)
 {
   // global-dynamic
   ResolveInfo* rsym = pReloc.symInfo();
   // must reserve two pairs of got and dynamic relocation
   if (!(rsym->reserved() & X86GNULDBackend::GOTRel)) {
-     return X86RelocationFactory::BadReloc;
+     return X86Relocator::BadReloc;
   }
 
   X86GNULDBackend& ld_backend = pParent.getTarget();
@@ -416,21 +402,21 @@
   // get first got entry, if there is already a got entry for rsym, then apply
   // this relocation to the got entry directly. If not, setup the corresponding
   // got and dyn relocation entries
-  GOT::Entry* got_entry1 = pParent.getSymGOTMap().lookUp(*rsym);
+  X86GOTEntry* got_entry1 = pParent.getSymGOTMap().lookUp(*rsym);
 
   if (NULL == got_entry1) {
     // get and init two got entries if not exist
     got_entry1 = ld_backend.getGOT().consume();
     pParent.getSymGOTMap().record(*rsym, *got_entry1);
-    GOT::Entry* got_entry2 = ld_backend.getGOT().consume();
-    got_entry1->setContent(0x0);
-    got_entry2->setContent(0x0);
+    X86GOTEntry* got_entry2 = ld_backend.getGOT().consume();
+    got_entry1->setValue(0x0);
+    got_entry2->setValue(0x0);
     // setup dyn rel for get_entry1
     Relocation& rel_entry1 = helper_DynRel(rsym, *got_entry1, 0x0,
                                         llvm::ELF::R_386_TLS_DTPMOD32, pParent);
     if (rsym->isLocal()) {
       // for local symbol, set got_entry2 to symbol value
-      got_entry2->setContent(pReloc.symValue());
+      got_entry2->setValue(pReloc.symValue());
 
       // for local tls symbol, add rel entry against the section symbol this
       // symbol belong to (.tdata or .tbss)
@@ -452,52 +438,49 @@
   }
 
   // perform relocation to the first got entry
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
   // GOT_OFF - the offset between the got_entry1 and _GLOBAL_OFFSET_TABLE (the
   // .got.plt section)
-  X86RelocationFactory::Address GOT_OFF =
+  X86Relocator::Address GOT_OFF =
      file_format->getGOT().addr() +
      got_entry1->getOffset() -
      file_format->getGOTPLT().addr();
   pReloc.target() = GOT_OFF + A;
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_TLS_LDM
-X86RelocationFactory::Result tls_ldm(Relocation& pReloc,
-                                     X86RelocationFactory& pParent)
+X86Relocator::Result tls_ldm(Relocation& pReloc, X86Relocator& pParent)
 {
   // FIXME: no linker optimization for TLS relocation
-  const GOT::Entry& got_entry = pParent.getTarget().getTLSModuleID();
+  const X86GOTEntry& got_entry = pParent.getTarget().getTLSModuleID();
 
   // All GOT offsets are relative to the end of the GOT.
-  X86RelocationFactory::SWord GOT_S = got_entry.getOffset() -
+  X86Relocator::SWord GOT_S = got_entry.getOffset() -
                                       (pParent.getTarget().getGOTPLT().addr() -
                                        pParent.getTarget().getGOT().addr());
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
   pReloc.target() = GOT_S + A;
 
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_TLS_LDO_32
-X86RelocationFactory::Result tls_ldo_32(Relocation& pReloc,
-                                        X86RelocationFactory& pParent)
+X86Relocator::Result tls_ldo_32(Relocation& pReloc, X86Relocator& pParent)
 {
   // FIXME: no linker optimization for TLS relocation
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
-  X86RelocationFactory::Address S = pReloc.symValue();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
+  X86Relocator::Address S = pReloc.symValue();
   pReloc.target() = S + A;
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_X86_TLS_IE
-X86RelocationFactory::Result tls_ie(Relocation& pReloc,
-                                    X86RelocationFactory& pParent)
+X86Relocator::Result tls_ie(Relocation& pReloc, X86Relocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
   if (!(rsym->reserved() & X86GNULDBackend::GOTRel)) {
-     return X86RelocationFactory::BadReloc;
+     return X86Relocator::BadReloc;
   }
 
   if (rsym->reserved() & X86GNULDBackend::ReserveRel) {
@@ -507,13 +490,13 @@
   }
 
   // set up the got and dynamic relocation entries if not exist
-  GOT::Entry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
+  X86GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
   if (NULL == got_entry) {
     // set got entry
     X86GNULDBackend& ld_backend = pParent.getTarget();
     got_entry = ld_backend.getGOT().consume();
     pParent.getSymGOTMap().record(*rsym, *got_entry);
-    got_entry->setContent(0x0);
+    got_entry->setValue(0x0);
     // set relocation entry
     Relocation& rel_entry = *ld_backend.getRelDyn().consumeEntry();
     rel_entry.setType(llvm::ELF::R_386_TLS_TPOFF);
@@ -522,32 +505,31 @@
   }
 
   // perform relocation to the absolute address of got_entry
-  X86RelocationFactory::Address GOT_S =
+  X86Relocator::Address GOT_S =
                  pParent.getTarget().getGOT().addr() + got_entry->getOffset();
 
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
   pReloc.target() = GOT_S + A;
 
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_386_TLS_GOTIE
-X86RelocationFactory::Result tls_gotie(Relocation& pReloc,
-                                       X86RelocationFactory& pParent)
+X86Relocator::Result tls_gotie(Relocation& pReloc, X86Relocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
   if (!(rsym->reserved() & X86GNULDBackend::GOTRel)) {
-     return X86RelocationFactory::BadReloc;
+     return X86Relocator::BadReloc;
   }
 
   // set up the got and dynamic relocation entries if not exist
-  GOT::Entry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
+  X86GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
   if (NULL == got_entry) {
     // set got entry
     X86GNULDBackend& ld_backend = pParent.getTarget();
     got_entry = ld_backend.getGOT().consume();
     pParent.getSymGOTMap().record(*rsym, *got_entry);
-    got_entry->setContent(0x0);
+    got_entry->setValue(0x0);
     // set relocation entry
     Relocation& rel_entry = *ld_backend.getRelDyn().consumeEntry();
     rel_entry.setType(llvm::ELF::R_386_TLS_TPOFF);
@@ -556,17 +538,16 @@
   }
 
   // All GOT offsets are relative to the end of the GOT.
-  X86RelocationFactory::SWord GOT_S = got_entry->getOffset() -
+  X86Relocator::SWord GOT_S = got_entry->getOffset() -
     (pParent.getTarget().getGOTPLT().addr() - pParent.getTarget().getGOT().addr());
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
   pReloc.target() = GOT_S + A;
 
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
 // R_X86_TLS_LE
-X86RelocationFactory::Result tls_le(Relocation& pReloc,
-                                    X86RelocationFactory& pParent)
+X86Relocator::Result tls_le(Relocation& pReloc, X86Relocator& pParent)
 {
   ResolveInfo* rsym = pReloc.symInfo();
   if (pReloc.symInfo()->reserved() & X86GNULDBackend::ReserveRel) {
@@ -575,22 +556,21 @@
                   pReloc.targetRef().offset(),
                   llvm::ELF::R_386_TLS_TPOFF,
                   pParent);
-    return X86RelocationFactory::OK;
+    return X86Relocator::OK;
   }
 
   // perform static relocation
   // get TLS segment
   ELFSegment* tls_seg = pParent.getTarget().elfSegmentTable().find(
                                        llvm::ELF::PT_TLS, llvm::ELF::PF_R, 0x0);
-  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
-  X86RelocationFactory::Address S = pReloc.symValue();
+  Relocator::DWord A = pReloc.target() + pReloc.addend();
+  X86Relocator::Address S = pReloc.symValue();
   pReloc.target() = S + A - tls_seg->memsz();
-  return X86RelocationFactory::OK;
+  return X86Relocator::OK;
 }
 
-X86RelocationFactory::Result unsupport(Relocation& pReloc,
-                                       X86RelocationFactory& pParent)
+X86Relocator::Result unsupport(Relocation& pReloc, X86Relocator& pParent)
 {
-  return X86RelocationFactory::Unsupport;
+  return X86Relocator::Unsupport;
 }
 
diff --git a/lib/Target/X86/X86RelocationFactory.h b/lib/Target/X86/X86Relocator.h
similarity index 64%
rename from lib/Target/X86/X86RelocationFactory.h
rename to lib/Target/X86/X86Relocator.h
index 92119f1..7d3c289 100644
--- a/lib/Target/X86/X86RelocationFactory.h
+++ b/lib/Target/X86/X86Relocator.h
@@ -1,4 +1,4 @@
-//===-  X86RelocationFactory.h --------------------------------------------===//
+//===-  X86Relocator.h --------------------------------------------===//
 //
 //                     The MCLinker Project
 //
@@ -12,7 +12,7 @@
 #include <gtest.h>
 #endif
 
-#include <mcld/LD/RelocationFactory.h>
+#include <mcld/LD/Relocator.h>
 #include <mcld/Target/GOT.h>
 #include <mcld/Target/PLT.h>
 #include <mcld/Target/SymbolEntryMap.h>
@@ -22,19 +22,20 @@
 
 class ResolveInfo;
 
-/** \class X86RelocationFactory
- *  \brief X86RelocationFactory creates and destroys the X86 relocations.
+/** \class X86Relocator
+ *  \brief X86Relocator creates and destroys the X86 relocations.
  *
  */
-class X86RelocationFactory : public RelocationFactory
+class X86Relocator : public Relocator
 {
 public:
-  typedef SymbolEntryMap<PLT::Entry> SymPLTMap;
-  typedef SymbolEntryMap<GOT::Entry> SymGOTMap;
+  typedef SymbolEntryMap<PLTEntryBase> SymPLTMap;
+  typedef SymbolEntryMap<X86GOTEntry> SymGOTMap;
+  typedef SymbolEntryMap<X86GOTPLTEntry> SymGOTPLTMap;
 
 public:
-  X86RelocationFactory(size_t pNum, X86GNULDBackend& pParent);
-  ~X86RelocationFactory();
+  X86Relocator(X86GNULDBackend& pParent);
+  ~X86Relocator();
 
   Result applyRelocation(Relocation& pRelocation);
 
@@ -52,14 +53,14 @@
   const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; }
   SymGOTMap&       getSymGOTMap()       { return m_SymGOTMap; }
 
-  const SymGOTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; }
-  SymGOTMap&       getSymGOTPLTMap()       { return m_SymGOTPLTMap; }
+  const SymGOTPLTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; }
+  SymGOTPLTMap&       getSymGOTPLTMap()       { return m_SymGOTPLTMap; }
 
 private:
   X86GNULDBackend& m_Target;
   SymPLTMap m_SymPLTMap;
   SymGOTMap m_SymGOTMap;
-  SymGOTMap m_SymGOTPLTMap;
+  SymGOTPLTMap m_SymGOTPLTMap;
 };
 
 } // namespace of mcld
diff --git a/tools/llvm-mcld/llvm-mcld.cpp b/tools/llvm-mcld/llvm-mcld.cpp
index 28a18c6..e7a48d0 100644
--- a/tools/llvm-mcld/llvm-mcld.cpp
+++ b/tools/llvm-mcld/llvm-mcld.cpp
@@ -283,7 +283,7 @@
            cl::value_desc("directory"),
            cl::ValueRequired);
 
-static cl::list<std::string>
+static cl::list<std::string, bool, llvm::cl::SearchDirParser>
 ArgSearchDirList("L",
                  cl::ZeroOrMore,
                  cl::desc("Add path searchdir to the list of paths that ld will search for archive libraries and ld control scripts."),
@@ -597,6 +597,26 @@
                        cl::desc("alias for -u"),
                        cl::aliasopt(ArgForceUndefined));
 
+static cl::opt<std::string>
+ArgVersionScript("version-script",
+                 cl::desc("Version script."),
+                 cl::value_desc("Version script"));
+
+static cl::opt<bool>
+ArgNoStdLib("nostdlib",
+            cl::desc("Only search lib dirs explicitly specified on cmdline"),
+            cl::init(false));
+
+static cl::opt<bool>
+ArgWarnCommon("warn-common",
+              cl::desc("warn common symbol"),
+              cl::init(false));
+
+static cl::opt<bool>
+ArgFatalWarnings("fatal-warnings",
+              cl::desc("turn all warnings into errors"),
+              cl::init(false));
+
 /// @{
 /// @name FIXME: end of unsupported options
 /// @}
@@ -606,6 +626,54 @@
                      cl::desc("Warn if adding DT_TEXTREL in a shared object."),
                      cl::init(false));
 
+namespace format {
+enum Format {
+  Binary,
+  Unknown // decided by triple
+};
+} // namespace of format
+
+static cl::opt<format::Format>
+ArgFormat("b",
+  cl::value_desc("Format"),
+  cl::desc("set input format"),
+  cl::init(format::Unknown),
+  cl::values(
+    clEnumValN(format::Binary, "binary",
+      "read in binary machine code."),
+    clEnumValEnd));
+
+static cl::alias
+ArgFormatAlias("format",
+               cl::desc("alias for -b"),
+               cl::aliasopt(ArgFormat));
+
+static cl::opt<format::Format>
+ArgOFormat("oformat",
+  cl::value_desc("Format"),
+  cl::desc("set output format"),
+  cl::init(format::Unknown),
+  cl::values(
+    clEnumValN(format::Binary, "binary",
+      "generate binary machine code."),
+    clEnumValEnd));
+
+static cl::opt<bool>
+ArgDefineCommon("d",
+                cl::ZeroOrMore,
+                cl::desc("Define common symbol"),
+                cl::init(false));
+
+static cl::alias
+ArgDefineCommonAlias1("dc",
+                      cl::desc("alias for -d"),
+                      cl::aliasopt(ArgDefineCommon));
+
+static cl::alias
+ArgDefineCommonAlias2("dp",
+                      cl::desc("alias for -d"),
+                      cl::aliasopt(ArgDefineCommon));
+
 //===----------------------------------------------------------------------===//
 // Scripting Options
 //===----------------------------------------------------------------------===//
@@ -743,6 +811,7 @@
     break;
   case mcld::CGFT_DSOFile:
   case mcld::CGFT_EXEFile:
+  case mcld::CGFT_BINARY:
   case mcld::CGFT_NULLFile:
     permission = 0755;
     break;
@@ -759,6 +828,44 @@
   return result_output;
 }
 
+/// ParseProgName - Parse program name
+/// This function simplifies cross-compiling by reading triple from the program
+/// name. For example, if the program name is `arm-linux-eabi-ld.mcld', we can
+/// get the triple is arm-linux-eabi by the program name.
+static void ParseProgName(const char *progname)
+{
+  static const char *suffixes[] = {
+    "ld",
+    "ld.mcld",
+  };
+
+  std::string ProgName(mcld::sys::fs::Path(progname).stem().native());
+
+  for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
+    if (ProgName == suffixes[i])
+      return;
+  }
+
+  StringRef ProgNameRef(ProgName);
+  StringRef Prefix;
+
+  for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
+    if (!ProgNameRef.endswith(suffixes[i]))
+      continue;
+
+    StringRef::size_type LastComponent = ProgNameRef.rfind('-',
+      ProgNameRef.size() - strlen(suffixes[i]));
+    if (LastComponent == StringRef::npos)
+      continue;
+    StringRef Prefix = ProgNameRef.slice(0, LastComponent);
+    std::string IgnoredError;
+    if (!llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError))
+      continue;
+    TargetTriple = Prefix.str();
+    return;
+  }
+}
+
 static bool ShouldColorize()
 {
    const char* term = getenv("TERM");
@@ -788,6 +895,9 @@
   // set up soname
   pConfig.options().setSOName(ArgSOName);
 
+  // --fatal-warnings
+  pConfig.options().setFatalWarnings(ArgFatalWarnings);
+
   // -shared or -pie
   if (true == ArgShared || true == ArgPIE) {
     ArgFileType = mcld::CGFT_DSOFile;
@@ -795,6 +905,13 @@
   else if (true == ArgRelocatable) {
     ArgFileType = mcld::CGFT_PARTIAL;
   }
+  else if (format::Binary == ArgOFormat) {
+    ArgFileType = mcld::CGFT_BINARY;
+  }
+
+  // -b [input-format], --format=[input-format]
+  if (format::Binary == ArgFormat)
+    pConfig.options().setBinaryInput();
 
   // -V
   if (ArgVersion) {
@@ -838,6 +955,7 @@
   pConfig.options().setStripDebug(ArgStripDebug);
   pConfig.options().setExportDynamic(ArgExportDynamic);
   pConfig.options().setWarnSharedTextrel(ArgWarnSharedTextrel);
+  pConfig.options().setDefineCommon(ArgDefineCommon);
 
   // set up rename map, for --wrap
   cl::list<std::string>::iterator wname;
@@ -968,13 +1086,6 @@
 {
   LLVMContext &Context = getGlobalContext();
   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
-  cl::ParseCommandLineOptions(argc, argv, "MCLinker\n");
-
-#ifdef ENABLE_UNITTEST
-  if (UnitTest) {
-    return unit_test( argc, argv );
-  }
-#endif
 
   // Initialize targets first, so that --version shows registered targets.
   InitializeAllTargets();
@@ -986,6 +1097,15 @@
   mcld::InitializeAllEmulations();
   mcld::InitializeAllDiagnostics();
 
+  ParseProgName(argv[0]);
+  cl::ParseCommandLineOptions(argc, argv, "MCLinker\n");
+
+#ifdef ENABLE_UNITTEST
+  if (UnitTest) {
+    return unit_test( argc, argv );
+  }
+#endif
+
   // Load the module to be compiled...
   std::auto_ptr<llvm::Module> M;
 
@@ -1003,7 +1123,8 @@
   if (ArgBitcodeFilename.empty() &&
       (mcld::CGFT_DSOFile != ArgFileType &&
        mcld::CGFT_EXEFile != ArgFileType &&
-       mcld::CGFT_PARTIAL != ArgFileType)) {
+       mcld::CGFT_PARTIAL != ArgFileType &&
+       mcld::CGFT_BINARY  != ArgFileType)) {
     // If the file is not given, forcefully read from stdin
     if (ArgVerbose >= 0) {
       errs() << "** The bitcode/llvm asm file is not given. Read from stdin.\n"
@@ -1087,7 +1208,7 @@
     }
   }
   // Set up mcld::LinkerConfig
-  LDConfig.setTriple(TheTriple);
+  LDConfig.targets().setTriple(TheTriple);
 
   // Package up features to be passed to target/subtarget
   std::string FeaturesStr;
@@ -1199,6 +1320,9 @@
     PM.run(mod);
   }
 
+  if (mcld::getDiagnosticEngine().getPrinter()->getNumErrors())
+    return 1;
+
   // Declare success.
   Out->keep();
   return 0;
diff --git a/tools/mcld/include/alone/Linker.h b/tools/mcld/include/alone/Linker.h
index b0bdc5e..987b36a 100644
--- a/tools/mcld/include/alone/Linker.h
+++ b/tools/mcld/include/alone/Linker.h
@@ -15,16 +15,11 @@
 namespace mcld {
 
 class Module;
-class TargetLDBackend;
-class ObjectLinker;
-class ContextFactory;
+class IRBuilder;
 class LinkerConfig;
-class TreeIteratorBase;
+class Linker;
 class Input;
-class InputFactory;
-class InputBuilder;
 class MemoryArea;
-class MemoryAreaFactory;
 
 namespace sys { namespace fs {
 
@@ -43,11 +38,10 @@
   enum ErrorCode {
     kSuccess,
     kDoubleConfig,
-    kCreateBackend,
     kDelegateLDInfo,
     kFindNameSpec,
-    kOpenNameSpec,
     kOpenObjectFile,
+    kOpenMemory,
     kNotConfig,
     kNotSetUpOutput,
     kOpenOutput,
@@ -62,15 +56,11 @@
 private:
   const mcld::LinkerConfig *mLDConfig;
   mcld::Module *mModule;
-  mcld::TargetLDBackend *mBackend;
-  mcld::ObjectLinker *mObjLinker;
-  mcld::InputFactory *mInputFactory;
-  mcld::MemoryAreaFactory *mMemAreaFactory;
-  mcld::ContextFactory *mContextFactory;
-  mcld::InputBuilder *mBuilder;
-  mcld::TreeIteratorBase *mRoot;
+  mcld::Linker *mLinker;
+  mcld::IRBuilder *mBuilder;
   std::string mSOName;
-  mcld::MemoryArea* mOutput;
+  std::string mOutputPath;
+  int mOutputHandler;
 
 public:
   Linker();
@@ -97,12 +87,6 @@
 
 private:
   enum ErrorCode extractFiles(const LinkerConfig& pConfig);
-
-  enum ErrorCode openFile(const mcld::sys::fs::Path& pPath,
-                          enum ErrorCode pCode,
-                          mcld::Input& pInput);
-
-  void advanceRoot();
 };
 
 } // end namespace alone
diff --git a/tools/mcld/include/alone/Support/LinkerConfig.h b/tools/mcld/include/alone/Support/LinkerConfig.h
index 0aa3277..6eecdd5 100644
--- a/tools/mcld/include/alone/Support/LinkerConfig.h
+++ b/tools/mcld/include/alone/Support/LinkerConfig.h
@@ -86,6 +86,8 @@
 
   void setBsymbolic(bool pEnable = true);
 
+  void setDefineCommon(bool pEnable = true);
+
   void setSOName(const std::string &pSOName);
 
   void setDyld(const std::string &pDyld);
diff --git a/tools/mcld/include/alone/Support/Log.h b/tools/mcld/include/alone/Support/Log.h
index bc91d44..e3c80d1 100644
--- a/tools/mcld/include/alone/Support/Log.h
+++ b/tools/mcld/include/alone/Support/Log.h
@@ -13,6 +13,6 @@
 #include <cstdio>
 
 #define ALOGE(fmt, args...) \
-printf("%s:%s:%d: "fmt, __FILE__, __FUNCTION__, __LINE__, args)
+printf("%s:%s:%d: " fmt, __FILE__, __FUNCTION__, __LINE__, args)
 
 #endif // ALONE_SUPPORT_LOG_H
diff --git a/tools/mcld/lib/Core/Linker.cpp b/tools/mcld/lib/Core/Linker.cpp
index d3f1450..83de5a8 100644
--- a/tools/mcld/lib/Core/Linker.cpp
+++ b/tools/mcld/lib/Core/Linker.cpp
@@ -15,20 +15,11 @@
 
 #include <mcld/Module.h>
 #include <mcld/IRBuilder.h>
-#include <mcld/InputTree.h>
-#include <mcld/Object/ObjectLinker.h>
-#include <mcld/Fragment/FragmentLinker.h>
-#include <mcld/MC/InputFactory.h>
-#include <mcld/MC/ContextFactory.h>
-#include <mcld/MC/InputBuilder.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/Linker.h>
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/LDContext.h>
-#include <mcld/Target/TargetLDBackend.h>
 #include <mcld/Support/Path.h>
-#include <mcld/Support/MemoryArea.h>
-#include <mcld/Support/FileHandle.h>
-#include <mcld/Support/MemoryAreaFactory.h>
-#include <mcld/Support/TargetRegistry.h>
 
 using namespace alone;
 
@@ -38,14 +29,10 @@
     "Successfully compiled.",
     /* kDoubleConfig */
     "Configure Linker twice.",
-    /* kCreateBackend */
-    "Cannot create backend.",
     /* kDelegateLDInfo */
     "Cannot get linker information",
     /* kFindNameSpec */
     "Cannot find -lnamespec",
-    /* kOpenNameSpec */
-    "Cannot open -lnamespec",
     /* kOpenObjectFile */
     "Cannot open object file",
     /* kNotConfig */
@@ -75,15 +62,13 @@
 // Linker
 //===----------------------------------------------------------------------===//
 Linker::Linker()
-  : mLDConfig(NULL), mModule(NULL), mBackend(NULL), mObjLinker(NULL),
-    mInputFactory(NULL), mMemAreaFactory(NULL), mContextFactory(NULL),
-    mBuilder(NULL), mRoot(NULL), mOutput(NULL) {
+  : mLDConfig(NULL), mModule(NULL), mLinker(NULL), mBuilder(NULL),
+    mOutputHandler(-1) {
 }
 
 Linker::Linker(const LinkerConfig& pConfig)
-  : mLDConfig(NULL), mModule(NULL), mBackend(NULL), mObjLinker(NULL),
-    mInputFactory(NULL), mMemAreaFactory(NULL), mContextFactory(NULL),
-    mBuilder(NULL), mRoot(NULL), mOutput(NULL) {
+  : mLDConfig(NULL), mModule(NULL), mLinker(NULL), mBuilder(NULL),
+    mOutputHandler(-1) {
 
   const std::string &triple = pConfig.getTriple();
 
@@ -98,14 +83,8 @@
 
 Linker::~Linker() {
   delete mModule;
-  delete mObjLinker;
-  // FIXME: current implementation can not change the order of deleting
-  // ObjectLinker and TargetLDBackend. Because the deletion of relocation list
-  // in FragmentLinker (FragmentLinker is deleted by ObjectLinker) depends on
-  // RelocationFactory in TargetLDBackend
-  delete mBackend;
+  delete mLinker;
   delete mBuilder;
-  delete mRoot;
 }
 
 enum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig) {
@@ -123,229 +102,73 @@
 
   extractFiles(pConfig);
 
-  mBackend = pConfig.getTarget()->createLDBackend(*mLDConfig);
-  if (mBackend == NULL) {
-    return kCreateBackend;
-  }
-
-  mInputFactory = new mcld::InputFactory(32, *mLDConfig);
-
-  mContextFactory = new mcld::ContextFactory(32);
-    /* 32 is a magic number, the estimated number of input files **/
-
-  mMemAreaFactory = new mcld::MemoryAreaFactory(32);
-
-  mBuilder = new mcld::InputBuilder(*mLDConfig,
-                                    *mInputFactory,
-                                    *mContextFactory,
-                                    *mMemAreaFactory,
-                                    true); // delegated
-
   mModule = new mcld::Module(mLDConfig->options().soname());
 
-  mRoot = new mcld::InputTree::iterator(mModule->getInputTree().root());
+  mBuilder = new mcld::IRBuilder(*mModule, *mLDConfig);
 
-  mObjLinker = new mcld::ObjectLinker(*mLDConfig, *mModule, *mBuilder, *mBackend);
+  mLinker = new mcld::Linker();
 
-  mObjLinker->initFragmentLinker();
+  mLinker->config(const_cast<mcld::LinkerConfig&>(*mLDConfig));
 
   return kSuccess;
 }
 
-void Linker::advanceRoot() {
-  if (mRoot->isRoot()) {
-    mRoot->move<mcld::TreeIteratorBase::Leftward>();
-  } else {
-    mRoot->move<mcld::TreeIteratorBase::Rightward>();
-  }
-  return;
-}
-
-enum Linker::ErrorCode Linker::openFile(const mcld::sys::fs::Path& pPath,
-                                        enum Linker::ErrorCode pCode,
-                                        mcld::Input& pInput) {
-  mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pPath,
-                                                    mcld::FileHandle::ReadOnly);
-
-  if (input_memory->handler()->isGood()) {
-    pInput.setMemArea(input_memory);
-  } else {
-    return pCode;
-  }
-
-  mBuilder->setContext(pInput);
-  return kSuccess;
-}
-
 enum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec) {
-  const mcld::sys::fs::Path* path = NULL;
-  // find out the real path of the namespec.
-  if (mLDConfig->attribute().constraint().isSharedSystem()) {
-    // In the system with shared object support, we can find both archive
-    // and shared object.
-
-    if (mInputFactory->attr().isStatic()) {
-      // with --static, we must search an archive.
-      path = mLDConfig->options().directories().find(pNameSpec,
-                                                     mcld::Input::Archive);
-    }
-    else {
-      // otherwise, with --Bdynamic, we can find either an archive or a
-      // shared object.
-      path = mLDConfig->options().directories().find(pNameSpec,
-                                                     mcld::Input::DynObj);
-    }
-  }
-  else {
-    // In the system without shared object support, we only look for an
-    // archive.
-    path = mLDConfig->options().directories().find(pNameSpec,
-                                                 mcld::Input::Archive);
-  }
-
-  if (NULL == path)
+  mcld::Input* input = mBuilder->ReadInput(pNameSpec);
+  if (NULL == input)
     return kFindNameSpec;
-
-  mcld::Input* input = mInputFactory->produce(pNameSpec, *path,
-                                              mcld::Input::Unknown);
-  mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
-
-  advanceRoot();
-
-  return openFile(*path, kOpenNameSpec, *input);
+  return kSuccess;
 }
 
 /// addObject - Add a object file by the filename.
 enum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath) {
-  mcld::Input* input = mInputFactory->produce(pObjectPath,
-                                              pObjectPath,
-                                              mcld::Input::Unknown);
-
-  mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
-
-  advanceRoot();
-
-  return openFile(pObjectPath, kOpenObjectFile, *input);
+  mcld::Input* input = mBuilder->ReadInput(pObjectPath, pObjectPath);
+  if (NULL == input)
+    return kOpenObjectFile;
+  return kSuccess;
 }
 
 /// addObject - Add a piece of memory. The memory is of ELF format.
 enum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize) {
-
-  mcld::Input* input = mInputFactory->produce("memory object", "NAN",
-                                              mcld::Input::Unknown);
-
-  mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
-
-  advanceRoot();
-
-  mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize);
-  input->setMemArea(input_memory);
-
-  mcld::LDContext *input_context = mContextFactory->produce();
-  input->setContext(input_context);
-
+  mcld::Input* input = mBuilder->ReadInput("NAN", pMemory, pSize);
+  if (NULL == input)
+    return kOpenMemory;
   return kSuccess;
 }
 
 enum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize) {
-  mcld::Input* input = mInputFactory->produce("code object", "NAN",
-                                              mcld::Input::External);
-
-  mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
-
-  advanceRoot();
-
-  mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize);
-  input->setMemArea(input_memory);
-
-  mcld::LDContext *input_context = mContextFactory->produce();
-  input->setContext(input_context);
-
-  // FIXME: So far, FragmentLinker must set up output before add input files.
-  // set up LDContext
-  if (mObjLinker->hasInitLinker()) {
-    return kNotConfig;
-  }
-
-  // create NULL section
-  mcld::LDSection* null = mcld::IRBuilder::CreateELFHeader(*input, "",
-                              llvm::ELF::SHT_NULL, 0, 0);
-  null->setSize(0);
-  null->setOffset(0);
-  null->setInfo(0);
-
-  // create .text section
-  mcld::LDSection* text = mcld::IRBuilder::CreateELFHeader(*input, ".text",
-                              llvm::ELF::SHT_PROGBITS,
-                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
-                              1);
-
-  text->setSize(pSize);
-  text->setOffset(0x0);
-  text->setInfo(0);
-
+  mcld::Input* input = mBuilder->CreateInput("NAN", "NAN", mcld::Input::Object);
+  mcld::LDSection* sect = mBuilder->CreateELFHeader(*input, ".text",
+                                llvm::ELF::SHT_PROGBITS,
+                                llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
+                                0x1);
+  mcld::SectionData* data = mBuilder->CreateSectionData(*sect);
+  mcld::Fragment* frag = mBuilder->CreateRegion(pMemory, pSize);
+  mBuilder->AppendFragment(*frag, *data);
   return kSuccess;
 }
 
 enum Linker::ErrorCode Linker::setOutput(const std::string &pPath) {
-  // -----  initialize output file  ----- //
-  mcld::FileHandle::Permission perm = 0755;
-
-  mOutput = mMemAreaFactory->produce(
-                      pPath,
-                      mcld::FileHandle::ReadWrite |
-                        mcld::FileHandle::Truncate |
-                        mcld::FileHandle::Create,
-                      perm);
-
-  if (!mOutput->handler()->isGood()) {
-    return kOpenOutput;
-  }
-
+  mOutputPath = pPath;
   return kSuccess;
 }
 
 enum Linker::ErrorCode Linker::setOutput(int pFileHandler) {
-  mOutput = mMemAreaFactory->produce(pFileHandler, mcld::FileHandle::ReadWrite);
-
-  if (!mOutput->handler()->isGood()) {
-    return kOpenOutput;
-  }
-
+  mOutputHandler = pFileHandler;
   return kSuccess;
 }
 
 enum Linker::ErrorCode Linker::link() {
-  if (NULL == mOutput)
-    return kNotSetUpOutput;
-
-  if (!mObjLinker->hasInitLinker()) {
-    return kNotConfig;
+  mLinker->link(*mModule, *mBuilder);
+  if (!mOutputPath.empty()) {
+    mLinker->emit(mOutputPath);
+    return kSuccess;
   }
 
-  mObjLinker->initStdSections();
-
-  mObjLinker->normalize();
-
-  if (!mObjLinker->readRelocations())
-    return kReadSections;
-
-  if (!mObjLinker->mergeSections())
-    return kReadSections;
-
-  if (!mObjLinker->addStandardSymbols() || !mObjLinker->addTargetSymbols()) {
-    return kAddAdditionalSymbols;
+  if (-1 != mOutputHandler) {
+    mLinker->emit(mOutputHandler);
+    return kSuccess;
   }
-
-  mObjLinker->scanRelocations();
-  mObjLinker->prelayout();
-  mObjLinker->layout();
-  mObjLinker->postlayout();
-  mObjLinker->finalizeSymbolValue();
-  mObjLinker->relocation();
-  mObjLinker->emitOutput(*mOutput);
-  mObjLinker->postProcessing(*mOutput);
-
-  return kSuccess;
+  return kNotSetUpOutput;
 }
 
diff --git a/tools/mcld/lib/Support/LinkerConfig.cpp b/tools/mcld/lib/Support/LinkerConfig.cpp
index 3a53ae1..3715bf8 100644
--- a/tools/mcld/lib/Support/LinkerConfig.cpp
+++ b/tools/mcld/lib/Support/LinkerConfig.cpp
@@ -157,6 +157,11 @@
   return;
 }
 
+void LinkerConfig::setDefineCommon(bool pEnable) {
+  mLDConfig->options().setDefineCommon(pEnable);
+  return;
+}
+
 void LinkerConfig::setSOName(const std::string &pSOName) {
   mLDConfig->options().setSOName(pSOName);
   return;
diff --git a/tools/mcld/lib/Support/TargetLinkerConfigs.cpp b/tools/mcld/lib/Support/TargetLinkerConfigs.cpp
index 0382c2a..1ce0237 100644
--- a/tools/mcld/lib/Support/TargetLinkerConfigs.cpp
+++ b/tools/mcld/lib/Support/TargetLinkerConfigs.cpp
@@ -10,7 +10,9 @@
 #include "alone/Config/Config.h"
 #include "alone/Support/TargetLinkerConfigs.h"
 
+#include <mcld/TargetOptions.h>
 #include <mcld/MC/InputFactory.h>
+#include <mcld/Fragment/Relocation.h>
 
 using namespace alone;
 
@@ -28,6 +30,10 @@
 #if defined(PROVIDE_ARM_CODEGEN)
 ARMLinkerConfig::ARMLinkerConfig() : LinkerConfig(DEFAULT_ARM_TRIPLE_STRING) {
 
+  // set up target-dependent options
+  getLDConfig()->targets().setEndian(mcld::TargetOptions::Little);
+  getLDConfig()->targets().setBitClass(32);
+
   // set up target-dependent constraints of attributes
   getLDConfig()->attribute().constraint().enableWholeArchive();
   getLDConfig()->attribute().constraint().disableAsNeeded();
@@ -53,6 +59,9 @@
     getLDConfig()->scripts().sectionMap().append(".ARM.extab", ".ARM.extab", exist);
     getLDConfig()->scripts().sectionMap().append(".ARM.attributes", ".ARM.attributes", exist);
   }
+
+  // set up relocation factory
+  mcld::Relocation::SetUp(*getLDConfig());
 }
 #endif // defined(PROVIDE_ARM_CODEGEN)
 
@@ -63,6 +72,10 @@
 MipsLinkerConfig::MipsLinkerConfig()
   : LinkerConfig(DEFAULT_MIPS_TRIPLE_STRING) {
 
+  // set up target-dependent options
+  getLDConfig()->targets().setEndian(mcld::TargetOptions::Little);
+  getLDConfig()->targets().setBitClass(32);
+
   // set up target-dependent constraints of attibutes
   getLDConfig()->attribute().constraint().enableWholeArchive();
   getLDConfig()->attribute().constraint().disableAsNeeded();
@@ -80,6 +93,9 @@
   if (!getLDConfig()->options().hasDyld()) {
     getLDConfig()->options().setDyld(gDefaultDyld);
   }
+
+  // set up relocation factory
+  mcld::Relocation::SetUp(*getLDConfig());
 }
 #endif // defined(PROVIDE_MIPS_CODEGEN)
 
@@ -89,6 +105,10 @@
 #if defined(PROVIDE_X86_CODEGEN)
 X86FamilyLinkerConfigBase::X86FamilyLinkerConfigBase(const std::string& pTriple)
   : LinkerConfig(pTriple) {
+  // set up target-dependent options
+  getLDConfig()->targets().setEndian(mcld::TargetOptions::Little);
+  getLDConfig()->targets().setBitClass(32);
+
   // set up target-dependent constraints of attibutes
   getLDConfig()->attribute().constraint().enableWholeArchive();
   getLDConfig()->attribute().constraint().disableAsNeeded();
@@ -106,6 +126,9 @@
   if (!getLDConfig()->options().hasDyld()) {
     getLDConfig()->options().setDyld(gDefaultDyld);
   }
+
+  // set up relocation factory
+  mcld::Relocation::SetUp(*getLDConfig());
 }
 
 X86_32LinkerConfig::X86_32LinkerConfig()
@@ -123,6 +146,11 @@
 //===----------------------------------------------------------------------===//
 GeneralLinkerConfig::GeneralLinkerConfig(const std::string& pTriple)
   : LinkerConfig(pTriple) {
+
+  // set up target-dependent options
+  getLDConfig()->targets().setEndian(mcld::TargetOptions::Little);
+  getLDConfig()->targets().setBitClass(32);
+
   // set up target-dependent constraints of attributes
   getLDConfig()->attribute().constraint().enableWholeArchive();
   getLDConfig()->attribute().constraint().disableAsNeeded();
@@ -133,12 +161,15 @@
   getLDConfig()->attribute().predefined().setDynamic();
 
   // set up section map
-  if (llvm::Triple::arm == getLDConfig()->triple().getArch() &&
+  if (llvm::Triple::arm == getLDConfig()->targets().triple().getArch() &&
       getLDConfig()->codeGenType() != mcld::LinkerConfig::Object) {
     bool exist = false;
     getLDConfig()->scripts().sectionMap().append(".ARM.exidx", ".ARM.exidx", exist);
     getLDConfig()->scripts().sectionMap().append(".ARM.extab", ".ARM.extab", exist);
     getLDConfig()->scripts().sectionMap().append(".ARM.attributes", ".ARM.attributes", exist);
   }
+
+  // set up relocation factory
+  mcld::Relocation::SetUp(*getLDConfig());
 }
 #endif // defined(TARGET_BUILD)
diff --git a/tools/mcld/main.cpp b/tools/mcld/main.cpp
index a66fb7c..58a9bb0 100644
--- a/tools/mcld/main.cpp
+++ b/tools/mcld/main.cpp
@@ -97,6 +97,33 @@
         llvm::cl::desc("Set the name of the dynamic linker."),
         llvm::cl::value_desc("Program"));
 
+static llvm::cl::opt<bool>
+OptRelocatable("relocatable",
+               llvm::cl::desc("Generate relocatable output"),
+               llvm::cl::init(false));
+
+static llvm::cl::alias
+OptRelocatableAlias("r",
+                    llvm::cl::desc("alias for --relocatable"),
+                    llvm::cl::aliasopt(OptRelocatable));
+
+static llvm::cl::opt<bool>
+OptDefineCommon("d",
+                llvm::cl::ZeroOrMore,
+                llvm::cl::desc("Define common symbol"),
+                llvm::cl::init(false));
+
+static llvm::cl::alias
+OptDefineCommonAlias1("dc",
+                      llvm::cl::desc("alias for -d"),
+                      llvm::cl::aliasopt(OptDefineCommon));
+
+static llvm::cl::alias
+OptDefineCommonAlias2("dp",
+                      llvm::cl::desc("alias for -d"),
+                      llvm::cl::aliasopt(OptDefineCommon));
+
+
 //===----------------------------------------------------------------------===//
 // Inputs
 //===----------------------------------------------------------------------===//
@@ -135,7 +162,7 @@
 static void MCLDVersionPrinter() {
   llvm::raw_ostream &os = llvm::outs();
   os << "mcld (The MCLinker Project, http://mclinker.googlecode.com/):\n"
-     << "  version: "MCLD_VERSION"\n"
+     << "  version: " MCLD_VERSION "\n"
      << "  Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n";
 
   os << "\n";
@@ -236,6 +263,9 @@
   // 8. Set up -Bsymbolic.
   config->setBsymbolic(OptBsymbolic);
 
+  // 9. Set up -d (define common symbols)
+  config->setDefineCommon(OptDefineCommon);
+
   Linker::ErrorCode result = pLinker.config(*config);
   if (Linker::kSuccess != result) {
     llvm::errs() << "Failed to configure the linker! (detail: "
diff --git a/unittests/FragmentTest.cpp b/unittests/FragmentTest.cpp
index 9713f48..43f51b6 100644
--- a/unittests/FragmentTest.cpp
+++ b/unittests/FragmentTest.cpp
@@ -47,9 +47,8 @@
   new Fragment(Fragment::Alignment, s);
   new Fragment(Fragment::Region, s);
   new Fragment(Fragment::Fillment, s);
-  new Fragment(Fragment::Relocation, s);
   new Fragment(Fragment::Target, s);
-  EXPECT_TRUE(6 == s->size());
+  EXPECT_TRUE(5 == s->size());
 
   LDSection::Destroy(test);
 //  SectionData::Destroy(s);
diff --git a/unittests/Linker/TestLinker.cpp b/unittests/Linker/TestLinker.cpp
deleted file mode 100644
index d1ead28..0000000
--- a/unittests/Linker/TestLinker.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-//===- TestLinker.cpp -----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include "TestLinker.h"
-
-#include <llvm/Support/TargetSelect.h>
-
-#include <mcld/Environment.h>
-#include <mcld/InputTree.h>
-#include <mcld/LD/TextDiagnosticPrinter.h>
-#include <mcld/MC/InputBuilder.h>
-#include <mcld/MC/InputFactory.h>
-#include <mcld/MC/MCLDDirectory.h>
-#include <mcld/Target/TargetLDBackend.h>
-#include <mcld/Support/Space.h>
-#include <mcld/Support/TargetSelect.h>
-#include <mcld/Support/MsgHandling.h>
-#include <mcld/Support/raw_ostream.h>
-#include <mcld/Support/SystemUtils.h>
-#include <mcld/Support/MemoryAreaFactory.h>
-#include <mcld/MC/ContextFactory.h>
-
-using namespace mcld;
-using namespace mcld::sys::fs;
-using namespace mcld::test;
-
-//===----------------------------------------------------------------------===//
-// TestLinker
-//===----------------------------------------------------------------------===//
-TestLinker::TestLinker()
-  : m_pTarget(NULL), m_pObjLinker(NULL), m_pConfig(NULL), m_pDiagLineInfo(NULL),
-    m_pDiagPrinter(NULL), m_pBackend(NULL), m_pBuilder(NULL), m_pOutput(NULL) {
-}
-
-TestLinker::~TestLinker()
-{
-  std::list<mcld::FileHandle*>::iterator file, fEnd = m_FileHandleList.end();
-  for (file = m_FileHandleList.begin(); file != fEnd; ++file)
-    delete (*file);
-
-  std::list<mcld::MemoryArea*>::iterator mem, mEnd = m_MemAreaList.end() ;
-  for (mem = m_MemAreaList.begin(); mem != mEnd; ++mem)
-    delete (*mem);
-
-  delete m_pObjLinker;
-  delete m_pConfig;
-  delete m_pDiagLineInfo;
-  delete m_pDiagPrinter;
-  delete m_pBackend;
-  delete m_pBuilder;
-  delete m_pOutput;
-}
-
-bool TestLinker::initialize(const std::string &pTriple)
-{
-  // initilaize all llvm::Target and mcld::Target
-  llvm::InitializeAllTargets();
-  llvm::InitializeAllAsmPrinters();
-  llvm::InitializeAllAsmParsers();
-  llvm::InitializeAllTargetMCs();
-  mcld::Initialize();
-
-  // create mcld::LinkerConfig
-  m_pConfig = new LinkerConfig(pTriple);
-
-  m_Root = m_Module.getInputTree().root();
-
-  // specify mcld::Target
-  std::string error;
-  m_pTarget = mcld::TargetRegistry::lookupTarget(pTriple, error);
-  if (NULL == m_pTarget) {
-    fatal(diag::fatal_cannot_init_target) << pTriple << error;
-    return false;
-  }
-
-  // create mcld::DiagnosticLineInfo
-  m_pDiagLineInfo = m_pTarget->createDiagnosticLineInfo(*m_pTarget, pTriple);
-  if (NULL == m_pDiagLineInfo) {
-    fatal(diag::fatal_cannot_init_lineinfo) << pTriple;
-    return false;
-  }
-  mcld::getDiagnosticEngine().setLineInfo(*m_pDiagLineInfo);
-
-  // create mcld::TargetLDBackend
-  m_pBackend = m_pTarget->createLDBackend(*m_pConfig);
-  if (NULL == m_pBackend) {
-    fatal(diag::fatal_cannot_init_backend) << pTriple;
-    return false;
-  }
-
-  m_pInputFactory = new mcld::InputFactory(10, *m_pConfig);
-  m_pContextFactory = new mcld::ContextFactory(10);
-  m_pMemAreaFactory = new mcld::MemoryAreaFactory(10);
-  m_pBuilder = new mcld::InputBuilder(*m_pConfig,
-                                      *m_pInputFactory,
-                                      *m_pContextFactory,
-                                      *m_pMemAreaFactory,
-                                      true);
-
-  m_pObjLinker = new mcld::ObjectLinker(*m_pConfig, m_Module, *m_pBuilder, *m_pBackend);
-  m_pObjLinker->initFragmentLinker();
-
-  return true;
-}
-
-void TestLinker::addSearchDir(const std::string &pDirPath)
-{
-  assert(NULL != m_pConfig && "initialize() must be called before addSearchDir");
-  assert(!m_pConfig->options().sysroot().empty() &&
-         "must setSysRoot before addSearchDir");
-
-  if (!m_pConfig->options().directories().insert(pDirPath)) {
-    mcld::warning(mcld::diag::warn_cannot_open_search_dir) << pDirPath;
-  }
-}
-
-void TestLinker::setSysRoot(const mcld::sys::fs::Path &pPath)
-{
-  assert(NULL != m_pConfig && "initialize() must be called before setSysRoot");
-  m_pConfig->options().setSysroot(pPath);
-}
-
-void TestLinker::addObject(const std::string &pPath)
-{
-  mcld::Input* input = m_pInputFactory->produce(pPath, pPath,
-                                                mcld::Input::Unknown);
-
-  m_Module.getInputTree().insert<mcld::InputTree::Positional>(m_Root, *input);
-
-  advanceRoot();
-
-  mcld::FileHandle* handler = new mcld::FileHandle();
-  m_FileHandleList.push_back(handler);
-  if (!handler->open(pPath, mcld::FileHandle::ReadOnly)) {
-    mcld::error(mcld::diag::err_cannot_open_file)
-                                      << pPath
-                                      << mcld::sys::strerror(handler->error());
-  }
-
-  mcld::MemoryArea* input_memory = new MemoryArea(*handler);
-  input->setMemArea(input_memory);
-  m_MemAreaList.push_back(input_memory);
-
-  m_pBuilder->setContext(*input);
-}
-
-void TestLinker::addObject(void* pMemBuffer, size_t pSize)
-{
-  mcld::Input* input = m_pInputFactory->produce("memory object", "NAN",
-                                                mcld::Input::Unknown);
-
-  m_Module.getInputTree().insert<mcld::InputTree::Positional>(m_Root, *input);
-
-  advanceRoot();
-
-  mcld::Space* space = Space::Create(pMemBuffer, pSize);
-  mcld::MemoryArea* input_memory = new MemoryArea(*space);
-  input->setMemArea(input_memory);
-  m_MemAreaList.push_back(input_memory);
-
-  mcld::LDContext* context = m_pContextFactory->produce();
-  input->setContext(context);
-}
-
-void TestLinker::addObject(int pFileHandler)
-{
-  mcld::Input* input = m_pInputFactory->produce("handler object", "NAN",
-                                                mcld::Input::Unknown);
-
-  m_Module.getInputTree().insert<mcld::InputTree::Positional>(m_Root, *input);
-
-  advanceRoot();
-
-  mcld::FileHandle* handler = new mcld::FileHandle();
-  m_FileHandleList.push_back(handler);
-  handler->delegate(pFileHandler);
-
-  mcld::MemoryArea* input_memory = new MemoryArea(*handler);
-  input->setMemArea(input_memory);
-  m_MemAreaList.push_back(input_memory);
-
-  mcld::LDContext* context = m_pContextFactory->produce();
-  input->setContext(context);
-}
-
-void TestLinker::addNameSpec(const std::string &pNameSpec)
-{
-  mcld::sys::fs::Path* path = NULL;
-  // find out the real path of the namespec.
-  if (m_pConfig->attribute().constraint().isSharedSystem()) {
-    // In the system with shared object support, we can find both archive
-    // and shared object.
-
-    if (m_pInputFactory->attr().isStatic()) {
-      // with --static, we must search an archive.
-      path = m_pConfig->options().directories().find(pNameSpec,
-                                                     mcld::Input::Archive);
-    }
-    else {
-      // otherwise, with --Bdynamic, we can find either an archive or a
-      // shared object.
-      path = m_pConfig->options().directories().find(pNameSpec,
-                                                   mcld::Input::DynObj);
-    }
-  }
-  else {
-    // In the system without shared object support, we only look for an
-    // archive.
-    path = m_pConfig->options().directories().find(pNameSpec,
-                                                 mcld::Input::Archive);
-  }
-
-  if (NULL == path) {
-    mcld::fatal(diag::err_cannot_find_namespec) << pNameSpec;
-    return;
-  }
-
-  mcld::Input* input = m_pInputFactory->produce(pNameSpec, *path,
-                                                mcld::Input::Unknown);
-
-  m_Module.getInputTree().insert<mcld::InputTree::Positional>(m_Root, *input);
-
-  advanceRoot();
-
-  mcld::FileHandle* handler = new mcld::FileHandle();
-  m_FileHandleList.push_back(handler);
-  if (!handler->open(*path, mcld::FileHandle::ReadOnly)) {
-    mcld::error(mcld::diag::err_cannot_open_file)
-                                      << *path
-                                      << mcld::sys::strerror(handler->error());
-  }
-
-  mcld::MemoryArea* input_memory = new MemoryArea(*handler);
-  input->setMemArea(input_memory);
-  m_MemAreaList.push_back(input_memory);
-
-  m_pBuilder->setContext(*input);
-}
-
-bool TestLinker::setOutput(const std::string &pPath)
-{
-  mcld::FileHandle* handler = new mcld::FileHandle();
-  m_FileHandleList.push_back(handler);
-  bool open_res = handler->open(pPath, mcld::FileHandle::ReadWrite |
-                                       mcld::FileHandle::Truncate |
-                                       mcld::FileHandle::Create,
-                                mcld::FileHandle::Permission(0755));
-  if (!open_res) {
-    mcld::error(mcld::diag::err_cannot_open_file)
-                                      << pPath
-                                      << mcld::sys::strerror(handler->error());
-  }
-
-  m_pOutput = new MemoryArea(*handler);
-
-  // FIXME: remove the initStdSections().
-  m_pObjLinker->initStdSections();
-  return true;
-}
-
-bool TestLinker::setOutput(const sys::fs::Path &pPath)
-{
-  return setOutput(pPath.native());
-}
-
-bool TestLinker::setOutput(int pFileHandler)
-{
-  mcld::FileHandle* handler = new mcld::FileHandle();
-  handler->delegate(pFileHandler);
-  m_FileHandleList.push_back(handler);
-
-  m_pOutput = new MemoryArea(*handler);
-
-  // FIXME: remove the initStdSections().
-  m_pObjLinker->initStdSections();
-  return true;
-}
-
-void TestLinker::advanceRoot()
-{
-    if (m_Root.isRoot())
-      --m_Root;
-    else
-      ++m_Root;
-}
diff --git a/unittests/Linker/TestLinker.h b/unittests/Linker/TestLinker.h
deleted file mode 100644
index 701a405..0000000
--- a/unittests/Linker/TestLinker.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===- TestLinker.h -------------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_TEST_LINKER_H
-#define MCLD_TEST_LINKER_H
-
-#include <gtest.h>
-
-#include <string>
-#include <list>
-
-#include <mcld/Module.h>
-#include <mcld/Object/ObjectLinker.h>
-#include <mcld/Fragment/FragmentLinker.h>
-#include <mcld/LD/DiagnosticPrinter.h>
-#include <mcld/LD/DiagnosticLineInfo.h>
-#include <mcld/Support/TargetRegistry.h>
-#include <mcld/Support/Path.h>
-
-namespace mcld {
-
-class FileHandle;
-class LinkerConfig;
-class TargetLDBackend;
-class RegionFactory;
-class InputFactory;
-class MemoryAreaFactory;
-class ContextFactory;
-class InputBuilder;
-
-namespace test {
-
-class TestLinker
-{
-public:
-  TestLinker();
-
-  ~TestLinker();
-
-  bool initialize(const std::string &pTriple);
-
-  LinkerConfig* config() {
-    assert(NULL != m_pConfig);
-    return m_pConfig;
-  }
-
-  const LinkerConfig* config() const {
-    assert(NULL != m_pConfig);
-    return m_pConfig;
-  }
-
-  const Module* module() const { return &m_Module; }
-  Module*       module()       { return &m_Module; }
-
-  // -----  search directories  ----- //
-  void addSearchDir(const std::string &pPath);
-
-  void setSysRoot(const mcld::sys::fs::Path &pPath);
-
-  // -----  input operators  ----- //
-  void addObject(const std::string &pPath);
-
-  void addObject(const mcld::sys::fs::Path &pPath)
-  { addObject(pPath.native()); }
-
-  void addObject(void* pMemBuffer, size_t pSize);
-
-  void addObject(int pFileHandler);
-
-  void addNameSpec(const std::string &pNameSpec);
-
-  bool setOutput(const std::string &pPath);
-
-  bool setOutput(int pFileHandler);
-
-  bool setOutput(const sys::fs::Path &pPath);
-
-  const MemoryArea* getOutput() const { return m_pOutput; }
-
-  MemoryArea*       getOutput()       { return m_pOutput; }
-
-  /// getObjLinker
-  ObjectLinker* getObjLinker() {
-    assert(NULL != m_pObjLinker);
-    return m_pObjLinker;
-  }
-
-  /// getObjLinker
-  const ObjectLinker* getObjLinker() const {
-    assert(NULL != m_pObjLinker);
-    return m_pObjLinker;
-  }
-
-  /// getLinker
-  FragmentLinker* getLinker() {
-    assert(NULL != m_pObjLinker);
-    return m_pObjLinker->getLinker();
-  }
-
-  /// getLinker
-  const FragmentLinker* getLinker() const {
-    assert(NULL != m_pObjLinker);
-    return m_pObjLinker->getLinker();
-  }
-
-private:
-  void advanceRoot();
-
-private:
-  const mcld::Target* m_pTarget;
-  mcld::ObjectLinker *m_pObjLinker;
-  mcld::LinkerConfig* m_pConfig;
-  mcld::Module m_Module;
-  mcld::DiagnosticLineInfo* m_pDiagLineInfo;
-  mcld::DiagnosticPrinter* m_pDiagPrinter;
-  mcld::TargetLDBackend* m_pBackend;
-  mcld::InputTree::iterator m_Root;
-  mcld::InputFactory* m_pInputFactory;
-  mcld::MemoryAreaFactory* m_pMemAreaFactory;
-  mcld::ContextFactory* m_pContextFactory;
-
-  mcld::InputBuilder* m_pBuilder;
-
-  std::list<mcld::FileHandle*> m_FileHandleList;
-  std::list<mcld::MemoryArea*> m_MemAreaList;
-
-  mcld::MemoryArea* m_pOutput;
-};
-
-} // namespace of test
-} // namespace of mcld
-
-#endif
-
diff --git a/unittests/LinkerTest.cpp b/unittests/LinkerTest.cpp
index 64da08d..00ba23b 100644
--- a/unittests/LinkerTest.cpp
+++ b/unittests/LinkerTest.cpp
@@ -352,6 +352,7 @@
   gotplt_o.append("test/PLT/gotplt.o");
   Input* input = builder.CreateInput("gotplt.o", gotplt_o, Input::Object);
 
+  /// Sections
   /// [ 0]                   NULL            00000000 000000 000000 00      0   0  0
   builder.CreateELFHeader(*input,
                           "",
@@ -374,25 +375,35 @@
   Fragment* text_frag = builder.CreateRegion(text_content, 0x10);
   builder.AppendFragment(*text_frag, *text_data);
 
-  // [ 3] .data             PROGBITS        00000000 000044 000000 00  WA  0   0  4
-  builder.CreateELFHeader(*input,
+  /// [ 2] .rel.text         REL             00000000 0002ac 000008 08      7   1  4
+  LDSection* rel_text = builder.CreateELFHeader(*input,
+                          ".rel.text",
+                          llvm::ELF::SHT_REL,
+                          0x0, 4);
+  rel_text->setLink(text);
+  builder.CreateRelocData(*rel_text);
+
+  /// [ 3] .data             PROGBITS        00000000 000044 000000 00  WA  0   0  4
+  LDSection* data = builder.CreateELFHeader(*input,
                           ".data",
                           llvm::ELF::SHT_PROGBITS,
                           llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
                           4);
 
-  // [ 4] .bss              NOBITS          00000000 000044 000000 00  WA  0   0  4
-  builder.CreateELFHeader(*input,
+  /// [ 4] .bss              NOBITS          00000000 000044 000000 00  WA  0   0  4
+  LDSection* bss = builder.CreateELFHeader(*input,
                           ".bss",
-                          llvm::ELF::SHT_PROGBITS,
+                          llvm::ELF::SHT_NOBITS,
                           llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
                           4);
-  // [ 5] .ARM.attributes   ARM_ATTRIBUTES  00000000 000044 000020 00      0   0  1
+  builder.CreateBSS(*bss);
+
+  /// [ 5] .ARM.attributes   ARM_ATTRIBUTES  00000000 000044 000020 00      0   0  1
   LDSection* attr = builder.CreateELFHeader(*input,
                               ".ARM.attributes",
                               llvm::ELF::SHT_ARM_ATTRIBUTES,
                               0x0,
-                              4);
+                              1);
 
   SectionData* attr_data = builder.CreateSectionData(*attr);
   static uint8_t attr_content[] = {
@@ -407,6 +418,48 @@
   Fragment* attr_frag = builder.CreateRegion(attr_content, 0x20);
   builder.AppendFragment(*attr_frag, *attr_data);
 
+  /// Symbols
+  /// 1: 00000000     0 FILE    LOCAL  DEFAULT  ABS Output/gotplt.bc
+  builder.AddSymbol(*input,
+                    "Output/gotplt.bc", ResolveInfo::File,
+                    ResolveInfo::Define, ResolveInfo::Local, 0);
+  /// 2: 00000000     0 SECTION LOCAL  DEFAULT    1 
+  builder.AddSymbol(*input,
+                    ".text", ResolveInfo::Section,
+                    ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, text);
+  /// 3: 00000000     0 SECTION LOCAL  DEFAULT    3
+  builder.AddSymbol(*input,
+                    ".data", ResolveInfo::Section,
+                    ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, data);
+  /// 4: 00000000     0 SECTION LOCAL  DEFAULT    4 
+  builder.AddSymbol(*input,
+                    ".bss", ResolveInfo::Section,
+                    ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, bss);
+  /// 5: 00000000     0 SECTION LOCAL  DEFAULT    5 
+  builder.AddSymbol(*input,
+                    ".ARM.attributes", ResolveInfo::Section,
+                    ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, attr);
+  /// 6: 00000000    16 FUNC    GLOBAL DEFAULT    1 _Z1fv
+  builder.AddSymbol(*input,
+                    "_Z1fv", ResolveInfo::Function,
+                    ResolveInfo::Define, ResolveInfo::Global,
+                    16,
+                    0x0,
+                    text);
+
+  /// 7: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z1gv
+  LDSymbol* z1gv = builder.AddSymbol(*input,
+                                     "_Z1gv",
+                                     ResolveInfo::NoType,
+                                     ResolveInfo::Undefined,
+                                     ResolveInfo::Global,
+                                     0);
+
+ /// Relocations
+ /// Offset     Info    Type            Sym.Value  Sym. Name
+ /// 00000004  0000071b R_ARM_PLT32       00000000   _Z1gv
+ builder.AddRelocation(*rel_text, llvm::ELF::R_ARM_PLT32, *z1gv, 0x4);
+
   if (linker.link(module, builder)) {
     linker.emit("libgotplt.so"); ///< -o libgotplt.so
   }
diff --git a/unittests/ReadStageTest.cpp b/unittests/ReadStageTest.cpp
deleted file mode 100644
index b2aaf8d..0000000
--- a/unittests/ReadStageTest.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-//===- ReadStageTest.cpp --------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include "ReadStageTest.h"
-
-#include <mcld/Module.h>
-#include <mcld/LD/LDContext.h>
-#include <mcld/LD/LDSection.h>
-#include <mcld/LD/SectionData.h>
-#include <mcld/Fragment/Fragment.h>
-#include <mcld/Fragment/FragmentRef.h>
-#include <mcld/LD/LDSymbol.h>
-#include <mcld/LD/ResolveInfo.h>
-#include <mcld/MC/InputFactory.h>
-#include <mcld/Support/FileHandle.h>
-
-#include <sstream>
-#include <iostream>
-
-using namespace std;
-
-using namespace mcld;
-using namespace mcld::test;
-
-
-// Constructor can do set-up work for all test here.
-ReadStageTest::ReadStageTest()
-  : m_pLinker(NULL) {
-}
-
-// Destructor can do clean-up work that doesn't throw exceptions here.
-ReadStageTest::~ReadStageTest()
-{
-}
-
-// SetUp() will be called immediately before each test.
-void ReadStageTest::SetUp()
-{
-  m_pLinker = new mcld::test::TestLinker();
-  m_pLinker->initialize("arm-none-linux-gnueabi");
-
-  // set up target-dependent constraints of attributes
-  m_pLinker->config()->attribute().constraint().enableWholeArchive();
-  m_pLinker->config()->attribute().constraint().disableAsNeeded();
-  m_pLinker->config()->attribute().constraint().setSharedSystem();
-
-  // set up the predefined attributes
-  m_pLinker->config()->attribute().predefined().setWholeArchive();
-  m_pLinker->config()->attribute().predefined().setDynamic();
-
-  // set up target dependent options
-  mcld::sys::fs::Path path = TOPDIR;
-  path.append("test/libs/ARM/Android/android-14");
-  m_pLinker->setSysRoot(path);
-  m_pLinker->addSearchDir("=/");
-
-  m_pLinker->config()->options().setDyld("/usr/lib/ld.so.1");
-  m_pLinker->config()->options().setBsymbolic(true);
-}
-
-// TearDown() will be called immediately after each test.
-void ReadStageTest::TearDown()
-{
-  delete m_pLinker;
-}
-
-void ReadStageTest::dumpInput(const mcld::Input &pInput, mcld::FileHandle &pFile, size_t pIdent)
-{
-  stringstream sstream;
-  for (size_t i=0; i < pIdent; ++i)
-    sstream << " ";
-  sstream << "<input name=\"" << pInput.name() << "\">\n";
-
-  LDContext::const_sect_iterator sect, sectEnd = pInput.context()->sectEnd();
-  for (sect = pInput.context()->sectBegin(); sect != sectEnd; ++sect) {
-    for (size_t i=0; i < (pIdent+1); ++i)
-      sstream << " ";
-    sstream << "<section name=\"" << (*sect)->name() << "\"/>\n";
-  }
-  for (size_t i=0; i < pIdent; ++i)
-    sstream << " ";
-  sstream << "</input>\n";
-
-  size_t org_size = pFile.size();
-  pFile.truncate(sstream.str().size() + org_size);
-  pFile.write(sstream.str().data(), org_size, sstream.str().size());
-}
-
-void ReadStageTest::dumpOutput(const mcld::Module& pModule, mcld::FileHandle &pFile, size_t pIdent)
-{
-  stringstream sstream;
-  for (size_t i=0; i < pIdent; ++i)
-    sstream << " ";
-  sstream << "<output name=\"" << m_pLinker->module()->name() << "\">\n";
-
-  Module::const_iterator sect, sectEnd = pModule.end();
-  for (sect = pModule.begin(); sect != sectEnd; ++sect) {
-    for (size_t i=0; i < (pIdent+1); ++i)
-      sstream << " ";
-    sstream << "<section name=\"" << (*sect)->name() << "\"/>\n";
-  }
-  for (size_t i=0; i < pIdent; ++i)
-    sstream << " ";
-  sstream << "</output>\n";
-
-  size_t org_size = pFile.size();
-  pFile.truncate(sstream.str().size() + org_size);
-  pFile.write(sstream.str().data(), org_size, sstream.str().size());
-}
-//===----------------------------------------------------------------------===//
-// Testcases
-//===----------------------------------------------------------------------===//
-TEST_F(ReadStageTest, quake) {
-  mcld::sys::fs::Path top_level = TOPDIR;
-
-  // set up output
-  m_pLinker->config()->setCodeGenType(mcld::LinkerConfig::DynObj);
-  m_pLinker->setOutput(top_level + "unittests/plasma.so");
-
-
-  // set up input
-  m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtbegin_so.o");
-  m_pLinker->addObject(top_level + "test/Android/Plasma/ARM/plasma.o");
-  m_pLinker->addNameSpec("m");
-  m_pLinker->addNameSpec("log");
-  m_pLinker->addNameSpec("jnigraphics");
-  m_pLinker->addNameSpec("c");
-  m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtend_so.o");
-
-  // dump status
-  m_pLinker->getObjLinker()->normalize();
-
-  FileHandle file;
-  file.open(top_level + "unittests/read_stage.xml",
-     FileHandle::ReadWrite | FileHandle::Create | FileHandle::Truncate, 0644);
-
-  Module::input_iterator input, inEnd = m_pLinker->module()->input_end();
-  for (input = m_pLinker->module()->input_begin(); input != inEnd; ++input) {
-    dumpInput(**input, file, 1);
-  }
-
-  dumpOutput(*m_pLinker->module(), file, 1);
-  // dump status
-  ASSERT_TRUE(m_pLinker->getObjLinker()->mergeSections());
-}
-
diff --git a/unittests/ReadStageTest.h b/unittests/ReadStageTest.h
deleted file mode 100644
index e799664..0000000
--- a/unittests/ReadStageTest.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===- ReadStageTest.h ----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_UNITTEST_READSTAGE_TEST_H
-#define MCLD_UNITTEST_READSTAGE_TEST_H
-
-#include <gtest.h>
-#include "Linker/TestLinker.h"
-
-namespace mcld {
-namespace test {
-
-class ReadStageTest : public ::testing::Test
-{
-public:
-  // Constructor can do set-up work for all test here.
-  ReadStageTest();
-
-  // Destructor can do clean-up work that doesn't throw exceptions here.
-  virtual ~ReadStageTest();
-
-  // SetUp() will be called immediately before each test.
-  virtual void SetUp();
-
-  // TearDown() will be called immediately after each test.
-  virtual void TearDown();
-
-  void dumpInput(const mcld::Input &pInput, mcld::FileHandle &pFile, size_t pIdent);
-
-  void dumpOutput(const mcld::Module &pModule, mcld::FileHandle &pFile, size_t pIdent);
-protected:
-  TestLinker* m_pLinker;
-};
-
-} // end of namespace test
-} // end of namespace mcld
-
-#endif
-
diff --git a/unittests/SectionDataTest.cpp b/unittests/SectionDataTest.cpp
index 5113068..dfabc15 100644
--- a/unittests/SectionDataTest.cpp
+++ b/unittests/SectionDataTest.cpp
@@ -60,9 +60,8 @@
   new Fragment(Fragment::Alignment, s);
   new Fragment(Fragment::Region, s);
   new Fragment(Fragment::Fillment, s);
-  new Fragment(Fragment::Relocation, s);
   new Fragment(Fragment::Target, s);
-  EXPECT_TRUE(6 == s->size());
+  EXPECT_TRUE(5 == s->size());
 
   //iterator
   llvm::iplist<Fragment>::iterator iter=s->begin();
@@ -74,8 +73,6 @@
   ++iter;
   EXPECT_TRUE(Fragment::Fillment == iter->getKind());
   ++iter;
-  EXPECT_TRUE(Fragment::Relocation == iter->getKind());
-  ++iter;
   EXPECT_TRUE(Fragment::Target == iter->getKind());
   ++iter;
   EXPECT_TRUE(iter == s->end());
diff --git a/unittests/StaticResolverTest.cpp b/unittests/StaticResolverTest.cpp
index cb4c668..bd40cd5 100644
--- a/unittests/StaticResolverTest.cpp
+++ b/unittests/StaticResolverTest.cpp
@@ -26,8 +26,6 @@
   // create testee. modify it if need
   m_pResolver = new StaticResolver();
 
-  mcld::InitializeAllDiagnostics();
-
   m_pConfig = new LinkerConfig("arm-none-linux-gnueabi");
 }
 
diff --git a/unittests/TestLinkerTest.cpp b/unittests/TestLinkerTest.cpp
deleted file mode 100644
index 0b1a141..0000000
--- a/unittests/TestLinkerTest.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-//===- TestLinkerTest.cpp -------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include "Linker/TestLinker.h"
-#include "TestLinkerTest.h"
-
-#include <mcld/Support/Path.h>
-#include <mcld/MC/MCLDDirectory.h>
-#include <mcld/MC/InputFactory.h>
-
-using namespace mcld;
-using namespace mcld::test;
-using namespace mcld::sys::fs;
-using namespace mcldtest;
-
-
-// Constructor can do set-up work for all test here.
-TestLinkerTest::TestLinkerTest()
-  : m_pLinker(NULL) {
-}
-
-// Destructor can do clean-up work that doesn't throw exceptions here.
-TestLinkerTest::~TestLinkerTest()
-{
-}
-
-// SetUp() will be called immediately before each test.
-void TestLinkerTest::SetUp()
-{
-  m_pLinker = new mcld::test::TestLinker();
-  m_pLinker->initialize("arm-none-linux-gnueabi");
-
-  // set up target-dependent constraints of attributes
-  m_pLinker->config()->attribute().constraint().enableWholeArchive();
-  m_pLinker->config()->attribute().constraint().disableAsNeeded();
-  m_pLinker->config()->attribute().constraint().setSharedSystem();
-
-  // set up the predefined attributes
-  m_pLinker->config()->attribute().predefined().setWholeArchive();
-  m_pLinker->config()->attribute().predefined().setDynamic();
-
-  // set up target dependent options
-  mcld::sys::fs::Path path = TOPDIR;
-  path.append("test/libs/ARM/Android/android-14");
-  m_pLinker->setSysRoot(path);
-  m_pLinker->addSearchDir("=/");
-
-  m_pLinker->config()->options().setDyld("/usr/lib/ld.so.1");
-  m_pLinker->config()->options().setBsymbolic(true);
-}
-
-// TearDown() will be called immediately after each test.
-void TestLinkerTest::TearDown()
-{
-  delete m_pLinker;
-}
-
-//===----------------------------------------------------------------------===//
-// Testcases
-//===----------------------------------------------------------------------===//
-TEST_F( TestLinkerTest, test) {
-  m_pLinker->config()->options().setVerbose(3);
-  mcld::sys::fs::Path top_level = TOPDIR;
-  m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtbegin_so.o");
-  m_pLinker->addObject(top_level + "test/Android/Plasma/ARM/plasma.o");
-  m_pLinker->addNameSpec("m");
-  m_pLinker->addNameSpec("log");
-  m_pLinker->addNameSpec("jnigraphics");
-  m_pLinker->addNameSpec("c");
-  m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtend_so.o");
-}
-
diff --git a/unittests/TestLinkerTest.h b/unittests/TestLinkerTest.h
deleted file mode 100644
index ba6efcf..0000000
--- a/unittests/TestLinkerTest.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===- TestLinkerTest.h ---------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_TEST_LINKER_TEST_H
-#define MCLD_TEST_LINKER_TEST_H
-#include <gtest.h>
-
-#include "Linker/TestLinker.h"
-
-namespace mcldtest
-{
-
-class TestLinkerTest : public ::testing::Test
-{
-public:
-  // Constructor can do set-up work for all test here.
-  TestLinkerTest();
-
-  // Destructor can do clean-up work that doesn't throw exceptions here.
-  virtual ~TestLinkerTest();
-
-  // SetUp() will be called immediately before each test.
-  virtual void SetUp();
-
-  // TearDown() will be called immediately after each test.
-  virtual void TearDown();
-
-protected:
-  mcld::test::TestLinker* m_pLinker;
-};
-
-} // namespace of mcldtest
-
-#endif
-
diff --git a/unittests/UniqueGCFactoryBaseTest.cpp b/unittests/UniqueGCFactoryBaseTest.cpp
index f8e098a..45a2aca 100644
--- a/unittests/UniqueGCFactoryBaseTest.cpp
+++ b/unittests/UniqueGCFactoryBaseTest.cpp
@@ -19,8 +19,6 @@
 // Constructor can do set-up work for all test here.
 UniqueGCFactoryBaseTest::UniqueGCFactoryBaseTest()
 {
-  InitializeAllDiagnostics();
-
   m_pConfig = new LinkerConfig("arm-none-linux-gnueabi");
 }