Merge "Update mclinker with upstream patches"
diff --git a/include/mcld/GeneralOptions.h b/include/mcld/GeneralOptions.h
index 165c027..787c5eb 100644
--- a/include/mcld/GeneralOptions.h
+++ b/include/mcld/GeneralOptions.h
@@ -27,16 +27,26 @@
  */
 class GeneralOptions {
  public:
-  enum StripSymbolMode {
+  enum class StripSymbolMode {
     KeepAllSymbols,
     StripTemporaries,
     StripLocals,
     StripAllSymbols
   };
 
-  enum HashStyle { SystemV = 0x1, GNU = 0x2, Both = 0x3 };
+  enum class HashStyle : uint8_t {
+    Unknown = 0x0,
+    SystemV = 0x1,
+    GNU = 0x2,
+    Both = 0x3
+  };
 
-  enum ICF { ICF_None, ICF_All, ICF_Safe };
+  enum class ICF {
+    Unknown,
+    None,
+    All,
+    Safe
+  };
 
   typedef std::vector<std::string> RpathList;
   typedef RpathList::iterator rpath_iterator;
@@ -246,9 +256,17 @@
 
   int getGPSize() const { return m_GPSize; }
 
-  unsigned int getHashStyle() const { return m_HashStyle; }
+  HashStyle getHashStyle() const { return m_HashStyle; }
 
-  void setHashStyle(unsigned int pStyle) { m_HashStyle = pStyle; }
+  bool hasGNUHash() const {
+    return m_HashStyle == HashStyle::GNU || m_HashStyle == HashStyle::Both;
+  }
+
+  bool hasSysVHash() const {
+    return m_HashStyle == HashStyle::SystemV || m_HashStyle == HashStyle::Both;
+  }
+
+  void setHashStyle(HashStyle pStyle) { m_HashStyle = pStyle; }
 
   ICF getICFMode() const { return m_ICF; }
 
@@ -260,7 +278,7 @@
 
   bool printICFSections() const { return m_bPrintICFSections; }
 
-  void setPrintICFSections(bool pPrintICFSections) {
+  void setPrintICFSections(bool pPrintICFSections = true) {
     m_bPrintICFSections = pPrintICFSections;
   }
 
@@ -375,7 +393,7 @@
   RpathList m_RpathList;
   ScriptList m_ScriptList;
   UndefSymList m_UndefSymList;  // -u [symbol], --undefined [symbol]
-  unsigned int m_HashStyle;
+  HashStyle m_HashStyle;
   std::string m_Filter;
   AuxiliaryList m_AuxiliaryList;
   ExcludeLIBS m_ExcludeLIBS;
diff --git a/include/mcld/LD/DiagReaders.inc b/include/mcld/LD/DiagReaders.inc
index 2409946..4384420 100644
--- a/include/mcld/LD/DiagReaders.inc
+++ b/include/mcld/LD/DiagReaders.inc
@@ -12,5 +12,5 @@
      "cannot scan .eh_frame section in input %0.")
 DIAG(fatal_cannot_read_input,
      DiagnosticEngine::Fatal,
-     "cannot read input input %0",
+     "cannot read input %0",
      "cannot read input %0")
diff --git a/include/mcld/LinkerScript.h b/include/mcld/LinkerScript.h
index 3e2737e..3d984c3 100644
--- a/include/mcld/LinkerScript.h
+++ b/include/mcld/LinkerScript.h
@@ -18,6 +18,7 @@
 #include "mcld/Script/Assignment.h"
 
 #include <llvm/ADT/StringRef.h>
+#include <llvm/ADT/SmallVector.h>
 
 #include <string>
 #include <vector>
@@ -43,6 +44,8 @@
 
   typedef std::vector<AssertCmd> Assertions;
 
+  typedef llvm::SmallVector<std::string, 8> DefSyms;
+
  public:
   LinkerScript();
 
@@ -63,6 +66,9 @@
   const Assertions& assertions() const { return m_Assertions; }
   Assertions& assertions() { return m_Assertions; }
 
+  const DefSyms& defsyms() const { return m_DefSyms; }
+  DefSyms& defsyms() { return m_DefSyms; }
+
   /// search directory
   const SearchDirs& directories() const { return m_SearchDirs; }
   SearchDirs& directories() { return m_SearchDirs; }
@@ -94,6 +100,7 @@
   SectionMap m_SectionMap;
   Assignments m_Assignments;
   Assertions m_Assertions;
+  DefSyms m_DefSyms;
   SearchDirs m_SearchDirs;
   std::string m_Entry;
   std::string m_OutputFile;
diff --git a/include/mcld/MC/CommandAction.h b/include/mcld/MC/CommandAction.h
index 85f3e2b..b1764d4 100644
--- a/include/mcld/MC/CommandAction.h
+++ b/include/mcld/MC/CommandAction.h
@@ -151,14 +151,14 @@
 /// DefSymAction
 class DefSymAction : public InputAction {
  public:
-  explicit DefSymAction(unsigned int pPosition, std::string& pAssignment);
+  explicit DefSymAction(unsigned int pPosition, const std::string& pAssignment);
 
   bool activate(InputBuilder&) const;
 
   const std::string& assignment() const { return m_Assignment; }
 
  private:
-  std::string& m_Assignment;
+  const std::string& m_Assignment;
 };
 
 /// ScriptAction
diff --git a/include/mcld/Support/CXADemangle.tcc b/include/mcld/Support/CXADemangle.tcc
index 4e66f84..e89bfec 100644
--- a/include/mcld/Support/CXADemangle.tcc
+++ b/include/mcld/Support/CXADemangle.tcc
@@ -1572,10 +1572,8 @@
         const char* t = first+1;
         if (t != last)
         {
-            bool externC = false;
             if (*t == 'Y')
             {
-                externC = true;
                 if (++t == last)
                     return first;
             }
diff --git a/include/mcld/Support/CommandLine.h b/include/mcld/Support/CommandLine.h
deleted file mode 100644
index 3474ce6..0000000
--- a/include/mcld/Support/CommandLine.h
+++ /dev/null
@@ -1,106 +0,0 @@
-//===- CommandLine.h ------------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_COMMANDLINE_H_
-#define MCLD_SUPPORT_COMMANDLINE_H_
-#include "mcld/MC/ZOption.h"
-#include "mcld/Support/FileSystem.h"
-
-#include <llvm/ADT/StringRef.h>
-#include <llvm/ADT/Triple.h>
-#include <llvm/Support/CommandLine.h>
-
-#include <string>
-
-namespace llvm {
-namespace cl {
-
-//===----------------------------------------------------------------------===//
-// SearchDirParser
-//===----------------------------------------------------------------------===//
-class SearchDirParser final : public basic_parser<std::string> {
- public:
-  explicit SearchDirParser(Option &O) : basic_parser(O) { }
-
-  // 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();
-};
-
-#if 0
-//===----------------------------------------------------------------------===//
-// FalseParser
-//===----------------------------------------------------------------------===//
-class FalseParser : public parser<bool> {
- public:
-  explicit FalseParser(Option &O) : parser<bool>(O) { }
-
-  // parse - Return true on error.
-  bool parse(cl::Option& O, StringRef ArgName, StringRef Arg, bool& Val) {
-    if (cl::parser<bool>::parse(O, ArgName, Arg, Val))
-      return false;
-    Val = false;
-    return false;
-  }
-};
-#endif
-
-//===----------------------------------------------------------------------===//
-// parser<mcld::sys::fs::Path>
-//===----------------------------------------------------------------------===//
-template <>
-class parser<mcld::sys::fs::Path> final : public basic_parser<mcld::sys::fs::Path> {
- public:
-  explicit parser(Option &O) : basic_parser(O) { }
-
-  bool parse(Option& O,
-             StringRef ArgName,
-             StringRef Arg,
-             mcld::sys::fs::Path& Val);
-
-  virtual const char* getValueName() const { return "path"; }
-  void printOptionDiff(const Option& O,
-                       const mcld::sys::fs::Path& V,
-                       OptVal Default,
-                       size_t GlobalWidth) const;
-  virtual void anchor();
-};
-
-//===----------------------------------------------------------------------===//
-// parser<mcld::ZOption>
-//===----------------------------------------------------------------------===//
-template <>
-class parser<mcld::ZOption> final : public basic_parser<mcld::ZOption> {
- public:
-  explicit parser(Option &O) : basic_parser(O) { }
-
-  bool parse(Option& O, StringRef ArgName, StringRef Arg, mcld::ZOption& Val);
-
-  virtual const char* getValueName() const { return "z-option"; }
-  void printOptionDiff(const Option& O,
-                       const mcld::ZOption& V,
-                       OptVal Default,
-                       size_t GlobalWidth) const;
-  virtual void anchor();
-};
-
-}  // namespace cl
-}  // namespace llvm
-
-#endif  // MCLD_SUPPORT_COMMANDLINE_H_
diff --git a/lib/Core/GeneralOptions.cpp b/lib/Core/GeneralOptions.cpp
index 6f7b57f..1996acf 100644
--- a/lib/Core/GeneralOptions.cpp
+++ b/lib/Core/GeneralOptions.cpp
@@ -20,7 +20,7 @@
     : m_Verbose(-1),
       m_MaxErrorNum(-1),
       m_MaxWarnNum(-1),
-      m_NumSpareDTags(1),
+      m_NumSpareDTags(5),
       m_ExecStack(Unknown),
       m_NoUndefined(Unknown),
       m_MulDefs(Unknown),
@@ -59,11 +59,11 @@
       m_bPrintGCSections(false),
       m_bGenUnwindInfo(true),
       m_bPrintICFSections(false),
-      m_ICF(ICF_None),
-      m_ICFIterations(0),
+      m_ICF(ICF::None),
+      m_ICFIterations(2),
       m_GPSize(8),
-      m_StripSymbols(KeepAllSymbols),
-      m_HashStyle(SystemV) {
+      m_StripSymbols(StripSymbolMode::KeepAllSymbols),
+      m_HashStyle(HashStyle::SystemV) {
 }
 
 GeneralOptions::~GeneralOptions() {
diff --git a/lib/LD/IdenticalCodeFolding.cpp b/lib/LD/IdenticalCodeFolding.cpp
index 7e047d3..527dccb 100644
--- a/lib/LD/IdenticalCodeFolding.cpp
+++ b/lib/LD/IdenticalCodeFolding.cpp
@@ -137,7 +137,7 @@
           }
 
           // Safe icf
-          if (m_Config.options().getICFMode() == GeneralOptions::ICF_Safe) {
+          if (m_Config.options().getICFMode() == GeneralOptions::ICF::Safe) {
             RelocData::iterator rel, relEnd = (*sect)->getRelocData()->end();
             for (rel = (*sect)->getRelocData()->begin(); rel != relEnd; ++rel) {
               LDSymbol* sym = rel->symInfo()->outSymbol();
@@ -166,7 +166,7 @@
     CandidateMap::iterator candidate, candidateEnd = candidate_map.end();
     for (candidate = candidate_map.begin(); candidate != candidateEnd;
          ++candidate) {
-      if ((m_Config.options().getICFMode() == GeneralOptions::ICF_All) ||
+      if ((m_Config.options().getICFMode() == GeneralOptions::ICF::All) ||
           (funcptr_access_set.count(candidate->first) == 0)) {
         size_t index = m_KeptSections.size();
         m_KeptSections[candidate->first] = ObjectAndId(*obj, index);
diff --git a/lib/MC/CommandAction.cpp b/lib/MC/CommandAction.cpp
index 4439d7e..37ded34 100644
--- a/lib/MC/CommandAction.cpp
+++ b/lib/MC/CommandAction.cpp
@@ -214,7 +214,8 @@
 //===----------------------------------------------------------------------===//
 // DefSymAction
 //===----------------------------------------------------------------------===//
-DefSymAction::DefSymAction(unsigned int pPosition, std::string& pAssignment)
+DefSymAction::DefSymAction(unsigned int pPosition,
+                           const std::string& pAssignment)
     : InputAction(pPosition), m_Assignment(pAssignment) {
 }
 
@@ -223,8 +224,9 @@
   Input* input = *pBuilder.getCurrentNode();
   pBuilder.setContext(*input, false);
 
-  m_Assignment.append(";");
-  pBuilder.setMemory(*input, &m_Assignment[0], m_Assignment.size());
+  // FIXME
+  void* base = static_cast<void*>(const_cast<char*>(m_Assignment.data()));
+  pBuilder.setMemory(*input, base, m_Assignment.size());
   return true;
 }
 
diff --git a/lib/Object/ObjectLinker.cpp b/lib/Object/ObjectLinker.cpp
index 801cbaf..4d8ffeb 100644
--- a/lib/Object/ObjectLinker.cpp
+++ b/lib/Object/ObjectLinker.cpp
@@ -273,7 +273,7 @@
   }
 
   // Identical code folding
-  if (m_Config.options().getICFMode() != GeneralOptions::ICF_None) {
+  if (m_Config.options().getICFMode() != GeneralOptions::ICF::None) {
     IdenticalCodeFolding icf(m_Config, m_LDBackend, *m_pModule);
     icf.foldIdenticalCode();
   }
diff --git a/lib/Script/CMakeLists.txt b/lib/Script/CMakeLists.txt
index 1426a23..c2bb146 100644
--- a/lib/Script/CMakeLists.txt
+++ b/lib/Script/CMakeLists.txt
@@ -6,7 +6,7 @@
 ADD_FLEX_BISON_DEPENDENCY(LEXER PARSER)
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
-add_mcld_library(MCLDScript
+add_llvm_library(MCLDScript
   AssertCmd.cpp
   Assignment.cpp
   BinaryOp.cpp
diff --git a/lib/Support/Android.mk b/lib/Support/Android.mk
index ad36732..54cfc22 100644
--- a/lib/Support/Android.mk
+++ b/lib/Support/Android.mk
@@ -1,7 +1,6 @@
 LOCAL_PATH:= $(call my-dir)
 
 mcld_support_SRC_FILES := \
-  CommandLine.cpp \
   Demangle.cpp \
   Directory.cpp \
   FileHandle.cpp \
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
deleted file mode 100644
index 15e739c..0000000
--- a/lib/Support/CommandLine.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-//===- CommandLine.cpp ----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include "mcld/Support/CommandLine.h"
-
-#include <llvm/ADT/StringRef.h>
-#include <llvm/ADT/StringSwitch.h>
-#include <llvm/ADT/Twine.h>
-#include <llvm/Support/ErrorHandling.h>
-
-static const size_t MaxOptWidth = 8;  // arbitrary spacing for printOptionDiff
-
-namespace llvm {
-namespace cl {
-
-//===----------------------------------------------------------------------===//
-// 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>
-//===----------------------------------------------------------------------===//
-bool parser<mcld::sys::fs::Path>::parse(llvm::cl::Option& O,
-                                        llvm::StringRef ArgName,
-                                        llvm::StringRef Arg,
-                                        mcld::sys::fs::Path& Val) {
-  Val.assign<llvm::StringRef::const_iterator>(Arg.begin(), Arg.end());
-  return false;
-}
-
-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,
-    size_t GlobalWidth) const {
-  printOptionName(O, GlobalWidth);
-  outs() << "= " << V;
-  size_t VSize = V.native().size();
-  size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;
-  outs().indent(NumSpaces) << " (default: ";
-  if (Default.hasValue())
-    outs() << Default.getValue().c_str();
-  else
-    outs() << "*no default*";
-  outs() << ")\n";
-}
-
-void parser<mcld::sys::fs::Path>::anchor() {
-  // do nothing
-}
-
-//===----------------------------------------------------------------------===//
-// parser<mcld::ZOption>
-//===----------------------------------------------------------------------===//
-bool parser<mcld::ZOption>::parse(llvm::cl::Option& O,
-                                  llvm::StringRef ArgName,
-                                  llvm::StringRef Arg,
-                                  mcld::ZOption& Val) {
-  if (Arg.equals("combreloc"))
-    Val.setKind(mcld::ZOption::CombReloc);
-  else if (Arg.equals("nocombreloc"))
-    Val.setKind(mcld::ZOption::NoCombReloc);
-  else if (Arg.equals("defs"))
-    Val.setKind(mcld::ZOption::Defs);
-  else if (Arg.equals("execstack"))
-    Val.setKind(mcld::ZOption::ExecStack);
-  else if (Arg.equals("noexecstack"))
-    Val.setKind(mcld::ZOption::NoExecStack);
-  else if (Arg.equals("initfirst"))
-    Val.setKind(mcld::ZOption::InitFirst);
-  else if (Arg.equals("interpose"))
-    Val.setKind(mcld::ZOption::InterPose);
-  else if (Arg.equals("loadfltr"))
-    Val.setKind(mcld::ZOption::LoadFltr);
-  else if (Arg.equals("muldefs"))
-    Val.setKind(mcld::ZOption::MulDefs);
-  else if (Arg.equals("nocopyreloc"))
-    Val.setKind(mcld::ZOption::NoCopyReloc);
-  else if (Arg.equals("nodefaultlib"))
-    Val.setKind(mcld::ZOption::NoDefaultLib);
-  else if (Arg.equals("nodelete"))
-    Val.setKind(mcld::ZOption::NoDelete);
-  else if (Arg.equals("nodlopen"))
-    Val.setKind(mcld::ZOption::NoDLOpen);
-  else if (Arg.equals("nodump"))
-    Val.setKind(mcld::ZOption::NoDump);
-  else if (Arg.equals("relro"))
-    Val.setKind(mcld::ZOption::Relro);
-  else if (Arg.equals("norelro"))
-    Val.setKind(mcld::ZOption::NoRelro);
-  else if (Arg.equals("lazy"))
-    Val.setKind(mcld::ZOption::Lazy);
-  else if (Arg.equals("now"))
-    Val.setKind(mcld::ZOption::Now);
-  else if (Arg.equals("origin"))
-    Val.setKind(mcld::ZOption::Origin);
-  else if (Arg.startswith("common-page-size=")) {
-    Val.setKind(mcld::ZOption::CommPageSize);
-    long long unsigned size = 0;
-    Arg.drop_front(17).getAsInteger(0, size);
-    Val.setPageSize(static_cast<uint64_t>(size));
-  } else if (Arg.startswith("max-page-size=")) {
-    Val.setKind(mcld::ZOption::MaxPageSize);
-    long long unsigned size = 0;
-    Arg.drop_front(14).getAsInteger(0, size);
-    Val.setPageSize(static_cast<uint64_t>(size));
-  }
-
-  if (mcld::ZOption::Unknown == Val.kind())
-    llvm::report_fatal_error(llvm::Twine("unknown -z option: `") + Arg +
-                             llvm::Twine("'\n"));
-  return false;
-}
-
-void parser<mcld::ZOption>::printOptionDiff(
-    const llvm::cl::Option& O,
-    const mcld::ZOption& V,
-    parser<mcld::ZOption>::OptVal Default,
-    size_t GlobalWidth) const {
-  // TODO
-}
-
-void parser<mcld::ZOption>::anchor() {
-  // do nothing
-}
-
-}  // namespace cl
-}  // namespace llvm
diff --git a/lib/Target/ARM/ARMLDBackend.cpp b/lib/Target/ARM/ARMLDBackend.cpp
index 5d7bc56..0907cac 100644
--- a/lib/Target/ARM/ARMLDBackend.cpp
+++ b/lib/Target/ARM/ARMLDBackend.cpp
@@ -693,8 +693,8 @@
                                                   *getBRIslandFactory());
             if (stub != NULL) {
               switch (config().options().getStripSymbolMode()) {
-                case GeneralOptions::StripAllSymbols:
-                case GeneralOptions::StripLocals:
+                case GeneralOptions::StripSymbolMode::StripAllSymbols:
+                case GeneralOptions::StripSymbolMode::StripLocals:
                   break;
                 default: {
                   // a stub symbol should be local
diff --git a/lib/Target/GNULDBackend.cpp b/lib/Target/GNULDBackend.cpp
index db612c1..79fa25f 100644
--- a/lib/Target/GNULDBackend.cpp
+++ b/lib/Target/GNULDBackend.cpp
@@ -737,7 +737,7 @@
        2. check whether the symbol is used
    */
   switch (config().options().getStripSymbolMode()) {
-    case GeneralOptions::StripAllSymbols: {
+    case GeneralOptions::StripSymbolMode::StripAllSymbols: {
       symtab = strtab = 0;
       break;
     }
@@ -775,8 +775,7 @@
         dynsym_local_cnt = 1 + symbols.numOfLocalDyns();
 
         // compute .gnu.hash
-        if (GeneralOptions::GNU == config().options().getHashStyle() ||
-            GeneralOptions::Both == config().options().getHashStyle()) {
+        if (config().options().hasGNUHash()) {
           // count the number of dynsym to hash
           size_t hashed_sym_cnt = 0;
           symEnd = symbols.dynamicEnd();
@@ -795,8 +794,7 @@
         }
 
         // compute .hash
-        if (GeneralOptions::SystemV == config().options().getHashStyle() ||
-            GeneralOptions::Both == config().options().getHashStyle()) {
+        if (config().options().hasSysVHash()) {
           // Both Elf32_Word and Elf64_Word are 4 bytes
           hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
                  sizeof(llvm::ELF::Elf32_Word);
@@ -1026,13 +1024,11 @@
 
   Module::SymbolTable& symbols = pModule.getSymbolTable();
   // emit .gnu.hash
-  if (GeneralOptions::GNU == config().options().getHashStyle() ||
-      GeneralOptions::Both == config().options().getHashStyle())
+  if (config().options().hasGNUHash())
     emitGNUHashTab(symbols, pOutput);
 
   // emit .hash
-  if (GeneralOptions::SystemV == config().options().getHashStyle() ||
-      GeneralOptions::Both == config().options().getHashStyle())
+  if (config().options().hasSysVHash())
     emitELFHashTab(symbols, pOutput);
 
   // emit .dynsym, and .dynstr (emit LocalDyn and Dynamic category)
@@ -1296,13 +1292,13 @@
 void GNULDBackend::orderSymbolTable(Module& pModule) {
   Module::SymbolTable& symbols = pModule.getSymbolTable();
 
-  if (GeneralOptions::GNU == config().options().getHashStyle() ||
-      GeneralOptions::Both == config().options().getHashStyle())
+  if (config().options().hasGNUHash()) {
     // Currently we may add output symbols after sizeNamePools(), and a
     // non-stable sort is used in SymbolCategory::arrange(), so we just
     // sort .dynsym right before emitting .gnu.hash
     std::stable_sort(
         symbols.dynamicBegin(), symbols.dynamicEnd(), DynsymCompare());
+  }
 }
 
 /// getSectionOrder
diff --git a/lib/Target/Mips/MipsLDBackend.cpp b/lib/Target/Mips/MipsLDBackend.cpp
index 63eeaf9..c629edd 100644
--- a/lib/Target/Mips/MipsLDBackend.cpp
+++ b/lib/Target/Mips/MipsLDBackend.cpp
@@ -287,8 +287,7 @@
 }  // anonymous namespace
 
 void MipsGNULDBackend::orderSymbolTable(Module& pModule) {
-  if (GeneralOptions::GNU == config().options().getHashStyle() ||
-      GeneralOptions::Both == config().options().getHashStyle()) {
+  if (config().options().hasGNUHash()) {
     // The MIPS ABI and .gnu.hash require .dynsym to be sorted
     // in different ways. The MIPS ABI requires a mapping between
     // the GOT and the symbol table. At the same time .gnu.hash
diff --git a/tools/mcld/Android.mk b/tools/mcld/Android.mk
index 8dcb836..a9e3dc6 100644
--- a/tools/mcld/Android.mk
+++ b/tools/mcld/Android.mk
@@ -8,17 +8,7 @@
 MCLD_C_INCLUDES := $(LOCAL_PATH)/include
 
 MCLD_SRC_FILES := \
-  main.cpp \
-  lib/DynamicSectionOptions.cpp \
-  lib/OptimizationOptions.cpp \
-  lib/OutputFormatOptions.cpp \
-  lib/PositionalOptions.cpp \
-  lib/PreferenceOptions.cpp \
-  lib/ScriptOptions.cpp \
-  lib/SearchPathOptions.cpp \
-  lib/SymbolOptions.cpp \
-  lib/TargetControlOptions.cpp \
-  lib/TripleOptions.cpp
+  Main.cpp
 
 
 MCLD_WHOLE_STATIC_LIBRARIES := \
@@ -43,9 +33,10 @@
 
 MCLD_MODULE:= ld.mc
 
-# Executable the device
+# Executable for the device
 # =====================================================
 include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
 
 LOCAL_C_INCLUDES := $(MCLD_C_INCLUDES)
 LOCAL_SRC_FILES := $(MCLD_SRC_FILES)
@@ -77,12 +68,21 @@
 LOCAL_SHARED_LIBRARIES := $(MCLD_SHARED_LIBRARIES) libz
 
 LOCAL_MODULE := $(MCLD_MODULE)
+LOCAL_MODULE_CLASS := EXECUTABLES
+
+# Build Options.inc from Options.td for the device
+intermediates := $(call local-generated-sources-dir)
+LOCAL_GENERATED_SOURCES += $(intermediates)/Options.inc
+$(intermediates)/Options.inc: $(LOCAL_PATH)/Options.td $(LLVM_ROOT_PATH)/include/llvm/Option/OptParser.td $(LLVM_TBLGEN)
+	$(call transform-device-td-to-out,opt-parser-defs)
+
 include $(MCLD_DEVICE_BUILD_MK)
 include $(BUILD_EXECUTABLE)
 
-# Executable the host
+# Executable for the host
 # =====================================================
 include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
 
 LOCAL_C_INCLUDES := $(MCLD_C_INCLUDES)
 LOCAL_SRC_FILES := $(MCLD_SRC_FILES)
@@ -98,5 +98,14 @@
 LOCAL_SHARED_LIBRARIES := $(MCLD_SHARED_LIBRARIES) libz-host
 
 LOCAL_MODULE := $(MCLD_MODULE)
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_IS_HOST_MODULE := true
+
+# Build Options.inc from Options.td for the host
+intermediates := $(call local-generated-sources-dir)
+LOCAL_GENERATED_SOURCES += $(intermediates)/Options.inc
+$(intermediates)/Options.inc: $(LOCAL_PATH)/Options.td $(LLVM_ROOT_PATH)/include/llvm/Option/OptParser.td $(LLVM_TBLGEN)
+	$(call transform-host-td-to-out,opt-parser-defs)
+
 include $(MCLD_HOST_BUILD_MK)
 include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/mcld/Main.cpp b/tools/mcld/Main.cpp
new file mode 100644
index 0000000..7231d3c
--- /dev/null
+++ b/tools/mcld/Main.cpp
@@ -0,0 +1,1064 @@
+//===- Main.cpp -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Environment.h>
+#include <mcld/IRBuilder.h>
+#include <mcld/Linker.h>
+#include <mcld/LinkerConfig.h>
+#include <mcld/LinkerScript.h>
+#include <mcld/Module.h>
+#include <mcld/ADT/StringEntry.h>
+#include <mcld/MC/InputAction.h>
+#include <mcld/MC/CommandAction.h>
+#include <mcld/MC/FileAction.h>
+#include <mcld/MC/ZOption.h>
+#include <mcld/Support/raw_ostream.h>
+#include <mcld/Support/MsgHandling.h>
+#include <mcld/Support/Path.h>
+#include <mcld/Support/SystemUtils.h>
+#include <mcld/Support/TargetRegistry.h>
+
+#include <llvm/ADT/ArrayRef.h>
+#include <llvm/ADT/SmallVector.h>
+#include <llvm/ADT/STLExtras.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/ADT/StringSwitch.h>
+#include <llvm/Option/Arg.h>
+#include <llvm/Option/ArgList.h>
+#include <llvm/Option/OptTable.h>
+#include <llvm/Option/Option.h>
+#include <llvm/Support/ManagedStatic.h>
+#include <llvm/Support/Process.h>
+#include <llvm/Support/Signals.h>
+
+#include <cassert>
+#include <cstdlib>
+#include <string>
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#include <io.h>
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+#endif
+
+namespace {
+
+class Driver {
+ private:
+  enum Option {
+    // This is not an option.
+    kOpt_INVALID = 0,
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+               HELPTEXT, METAVAR) \
+    kOpt_ ## ID,
+#include "Options.inc"  // NOLINT
+#undef OPTION
+    kOpt_LastOption
+  };
+
+  class OptTable : public llvm::opt::OptTable {
+   private:
+#define PREFIX(NAME, VALUE) \
+    static const char* const NAME[];
+#include "Options.inc"  // NOLINT
+#undef PREFIX
+    static const llvm::opt::OptTable::Info InfoTable[];
+
+   public:
+    OptTable();
+  };
+
+ private:
+  Driver(const char* prog_name, std::unique_ptr<llvm::opt::InputArgList> args)
+      : prog_name_(prog_name),
+        args_(std::move(args)),
+        module_(script_),
+        ir_builder_(module_, config_) {
+    return;
+  }
+
+ public:
+  static std::unique_ptr<Driver> Create(llvm::ArrayRef<const char*> argv);
+
+  bool Run();
+
+ private:
+  bool TranslateArguments();
+
+ private:
+  const char* prog_name_;
+
+  std::unique_ptr<llvm::opt::InputArgList> args_;
+
+  mcld::LinkerScript script_;
+
+  mcld::LinkerConfig config_;
+
+  mcld::Module module_;
+
+  mcld::IRBuilder ir_builder_;
+
+  mcld::Linker linker_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Driver);
+};
+
+#define PREFIX(NAME, VALUE) \
+    const char* const Driver::OptTable::NAME[] = VALUE;
+#include "Options.inc"  // NOLINT
+#undef PREFIX
+
+const llvm::opt::OptTable::Info Driver::OptTable::InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+               HELPTEXT, METAVAR) \
+    { PREFIX, NAME, HELPTEXT, METAVAR, kOpt_ ## ID, \
+      llvm::opt::Option::KIND ## Class, PARAM, FLAGS, kOpt_ ## GROUP, \
+      kOpt_ ## ALIAS, ALIASARGS },
+#include "Options.inc"
+#undef OPTION
+};
+
+Driver::OptTable::OptTable()
+    : llvm::opt::OptTable(InfoTable, llvm::array_lengthof(InfoTable)) { }
+
+inline bool ShouldColorize() {
+  const char* term = getenv("TERM");
+  return term && (0 != strcmp(term, "dumb"));
+}
+
+/// 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.
+inline std::string ParseProgName(const char* prog_name) {
+  static const char* suffixes[] = {"ld", "ld.mcld"};
+
+  std::string name(mcld::sys::fs::Path(prog_name).stem().native());
+
+  for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
+    if (name == suffixes[i])
+      return std::string();
+  }
+
+  llvm::StringRef prog_name_ref(prog_name);
+  llvm::StringRef prefix;
+
+  for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
+    if (!prog_name_ref.endswith(suffixes[i]))
+      continue;
+
+    llvm::StringRef::size_type last_component =
+        prog_name_ref.rfind('-', prog_name_ref.size() - strlen(suffixes[i]));
+    if (last_component == llvm::StringRef::npos)
+      continue;
+    llvm::StringRef prefix = prog_name_ref.slice(0, last_component);
+    std::string ignored_error;
+    if (!mcld::TargetRegistry::lookupTarget(prefix, ignored_error))
+      continue;
+    return prefix.str();
+  }
+  return std::string();
+}
+
+inline void ParseEmulation(llvm::Triple& triple, const char* emulation) {
+  llvm::Triple emu_triple =
+      llvm::StringSwitch<llvm::Triple>(emulation)
+          .Case("aarch64linux", llvm::Triple("aarch64", "", "linux", "gnu"))
+          .Case("armelf_linux_eabi", llvm::Triple("arm", "", "linux", "gnu"))
+          .Case("elf_i386", llvm::Triple("i386", "", "", "gnu"))
+          .Case("elf_x86_64", llvm::Triple("x86_64", "", "", "gnu"))
+          .Case("elf32_x86_64", llvm::Triple("x86_64", "", "", "gnux32"))
+          .Case("elf_i386_fbsd", llvm::Triple("i386", "", "freebsd", "gnu"))
+          .Case("elf_x86_64_fbsd", llvm::Triple("x86_64", "", "freebsd", "gnu"))
+          .Case("elf32ltsmip", llvm::Triple("mipsel", "", "", "gnu"))
+          .Case("elf64ltsmip", llvm::Triple("mips64el", "", "", "gnu"))
+          .Default(llvm::Triple());
+
+  if (emu_triple.getArch() == llvm::Triple::UnknownArch &&
+      emu_triple.getOS() == llvm::Triple::UnknownOS &&
+      emu_triple.getEnvironment() == llvm::Triple::UnknownEnvironment)
+    mcld::error(mcld::diag::err_invalid_emulation) << emulation << "\n";
+
+  if (emu_triple.getArch() != llvm::Triple::UnknownArch)
+    triple.setArch(emu_triple.getArch());
+
+  if (emu_triple.getOS() != llvm::Triple::UnknownOS)
+    triple.setOS(emu_triple.getOS());
+
+  if (emu_triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
+    triple.setEnvironment(emu_triple.getEnvironment());
+}
+
+/// Configure the output filename.
+inline bool ConfigureOutputName(llvm::StringRef output_name,
+                                mcld::Module& module,
+                                mcld::LinkerConfig& config) {
+  std::string output(output_name.str());
+  if (output.empty()) {
+    if (config.targets().triple().getOS() == llvm::Triple::Win32) {
+      output.assign("_out");
+      switch (config.codeGenType()) {
+        case mcld::LinkerConfig::Object: {
+          output += ".obj";
+          break;
+        }
+        case mcld::LinkerConfig::DynObj: {
+          output += ".dll";
+          break;
+        }
+        case mcld::LinkerConfig::Exec: {
+          output += ".exe";
+          break;
+        }
+        case mcld::LinkerConfig::External:
+          break;
+        default: {
+          return false;
+          break;
+        }
+      }  // switch (config.codeGenType())
+    } else {
+      output.assign("a.out");
+    }
+  }  // if (output.empty())
+
+  module.setName(output);
+  return true;
+}
+
+bool InitializeInputs(mcld::IRBuilder& ir_builder,
+    std::vector<std::unique_ptr<mcld::InputAction>>& input_actions) {
+  for (auto& action : input_actions) {
+    assert(action != nullptr);
+    action->activate(ir_builder.getInputBuilder());
+  }
+
+  if (ir_builder.getInputBuilder().isInGroup()) {
+    mcld::fatal(mcld::diag::fatal_forbid_nest_group);
+    return false;
+  }
+
+  return true;
+}
+
+bool Driver::TranslateArguments() {
+  //===--------------------------------------------------------------------===//
+  // Preference
+  //===--------------------------------------------------------------------===//
+
+  // --color=mode
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Color)) {
+    bool res = llvm::StringSwitch<bool>(arg->getValue())
+                   .Case("never", false)
+                   .Case("always", true)
+                   .Case("auto", ShouldColorize() &&
+                                 llvm::sys::Process::FileDescriptorIsDisplayed(
+                                     STDOUT_FILENO))
+                   .Default(false);
+    config_.options().setColor(res);
+    mcld::outs().setColor(res);
+    mcld::errs().setColor(res);
+  }
+
+  // --trace
+  config_.options().setTrace(args_->hasArg(kOpt_Trace));
+
+  // --verbose=level
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Verbose)) {
+    llvm::StringRef value = arg->getValue();
+    int level;
+    if (value.getAsInteger(0, level)) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue();
+      return false;
+    }
+    config_.options().setVerbose(level);
+  }
+
+  // --error-limit NUMBER
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ErrorLimit)) {
+    llvm::StringRef value = arg->getValue();
+    int num;
+    if (value.getAsInteger(0, num) || (num < 0)) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue();
+      return false;
+    }
+    config_.options().setMaxErrorNum(num);
+  }
+
+  // --warning-limit NUMBER
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_WarningLimit)) {
+    llvm::StringRef value = arg->getValue();
+    int num;
+    if (value.getAsInteger(0, num) || (num < 0)) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue();
+      return false;
+    }
+    config_.options().setMaxWarnNum(num);
+  }
+
+  // --warn-shared-textrel
+  config_.options().setWarnSharedTextrel(args_->hasArg(kOpt_WarnSharedTextrel));
+
+  //===--------------------------------------------------------------------===//
+  // Target
+  //===--------------------------------------------------------------------===//
+  llvm::Triple triple;
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Triple)) {
+    // 1. Use the triple from command.
+    // -mtriple=value
+    triple.setTriple(arg->getValue());
+  } else {
+    std::string prog_triple = ParseProgName(prog_name_);
+    if (!prog_triple.empty()) {
+      // 2. Use the triple from the program name prefix.
+      triple.setTriple(prog_triple);
+    } else {
+      // 3. Use the default target triple.
+      triple.setTriple(mcld::sys::getDefaultTargetTriple());
+    }
+  }
+
+  // If a specific emulation was requested, apply it now.
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Emulation)) {
+    // -m emulation
+    ParseEmulation(triple, arg->getValue());
+  } else if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Arch)) {
+    // -march=value
+    config_.targets().setArch(arg->getValue());
+  }
+
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_CPU)) {
+    config_.targets().setTargetCPU(arg->getValue());
+  }
+
+  config_.targets().setTriple(triple);
+
+  // --gpsize=value
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_GPSize)) {
+    llvm::StringRef value = arg->getValue();
+    int size;
+    if (value.getAsInteger(0, size) || (size< 0)) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue() << "\n";
+      return false;
+    }
+    config_.options().setGPSize(size);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Dynamic
+  //===--------------------------------------------------------------------===//
+
+  // --entry=entry
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Entry)) {
+    script_.setEntry(arg->getValue());
+  }
+
+  // -Bsymbolic
+  config_.options().setBsymbolic(args_->hasArg(kOpt_Bsymbolic));
+
+  // -Bgroup
+  config_.options().setBgroup(args_->hasArg(kOpt_Bgroup));
+
+  // -soname=name
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_SOName)) {
+    config_.options().setSOName(arg->getValue());
+  }
+
+  // --no-undefined
+  if (args_->hasArg(kOpt_NoUndef)) {
+    config_.options().setNoUndefined(true);
+  }
+
+  // --allow-multiple-definition
+  if (args_->hasArg(kOpt_AllowMulDefs)) {
+    config_.options().setMulDefs(true);
+  }
+
+  // -z options
+  for (llvm::opt::Arg* arg : args_->filtered(kOpt_Z)) {
+    llvm::StringRef value = arg->getValue();
+    mcld::ZOption z_opt =
+        llvm::StringSwitch<mcld::ZOption>(value)
+            .Case("combreloc", mcld::ZOption(mcld::ZOption::CombReloc))
+            .Case("nocombreloc", mcld::ZOption(mcld::ZOption::NoCombReloc))
+            .Case("defs", mcld::ZOption(mcld::ZOption::Defs))
+            .Case("execstack", mcld::ZOption(mcld::ZOption::ExecStack))
+            .Case("noexecstack", mcld::ZOption(mcld::ZOption::NoExecStack))
+            .Case("initfirst", mcld::ZOption(mcld::ZOption::InitFirst))
+            .Case("interpose", mcld::ZOption(mcld::ZOption::InterPose))
+            .Case("loadfltr", mcld::ZOption(mcld::ZOption::LoadFltr))
+            .Case("muldefs", mcld::ZOption(mcld::ZOption::MulDefs))
+            .Case("nocopyreloc", mcld::ZOption(mcld::ZOption::NoCopyReloc))
+            .Case("nodefaultlib", mcld::ZOption(mcld::ZOption::NoDefaultLib))
+            .Case("nodelete", mcld::ZOption(mcld::ZOption::NoDelete))
+            .Case("nodlopen", mcld::ZOption(mcld::ZOption::NoDLOpen))
+            .Case("nodump", mcld::ZOption(mcld::ZOption::NoDump))
+            .Case("relro", mcld::ZOption(mcld::ZOption::Relro))
+            .Case("norelro", mcld::ZOption(mcld::ZOption::NoRelro))
+            .Case("lazy", mcld::ZOption(mcld::ZOption::Lazy))
+            .Case("now", mcld::ZOption(mcld::ZOption::Now))
+            .Case("origin", mcld::ZOption(mcld::ZOption::Origin))
+            .Default(mcld::ZOption());
+
+    if (z_opt.kind() == mcld::ZOption::Unknown) {
+      if (value.startswith("common-page-size=")) {
+        // -z common-page-size=value
+        z_opt.setKind(mcld::ZOption::CommPageSize);
+        long long unsigned size = 0;
+        value.drop_front(17).getAsInteger(0, size);
+        z_opt.setPageSize(static_cast<uint64_t>(size));
+      } else if (value.startswith("max-page-size=")) {
+        // -z max-page-size=value
+        z_opt.setKind(mcld::ZOption::MaxPageSize);
+        long long unsigned size = 0;
+        value.drop_front(14).getAsInteger(0, size);
+        z_opt.setPageSize(static_cast<uint64_t>(size));
+      }
+    }
+    config_.options().addZOption(z_opt);
+  }
+
+  // --dynamic-linker=file
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Dyld)) {
+    config_.options().setDyld(arg->getValue());
+  }
+
+  // --enable-new-dtags
+  config_.options().setNewDTags(args_->hasArg(kOpt_EnableNewDTags));
+
+  // --spare-dyanmic-tags COUNT
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_SpareDTags)) {
+    llvm::StringRef value = arg->getValue();
+    int num;
+    if (value.getAsInteger(0, num) || (num < 0)) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue() << "\n";
+      return false;
+    }
+    config_.options().setNumSpareDTags(num);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Output
+  //===--------------------------------------------------------------------===//
+
+  // Setup the codegen type.
+  if (args_->hasArg(kOpt_Shared) || args_->hasArg(kOpt_PIE)) {
+    // -shared, -pie
+    config_.setCodeGenType(mcld::LinkerConfig::DynObj);
+  } else if (args_->hasArg(kOpt_Relocatable)) {
+    // -r
+    config_.setCodeGenType(mcld::LinkerConfig::Object);
+  } else if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_OutputFormat)) {
+    // --oformat=value
+    llvm::StringRef value = arg->getValue();
+    if (value.equals("binary")) {
+      config_.setCodeGenType(mcld::LinkerConfig::Binary);
+    }
+  } else {
+    config_.setCodeGenType(mcld::LinkerConfig::Exec);
+  }
+
+  // Setup the output filename.
+  llvm::StringRef output_name;
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Output)) {
+    output_name = arg->getValue();
+  }
+  if (!ConfigureOutputName(output_name, module_, config_)) {
+    mcld::unreachable(mcld::diag::unrecognized_output_file) << module_.name();
+    return false;
+  } else {
+    if (!args_->hasArg(kOpt_SOName)) {
+      config_.options().setSOName(module_.name());
+    }
+  }
+
+  // --format=value
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_InputFormat)) {
+    llvm::StringRef value = arg->getValue();
+    if (value.equals("binary")) {
+      config_.options().setBinaryInput();
+    }
+  }
+
+  // Setup debug info stripping.
+  config_.options().setStripDebug(args_->hasArg(kOpt_StripDebug) ||
+                                  args_->hasArg(kOpt_StripAll));
+
+  // Setup symbol stripping mode.
+  if (args_->hasArg(kOpt_StripAll)) {
+    config_.options().setStripSymbols(
+        mcld::GeneralOptions::StripSymbolMode::StripAllSymbols);
+  } else if (args_->hasArg(kOpt_DiscardAll)) {
+    config_.options().setStripSymbols(
+        mcld::GeneralOptions::StripSymbolMode::StripLocals);
+  } else if (args_->hasArg(kOpt_DiscardLocals)) {
+    config_.options().setStripSymbols(
+        mcld::GeneralOptions::StripSymbolMode::StripTemporaries);
+  } else {
+    config_.options().setStripSymbols(
+        mcld::GeneralOptions::StripSymbolMode::KeepAllSymbols);
+  }
+
+  // --eh-frame-hdr
+  config_.options().setEhFrameHdr(args_->hasArg(kOpt_EHFrameHdr));
+
+  // -pie
+  config_.options().setPIE(args_->hasArg(kOpt_PIE));
+
+  // --nmagic
+  config_.options().setNMagic(args_->hasArg(kOpt_NMagic));
+
+  // --omagic
+  config_.options().setOMagic(args_->hasArg(kOpt_OMagic));
+
+  // --hash-style=style
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_HashStyle)) {
+    mcld::GeneralOptions::HashStyle style =
+        llvm::StringSwitch<mcld::GeneralOptions::HashStyle>(arg->getValue())
+            .Case("sysv", mcld::GeneralOptions::HashStyle::SystemV)
+            .Case("gnu", mcld::GeneralOptions::HashStyle::GNU)
+            .Case("both", mcld::GeneralOptions::HashStyle::Both)
+            .Default(mcld::GeneralOptions::HashStyle::Unknown);
+    if (style != mcld::GeneralOptions::HashStyle::Unknown) {
+      config_.options().setHashStyle(style);
+    }
+  }
+
+  // --[no]-export-dynamic
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ExportDynamic,
+                                              kOpt_NoExportDynamic)) {
+    if (arg->getOption().matches(kOpt_ExportDynamic)) {
+      config_.options().setExportDynamic(true);
+    } else {
+      config_.options().setExportDynamic(false);
+    }
+  }
+
+  // --no-warn-mismatch
+  config_.options().setWarnMismatch(!args_->hasArg(kOpt_NoWarnMismatch));
+
+  // --exclude-libs
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ExcludeLibs)) {
+    llvm::StringRef value = arg->getValue();
+    do {
+      std::pair<llvm::StringRef, llvm::StringRef> res = value.split(',');
+      config_.options().excludeLIBS().insert(res.first.str());
+      value = res.second;
+    } while (!value.empty());
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Search Path
+  //===--------------------------------------------------------------------===//
+
+  // --sysroot
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Sysroot)) {
+    mcld::sys::fs::Path path(arg->getValue());
+    if (mcld::sys::fs::exists(path) && mcld::sys::fs::is_directory(path)) {
+      script_.setSysroot(path);
+    }
+  }
+
+  // -L searchdir
+  for (llvm::opt::Arg* arg : args_->filtered(kOpt_LibraryPath)) {
+    if (!script_.directories().insert(arg->getValue())) {
+      // FIXME: need a warning function
+      mcld::errs() << "WARNING: can not open search directory `-L"
+                   << arg->getValue() << "'.\n";
+    }
+  }
+
+  // -nostdlib
+  config_.options().setNoStdlib(args_->hasArg(kOpt_NoStdlib));
+
+  // -rpath=path
+  for (llvm::opt::Arg* arg : args_->filtered(kOpt_RPath)) {
+    config_.options().getRpathList().push_back(arg->getValue());
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Symbol
+  //===--------------------------------------------------------------------===//
+
+  // -d/-dc/-dp
+  config_.options().setDefineCommon(args_->hasArg(kOpt_DefineCommon));
+
+  // -u symbol
+  for (llvm::opt::Arg* arg : args_->filtered(kOpt_Undefined)) {
+    config_.options().getUndefSymList().push_back(arg->getValue());
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Script
+  //===--------------------------------------------------------------------===//
+
+  // --wrap=symbol
+  for (llvm::opt::Arg* arg : args_->filtered(kOpt_Wrap)) {
+    bool exist = false;
+    const char* symbol = arg->getValue();
+    // symbol -> __wrap_symbol
+    mcld::StringEntry<llvm::StringRef>* to_wrap =
+        script_.renameMap().insert(symbol, exist);
+
+    std::string to_wrap_str;
+    to_wrap_str.append("__wrap_")
+               .append(symbol);
+    to_wrap->setValue(to_wrap_str);
+
+    if (exist)
+      mcld::warning(mcld::diag::rewrap) << symbol << to_wrap_str;
+
+    // __real_symbol -> symbol
+    std::string from_real_str;
+    to_wrap_str.append("__real_")
+               .append(symbol);
+    mcld::StringEntry<llvm::StringRef>* from_real =
+        script_.renameMap().insert(from_real_str, exist);
+    from_real->setValue(symbol);
+
+    if (exist)
+      mcld::warning(mcld::diag::rewrap) << symbol << from_real_str;
+  }
+
+  // --portalbe=symbol
+  for (llvm::opt::Arg* arg : args_->filtered(kOpt_Wrap)) {
+    bool exist = false;
+    const char* symbol = arg->getValue();
+    // symbol -> symbol_portable
+    mcld::StringEntry<llvm::StringRef>* to_wrap =
+        script_.renameMap().insert(symbol, exist);
+
+    std::string to_wrap_str;
+    to_wrap_str.append(symbol)
+               .append("_portable");
+    to_wrap->setValue(to_wrap_str);
+
+    if (exist)
+      mcld::warning(mcld::diag::rewrap) << symbol << to_wrap_str;
+
+    // __real_symbol -> symbol
+    std::string from_real_str;
+    to_wrap_str.append("__real_")
+               .append(symbol);
+    mcld::StringEntry<llvm::StringRef>* from_real =
+        script_.renameMap().insert(from_real_str, exist);
+    from_real->setValue(symbol);
+
+    if (exist)
+      mcld::warning(mcld::diag::rewrap) << symbol << from_real_str;
+  }
+
+  // --section-start=section=addr
+  for (llvm::opt::Arg* arg : args_->filtered(kOpt_SectionStart)) {
+    llvm::StringRef value = arg->getValue();
+    const size_t pos = value.find('=');
+    uint64_t addr = 0;
+    value.substr(pos + 1).getAsInteger(0, addr);
+    bool exist = false;
+    mcld::StringEntry<uint64_t>* mapping =
+        script_.addressMap().insert(value.substr(0, pos), exist);
+    mapping->setValue(addr);
+  }
+
+  // -Tbss=value
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Tbss)) {
+    llvm::StringRef value = arg->getValue();
+    uint64_t addr = 0;
+    if (value.getAsInteger(0, addr)) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue() << "\n";
+      return false;
+    }
+    bool exist = false;
+    mcld::StringEntry<uint64_t>* mapping =
+        script_.addressMap().insert(".bss", exist);
+    mapping->setValue(addr);
+  }
+
+  // -Tdata=value
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Tdata)) {
+    llvm::StringRef value = arg->getValue();
+    uint64_t addr = 0;
+    if (value.getAsInteger(0, addr)) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue() << "\n";
+      return false;
+    }
+    bool exist = false;
+    mcld::StringEntry<uint64_t>* mapping =
+        script_.addressMap().insert(".data", exist);
+    mapping->setValue(addr);
+  }
+
+  // -Ttext=value
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Ttext)) {
+    llvm::StringRef value = arg->getValue();
+    uint64_t addr = 0;
+    if (value.getAsInteger(0, addr)) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue() << "\n";
+      return false;
+    }
+    bool exist = false;
+    mcld::StringEntry<uint64_t>* mapping =
+        script_.addressMap().insert(".text", exist);
+    mapping->setValue(addr);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Optimization
+  //===--------------------------------------------------------------------===//
+
+  // --[no-]gc-sections
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_GCSections,
+                                              kOpt_NoGCSections)) {
+    if (arg->getOption().matches(kOpt_GCSections)) {
+      config_.options().setGCSections(true);
+    } else {
+      config_.options().setGCSections(false);
+    }
+  }
+
+  // --[no-]print-gc-sections
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_PrintGCSections,
+                                              kOpt_NoPrintGCSections)) {
+    if (arg->getOption().matches(kOpt_PrintGCSections)) {
+      config_.options().setPrintGCSections(true);
+    } else {
+      config_.options().setPrintGCSections(false);
+    }
+  }
+
+  // --[no-]ld-generated-unwind-info
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_LDGeneratedUnwindInfo,
+                                              kOpt_NoLDGeneratedUnwindInfo)) {
+    if (arg->getOption().matches(kOpt_LDGeneratedUnwindInfo)) {
+      config_.options().setGenUnwindInfo(true);
+    } else {
+      config_.options().setGenUnwindInfo(false);
+    }
+  }
+
+  // --icf=mode
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ICF)) {
+    mcld::GeneralOptions::ICF mode =
+        llvm::StringSwitch<mcld::GeneralOptions::ICF>(arg->getValue())
+            .Case("none", mcld::GeneralOptions::ICF::None)
+            .Case("all", mcld::GeneralOptions::ICF::All)
+            .Case("safe", mcld::GeneralOptions::ICF::Safe)
+            .Default(mcld::GeneralOptions::ICF::Unknown);
+    if (mode == mcld::GeneralOptions::ICF::Unknown) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue() << "\n";
+      return false;
+    }
+    config_.options().setICFMode(mode);
+  }
+
+  // --icf-iterations
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ICFIters)) {
+    llvm::StringRef value = arg->getValue();
+    int num;
+    if (value.getAsInteger(0, num) || (num < 0)) {
+      mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+                   << ": " << arg->getValue() << "\n";
+      return false;
+    }
+    config_.options().setICFIterations(num);
+  }
+
+  // --[no-]print-icf-sections
+  if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_PrintICFSections,
+                                              kOpt_NoPrintICFSections)) {
+    if (arg->getOption().matches(kOpt_PrintICFSections)) {
+      config_.options().setPrintICFSections(true);
+    } else {
+      config_.options().setPrintICFSections(false);
+    }
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Positional
+  //===--------------------------------------------------------------------===//
+
+  // # of regular objects, script, and namespec.
+  size_t input_num = 0;
+  typedef std::unique_ptr<mcld::InputAction> Action;
+
+  std::vector<Action> actions;
+  Action action;
+  actions.reserve(32);
+
+  for (llvm::opt::Arg* arg : *args_) {
+    const unsigned index = arg->getIndex();
+
+    switch (arg->getOption().getID()) {
+      // -T script
+      case kOpt_Script: {
+        const char* value = arg->getValue();
+        config_.options().getScriptList().push_back(value);
+
+        // FIXME: Let index of script file be 0.
+        action.reset(new mcld::ScriptAction(
+            0x0, value, mcld::ScriptFile::LDScript, script_.directories()));
+        actions.push_back(std::move(action));
+
+        action.reset(new mcld::ContextAction(0x0));
+        actions.push_back(std::move(action));
+
+        action.reset(new mcld::MemoryAreaAction(0x0,
+                                                mcld::FileHandle::ReadOnly));
+        actions.push_back(std::move(action));
+
+        ++input_num;
+        break;
+      }
+
+      // --defsym=symbol=expr
+      case kOpt_DefSym: {
+        std::string expr;
+        expr.append(arg->getValue())
+            .append(";");
+        script_.defsyms().push_back(std::move(expr));
+        action.reset(new mcld::DefSymAction(index, script_.defsyms().back()));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // -l namespec
+      case kOpt_Namespec: {
+        action.reset(new mcld::NamespecAction(
+            index, arg->getValue(), script_.directories()));
+        actions.push_back(std::move(action));
+
+        action.reset(new mcld::ContextAction(index));
+        actions.push_back(std::move(action));
+
+        action.reset(new mcld::MemoryAreaAction(index,
+                                                mcld::FileHandle::ReadOnly));
+        actions.push_back(std::move(action));
+
+        ++input_num;
+        break;
+      }
+
+      // --whole-archive
+      case kOpt_WholeArchive: {
+        action.reset(new mcld::WholeArchiveAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // --no-whole-archive
+      case kOpt_NoWholeArchive: {
+        action.reset(new mcld::NoWholeArchiveAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // --as-needed
+      case kOpt_AsNeeded: {
+        action.reset(new mcld::AsNeededAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // --no-as-needed
+      case kOpt_NoAsNeeded: {
+        action.reset(new mcld::NoAsNeededAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // --add-needed
+      // FIXME: This is deprecated. Should be --copy-dt-needed-entries.
+      case kOpt_AddNeeded:
+      case kOpt_CopyDTNeeded: {
+        action.reset(new mcld::AddNeededAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // --no-add-needed
+      // FIXME: This is deprecated. Should be --no-copy-dt-needed-entries.
+      case kOpt_NoAddNeeded:
+      case kOpt_NoCopyDTNeeded: {
+        action.reset(new mcld::AddNeededAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // -Bdynamic
+      case kOpt_Bdynamic: {
+        action.reset(new mcld::BDynamicAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // -Bstatic
+      case kOpt_Bstatic: {
+        action.reset(new mcld::BStaticAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // --start-group
+      case kOpt_StartGroup: {
+        action.reset(new mcld::StartGroupAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      // --end-group
+      case kOpt_EndGroup: {
+        action.reset(new mcld::EndGroupAction(index));
+        actions.push_back(std::move(action));
+        break;
+      }
+
+      case kOpt_INPUT: {
+        action.reset(new mcld::InputFileAction(index, arg->getValue()));
+        actions.push_back(std::move(action));
+
+        action.reset(new mcld::ContextAction(index));
+        actions.push_back(std::move(action));
+
+        action.reset(new mcld::MemoryAreaAction(index,
+                                                mcld::FileHandle::ReadOnly));
+        actions.push_back(std::move(action));
+
+        ++input_num;
+        break;
+      }
+
+      default:
+        break;
+    }
+  }
+
+  if (input_num == 0) {
+    mcld::fatal(mcld::diag::err_no_inputs);
+    return false;
+  }
+
+  // Stable sort
+  std::stable_sort(actions.begin(),
+                   actions.end(),
+                   [] (const Action& X, const Action& Y) {
+                     return X->position() < Y->position();
+                   });
+
+  if (!InitializeInputs(ir_builder_, actions)) {
+    mcld::errs() << "Failed to initialize input tree!\n";
+    return false;
+  }
+
+  return true;
+}
+
+std::unique_ptr<llvm::opt::InputArgList>
+ParseArgs(const llvm::opt::OptTable& opt_table,
+          llvm::ArrayRef<const char*> argv) {
+  unsigned missing_arg_idx;
+  unsigned missing_arg_count;
+
+  std::unique_ptr<llvm::opt::InputArgList> args(
+      opt_table.ParseArgs(argv.begin(), argv.end(), missing_arg_idx,
+                          missing_arg_count));
+  if (missing_arg_count > 0) {
+    mcld::errs() << "Argument to '" << args->getArgString(missing_arg_idx)
+                 << "' is missing (expected " << missing_arg_count
+                 << ((missing_arg_count > 1) ? " values" : " value") << ")\n";
+    return nullptr;
+  }
+
+  return args;
+}
+
+std::unique_ptr<Driver> Driver::Create(llvm::ArrayRef<const char*> argv) {
+  // Parse command line options.
+  OptTable opt_table;
+  std::unique_ptr<llvm::opt::InputArgList> args = ParseArgs(opt_table,
+                                                            argv.slice(1));
+  if (args == nullptr) {
+    return nullptr;
+  }
+
+  std::unique_ptr<Driver> result(new Driver(argv[0], std::move(args)));
+
+  // Return quickly if -help is specified.
+  if (result->args_->hasArg(kOpt_Help)) {
+    opt_table.PrintHelp(mcld::outs(), argv[0], "MCLinker",
+                        /* FlagsToInclude */0, /* FlagsToExclude */0);
+    return nullptr;
+  }
+
+  // Print version information if requested.
+  if (result->args_->hasArg(kOpt_Version)) {
+    mcld::outs() << result->config_.options().getVersionString() << "\n";
+  }
+
+  // Setup instance from arguments.
+  if (!result->TranslateArguments()) {
+    return nullptr;
+  }
+
+  return result;
+}
+
+bool Driver::Run() {
+  mcld::Initialize();
+
+  if (!linker_.emulate(script_, config_)) {
+    mcld::errs() << "Failed to emulate target!\n";
+    return false;
+  }
+
+  if (!linker_.link(module_, ir_builder_)) {
+    mcld::errs() << "Failed to link objects!\n";
+    return false;
+  }
+
+  if (!linker_.emit(module_, module_.name())) {
+    mcld::errs() << "Failed to emit output!\n";
+    return false;
+  }
+
+  mcld::Finalize();
+  return true;
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  std::unique_ptr<Driver> driver =
+      Driver::Create(llvm::makeArrayRef(argv, argc));
+
+  if ((driver == nullptr) || !driver->Run()) {
+    return EXIT_FAILURE;
+  } else {
+    return EXIT_SUCCESS;
+  }
+}
diff --git a/tools/mcld/Options.td b/tools/mcld/Options.td
new file mode 100644
index 0000000..80655a7
--- /dev/null
+++ b/tools/mcld/Options.td
@@ -0,0 +1,492 @@
+//===- Options.td ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+include "llvm/Option/OptParser.td"
+
+//===----------------------------------------------------------------------===//
+// Dynamic
+//===----------------------------------------------------------------------===//
+def DynamicGroup : OptionGroup<"dynamic">,
+                   HelpText<"DYNAMIC OPTIONS">;
+
+def Entry : Joined<["--"], "entry=">,
+            Group<DynamicGroup>,
+            HelpText<"Use the explicit symbol as the entrance of your program">;
+def EntryAlias : Separate<["-"], "e">,
+                 Alias<Entry>;
+
+def Bsymbolic : Flag<["-"], "Bsymbolic">,
+                Group<DynamicGroup>,
+                HelpText<"Bind references within the shared library">;
+
+def Bgroup : Flag<["-"], "Bgroup">,
+             Group<DynamicGroup>,
+             HelpText<"Info the dynamic linker to lookup only inside the group">;
+
+def SOName : Joined<["-"], "soname=">,
+             Group<DynamicGroup>,
+             HelpText<"Set internal name of shared library">;
+def SONameAlias : Separate<["-"], "soname">,
+                  Group<DynamicGroup>,
+                  Alias<SOName>;
+
+def NoUndef : Flag<["--"], "no-undefined">,
+              Group<DynamicGroup>,
+              HelpText<"Do not allow unresolved references">;
+
+def AllowMulDefs : Flag<["--"], "allow-multiple-definition">,
+                   Group<DynamicGroup>,
+                   HelpText<"Allow multiple definitions">;
+
+def Z : Separate<["-"], "z">,
+        Group<DynamicGroup>,
+        HelpText<"Extensions for GNU ld compatibility">;
+
+def Dyld : Joined<["--"], "dynamic-linker=">,
+           Group<DynamicGroup>,
+           HelpText<"Set the name of the dynamic linker">;
+def DyldAlias : Separate<["-"], "dynamic-linker">,
+                Group<DynamicGroup>,
+                Alias<Dyld>;
+
+def EnableNewDTags : Flag<["--"], "enable-new-dtags">,
+                     Group<DynamicGroup>,
+                     HelpText<"Enable use of DT_RUNPATH and DT_FLAGS">;
+
+def SpareDTags: Separate<["--"], "spare-dynamic-tags">,
+                Group<DynamicGroup>,
+                HelpText<"Set the number of spare dyanmic tags (DT_NULL)">;
+
+//===----------------------------------------------------------------------===//
+// Optimization
+//===----------------------------------------------------------------------===//
+def OptimizationGroup : OptionGroup<"optimization">,
+                        HelpText<"OPTIMIZATION OPTIONS">;
+
+def GCSections : Flag<["--"], "gc-sections">,
+                 Group<OptimizationGroup>,
+                 HelpText<"Enable garbage collection of unused input sections">;
+
+def NoGCSections : Flag<["--"], "no-gc-sections">,
+                   Group<OptimizationGroup>,
+                   HelpText<"Disable garbage collection of unused input sections">;
+
+def PrintGCSections : Flag<["--"], "print-gc-sections">,
+                      Group<OptimizationGroup>,
+                      HelpText<"List all sections removed by garbage collection">;
+
+def NoPrintGCSections : Flag<["--"], "no-print-gc-sections">,
+                        Group<OptimizationGroup>,
+                        HelpText<"Do not list sections removed by garbage collection">;
+
+def LDGeneratedUnwindInfo : Flag<["--"], "ld-generated-unwind-info">,
+                            Group<OptimizationGroup>,
+                            HelpText<"Request creation of unwind info for linker generated code sections like PLT">;
+
+def NoLDGeneratedUnwindInfo : Flag<["--"], "no-ld-generated-unwind-info">,
+                              Group<OptimizationGroup>,
+                              HelpText<"Don't create unwind info for linker generated sections to save size">;
+
+def ICF : Joined<["--"], "icf=">,
+          Group<OptimizationGroup>,
+          HelpText<"Identical Code Folding">;
+
+def ICFIters : Separate<["--"], "icf-iterations">,
+               Group<OptimizationGroup>,
+               HelpText<"Set number of iterations to do ICF">;
+
+def PrintICFSections : Flag<["--"], "print-icf-sections">,
+                       Group<OptimizationGroup>,
+                       HelpText<"List all sections folded by ICF">;
+
+def NoPrintICFSections : Flag<["--"], "no-print-icf-sections">,
+                         Group<OptimizationGroup>,
+                         HelpText<"Do not list sections folded by ICF">;
+
+//===----------------------------------------------------------------------===//
+// Output
+//===----------------------------------------------------------------------===//
+def OutputGroup : OptionGroup<"output">,
+                  HelpText<"OUTPUT OPTIONS">;
+
+def Output : Separate<["-"], "o">,
+             Group<OutputGroup>,
+             HelpText<"Output filename">;
+def OutputAlias : Joined<["--"], "output=">,
+                  Group<OutputGroup>,
+                  Alias<Output>;
+
+def OutputFormat: Joined<["--"], "oformat=">,
+                  Group<OutputGroup>,
+                  HelpText<"Output format">;
+
+def Shared : Flag<["-"], "shared">,
+             Group<OutputGroup>,
+             HelpText<"Create a shared library">;
+def Bshareable : Flag<["-"], "Bshareable">,
+                 Group<OutputGroup>,
+                 Alias<Shared>;
+
+def Bdynamic : Flag<["-"], "Bdynamic">,
+               Group<OutputGroup>,
+               HelpText<"Link against dynamic library">;
+def BdynamicAlias1 : Flag<["-"], "dy">,
+                     Group<OutputGroup>,
+                     Alias<Bdynamic>;
+def BdynamicAlias2 : Flag<["-"], "call_shared">,
+                     Group<OutputGroup>,
+                     Alias<Bdynamic>;
+
+def Bstatic : Flag<["-"], "Bstatic">,
+              Group<OutputGroup>,
+              HelpText<"Link against static library">;
+def BstaticAlias1 : Flag<["-"], "dn">,
+                    Group<OutputGroup>,
+                    Alias<Bstatic>;
+def BstaticAlias2 : Flag<["-"], "non_shared">,
+                    Group<OutputGroup>,
+                    Alias<Bstatic>;
+def BstaticAlias3 : Flag<["-"], "static">,
+                    Group<OutputGroup>,
+                    Alias<Bstatic>;
+
+def PIE : Flag<["-"], "pie">,
+          Group<OutputGroup>,
+          HelpText<"Emit a position-independent executable file">;
+def PICExec : Flag<["--"], "pic-executable">,
+              Group<OutputGroup>,
+              Alias<PIE>;
+
+def Relocatable : Flag<["--"], "relocatable">,
+                  Group<OutputGroup>,
+                  HelpText<"Generate relocatable output">;
+def RelocatableAlias : Flag<["-"], "r">,
+                       Group<OutputGroup>,
+                       Alias<Relocatable>;
+
+def InputFormat : Joined<["--"], "format=">,
+                  Group<OutputGroup>,
+                  HelpText<"Specify the binary format for input object files that follow this option on the command line">;
+def InputFormatAlias : Separate<["-"], "b">,
+                       Group<OutputGroup>,
+                       Alias<InputFormat>;
+
+def StripDebug : Flag<["--"], "strip-debug">,
+                 Group<OutputGroup>,
+                 HelpText<"Omit debugger symbol information from the output file">;
+def StripDebugAlias : Flag<["-"], "S">,
+                      Group<OutputGroup>,
+                      Alias<StripDebug>;
+
+def StripAll : Flag<["--"], "strip-all">,
+               Group<OutputGroup>,
+               HelpText<"Omit all symbol information from the output file">;
+def StripAllAlias : Flag<["-"], "s">,
+                    Group<OutputGroup>,
+                    Alias<StripAll>;
+
+def DiscardLocals : Flag<["--"], "discard-debug">,
+                    Group<OutputGroup>,
+                    HelpText<"Discard all temporary local symbols">;
+def DiscardLocalsAlias : Flag<["-"], "X">,
+                         Group<OutputGroup>,
+                         Alias<DiscardLocals>;
+
+def DiscardAll : Flag<["--"], "discard-all">,
+                 Group<OutputGroup>,
+                 HelpText<"Discard all local symbols">;
+def DiscardAllAlias : Flag<["-"], "x">,
+                      Group<OutputGroup>,
+                      Alias<DiscardAll>;
+
+def EHFrameHdr : Flag<["--"], "eh-frame-hdr">,
+                 Group<OutputGroup>,
+                 HelpText<"Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment">;
+
+def NMagic : Flag<["--"], "nmagic">,
+             Group<OutputGroup>,
+             HelpText<"Do not page align data">;
+def NMagicAlias : Flag<["-"], "n">,
+                  Group<OutputGroup>,
+                  Alias<NMagic>;
+
+def OMagic : Flag<["--"], "omagic">,
+             Group<OutputGroup>,
+             HelpText<"Do not page align data, do not make text readonly">;
+def OMagicAlias : Flag<["-"], "N">,
+                  Group<OutputGroup>,
+                  Alias<OMagic>;
+
+def HashStyle : Joined<["--"], "hash-style=">,
+                Group<OutputGroup>,
+                HelpText<"Set the type of linker's hash table(s)">;
+
+def ExportDynamic : Flag<["--"], "export-dynamic">,
+                    Group<OutputGroup>,
+                    HelpText<"Export all dynamic symbols">;
+def ExportDynamicAlias : Flag<["-"], "E">,
+                         Group<OutputGroup>,
+                         Alias<ExportDynamic>;
+
+def NoExportDynamic : Flag<["--"], "no-export-dynamic">,
+                   Group<OutputGroup>,
+                   HelpText<"Not export all dynamic symbols">;
+
+
+
+def NoWarnMismatch : Flag<["--"], "no-warn-mismatch">,
+                     Group<OutputGroup>,
+                     HelpText<"Allow linking together mismatched input files">;
+
+def ExcludeLibs : Separate<["--"], "exclude-libs">,
+                  Group<OutputGroup>,
+                  HelpText<"Allow linking together mismatched input files">;
+
+def BuildID : Flag<["--"], "build-id">,
+              Group<OutputGroup>,
+              HelpText<"Request creation of .note.gnu.build-id ELF note section">;
+
+//===----------------------------------------------------------------------===//
+// Positional
+//===----------------------------------------------------------------------===//
+def PositionalGroup : OptionGroup<"positional">,
+                      HelpText<"POSITIONAL OPTIONS">;
+
+def Script : Joined<["--"], "script=">,
+             Group<PositionalGroup>,
+             HelpText<"Use the given file as the linker script">;
+def ScriptAlias : Separate<["-"], "T">,
+                  Group<PositionalGroup>,
+                  Alias<Script>;
+
+def Namespec : Joined<["--"], "library=">,
+               Group<PositionalGroup>,
+               HelpText<"Add the archive or object file specified by namespec to the list of files to link">;
+def NamespecAlias : Joined<["-"], "l">,
+                    Group<PositionalGroup>,
+                    Alias<Namespec>;
+
+def WholeArchive : Flag<["--"], "whole-archive">,
+                   Group<PositionalGroup>,
+                   HelpText<"Include every object file in the archive in the link">;
+
+def NoWholeArchive : Flag<["--"], "no-whole-archive">,
+                     Group<PositionalGroup>,
+                     HelpText<"Turn off the effect of the --whole-archive option">;
+
+def AsNeeded : Flag<["--"], "as-needed">,
+               Group<PositionalGroup>,
+               HelpText<"Add the dynamic libraries mentioned to DT_NEEDED where there is "
+                        "a non-weak undefined symbol reference from">;
+
+def NoAsNeeded : Flag<["--"], "no-as-needed">,
+                 Group<PositionalGroup>,
+                 HelpText<"Turn off the effect of the --as-needed">;
+
+def AddNeeded : Flag<["--"], "add-needed">,
+                Group<PositionalGroup>,
+                HelpText<"Deprecated">;
+
+def NoAddNeeded : Flag<["--"], "no-add-needed">,
+                  Group<PositionalGroup>,
+                  HelpText<"Deprecated">;
+
+def CopyDTNeeded : Flag<["--"], "copy-dt-needed-entries">,
+                   Group<PositionalGroup>,
+                   HelpText<"Add the dynamic libraries mentioned to DT_NEEDED">;
+
+def NoCopyDTNeeded : Flag<["--"], "no-copy-dt-needed-entries">,
+                     Group<PositionalGroup>,
+                     HelpText<"Turn off the effect of the --copy-dt-needed-entries">;
+
+def StartGroup : Flag<["--"], "start-group">,
+                 Group<PositionalGroup>,
+                 HelpText<"Start to record a group of archives">;
+def StartGroupAlias : Flag<["-"], "(">,
+                      Group<PositionalGroup>,
+                      Alias<StartGroup>;
+
+def EndGroup : Flag<["--"], "end-group">,
+               Group<PositionalGroup>,
+               HelpText<"Stop recording a group of archives">;
+def EndGroupAlias : Flag<["-"], ")">,
+                    Group<PositionalGroup>,
+                    Alias<EndGroup>;
+
+//===----------------------------------------------------------------------===//
+// Preference
+//===----------------------------------------------------------------------===//
+def PreferenceGroup : OptionGroup<"preference">,
+                      HelpText<"PREFERENCE OPTIONS">;
+
+def Color : Joined<["--"], "colormc=">,
+            Group<PreferenceGroup>,
+            HelpText<"Surround the result strings with the marker">;
+
+def Trace : Flag<["--"], "trace">,
+            Group<PreferenceGroup>,
+            HelpText<"Print the names of the input files as ld processes them">;
+def TraceAlias : Flag<["-"], "t">,
+                 Group<PreferenceGroup>,
+                 Alias<Trace>;
+
+def Help : Flag<["-", "--"], "help">,
+           Group<PreferenceGroup>,
+           HelpText<"Display available options (to standard output)">;
+def HelpAlias : Flag<["-"], "h">,
+                Group<PreferenceGroup>,
+                Alias<Help>;
+
+def Verbose : Joined<["--"], "verbose=">,
+              Group<PreferenceGroup>,
+              HelpText<"Set linker diagnostic output level">;
+
+def Version : Flag<["--"], "version">,
+              Group<PreferenceGroup>,
+              HelpText<"Display MCLinker version">;
+def VersionAlias1 : Flag<["-"], "v">,
+                    Group<PreferenceGroup>,
+                    Alias<Version>;
+def VersionAlias2 : Flag<["-"], "V">,
+                    Group<PreferenceGroup>,
+                    Alias<Version>;
+
+def ErrorLimit : Joined<["--"], "error-limit=">,
+                 Group<PreferenceGroup>,
+                 HelpText<"Set the maximum limit of errors">;
+
+def WarningLimit : Joined<["--"], "warning-limit=">,
+                   Group<PreferenceGroup>,
+                   HelpText<"Set the maximum limit of warnings">;
+
+def FatalWarnings : Flag<["--"], "fatal-warnings">,
+                    Group<PreferenceGroup>,
+                    HelpText<"Turn all warnings into errors">;
+
+def NoFatalWarnings : Flag<["--"], "no-fatal-warnings">,
+                      Group<PreferenceGroup>,
+                      HelpText<"Do not turn all warnings into errors">;
+
+def WarnSharedTextrel : Flag<["--"], "warn-shared-textrel">,
+                        Group<PreferenceGroup>,
+                        HelpText<"Warn if there is a text relocation in the output shared object">;
+
+//===----------------------------------------------------------------------===//
+// Script
+//===----------------------------------------------------------------------===//
+def ScriptGroup : OptionGroup<"script">,
+                  HelpText<"SCRIPT OPTIONS">;
+
+def DefSym : Joined<["--"], "defsym=">,
+             Group<ScriptGroup>,
+             HelpText<"Define a symbol">;
+
+def Wrap : Joined<["--"], "wrap=">,
+           Group<ScriptGroup>,
+           HelpText<"Use a wrap function for the symbol">;
+
+def Portable : Joined<["--"], "portable=">,
+               Group<ScriptGroup>,
+               HelpText<"Use a portable function for the symbol">;
+
+def SectionStart : Joined<["--"], "section-start=">,
+                   Group<ScriptGroup>,
+                   HelpText<"Locate a output section at the given absolute address">;
+
+def Tbss : Joined<["-"], "Tbss=">,
+           Group<ScriptGroup>,
+           HelpText<"Set the address of the bss segment">;
+
+def Tdata : Joined<["-"], "Tdata=">,
+            Group<ScriptGroup>,
+            HelpText<"Set the address of the data segment">;
+
+def Ttext : Joined<["-"], "Ttext=">,
+            Group<ScriptGroup>,
+            HelpText<"Set the address of the text segment">;
+
+//===----------------------------------------------------------------------===//
+// Search Path
+//===----------------------------------------------------------------------===//
+def SearchpathGroup : OptionGroup<"searchpath">,
+                      HelpText<"SEARCHPATH OPTIONS">;
+
+def Sysroot : Joined<["--"], "sysroot=">,
+              Group<SearchpathGroup>,
+              HelpText<"Use the given directory as the location of the sysroot">;
+
+def LibraryPath : Joined<["--"], "library-path=">,
+                  Group<SearchpathGroup>,
+                  HelpText<"Add the given directory to the list of search paths">;
+def LibraryPathAlias : Joined<["-"], "L">,
+                       Group<SearchpathGroup>,
+                       Alias<LibraryPath>;
+
+def NoStdlib : Flag<["-"], "nostdlib">,
+               Group<SearchpathGroup>,
+               HelpText<"Only search lib dirs explicitly specified on cmdline">;
+
+def RPath : Joined<["-"], "rpath=">,
+            Group<SearchpathGroup>,
+            HelpText<"Add a directory to the runtime library search path">;
+
+def RPathLink : Joined<["-"], "rpath-link=">,
+                Group<SearchpathGroup>,
+                HelpText<"Add a directory to the link time library search path">;
+
+//===----------------------------------------------------------------------===//
+// Symbol
+//===----------------------------------------------------------------------===//
+def SymbolGroup : OptionGroup<"symbol">,
+                  HelpText<"SYMBOL OPTIONS">;
+
+def Undefined : Joined<["--"], "undefined=">,
+                Group<SymbolGroup>,
+                HelpText<"Force symbol to be undefined in the output file">;
+def UndefinedAlias : Separate<["-"], "u">,
+                     Group<SymbolGroup>,
+                     Alias<Undefined>;
+
+def DefineCommon : Flag<["-"], "d">,
+                   Group<SymbolGroup>,
+                   HelpText<"Define common symbol">;
+def DefineCommonAlias1 : Flag<["-"], "dc">,
+                         Group<SymbolGroup>,
+                         Alias<DefineCommon>;
+def DefineCommonAlias2 : Flag<["-"], "dp">,
+                         Group<SymbolGroup>,
+                         Alias<DefineCommon>;
+
+//===----------------------------------------------------------------------===//
+// Target
+//===----------------------------------------------------------------------===//
+def TargetGroup : OptionGroup<"target">,
+                  HelpText<"TARGET OPTIONS">;
+
+def GPSize : Joined<["--"], "gpsize=">,
+             Group<TargetGroup>,
+             HelpText<"Set the maximum size of objects to be optimized using GP">;
+def GPSizeAlias : Separate<["-"], "G">,
+                  Group<TargetGroup>,
+                  Alias<GPSize>;
+
+def Triple : Joined<["-"], "mtriple=">,
+             Group<TargetGroup>,
+             HelpText<"Override target triple for module">;
+
+def Arch : Joined<["-"], "march=">,
+           Group<TargetGroup>,
+           HelpText<"Architecture to generate code for">;
+
+def CPU : Joined<["-"], "mcpu=">,
+          Group<TargetGroup>,
+          HelpText<"Set a specific cpu type">;
+
+def Emulation : Separate<["-"], "m">,
+                Group<TargetGroup>,
+                HelpText<"Set GNU linker emulation">;
diff --git a/tools/mcld/include/mcld/DynamicSectionOptions.h b/tools/mcld/include/mcld/DynamicSectionOptions.h
deleted file mode 100644
index 2902118..0000000
--- a/tools/mcld/include/mcld/DynamicSectionOptions.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===- DynamicSectionOptions.h --------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_DYNAMIC_SECTION_OPTIONS_H
-#define MCLD_LDLITE_DYNAMIC_SECTION_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <mcld/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class ZOption;
-class LinkerConfig;
-class LinkerScript;
-
-class DynamicSectionOptions {
- public:
-  DynamicSectionOptions();
-
-  bool parse(LinkerConfig& pConfig, LinkerScript& pScript);
-
- private:
-  llvm::cl::opt<std::string>& m_Entry;
-  llvm::cl::opt<bool>& m_Bsymbolic;
-  llvm::cl::opt<bool>& m_Bgroup;
-  llvm::cl::opt<std::string>& m_SOName;
-  llvm::cl::opt<llvm::cl::boolOrDefault>& m_NoUndefined;
-  llvm::cl::opt<llvm::cl::boolOrDefault>& m_AllowMulDefs;
-  llvm::cl::list<ZOption, bool, llvm::cl::parser<ZOption> >& m_ZOptionList;
-  llvm::cl::opt<std::string>& m_Dyld;
-  llvm::cl::opt<bool>& m_EnableNewDTags;
-  llvm::cl::opt<unsigned>& m_NumSpareDTags;
-
-  llvm::cl::list<std::string>& m_Auxiliary;
-  llvm::cl::opt<std::string>& m_Filter;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/OptimizationOptions.h b/tools/mcld/include/mcld/OptimizationOptions.h
deleted file mode 100644
index 1016c87..0000000
--- a/tools/mcld/include/mcld/OptimizationOptions.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===- OptimizationOptions.h ----------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_OPTIMIZATION_OPTIONS_H
-#define MCLD_LDLITE_OPTIMIZATION_OPTIONS_H
-#include <mcld/GeneralOptions.h>
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class OptimizationOptions {
- public:
-  OptimizationOptions();
-
-  bool parse(LinkerConfig& pConfig);
-
- private:
-  bool& m_GCSections;
-  bool& m_PrintGCSections;
-  bool& m_GenUnwindInfo;
-  llvm::cl::opt<mcld::GeneralOptions::ICF>& m_ICF;
-  llvm::cl::opt<unsigned>& m_ICFIterations;
-  llvm::cl::opt<bool>& m_PrintICFSections;
-  llvm::cl::opt<char>& m_OptLevel;
-  llvm::cl::list<std::string>& m_Plugin;
-  llvm::cl::list<std::string>& m_PluginOpt;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/OutputFormatOptions.h b/tools/mcld/include/mcld/OutputFormatOptions.h
deleted file mode 100644
index 81810eb..0000000
--- a/tools/mcld/include/mcld/OutputFormatOptions.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===- OutputFormatOptions.h ----------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_OUTPUT_FORMAT_OPTIONS_H
-#define MCLD_LDLITE_OUTPUT_FORMAT_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <mcld/Support/CommandLine.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/GeneralOptions.h>
-#include <mcld/Support/Path.h>
-#include <mcld/MC/Input.h>
-#include <string>
-
-namespace mcld {
-
-class Module;
-
-class OutputFormatOptions {
- public:
-  OutputFormatOptions();
-
-  bool parse(Module& pModule, LinkerConfig& pConfig);
-
-  bool parseOutput(Module& pModule, LinkerConfig& pConfig);
-
- private:
-  llvm::cl::opt<mcld::sys::fs::Path,
-                false,
-                llvm::cl::parser<mcld::sys::fs::Path> >& m_OutputFilename;
-  llvm::cl::opt<mcld::LinkerConfig::CodeGenType>& m_FileType;
-  llvm::cl::opt<mcld::LinkerConfig::CodeGenType>& m_OFormat;
-  llvm::cl::opt<bool>& m_Shared;
-  llvm::cl::opt<bool>& m_PIE;
-  llvm::cl::opt<bool>& m_Relocatable;
-  llvm::cl::opt<mcld::Input::Type>& m_Format;
-  llvm::cl::opt<bool>& m_StripDebug;
-  llvm::cl::opt<bool>& m_StripAll;
-  llvm::cl::opt<bool>& m_DiscardAll;
-  llvm::cl::opt<bool>& m_DiscardLocals;
-  llvm::cl::opt<bool>& m_EhFrameHdr;
-  llvm::cl::opt<bool>& m_NMagic;
-  llvm::cl::opt<bool>& m_OMagic;
-  llvm::cl::opt<mcld::GeneralOptions::HashStyle>& m_HashStyle;
-
-  llvm::cl::opt<bool>& m_ExportDynamic;
-  llvm::cl::opt<std::string>& m_BuildID;
-  llvm::cl::list<std::string>& m_ExcludeLIBS;
-
-  llvm::cl::opt<bool>& m_NoWarnMismatch;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/PositionalOptions.h b/tools/mcld/include/mcld/PositionalOptions.h
deleted file mode 100644
index 326a2d0..0000000
--- a/tools/mcld/include/mcld/PositionalOptions.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//===- PositionalOptions.h ------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_POSITIONAL_OPTIONS_H
-#define MCLD_LDLITE_POSITIONAL_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <mcld/Support/CommandLine.h>
-#include <mcld/Support/Path.h>
-#include <string>
-
-namespace mcld {
-
-class InputAction;
-class LinkerConfig;
-class LinkerScript;
-
-/** \class PositionalOptions
- *
- *  The meaning of a positional option depends on its position and its related
- *  positions with the other positional options. There are four kinds of
- *  positional options:
- *   1. Inputs, object files, such as /tmp/XXXX.o
- *   2. Namespecs, short names of libraries. A namespec may refer to an archive
- *      or a shared library. For example, -lm.
- *   3. Attributes of inputs. Attributes describe inputs appears after them.
- *      For example, --as-needed and --whole-archive.
- *   4. Groups. A Group is a set of archives. Linkers repeatedly read archives
- *      in groups until there is no new undefined symbols.
- *   5. Definitions of symbols. --defsym option depends on
- */
-class PositionalOptions {
- public:
-  PositionalOptions();
-
-  size_t numOfInputs() const;
-
-  bool parse(std::vector<InputAction*>& pActions,
-             LinkerConfig& pConfig,
-             const LinkerScript& pScript);
-
- private:
-  size_t numOfActions() const;
-
- private:
-  llvm::cl::list<mcld::sys::fs::Path>& m_InputObjectFiles;
-  llvm::cl::list<std::string>& m_LinkerScript;
-  llvm::cl::list<std::string>& m_NameSpecList;
-  llvm::cl::list<bool>& m_WholeArchiveList;
-  llvm::cl::list<bool>& m_NoWholeArchiveList;
-  llvm::cl::list<bool>& m_AsNeededList;
-  llvm::cl::list<bool>& m_NoAsNeededList;
-  llvm::cl::list<bool>& m_AddNeededList;
-  llvm::cl::list<bool>& m_NoAddNeededList;
-  llvm::cl::list<bool>& m_BDynamicList;
-  llvm::cl::list<bool>& m_BStaticList;
-  llvm::cl::list<bool>& m_StartGroupList;
-  llvm::cl::list<bool>& m_EndGroupList;
-  llvm::cl::list<std::string>& m_DefSymList;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/PreferenceOptions.h b/tools/mcld/include/mcld/PreferenceOptions.h
deleted file mode 100644
index 523c133..0000000
--- a/tools/mcld/include/mcld/PreferenceOptions.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===- PreferenceOptions.h ------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_PREFERENCE_OPTIONS_H
-#define MCLD_LDLITE_PREFERENCE_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class PreferenceOptions {
- public:
-  enum Color { COLOR_Never, COLOR_Always, COLOR_Auto };
-
- public:
-  PreferenceOptions();
-
-  bool parse(LinkerConfig& pConfig);
-
- private:
-  llvm::cl::opt<bool>& m_Trace;
-  llvm::cl::opt<int>& m_Verbose;
-  llvm::cl::opt<bool>& m_Version;
-  llvm::cl::opt<int>& m_MaxErrorNum;
-  llvm::cl::opt<int>& m_MaxWarnNum;
-  llvm::cl::opt<Color>& m_Color;
-  llvm::cl::opt<bool>& m_PrintMap;
-  bool& m_FatalWarnings;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/ScriptOptions.h b/tools/mcld/include/mcld/ScriptOptions.h
deleted file mode 100644
index 55e3204..0000000
--- a/tools/mcld/include/mcld/ScriptOptions.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===- ScriptOptions.h ----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_SCRIPT_OPTIONS_H
-#define MCLD_LDLITE_SCRIPT_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerScript;
-
-/** \class ScriptOptions
- *  \brief ScriptOptions are used to modify the default link script. Some
- *  positional options, such as --defsym, also can modify default link script
- *  is not listed here. These special options belong to Positional Options.
- */
-class ScriptOptions {
- public:
-  ScriptOptions();
-
-  bool parse(LinkerScript& pScript);
-
- private:
-  llvm::cl::list<std::string>& m_WrapList;
-  llvm::cl::list<std::string>& m_PortList;
-  llvm::cl::list<std::string>& m_AddressMapList;
-  llvm::cl::opt<unsigned long long>& m_BssSegAddr;
-  llvm::cl::opt<unsigned long long>& m_DataSegAddr;
-  llvm::cl::opt<unsigned long long>& m_TextSegAddr;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/SearchPathOptions.h b/tools/mcld/include/mcld/SearchPathOptions.h
deleted file mode 100644
index ec5a956..0000000
--- a/tools/mcld/include/mcld/SearchPathOptions.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===- SearchPathOptions.h ------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_SEARCH_PATH_OPTIONS_H
-#define MCLD_LDLITE_SEARCH_PATH_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <mcld/Support/Path.h>
-#include <mcld/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-class LinkerScript;
-
-class SearchPathOptions {
- public:
-  SearchPathOptions();
-
-  bool parse(LinkerConfig& pConfig, LinkerScript& pScript);
-
- private:
-  llvm::cl::opt<mcld::sys::fs::Path,
-                false,
-                llvm::cl::parser<mcld::sys::fs::Path> >& m_SysRoot;
-  llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser>& m_SearchDirList;
-  llvm::cl::opt<bool>& m_NoStdlib;
-  llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser>& m_RuntimePath;
-
-  // not supported yet
-  llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser>&
-      m_RuntimePathLink;
-  llvm::cl::list<std::string>& m_Y;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/SymbolOptions.h b/tools/mcld/include/mcld/SymbolOptions.h
deleted file mode 100644
index 8e7124c..0000000
--- a/tools/mcld/include/mcld/SymbolOptions.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- SymbolOptions.h ----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_SYMBOL_OPTIONS_H
-#define MCLD_LDLITE_SYMBOL_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class SymbolOptions {
- public:
-  SymbolOptions();
-
-  bool parse(LinkerConfig& pConfig);
-
- private:
-  // not supported yet
-  llvm::cl::list<std::string>& m_ForceUndefined;
-  llvm::cl::opt<std::string>& m_VersionScript;
-  llvm::cl::opt<bool>& m_WarnCommon;
-  llvm::cl::opt<bool>& m_DefineCommon;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/TargetControlOptions.h b/tools/mcld/include/mcld/TargetControlOptions.h
deleted file mode 100644
index 1603452..0000000
--- a/tools/mcld/include/mcld/TargetControlOptions.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- TargetControlOptions.h ---------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_TARGET_CONTROL_OPTIONS_H
-#define MCLD_LDLITE_TARGET_CONTROL_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class TargetControlOptions {
- public:
-  TargetControlOptions();
-
-  bool parse(LinkerConfig& pConfig);
-
- private:
-  llvm::cl::opt<int>& m_GPSize;
-  llvm::cl::opt<bool>& m_WarnSharedTextrel;
-  llvm::cl::opt<bool>& m_FIXCA8;
-  llvm::cl::opt<bool>& m_FIXCA53Erratum835769;
-  llvm::cl::opt<bool>& m_EB;
-  llvm::cl::opt<bool>& m_EL;
-  llvm::cl::opt<bool>& m_SVR4Compatibility;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/TripleOptions.h b/tools/mcld/include/mcld/TripleOptions.h
deleted file mode 100644
index 7b10958..0000000
--- a/tools/mcld/include/mcld/TripleOptions.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===- TripleOptions.h ----------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_TRIPLE_OPTIONS_H
-#define MCLD_LDLITE_TRIPLE_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class TripleOptions {
- public:
-  TripleOptions();
-
-  bool parse(int pArgc, char* pArgv[], LinkerConfig& pConfig);
-
- private:
-  llvm::cl::opt<std::string>& m_TargetTriple;
-  llvm::cl::opt<std::string>& m_MArch;
-  llvm::cl::opt<std::string>& m_MCPU;
-  llvm::cl::opt<std::string>& m_Emulation;
-};
-
-}  // namespace of mcld
-
-#endif
diff --git a/tools/mcld/lib/DynamicSectionOptions.cpp b/tools/mcld/lib/DynamicSectionOptions.cpp
deleted file mode 100644
index 958a94d..0000000
--- a/tools/mcld/lib/DynamicSectionOptions.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-//===- DynamicSectionOptions.cpp ------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/DynamicSectionOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/MC/ZOption.h>
-
-namespace {
-
-llvm::cl::opt<std::string> ArgEntry(
-    "e",
-    llvm::cl::desc("Use the explicit symbol as the entrance of your program."),
-    llvm::cl::value_desc("entry"),
-    llvm::cl::ValueRequired);
-
-llvm::cl::alias ArgEntryAlias("entry",
-                              llvm::cl::desc("alias for -e"),
-                              llvm::cl::aliasopt(ArgEntry));
-
-llvm::cl::opt<bool> ArgBsymbolic(
-    "Bsymbolic",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Bind references within the shared library."),
-    llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgBgroup(
-    "Bgroup",
-    llvm::cl::desc("Info the dynamic linker to lookups only inside the group."),
-    llvm::cl::init(false));
-
-llvm::cl::opt<std::string> ArgSOName(
-    "soname",
-    llvm::cl::desc("Set internal name of shared library"),
-    llvm::cl::value_desc("name"));
-
-llvm::cl::opt<llvm::cl::boolOrDefault> ArgNoUndefined(
-    "no-undefined",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Do not allow unresolved references"));
-
-llvm::cl::opt<llvm::cl::boolOrDefault> ArgAllowMulDefs(
-    "allow-multiple-definition",
-    llvm::cl::desc("Allow multiple definition"));
-
-llvm::cl::list<mcld::ZOption, bool, llvm::cl::parser<mcld::ZOption> >
-    ArgZOptionList("z",
-                   llvm::cl::ZeroOrMore,
-                   llvm::cl::desc("The -z options for GNU ld compatibility."),
-                   llvm::cl::value_desc("keyword"),
-                   llvm::cl::Prefix);
-
-llvm::cl::opt<std::string> ArgDyld(
-    "dynamic-linker",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Set the name of the dynamic linker."),
-    llvm::cl::value_desc("Program"));
-
-llvm::cl::opt<bool> ArgEnableNewDTags(
-    "enable-new-dtags",
-    llvm::cl::desc("Enable use of DT_RUNPATH and DT_FLAGS"),
-    llvm::cl::init(false));
-
-llvm::cl::opt<unsigned> ArgNumSpareDTags(
-    "spare-dynamic-tags",
-    llvm::cl::desc("Set the number of spare dyanmic tags (DT_NULL)"),
-    llvm::cl::init(5));
-
-// Not supported yet {
-llvm::cl::list<std::string> ArgAuxiliary(
-    "f",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Auxiliary filter for shared object symbol table"),
-    llvm::cl::value_desc("name"));
-
-llvm::cl::alias ArgAuxiliaryAlias("auxiliary",
-                                  llvm::cl::desc("alias for -f"),
-                                  llvm::cl::aliasopt(ArgAuxiliary));
-
-llvm::cl::opt<std::string> ArgFilter(
-    "F",
-    llvm::cl::desc("Filter for shared object symbol table"),
-    llvm::cl::value_desc("name"));
-
-llvm::cl::alias ArgFilterAlias("filter",
-                               llvm::cl::desc("alias for -F"),
-                               llvm::cl::aliasopt(ArgFilter));
-
-// } Not supported yet
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// DynamicSectionOptions
-//===----------------------------------------------------------------------===//
-DynamicSectionOptions::DynamicSectionOptions()
-    : m_Entry(ArgEntry),
-      m_Bsymbolic(ArgBsymbolic),
-      m_Bgroup(ArgBgroup),
-      m_SOName(ArgSOName),
-      m_NoUndefined(ArgNoUndefined),
-      m_AllowMulDefs(ArgAllowMulDefs),
-      m_ZOptionList(ArgZOptionList),
-      m_Dyld(ArgDyld),
-      m_EnableNewDTags(ArgEnableNewDTags),
-      m_NumSpareDTags(ArgNumSpareDTags),
-      m_Auxiliary(ArgAuxiliary),
-      m_Filter(ArgFilter) {
-}
-
-bool DynamicSectionOptions::parse(LinkerConfig& pConfig,
-                                  LinkerScript& pScript) {
-  // set up entry point from -e
-  pScript.setEntry(m_Entry);
-
-  // --Bsymbolic
-  pConfig.options().setBsymbolic(m_Bsymbolic);
-
-  // --Bgroup
-  pConfig.options().setBgroup(m_Bgroup);
-
-  // set --soname [soname]
-  pConfig.options().setSOName(m_SOName);
-
-  // set -z options
-  llvm::cl::list<ZOption>::iterator zOpt;
-  llvm::cl::list<ZOption>::iterator zOptEnd = m_ZOptionList.end();
-  for (zOpt = m_ZOptionList.begin(); zOpt != zOptEnd; ++zOpt) {
-    pConfig.options().addZOption(*zOpt);
-  }
-
-  // set --no-undefined
-  if (llvm::cl::BOU_UNSET != m_NoUndefined)
-    pConfig.options().setNoUndefined(llvm::cl::BOU_TRUE == m_NoUndefined);
-
-  // set --allow-multiple-definition
-  if (llvm::cl::BOU_UNSET != m_AllowMulDefs)
-    pConfig.options().setMulDefs(llvm::cl::BOU_TRUE == m_AllowMulDefs);
-
-  // set --dynamic-linker [dyld]
-  pConfig.options().setDyld(m_Dyld);
-
-  // set --enable-new-dtags
-  pConfig.options().setNewDTags(m_EnableNewDTags);
-
-  // set --spare-dyanmic-tags
-  pConfig.options().setNumSpareDTags(m_NumSpareDTags);
-
-  // set --auxiliary, -f
-  llvm::cl::list<std::string>::iterator aux;
-  llvm::cl::list<std::string>::iterator auxEnd = m_Auxiliary.end();
-  for (aux = m_Auxiliary.begin(); aux != auxEnd; ++aux)
-    pConfig.options().getAuxiliaryList().push_back(*aux);
-
-  // set --filter, -F
-  pConfig.options().setFilter(m_Filter);
-
-  return true;
-}
diff --git a/tools/mcld/lib/OptimizationOptions.cpp b/tools/mcld/lib/OptimizationOptions.cpp
deleted file mode 100644
index 50ea73f..0000000
--- a/tools/mcld/lib/OptimizationOptions.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-//===- OptimizationOptions.cpp --------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/OptimizationOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/Support/CommandLine.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-bool ArgGCSections;
-
-llvm::cl::opt<bool, true> ArgGCSectionsFlag(
-    "gc-sections",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::location(ArgGCSections),
-    llvm::cl::desc("Enable garbage collection of unused input sections."),
-    llvm::cl::init(false));
-
-llvm::cl::opt<bool, true> ArgNoGCSectionsFlag(
-    "no-gc-sections",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::location(ArgGCSections),
-    llvm::cl::desc("disable garbage collection of unused input sections."),
-    llvm::cl::init(false));
-
-bool ArgPrintGCSections;
-
-llvm::cl::opt<bool, true> ArgPrintGCSectionsFlag(
-    "print-gc-sections",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::location(ArgPrintGCSections),
-    llvm::cl::desc("List all sections removed by garbage collection."),
-    llvm::cl::init(false));
-
-llvm::cl::opt<bool, true> ArgNoPrintGCSectionsFlag(
-    "no-print-gc-sections",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::location(ArgPrintGCSections),
-    llvm::cl::desc("disable --print-gc-sections"),
-    llvm::cl::init(false));
-
-bool ArgGenUnwindInfo;
-
-llvm::cl::opt<bool, true> ArgNoGenUnwindInfoFlag(
-    "no-ld-generated-unwind-info",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::location(ArgGenUnwindInfo),
-    llvm::cl::desc(
-        "Don't create unwind info for linker"
-        " generated sections to save size"),
-    llvm::cl::init(false),
-    llvm::cl::ValueDisallowed);
-llvm::cl::opt<bool, true> ArgGenUnwindInfoFlag(
-    "ld-generated-unwind-info",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::location(ArgGenUnwindInfo),
-    llvm::cl::desc(
-        "Request creation of unwind info for linker"
-        " generated code sections like PLT."),
-    llvm::cl::init(true),
-    llvm::cl::ValueDisallowed);
-
-llvm::cl::opt<mcld::GeneralOptions::ICF> ArgICF(
-    "icf",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Identical Code Folding"),
-    llvm::cl::init(mcld::GeneralOptions::ICF_None),
-    llvm::cl::values(
-        clEnumValN(mcld::GeneralOptions::ICF_None,
-                   "none",
-                   "do not perform cold folding"),
-        clEnumValN(mcld::GeneralOptions::ICF_All,
-                   "all",
-                   "always preform cold folding"),
-        clEnumValN(mcld::GeneralOptions::ICF_Safe,
-                   "safe",
-                   "Folds those whose pointers are definitely not taken."),
-        clEnumValEnd));
-
-llvm::cl::opt<unsigned> ArgICFIterations(
-    "icf-iterations",
-    llvm::cl::desc("Number of iterations to do ICF."),
-    llvm::cl::init(2));
-
-llvm::cl::opt<bool> ArgPrintICFSections(
-    "print-icf-sections",
-    llvm::cl::desc("Print the folded identical sections."),
-    llvm::cl::init(false));
-
-llvm::cl::opt<char> ArgOptLevel(
-    "O",
-    llvm::cl::desc(
-        "Optimization level. [-O0, -O1, -O2, or -O3] "
-        "(default = '-O2')"),
-    llvm::cl::Prefix,
-    llvm::cl::ZeroOrMore,
-    llvm::cl::init(' '));
-
-llvm::cl::list<std::string> ArgPlugin("plugin",
-                                      llvm::cl::desc("Load a plugin library."),
-                                      llvm::cl::value_desc("plugin"));
-
-llvm::cl::list<std::string> ArgPluginOpt(
-    "plugin-opt",
-    llvm::cl::desc("Pass an option to the plugin."),
-    llvm::cl::value_desc("option"));
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// OptimizationOptions
-//===----------------------------------------------------------------------===//
-OptimizationOptions::OptimizationOptions()
-    : m_GCSections(ArgGCSections),
-      m_PrintGCSections(ArgPrintGCSections),
-      m_GenUnwindInfo(ArgGenUnwindInfo),
-      m_ICF(ArgICF),
-      m_ICFIterations(ArgICFIterations),
-      m_PrintICFSections(ArgPrintICFSections),
-      m_OptLevel(ArgOptLevel),
-      m_Plugin(ArgPlugin),
-      m_PluginOpt(ArgPluginOpt) {
-}
-
-bool OptimizationOptions::parse(LinkerConfig& pConfig) {
-  // set --gc-sections
-  if (m_GCSections)
-    pConfig.options().setGCSections();
-
-  // set --print-gc-sections
-  if (m_PrintGCSections)
-    pConfig.options().setPrintGCSections();
-
-  // set --ld-generated-unwind-info (or not)
-  pConfig.options().setGenUnwindInfo(m_GenUnwindInfo);
-
-  // set --icf [mode]
-  pConfig.options().setICFMode(m_ICF);
-  pConfig.options().setICFIterations(m_ICFIterations);
-  pConfig.options().setPrintICFSections(m_PrintICFSections);
-
-  return true;
-}
diff --git a/tools/mcld/lib/OutputFormatOptions.cpp b/tools/mcld/lib/OutputFormatOptions.cpp
deleted file mode 100644
index 5dd91c7..0000000
--- a/tools/mcld/lib/OutputFormatOptions.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-//===- OutputFormatOptions.cpp --------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/OutputFormatOptions.h>
-#include <mcld/Module.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-llvm::cl::opt<mcld::sys::fs::Path,
-              false,
-              llvm::cl::parser<mcld::sys::fs::Path> >
-    ArgOutputFilename("o",
-                      llvm::cl::desc("Output filename"),
-                      llvm::cl::value_desc("filename"));
-
-llvm::cl::alias AliasOutputFilename("output",
-                                    llvm::cl::desc("alias for -o"),
-                                    llvm::cl::aliasopt(ArgOutputFilename));
-
-llvm::cl::opt<mcld::LinkerConfig::CodeGenType> ArgFileType(
-    "filetype",
-    llvm::cl::init(mcld::LinkerConfig::Exec),
-    llvm::cl::desc(
-        "Choose a file type\n"
-        "(not all types are supported by all targets):"),
-    llvm::cl::values(
-        clEnumValN(mcld::LinkerConfig::Object,
-                   "obj",
-                   "Emit a relocatable object ('.o') file"),
-        clEnumValN(mcld::LinkerConfig::DynObj,
-                   "dso",
-                   "Emit an dynamic shared object ('.so') file"),
-        clEnumValN(mcld::LinkerConfig::Exec,
-                   "exe",
-                   "Emit an executable ('.exe') file"),
-        clEnumValN(mcld::LinkerConfig::Binary, "bin", "Emit a binary file"),
-        clEnumValN(mcld::LinkerConfig::External,
-                   "null",
-                   "Emit nothing for performance testing"),
-        clEnumValEnd));
-
-llvm::cl::opt<mcld::LinkerConfig::CodeGenType> ArgOFormat(
-    "oformat",
-    llvm::cl::value_desc("Format"),
-    llvm::cl::desc("set output format"),
-    llvm::cl::init(mcld::LinkerConfig::Unknown),
-    llvm::cl::values(clEnumValN(mcld::LinkerConfig::Binary,
-                                "binary",
-                                "generate binary machine code."),
-                     clEnumValEnd));
-
-llvm::cl::opt<bool> ArgShared("shared",
-                              llvm::cl::ZeroOrMore,
-                              llvm::cl::desc("Create a shared library."),
-                              llvm::cl::init(false));
-
-llvm::cl::alias ArgSharedAlias("Bshareable",
-                               llvm::cl::desc("alias for -shared"),
-                               llvm::cl::aliasopt(ArgShared));
-
-llvm::cl::opt<bool> ArgPIE(
-    "pie",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Emit a position-independent executable file"),
-    llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgRelocatable(
-    "relocatable",
-    llvm::cl::desc("Generate relocatable output"),
-    llvm::cl::init(false));
-
-llvm::cl::alias ArgRelocatableAlias("r",
-                                    llvm::cl::desc("alias for --relocatable"),
-                                    llvm::cl::aliasopt(ArgRelocatable));
-
-llvm::cl::opt<mcld::Input::Type> ArgFormat(
-    "b",
-    llvm::cl::value_desc("Format"),
-    llvm::cl::desc("set input format"),
-    llvm::cl::init(mcld::Input::Unknown),
-    llvm::cl::values(clEnumValN(mcld::Input::Binary,
-                                "binary",
-                                "read in binary machine code."),
-                     clEnumValEnd));
-
-llvm::cl::alias ArgFormatAlias("format",
-                               llvm::cl::desc("alias for -b"),
-                               llvm::cl::aliasopt(ArgFormat));
-
-llvm::cl::opt<bool> ArgStripDebug(
-    "strip-debug",
-    llvm::cl::desc("Omit debugger symbol information from the output file."),
-    llvm::cl::init(false));
-
-llvm::cl::alias ArgStripDebugAlias("S",
-                                   llvm::cl::desc("alias for --strip-debug"),
-                                   llvm::cl::aliasopt(ArgStripDebug));
-
-llvm::cl::opt<bool> ArgStripAll(
-    "strip-all",
-    llvm::cl::desc("Omit all symbol information from the output file."),
-    llvm::cl::init(false));
-
-llvm::cl::alias ArgStripAllAlias("s",
-                                 llvm::cl::desc("alias for --strip-all"),
-                                 llvm::cl::aliasopt(ArgStripAll));
-
-llvm::cl::opt<bool> ArgDiscardAll("discard-all",
-                                  llvm::cl::desc("Delete all local symbols."),
-                                  llvm::cl::init(false));
-
-llvm::cl::alias ArgDiscardAllAlias("x",
-                                   llvm::cl::desc("alias for --discard-all"),
-                                   llvm::cl::aliasopt(ArgDiscardAll));
-
-llvm::cl::opt<bool> ArgDiscardLocals(
-    "discard-locals",
-    llvm::cl::desc("Delete all temporary local symbols."),
-    llvm::cl::init(false));
-
-llvm::cl::alias ArgDiscardLocalsAlias(
-    "X",
-    llvm::cl::desc("alias for --discard-locals"),
-    llvm::cl::aliasopt(ArgDiscardLocals));
-
-llvm::cl::opt<bool> ArgEhFrameHdr(
-    "eh-frame-hdr",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc(
-        "Request creation of \".eh_frame_hdr\" section and\n"
-        "ELF \"PT_GNU_EH_FRAME\" segment header."),
-    llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgNMagic("nmagic",
-                              llvm::cl::desc("Do not page align data"),
-                              llvm::cl::init(false));
-
-llvm::cl::alias ArgNMagicAlias("n",
-                               llvm::cl::desc("alias for --nmagic"),
-                               llvm::cl::aliasopt(ArgNMagic));
-
-llvm::cl::opt<bool> ArgOMagic(
-    "omagic",
-    llvm::cl::desc("Do not page align data, do not make text readonly"),
-    llvm::cl::init(false));
-
-llvm::cl::alias ArgOMagicAlias("N",
-                               llvm::cl::desc("alias for --omagic"),
-                               llvm::cl::aliasopt(ArgOMagic));
-
-llvm::cl::opt<mcld::GeneralOptions::HashStyle> ArgHashStyle(
-    "hash-style",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::init(mcld::GeneralOptions::SystemV),
-    llvm::cl::desc("Set the type of linker's hash table(s)."),
-    llvm::cl::values(
-        clEnumValN(mcld::GeneralOptions::SystemV,
-                   "sysv",
-                   "classic ELF .hash section"),
-        clEnumValN(mcld::GeneralOptions::GNU,
-                   "gnu",
-                   "new style GNU .gnu.hash section"),
-        clEnumValN(mcld::GeneralOptions::Both,
-                   "both",
-                   "both the classic ELF and new style GNU hash tables"),
-        clEnumValEnd));
-
-llvm::cl::opt<bool> ArgNoWarnMismatch(
-    "no-warn-mismatch",
-    llvm::cl::desc("Allow linking together mismatched input files."),
-    llvm::cl::init(false));
-
-// Not supported yet {
-llvm::cl::opt<bool> ArgExportDynamic(
-    "export-dynamic",
-    llvm::cl::desc("Export all dynamic symbols"),
-    llvm::cl::init(false));
-
-llvm::cl::alias ArgExportDynamicAlias(
-    "E",
-    llvm::cl::desc("alias for --export-dynamic"),
-    llvm::cl::aliasopt(ArgExportDynamic));
-
-llvm::cl::opt<std::string> ArgBuildID(
-    "build-id",
-    llvm::cl::desc(
-        "Request creation of \".note.gnu.build-id\" ELF note section."),
-    llvm::cl::value_desc("style"),
-    llvm::cl::ValueOptional);
-
-llvm::cl::list<std::string> ArgExcludeLIBS(
-    "exclude-libs",
-    llvm::cl::CommaSeparated,
-    llvm::cl::desc("Exclude libraries from automatic export"),
-    llvm::cl::value_desc("lib1,lib2,..."));
-
-// } Not supported yet
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// OutputFormatOptions
-//===----------------------------------------------------------------------===//
-OutputFormatOptions::OutputFormatOptions()
-    : m_OutputFilename(ArgOutputFilename),
-      m_FileType(ArgFileType),
-      m_OFormat(ArgOFormat),
-      m_Shared(ArgShared),
-      m_PIE(ArgPIE),
-      m_Relocatable(ArgRelocatable),
-      m_Format(ArgFormat),
-      m_StripDebug(ArgStripDebug),
-      m_StripAll(ArgStripAll),
-      m_DiscardAll(ArgDiscardAll),
-      m_DiscardLocals(ArgDiscardLocals),
-      m_EhFrameHdr(ArgEhFrameHdr),
-      m_NMagic(ArgNMagic),
-      m_OMagic(ArgOMagic),
-      m_HashStyle(ArgHashStyle),
-      m_ExportDynamic(ArgExportDynamic),
-      m_BuildID(ArgBuildID),
-      m_ExcludeLIBS(ArgExcludeLIBS),
-      m_NoWarnMismatch(ArgNoWarnMismatch) {
-}
-
-bool OutputFormatOptions::parse(mcld::Module& pModule, LinkerConfig& pConfig) {
-  if (!parseOutput(pModule, pConfig)) {
-    mcld::unreachable(mcld::diag::unrecognized_output_file) << pModule.name();
-    return false;
-  }
-
-  if (mcld::Input::Binary == m_Format)
-    pConfig.options().setBinaryInput();
-
-  pConfig.options().setStripDebug(m_StripDebug || m_StripAll);
-  if (m_StripAll)
-    pConfig.options().setStripSymbols(mcld::GeneralOptions::StripAllSymbols);
-  else if (m_DiscardAll)
-    pConfig.options().setStripSymbols(mcld::GeneralOptions::StripLocals);
-  else if (m_DiscardLocals)
-    pConfig.options().setStripSymbols(mcld::GeneralOptions::StripTemporaries);
-  else
-    pConfig.options().setStripSymbols(mcld::GeneralOptions::KeepAllSymbols);
-
-  pConfig.options().setEhFrameHdr(m_EhFrameHdr);
-  pConfig.options().setPIE(m_PIE);
-  pConfig.options().setNMagic(m_NMagic);
-  pConfig.options().setOMagic(m_OMagic);
-  pConfig.options().setHashStyle(m_HashStyle);
-  pConfig.options().setExportDynamic(m_ExportDynamic);
-
-  // --exclude-libs
-  llvm::cl::list<std::string>::iterator exclude,
-      excludeEnd = m_ExcludeLIBS.end();
-  for (exclude = m_ExcludeLIBS.begin(); exclude != excludeEnd; ++exclude) {
-    pConfig.options().excludeLIBS().insert(*exclude);
-  }
-
-  if (m_NoWarnMismatch)
-    pConfig.options().setWarnMismatch(false);
-  else
-    pConfig.options().setWarnMismatch(true);
-  // build-id
-  // exclude-libs
-
-  return true;
-}
-
-/// configure the output filename
-bool OutputFormatOptions::parseOutput(Module& pModule, LinkerConfig& pConfig) {
-  if (true == m_Shared || true == m_PIE) {
-    // -shared or -pie
-    m_FileType = mcld::LinkerConfig::DynObj;
-  } else if (true == m_Relocatable) {
-    // partial linking
-    m_FileType = mcld::LinkerConfig::Object;
-  } else if (mcld::LinkerConfig::Binary == m_OFormat) {
-    // binary output
-    m_FileType = mcld::LinkerConfig::Binary;
-  }
-
-  pConfig.setCodeGenType(m_FileType);
-
-  std::string output_filename(m_OutputFilename.native());
-
-  if (m_OutputFilename.empty()) {
-    if (llvm::Triple::Win32 == pConfig.targets().triple().getOS()) {
-      output_filename.assign("_out");
-      switch (m_FileType) {
-        case mcld::LinkerConfig::Object: {
-          output_filename += ".obj";
-          break;
-        }
-        case mcld::LinkerConfig::DynObj: {
-          output_filename += ".dll";
-          break;
-        }
-        case mcld::LinkerConfig::Exec: {
-          output_filename += ".exe";
-          break;
-        }
-        case mcld::LinkerConfig::External:
-          break;
-        default: {
-          return false;
-          break;
-        }
-      }  // switch
-    } else {
-      if (mcld::LinkerConfig::Object == m_FileType ||
-          mcld::LinkerConfig::DynObj == m_FileType ||
-          mcld::LinkerConfig::Exec == m_FileType ||
-          mcld::LinkerConfig::External == m_FileType) {
-        output_filename.assign("a.out");
-      } else {
-        return false;
-      }
-    }
-  }  // end of if empty m_OutputFilename
-
-  pModule.setName(output_filename);
-  return true;
-}
diff --git a/tools/mcld/lib/PositionalOptions.cpp b/tools/mcld/lib/PositionalOptions.cpp
deleted file mode 100644
index 43d271b..0000000
--- a/tools/mcld/lib/PositionalOptions.cpp
+++ /dev/null
@@ -1,346 +0,0 @@
-//===- PositionalOptions.cpp ----------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/PositionalOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/MC/InputAction.h>
-#include <mcld/MC/CommandAction.h>
-#include <mcld/MC/FileAction.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-//===----------------------------------------------------------------------===//
-// Normal input files
-//===----------------------------------------------------------------------===//
-llvm::cl::list<mcld::sys::fs::Path> ArgInputObjectFiles(
-    llvm::cl::Positional,
-    llvm::cl::desc("[input object files]"),
-    llvm::cl::ZeroOrMore);
-
-// --script is an alias, but cl::alias doesn't work correctly with cl::list.
-llvm::cl::list<std::string> ArgLinkerScript("T",
-                                            llvm::cl::ZeroOrMore,
-                                            llvm::cl::desc("Linker script"),
-                                            llvm::cl::value_desc("file"));
-
-//===----------------------------------------------------------------------===//
-// Namespecs
-//===----------------------------------------------------------------------===//
-llvm::cl::list<std::string> ArgNameSpecList(
-    "l",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc(
-        "Add the archive or object file specified by namespec to\n"
-        "the list of files to link."),
-    llvm::cl::value_desc("namespec"),
-    llvm::cl::Prefix);
-
-llvm::cl::alias ArgNameSpecListAlias("library",
-                                     llvm::cl::desc("alias for -l"),
-                                     llvm::cl::aliasopt(ArgNameSpecList));
-
-//===----------------------------------------------------------------------===//
-// Attributes
-//===----------------------------------------------------------------------===//
-llvm::cl::list<bool> ArgWholeArchiveList(
-    "whole-archive",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc(
-        "For each archive mentioned on the command line after\n"
-        "the --whole-archive option, include all object files\n"
-        "in the archive."));
-
-llvm::cl::list<bool> ArgNoWholeArchiveList(
-    "no-whole-archive",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc(
-        "Turn off the effect of the --whole-archive option for\n"
-        "subsequent archive files."));
-
-llvm::cl::list<bool> ArgAsNeededList(
-    "as-needed",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc(
-        "This option affects ELF DT_NEEDED tags for dynamic\n"
-        "libraries mentioned on the command line after the\n"
-        "--as-needed option."));
-
-llvm::cl::list<bool> ArgNoAsNeededList(
-    "no-as-needed",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc(
-        "Turn off the effect of the --as-needed option for\n"
-        "subsequent dynamic libraries"));
-
-llvm::cl::list<bool> ArgAddNeededList(
-    "add-needed",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc(
-        "--add-needed causes DT_NEEDED tags are always\n"
-        "emitted for those libraries from DT_NEEDED tags.\n"
-        "This is the default behavior."));
-
-llvm::cl::list<bool> ArgNoAddNeededList(
-    "no-add-needed",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc(
-        "--no-add-needed causes DT_NEEDED tags will never be\n"
-        "emitted for those libraries from DT_NEEDED tags"));
-
-llvm::cl::list<bool> ArgBDynamicList(
-    "Bdynamic",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc("Link against dynamic library"));
-
-llvm::cl::alias ArgBDynamicListAlias1("dy",
-                                      llvm::cl::desc("alias for --Bdynamic"),
-                                      llvm::cl::aliasopt(ArgBDynamicList));
-
-llvm::cl::alias ArgBDynamicListAlias2("call_shared",
-                                      llvm::cl::desc("alias for --Bdynamic"),
-                                      llvm::cl::aliasopt(ArgBDynamicList));
-
-llvm::cl::list<bool> ArgBStaticList(
-    "Bstatic",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc("Link against static library"));
-
-llvm::cl::alias ArgBStaticListAlias1("dn",
-                                     llvm::cl::desc("alias for --Bstatic"),
-                                     llvm::cl::aliasopt(ArgBStaticList));
-
-llvm::cl::alias ArgBStaticListAlias2("static",
-                                     llvm::cl::desc("alias for --Bstatic"),
-                                     llvm::cl::aliasopt(ArgBStaticList));
-
-llvm::cl::alias ArgBStaticListAlias3("non_shared",
-                                     llvm::cl::desc("alias for --Bstatic"),
-                                     llvm::cl::aliasopt(ArgBStaticList));
-
-//===----------------------------------------------------------------------===//
-// Groups
-//===----------------------------------------------------------------------===//
-llvm::cl::list<bool> ArgStartGroupList(
-    "start-group",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc("start to record a group of archives"));
-
-llvm::cl::alias ArgStartGroupListAlias(
-    "(",
-    llvm::cl::desc("alias for --start-group"),
-    llvm::cl::aliasopt(ArgStartGroupList));
-
-llvm::cl::list<bool> ArgEndGroupList(
-    "end-group",
-    llvm::cl::ValueDisallowed,
-    llvm::cl::desc("stop recording a group of archives"));
-
-llvm::cl::alias ArgEndGroupListAlias(")",
-                                     llvm::cl::desc("alias for --end-group"),
-                                     llvm::cl::aliasopt(ArgEndGroupList));
-
-//===----------------------------------------------------------------------===//
-// --defsym
-//===----------------------------------------------------------------------===//
-llvm::cl::list<std::string> ArgDefSymList(
-    "defsym",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Define a symbol"),
-    llvm::cl::value_desc("symbol=expression"));
-
-//===----------------------------------------------------------------------===//
-// Help Functions
-//===----------------------------------------------------------------------===//
-inline bool CompareAction(const mcld::InputAction* X,
-                          const mcld::InputAction* Y) {
-  return (X->position() < Y->position());
-}
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// PositionalOptions
-//===----------------------------------------------------------------------===//
-PositionalOptions::PositionalOptions()
-    : m_InputObjectFiles(ArgInputObjectFiles),
-      m_LinkerScript(ArgLinkerScript),
-      m_NameSpecList(ArgNameSpecList),
-      m_WholeArchiveList(ArgWholeArchiveList),
-      m_NoWholeArchiveList(ArgNoWholeArchiveList),
-      m_AsNeededList(ArgAsNeededList),
-      m_NoAsNeededList(ArgNoAsNeededList),
-      m_AddNeededList(ArgAddNeededList),
-      m_NoAddNeededList(ArgNoAddNeededList),
-      m_BDynamicList(ArgBDynamicList),
-      m_BStaticList(ArgBStaticList),
-      m_StartGroupList(ArgStartGroupList),
-      m_EndGroupList(ArgEndGroupList),
-      m_DefSymList(ArgDefSymList) {
-}
-
-size_t PositionalOptions::numOfActions() const {
-  return m_InputObjectFiles.size() + m_LinkerScript.size() +
-         m_NameSpecList.size() + m_WholeArchiveList.size() +
-         m_NoWholeArchiveList.size() + m_AsNeededList.size() +
-         m_NoAsNeededList.size() + m_AddNeededList.size() +
-         m_NoAddNeededList.size() + m_BDynamicList.size() +
-         m_BStaticList.size() + m_StartGroupList.size() +
-         m_EndGroupList.size() + m_DefSymList.size();
-}
-
-size_t PositionalOptions::numOfInputs() const {
-  return (m_InputObjectFiles.size() + m_LinkerScript.size() +
-          m_NameSpecList.size());
-}
-
-bool PositionalOptions::parse(std::vector<InputAction*>& pActions,
-                              LinkerConfig& pConfig,
-                              const LinkerScript& pScript) {
-  if (0 == numOfInputs()) {
-    fatal(diag::err_no_inputs);
-    return false;
-  }
-
-  pActions.reserve(numOfActions());
-
-  // -T/--script
-  // FIXME:
-  llvm::cl::list<std::string>::iterator sp;
-  llvm::cl::list<std::string>::iterator spEnd = m_LinkerScript.end();
-  for (sp = m_LinkerScript.begin(); sp != spEnd; ++sp) {
-    pConfig.options().getScriptList().push_back(*sp);
-
-    pActions.push_back(new ScriptAction(
-        0x0, *sp, ScriptFile::LDScript, pScript.directories()));
-    pActions.push_back(new ContextAction(0x0));
-    pActions.push_back(new MemoryAreaAction(0x0, FileHandle::ReadOnly));
-  }
-
-  // --defsym
-  llvm::cl::list<std::string>::iterator defsym, dsBegin, dsEnd;
-  dsBegin = m_DefSymList.begin();
-  dsEnd = m_DefSymList.end();
-  for (defsym = dsBegin; defsym != dsEnd; ++defsym) {
-    unsigned int pos = m_DefSymList.getPosition(defsym - dsBegin);
-    pActions.push_back(new DefSymAction(pos, *defsym));
-  }
-
-  // set input
-  llvm::cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd;
-  inBegin = m_InputObjectFiles.begin();
-  inEnd = m_InputObjectFiles.end();
-  for (input = inBegin; input != inEnd; ++input) {
-    unsigned int pos = m_InputObjectFiles.getPosition(input - inBegin);
-    pActions.push_back(new InputFileAction(pos, *input));
-    pActions.push_back(new ContextAction(pos));
-    pActions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
-  }
-
-  // set -l[namespec]
-  llvm::cl::list<std::string>::iterator namespec, nsBegin, nsEnd;
-  nsBegin = m_NameSpecList.begin();
-  nsEnd = m_NameSpecList.end();
-  for (namespec = nsBegin; namespec != nsEnd; ++namespec) {
-    unsigned int pos = m_NameSpecList.getPosition(namespec - nsBegin);
-    pActions.push_back(
-        new NamespecAction(pos, *namespec, pScript.directories()));
-    pActions.push_back(new ContextAction(pos));
-    pActions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
-  }
-
-  // set --whole-archive
-  llvm::cl::list<bool>::iterator attr, attrBegin, attrEnd;
-  attrBegin = m_WholeArchiveList.begin();
-  attrEnd = m_WholeArchiveList.end();
-  for (attr = attrBegin; attr != attrEnd; ++attr) {
-    unsigned int pos = m_WholeArchiveList.getPosition(attr - attrBegin);
-    pActions.push_back(new WholeArchiveAction(pos));
-  }
-
-  // set --no-whole-archive
-  attrBegin = m_NoWholeArchiveList.begin();
-  attrEnd = m_NoWholeArchiveList.end();
-  for (attr = attrBegin; attr != attrEnd; ++attr) {
-    unsigned int pos = m_NoWholeArchiveList.getPosition(attr - attrBegin);
-    pActions.push_back(new NoWholeArchiveAction(pos));
-  }
-
-  // set --as-needed
-  attrBegin = m_AsNeededList.begin();
-  attrEnd = m_AsNeededList.end();
-  for (attr = attrBegin; attr != attrEnd; ++attr) {
-    unsigned int pos = m_AsNeededList.getPosition(attr - attrBegin);
-    pActions.push_back(new AsNeededAction(pos));
-  }
-
-  // set --no-as-needed
-  attrBegin = m_NoAsNeededList.begin();
-  attrEnd = m_NoAsNeededList.end();
-  for (attr = attrBegin; attr != attrEnd; ++attr) {
-    unsigned int pos = m_NoAsNeededList.getPosition(attr - attrBegin);
-    pActions.push_back(new NoAsNeededAction(pos));
-  }
-
-  // set --add--needed
-  attrBegin = m_AddNeededList.begin();
-  attrEnd = m_AddNeededList.end();
-  for (attr = attrBegin; attr != attrEnd; ++attr) {
-    unsigned int pos = m_AddNeededList.getPosition(attr - attrBegin);
-    pActions.push_back(new AddNeededAction(pos));
-  }
-
-  // set --no-add--needed
-  attrBegin = m_NoAddNeededList.begin();
-  attrEnd = m_NoAddNeededList.end();
-  for (attr = attrBegin; attr != attrEnd; ++attr) {
-    unsigned int pos = m_NoAddNeededList.getPosition(attr - attrBegin);
-    pActions.push_back(new NoAddNeededAction(pos));
-  }
-
-  // set --Bdynamic
-  attrBegin = m_BDynamicList.begin();
-  attrEnd = m_BDynamicList.end();
-  for (attr = attrBegin; attr != attrEnd; ++attr) {
-    unsigned int pos = m_BDynamicList.getPosition(attr - attrBegin);
-    pActions.push_back(new BDynamicAction(pos));
-  }
-
-  // set --Bstatic
-  attrBegin = m_BStaticList.begin();
-  attrEnd = m_BStaticList.end();
-  for (attr = attrBegin; attr != attrEnd; ++attr) {
-    unsigned int pos = m_BStaticList.getPosition(attr - attrBegin);
-    pActions.push_back(new BStaticAction(pos));
-  }
-
-  // set --start-group
-  llvm::cl::list<bool>::iterator group, gsBegin, gsEnd;
-  gsBegin = m_StartGroupList.begin();
-  gsEnd = m_StartGroupList.end();
-  for (group = gsBegin; group != gsEnd; ++group) {
-    unsigned int pos = m_StartGroupList.getPosition(group - gsBegin);
-    pActions.push_back(new StartGroupAction(pos));
-  }
-
-  // set --end-group
-  gsBegin = m_EndGroupList.begin();
-  gsEnd = m_EndGroupList.end();
-  for (group = gsBegin; group != gsEnd; ++group) {
-    unsigned int pos = m_EndGroupList.getPosition(group - gsBegin);
-    pActions.push_back(new EndGroupAction(pos));
-  }
-
-  // stable sort
-  std::stable_sort(pActions.begin(), pActions.end(), CompareAction);
-
-  return true;
-}
diff --git a/tools/mcld/lib/PreferenceOptions.cpp b/tools/mcld/lib/PreferenceOptions.cpp
deleted file mode 100644
index ec20d88..0000000
--- a/tools/mcld/lib/PreferenceOptions.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-//===- PreferenceOptions.cpp ----------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/PreferenceOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/Support/CommandLine.h>
-#include <mcld/Support/raw_ostream.h>
-#include <llvm/Support/Process.h>
-
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#include <io.h>
-#ifndef STDIN_FILENO
-#define STDIN_FILENO 0
-#endif
-#ifndef STDOUT_FILENO
-#define STDOUT_FILENO 1
-#endif
-#ifndef STDERR_FILENO
-#define STDERR_FILENO 2
-#endif
-#endif
-
-namespace {
-
-llvm::cl::opt<bool> ArgTrace(
-    "t",
-    llvm::cl::desc("Print the names of the input files as ld processes them."));
-
-llvm::cl::alias ArgTraceAlias("trace",
-                              llvm::cl::desc("alias for -t"),
-                              llvm::cl::aliasopt(ArgTrace));
-
-llvm::cl::opt<int> ArgVerbose(
-    "verbose",
-    llvm::cl::init(-1),
-    llvm::cl::desc(
-        "Display the version number for ld and list the\n"
-        "linker emulations supported."));
-
-llvm::cl::opt<bool> ArgVersion(
-    "Version",
-    llvm::cl::init(false),
-    llvm::cl::desc("Display the version number for MCLinker."));
-
-llvm::cl::alias ArgVersionAlias("v",
-                                llvm::cl::desc("alias for -Version"),
-                                llvm::cl::aliasopt(ArgVersion));
-
-llvm::cl::opt<int> ArgMaxErrorNum(
-    "error-limit",
-    llvm::cl::init(-1),
-    llvm::cl::desc("limits the maximum number of erros."));
-
-llvm::cl::opt<int> ArgMaxWarnNum(
-    "warning-limit",
-    llvm::cl::init(-1),
-    llvm::cl::desc("limits the maximum number of warnings."));
-
-llvm::cl::opt<mcld::PreferenceOptions::Color> ArgColor(
-    "colormc",
-    llvm::cl::value_desc("When"),
-    llvm::cl::desc("Surround the result strings with the marker"),
-    llvm::cl::init(mcld::PreferenceOptions::COLOR_Auto),
-    llvm::cl::values(
-        clEnumValN(mcld::PreferenceOptions::COLOR_Never,
-                   "never",
-                   "do not surround result"),
-        clEnumValN(mcld::PreferenceOptions::COLOR_Always,
-                   "always",
-                   "always surround results, even the output is a plain file"),
-        clEnumValN(mcld::PreferenceOptions::COLOR_Auto,
-                   "auto",
-                   "surround result strings only if the output is a tty"),
-        clEnumValEnd));
-
-llvm::cl::opt<bool> ArgPrintMap(
-    "M",
-    llvm::cl::desc("Print a link map to the standard output."),
-    llvm::cl::init(false));
-
-llvm::cl::alias ArgPrintMapAlias("print-map",
-                                 llvm::cl::desc("alias for -M"),
-                                 llvm::cl::aliasopt(ArgPrintMap));
-
-bool ArgFatalWarnings;
-
-llvm::cl::opt<bool, true> ArgNoFatalWarnings(
-    "no-fatal-warnings",
-    llvm::cl::location(ArgFatalWarnings),
-    llvm::cl::desc("do not turn warnings into errors"),
-    llvm::cl::init(false),
-    llvm::cl::ValueDisallowed);
-
-llvm::cl::opt<bool, true> ArgFatalWarningsFlag(
-    "fatal-warnings",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::location(ArgFatalWarnings),
-    llvm::cl::desc("turn all warnings into errors"),
-    llvm::cl::init(false),
-    llvm::cl::ValueDisallowed);
-
-llvm::cl::opt<std::string> ArgUseLD(
-    "fuse-ld",
-    llvm::cl::desc("Ignored for GCC/collect2 linker compatibility."),
-    llvm::cl::init("mcld"));
-
-llvm::cl::opt<bool> ArgUseMCLD(
-    "use-mcld",
-    llvm::cl::desc("Ignored for GCC/collect2 linker compatibility."),
-    llvm::cl::init(false));
-
-//===----------------------------------------------------------------------===//
-// Non-member functions
-//===----------------------------------------------------------------------===//
-inline bool ShouldColorize() {
-  const char* term = getenv("TERM");
-  return term && (0 != strcmp(term, "dumb"));
-}
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// PreferenceOptions
-//===----------------------------------------------------------------------===//
-PreferenceOptions::PreferenceOptions()
-    : m_Trace(ArgTrace),
-      m_Verbose(ArgVerbose),
-      m_Version(ArgVersion),
-      m_MaxErrorNum(ArgMaxErrorNum),
-      m_MaxWarnNum(ArgMaxWarnNum),
-      m_Color(ArgColor),
-      m_PrintMap(ArgPrintMap),
-      m_FatalWarnings(ArgFatalWarnings) {
-}
-
-bool PreferenceOptions::parse(LinkerConfig& pConfig) {
-  // set -t
-  pConfig.options().setTrace(m_Trace);
-
-  // set --verbose
-  pConfig.options().setVerbose(m_Verbose);
-
-  // set --error-limit [number]
-  pConfig.options().setMaxErrorNum(m_MaxErrorNum);
-
-  // set --warning-limit [number]
-  pConfig.options().setMaxWarnNum(m_MaxWarnNum);
-
-  // set --color [mode]
-  switch (m_Color) {
-    case COLOR_Never:
-      pConfig.options().setColor(false);
-      break;
-    case COLOR_Always:
-      pConfig.options().setColor(true);
-      break;
-    case COLOR_Auto:
-      bool color_option =
-          ShouldColorize() &&
-          llvm::sys::Process::FileDescriptorIsDisplayed(STDOUT_FILENO);
-      pConfig.options().setColor(color_option);
-      break;
-  }
-
-  mcld::outs().setColor(pConfig.options().color());
-  mcld::errs().setColor(pConfig.options().color());
-
-  if (m_Version)
-    mcld::outs() << pConfig.options().getVersionString() << "\n";
-
-  return true;
-}
diff --git a/tools/mcld/lib/ScriptOptions.cpp b/tools/mcld/lib/ScriptOptions.cpp
deleted file mode 100644
index 55dadab..0000000
--- a/tools/mcld/lib/ScriptOptions.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-//===- ScriptOptions.cpp --------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/ScriptOptions.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/ADT/StringEntry.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-//===----------------------------------------------------------------------===//
-// Script Options
-// Script options are used to modify the default link script. Some positional
-// options, such as --defsym, also can modify default link script is not listed
-// here. These special options belong to Positional Options.
-//===----------------------------------------------------------------------===//
-static llvm::cl::list<std::string> ArgWrapList(
-    "wrap",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Use a wrap function fo symbol."),
-    llvm::cl::value_desc("symbol"));
-
-static llvm::cl::list<std::string> ArgPortList(
-    "portable",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Use a portable function fo symbol."),
-    llvm::cl::value_desc("symbol"));
-
-static llvm::cl::list<std::string> ArgAddressMapList(
-    "section-start",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Locate a output section at the given absolute address"),
-    llvm::cl::value_desc("Set address of section"),
-    llvm::cl::Prefix);
-
-static llvm::cl::opt<unsigned long long> ArgBssSegAddr(
-    "Tbss",
-    llvm::cl::desc("Set the address of the bss segment"),
-    llvm::cl::init(-1U));
-
-static llvm::cl::opt<unsigned long long> ArgDataSegAddr(
-    "Tdata",
-    llvm::cl::desc("Set the address of the data segment"),
-    llvm::cl::init(-1U));
-
-static llvm::cl::opt<unsigned long long> ArgTextSegAddr(
-    "Ttext",
-    llvm::cl::desc("Set the address of the text segment"),
-    llvm::cl::init(-1U));
-
-static llvm::cl::alias ArgTextSegAddrAlias("Ttext-segment",
-                                           llvm::cl::desc("alias for -Ttext"),
-                                           llvm::cl::aliasopt(ArgTextSegAddr));
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// ScriptOptions
-//===----------------------------------------------------------------------===//
-ScriptOptions::ScriptOptions()
-    : m_WrapList(ArgWrapList),
-      m_PortList(ArgPortList),
-      m_AddressMapList(ArgAddressMapList),
-      m_BssSegAddr(ArgBssSegAddr),
-      m_DataSegAddr(ArgDataSegAddr),
-      m_TextSegAddr(ArgTextSegAddr) {
-}
-
-bool ScriptOptions::parse(LinkerScript& pScript) {
-  // set up rename map, for --wrap
-  llvm::cl::list<std::string>::iterator wname;
-  llvm::cl::list<std::string>::iterator wnameEnd = ArgWrapList.end();
-  for (wname = ArgWrapList.begin(); wname != wnameEnd; ++wname) {
-    bool exist = false;
-
-    // add wname -> __wrap_wname
-    StringEntry<llvm::StringRef>* to_wrap =
-        pScript.renameMap().insert(*wname, exist);
-
-    std::string to_wrap_str = "__wrap_" + *wname;
-    to_wrap->setValue(to_wrap_str);
-
-    if (exist)
-      warning(mcld::diag::rewrap) << *wname << to_wrap_str;
-
-    // add __real_wname -> wname
-    std::string from_real_str = "__real_" + *wname;
-    StringEntry<llvm::StringRef>* from_real =
-        pScript.renameMap().insert(from_real_str, exist);
-    from_real->setValue(*wname);
-    if (exist)
-      mcld::warning(mcld::diag::rewrap) << *wname << from_real_str;
-  }
-
-  // set up rename map, for --portable
-  llvm::cl::list<std::string>::iterator pname;
-  llvm::cl::list<std::string>::iterator pnameEnd = ArgPortList.end();
-  for (pname = ArgPortList.begin(); pname != pnameEnd; ++pname) {
-    bool exist = false;
-
-    // add pname -> pname_portable
-    StringEntry<llvm::StringRef>* to_port =
-        pScript.renameMap().insert(*pname, exist);
-
-    std::string to_port_str = *pname + "_portable";
-    to_port->setValue(to_port_str);
-
-    if (exist)
-      warning(mcld::diag::rewrap) << *pname << to_port_str;
-
-    // add __real_pname -> pname
-    std::string from_real_str = "__real_" + *pname;
-    StringEntry<llvm::StringRef>* from_real =
-        pScript.renameMap().insert(from_real_str, exist);
-
-    from_real->setValue(*pname);
-    if (exist)
-      warning(mcld::diag::rewrap) << *pname << from_real_str;
-  }  // end of for
-
-  // set --section-start SECTION=ADDRESS
-  for (llvm::cl::list<std::string>::iterator it = ArgAddressMapList.begin(),
-                                             ie = ArgAddressMapList.end();
-       it != ie;
-       ++it) {
-    // FIXME: Add a cl::parser
-    size_t pos = (*it).find_last_of('=');
-    llvm::StringRef script(*it);
-    uint64_t address = 0x0;
-    script.substr(pos + 1).getAsInteger(0, address);
-    bool exist = false;
-    StringEntry<uint64_t>* addr_mapping =
-        pScript.addressMap().insert(script.substr(0, pos), exist);
-    addr_mapping->setValue(address);
-  }
-
-  // set -Tbss [address]
-  if (-1U != ArgBssSegAddr) {
-    bool exist = false;
-    StringEntry<uint64_t>* bss_mapping =
-        pScript.addressMap().insert(".bss", exist);
-    bss_mapping->setValue(ArgBssSegAddr);
-  }
-
-  // set -Tdata [address]
-  if (-1U != ArgDataSegAddr) {
-    bool exist = false;
-    StringEntry<uint64_t>* data_mapping =
-        pScript.addressMap().insert(".data", exist);
-    data_mapping->setValue(ArgDataSegAddr);
-  }
-
-  // set -Ttext [address]
-  if (-1U != ArgTextSegAddr) {
-    bool exist = false;
-    StringEntry<uint64_t>* text_mapping =
-        pScript.addressMap().insert(".text", exist);
-    text_mapping->setValue(ArgTextSegAddr);
-  }
-
-  return true;
-}
diff --git a/tools/mcld/lib/SearchPathOptions.cpp b/tools/mcld/lib/SearchPathOptions.cpp
deleted file mode 100644
index 8096b90..0000000
--- a/tools/mcld/lib/SearchPathOptions.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-//===- SearchPathOptions.cpp ----------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/SearchPathOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/Support/raw_ostream.h>
-
-namespace {
-
-llvm::cl::opt<mcld::sys::fs::Path,
-              false,
-              llvm::cl::parser<mcld::sys::fs::Path> >
-    ArgSysRoot("sysroot",
-               llvm::cl::desc("Use directory as the location of the sysroot"),
-               llvm::cl::value_desc("directory"),
-               llvm::cl::ValueRequired);
-
-llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser> ArgSearchDirList(
-    "L",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Add [searchdir] to the list of search paths"),
-    llvm::cl::value_desc("searchdir"),
-    llvm::cl::Prefix);
-
-llvm::cl::alias ArgSearchDirListAlias("library-path",
-                                      llvm::cl::desc("alias for -L"),
-                                      llvm::cl::aliasopt(ArgSearchDirList));
-
-llvm::cl::opt<bool> ArgNoStdlib(
-    "nostdlib",
-    llvm::cl::desc("Only search lib dirs explicitly specified on cmdline"),
-    llvm::cl::init(false));
-
-llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser> ArgRuntimePath(
-    "rpath",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Add a directory to the runtime library search path"),
-    llvm::cl::value_desc("dir"));
-
-llvm::cl::alias ArgRuntimePathAlias("R",
-                                    llvm::cl::desc("alias for --rpath"),
-                                    llvm::cl::aliasopt(ArgRuntimePath),
-                                    llvm::cl::Prefix);
-
-// Not supported yet {
-llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser> ArgRuntimePathLink(
-    "rpath-link",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Add a directory to the link time library search path"),
-    llvm::cl::value_desc("dir"));
-
-llvm::cl::list<std::string> ArgY(
-    "Y",
-    llvm::cl::desc("Add path to the default library search path"),
-    llvm::cl::value_desc("default-search-path"));
-// } Not supported yet
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// SearchPathOptions
-//===----------------------------------------------------------------------===//
-SearchPathOptions::SearchPathOptions()
-    : m_SysRoot(ArgSysRoot),
-      m_SearchDirList(ArgSearchDirList),
-      m_NoStdlib(ArgNoStdlib),
-      m_RuntimePath(ArgRuntimePath),
-      m_RuntimePathLink(ArgRuntimePathLink),
-      m_Y(ArgY) {
-}
-
-bool SearchPathOptions::parse(LinkerConfig& pConfig, LinkerScript& pScript) {
-  // set --sysroot
-  if (!m_SysRoot.empty()) {
-    if (exists(m_SysRoot) && is_directory(m_SysRoot))
-      pScript.setSysroot(m_SysRoot);
-  }
-
-  // set -L[path]
-  llvm::cl::list<std::string>::iterator sd;
-  llvm::cl::list<std::string>::iterator sdEnd = m_SearchDirList.end();
-  for (sd = m_SearchDirList.begin(); sd != sdEnd; ++sd) {
-    if (!pScript.directories().insert(*sd)) {
-      // FIXME: need a warning function
-      errs() << "WARNING: can not open search directory `-L" << *sd << "'.\n";
-    }
-  }
-
-  // set -no-stdlib
-  pConfig.options().setNoStdlib(m_NoStdlib);
-
-  // set --rpath [path]
-  llvm::cl::list<std::string>::iterator rp;
-  llvm::cl::list<std::string>::iterator rpEnd = m_RuntimePath.end();
-  for (rp = m_RuntimePath.begin(); rp != rpEnd; ++rp) {
-    pConfig.options().getRpathList().push_back(*rp);
-  }
-
-  return true;
-}
diff --git a/tools/mcld/lib/SymbolOptions.cpp b/tools/mcld/lib/SymbolOptions.cpp
deleted file mode 100644
index 389aa12..0000000
--- a/tools/mcld/lib/SymbolOptions.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//===- SymbolOptions.cpp --------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/SymbolOptions.h>
-#include <mcld/LinkerConfig.h>
-
-namespace {
-
-// Not supprted yet {
-llvm::cl::list<std::string> ArgForceUndefined(
-    "u",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Force symbol to be undefined in the output file"),
-    llvm::cl::value_desc("symbol"));
-
-llvm::cl::alias ArgForceUndefinedAlias("undefined",
-                                       llvm::cl::ZeroOrMore,
-                                       llvm::cl::desc("alias for -u"),
-                                       llvm::cl::aliasopt(ArgForceUndefined));
-
-llvm::cl::opt<std::string> ArgVersionScript(
-    "version-script",
-    llvm::cl::desc("Version script."),
-    llvm::cl::value_desc("Version script"));
-
-llvm::cl::opt<bool> ArgWarnCommon("warn-common",
-                                  llvm::cl::desc("warn common symbol"),
-                                  llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgDefineCommon("d",
-                                    llvm::cl::ZeroOrMore,
-                                    llvm::cl::desc("Define common symbol"),
-                                    llvm::cl::init(false));
-
-llvm::cl::alias ArgDefineCommonAlias1("dc",
-                                      llvm::cl::ZeroOrMore,
-                                      llvm::cl::desc("alias for -d"),
-                                      llvm::cl::aliasopt(ArgDefineCommon));
-
-llvm::cl::alias ArgDefineCommonAlias2("dp",
-                                      llvm::cl::ZeroOrMore,
-                                      llvm::cl::desc("alias for -d"),
-                                      llvm::cl::aliasopt(ArgDefineCommon));
-
-// } Not supported yet
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// SymbolOptions
-//===----------------------------------------------------------------------===//
-SymbolOptions::SymbolOptions()
-    : m_ForceUndefined(ArgForceUndefined),
-      m_VersionScript(ArgVersionScript),
-      m_WarnCommon(ArgWarnCommon),
-      m_DefineCommon(ArgDefineCommon) {
-}
-
-bool SymbolOptions::parse(LinkerConfig& pConfig) {
-  // set -d
-  pConfig.options().setDefineCommon(m_DefineCommon);
-
-  // set -u/--undefined symbols
-  llvm::cl::list<std::string>::iterator usym, usymEnd = m_ForceUndefined.end();
-  for (usym = m_ForceUndefined.begin(); usym != usymEnd; ++usym)
-    pConfig.options().getUndefSymList().push_back(*usym);
-
-  return true;
-}
diff --git a/tools/mcld/lib/TargetControlOptions.cpp b/tools/mcld/lib/TargetControlOptions.cpp
deleted file mode 100644
index 365bafd..0000000
--- a/tools/mcld/lib/TargetControlOptions.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-//===- TargetControlOptions.cpp -------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/TargetControlOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-llvm::cl::opt<int> ArgGPSize(
-    "G",
-    llvm::cl::desc("Set the maximum size of objects to be optimized using GP"),
-    llvm::cl::init(8));
-
-llvm::cl::opt<bool> ArgWarnSharedTextrel(
-    "warn-shared-textrel",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Warn if adding DT_TEXTREL in a shared object."),
-    llvm::cl::init(false));
-
-// Not supported yet {
-llvm::cl::opt<bool> ArgFIXCA8(
-    "fix-cortex-a8",
-    llvm::cl::desc("Enable Cortex-A8 Thumb-2 branch erratum fix"),
-    llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgFixCA53Erratum835769(
-    "fix-cortex-a53-835769",
-    llvm::cl::desc("Enable Cortex-CA53 Erratum 835769 fix"),
-    llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgEB(
-    "EB",
-    llvm::cl::desc("Link big-endian objects. This affects the output format."),
-    llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgEL(
-    "EL",
-    llvm::cl::desc(
-        "Link little-endian objects. This affects the output format."),
-    llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgSVR4Compatibility(
-    "Qy",
-    llvm::cl::desc("This option is ignored for SVR4 compatibility"),
-    llvm::cl::init(false));
-
-// } Not supported yet
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// TargetControlOptions
-//===----------------------------------------------------------------------===//
-TargetControlOptions::TargetControlOptions()
-    : m_GPSize(ArgGPSize),
-      m_WarnSharedTextrel(ArgWarnSharedTextrel),
-      m_FIXCA8(ArgFIXCA8),
-      m_FIXCA53Erratum835769(ArgFixCA53Erratum835769),
-      m_EB(ArgEB),
-      m_EL(ArgEL),
-      m_SVR4Compatibility(ArgSVR4Compatibility) {
-}
-
-bool TargetControlOptions::parse(LinkerConfig& pConfig) {
-  // set -G [size]
-  pConfig.options().setGPSize(m_GPSize);
-
-  // set --warn-shared-textrel
-  pConfig.options().setWarnSharedTextrel(m_WarnSharedTextrel);
-
-  // set --fix-cortex-a8
-  if (m_FIXCA8)
-    mcld::warning(mcld::diag::warn_unsupported_option) << m_FIXCA8.ArgStr;
-
-  // set --fix-cortex-a53-835769
-  if (m_FIXCA53Erratum835769) {
-    mcld::warning(mcld::diag::warn_unsupported_option)
-        << m_FIXCA53Erratum835769.ArgStr;
-  }
-
-  return true;
-}
diff --git a/tools/mcld/lib/TripleOptions.cpp b/tools/mcld/lib/TripleOptions.cpp
deleted file mode 100644
index d4217c6..0000000
--- a/tools/mcld/lib/TripleOptions.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===- TripleOptions.cpp --------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/TripleOptions.h>
-
-#include <mcld/LinkerConfig.h>
-#include <mcld/Support/Path.h>
-#include <mcld/Support/TargetRegistry.h>
-#include <mcld/Support/MsgHandling.h>
-#include <mcld/Support/SystemUtils.h>
-
-#include <llvm/ADT/StringSwitch.h>
-
-namespace {
-
-llvm::cl::opt<std::string> ArgTargetTriple(
-    "mtriple",
-    llvm::cl::desc("Override target triple for module"));
-
-llvm::cl::opt<std::string> ArgMArch(
-    "march",
-    llvm::cl::desc("Architecture to generate code for (see --version)"));
-
-llvm::cl::opt<std::string> ArgMCPU(
-    "mcpu",
-    llvm::cl::desc("Target a specific cpu type (-mcpu=help for details)"),
-    llvm::cl::value_desc("cpu-name"),
-    llvm::cl::init(""));
-
-llvm::cl::opt<std::string> ArgEmulation(
-    "m",
-    llvm::cl::ZeroOrMore,
-    llvm::cl::desc("Set GNU linker emulation"),
-    llvm::cl::value_desc("emulation"),
-    llvm::cl::Prefix);
-
-/// 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.
-inline std::string ParseProgName(const char* pProgName) {
-  static const char* suffixes[] = {"ld", "ld.mcld"};
-
-  std::string ProgName(mcld::sys::fs::Path(pProgName).stem().native());
-
-  for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
-    if (ProgName == suffixes[i])
-      return std::string();
-  }
-
-  llvm::StringRef ProgNameRef(ProgName);
-  llvm::StringRef Prefix;
-
-  for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
-    if (!ProgNameRef.endswith(suffixes[i]))
-      continue;
-
-    llvm::StringRef::size_type LastComponent =
-        ProgNameRef.rfind('-', ProgNameRef.size() - strlen(suffixes[i]));
-    if (LastComponent == llvm::StringRef::npos)
-      continue;
-    llvm::StringRef Prefix = ProgNameRef.slice(0, LastComponent);
-    std::string IgnoredError;
-    if (!mcld::TargetRegistry::lookupTarget(Prefix, IgnoredError))
-      continue;
-    return Prefix.str();
-  }
-  return std::string();
-}
-
-inline void ParseEmulation(llvm::Triple& pTriple,
-                           const std::string& pEmulation) {
-  llvm::Triple triple =
-      llvm::StringSwitch<llvm::Triple>(pEmulation)
-          .Case("aarch64linux", llvm::Triple("aarch64", "", "linux", "gnu"))
-          .Case("armelf_linux_eabi",
-                llvm::Triple("arm", "", "linux", "gnueabi"))
-          .Case("elf_i386", llvm::Triple("i386", "", "", "gnu"))
-          .Case("elf_x86_64", llvm::Triple("x86_64", "", "", "gnu"))
-          .Case("elf32_x86_64", llvm::Triple("x86_64", "", "", "gnux32"))
-          .Case("elf_i386_fbsd", llvm::Triple("i386", "", "freebsd", "gnu"))
-          .Case("elf_x86_64_fbsd", llvm::Triple("x86_64", "", "freebsd", "gnu"))
-          .Case("elf32ltsmip", llvm::Triple("mipsel", "", "", "gnu"))
-          .Case("elf64ltsmip", llvm::Triple("mips64el", "", "", "gnu"))
-          .Default(llvm::Triple());
-
-  if (triple.getArch() == llvm::Triple::UnknownArch &&
-      triple.getOS() == llvm::Triple::UnknownOS &&
-      triple.getEnvironment() == llvm::Triple::UnknownEnvironment)
-    mcld::error(mcld::diag::err_invalid_emulation) << pEmulation << "\n";
-
-  if (triple.getArch() != llvm::Triple::UnknownArch)
-    pTriple.setArch(triple.getArch());
-
-  if (triple.getOS() != llvm::Triple::UnknownOS)
-    pTriple.setOS(triple.getOS());
-
-  if (triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
-    pTriple.setEnvironment(triple.getEnvironment());
-}
-
-}  // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// TripleOptions
-//===----------------------------------------------------------------------===//
-TripleOptions::TripleOptions()
-    : m_TargetTriple(ArgTargetTriple),
-      m_MArch(ArgMArch),
-      m_MCPU(ArgMCPU),
-      m_Emulation(ArgEmulation) {
-}
-
-bool TripleOptions::parse(int pArgc, char* pArgv[], LinkerConfig& pConfig) {
-  llvm::Triple triple;
-  if (!m_TargetTriple.empty()) {
-    // 1. Use the triple from command.
-    triple.setTriple(m_TargetTriple);
-  } else {
-    std::string prog_triple = ParseProgName(pArgv[0]);
-    if (!prog_triple.empty()) {
-      // 2. Use the triple from the program name prefix.
-      triple.setTriple(prog_triple);
-    } else {
-      // 3. Use the default target triple.
-      triple.setTriple(mcld::sys::getDefaultTargetTriple());
-    }
-  }
-
-  // If a specific emulation was requested, apply it now.
-  if (!m_Emulation.empty())
-    ParseEmulation(triple, m_Emulation);
-  else
-    pConfig.targets().setArch(m_MArch);
-
-  pConfig.targets().setTriple(triple);
-  pConfig.targets().setTargetCPU(m_MCPU);
-
-  return true;
-}
diff --git a/tools/mcld/main.cpp b/tools/mcld/main.cpp
deleted file mode 100644
index 68900ba..0000000
--- a/tools/mcld/main.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-//===- main.cpp -----------------------------------------------------------===//
-//
-//                     The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/PreferenceOptions.h>
-#include <mcld/TripleOptions.h>
-#include <mcld/DynamicSectionOptions.h>
-#include <mcld/OutputFormatOptions.h>
-#include <mcld/SearchPathOptions.h>
-#include <mcld/OptimizationOptions.h>
-#include <mcld/SymbolOptions.h>
-#include <mcld/TargetControlOptions.h>
-#include <mcld/ScriptOptions.h>
-#include <mcld/PositionalOptions.h>
-
-#include <mcld/Module.h>
-#include <mcld/Environment.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/Linker.h>
-#include <mcld/IRBuilder.h>
-#include <mcld/MC/InputAction.h>
-#include <mcld/Support/raw_ostream.h>
-#include <mcld/Support/MsgHandling.h>
-#include <llvm/Support/ManagedStatic.h>
-#include <llvm/Support/Signals.h>
-#include <string>
-#include <cassert>
-#include <cstdlib>
-
-/// configure linker
-static inline bool ConfigLinker(
-    int pArgc,
-    char* pArgv[],
-    const char* pName,
-    mcld::Module& pModule,
-    mcld::LinkerScript& pScript,
-    mcld::LinkerConfig& pConfig,
-    mcld::IRBuilder& pBuilder,
-    std::vector<mcld::InputAction*>& pInputActions) {
-  mcld::PreferenceOptions preference;
-  mcld::TripleOptions triple;
-  mcld::DynamicSectionOptions dynamic_section;
-  mcld::OutputFormatOptions output_format;
-  mcld::SearchPathOptions search_path;
-  mcld::OptimizationOptions optimization;
-  mcld::SymbolOptions symbol;
-  mcld::TargetControlOptions target_control;
-  mcld::ScriptOptions script;
-  mcld::PositionalOptions positional;
-
-  llvm::cl::ParseCommandLineOptions(pArgc, pArgv, pName);
-
-  if (!preference.parse(pConfig))
-    return false;
-
-  if (!triple.parse(pArgc, pArgv, pConfig))
-    return false;
-
-  if (!dynamic_section.parse(pConfig, pScript))
-    return false;
-
-  if (!output_format.parse(pModule, pConfig))
-    return false;
-
-  if (!search_path.parse(pConfig, pScript))
-    return false;
-
-  if (!optimization.parse(pConfig))
-    return false;
-
-  if (!symbol.parse(pConfig))
-    return false;
-
-  if (!target_control.parse(pConfig))
-    return false;
-
-  if (!script.parse(pScript))
-    return false;
-
-  if (!positional.parse(pInputActions, pConfig, pScript))
-    return false;
-
-  if (pConfig.options().soname().empty())
-    pConfig.options().setSOName(pModule.name());
-
-  return true;
-}
-
-static inline bool InitializeInputs(
-    mcld::IRBuilder& pBuilder,
-    std::vector<mcld::InputAction*>& pInputActions) {
-  for (
-      std::vector<mcld::InputAction*>::iterator action = pInputActions.begin(),
-                                                actionEnd = pInputActions.end();
-      action != actionEnd;
-      ++action) {
-    assert(*action != NULL);
-    (*action)->activate(pBuilder.getInputBuilder());
-    delete *action;
-  }
-
-  if (pBuilder.getInputBuilder().isInGroup()) {
-    mcld::fatal(mcld::diag::fatal_forbid_nest_group);
-    return false;
-  }
-
-  return true;
-}
-
-int main(int argc, char* argv[]) {
-  llvm::sys::PrintStackTraceOnErrorSignal();
-  llvm::llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
-  mcld::Initialize();
-
-  mcld::LinkerScript script;
-  mcld::LinkerConfig config;
-  mcld::Module module(script);
-  mcld::IRBuilder builder(module, config);
-  std::vector<mcld::InputAction*> input_actions;
-
-  if (!ConfigLinker(argc,
-                    argv,
-                    "MCLinker\n",
-                    module,
-                    script,
-                    config,
-                    builder,
-                    input_actions)) {
-    mcld::errs() << argv[0]
-                 << ": failed to process linker options from command line!\n";
-    return EXIT_FAILURE;
-  }
-
-  mcld::Linker linker;
-  if (!linker.emulate(script, config)) {
-    mcld::errs() << argv[0] << ": failed to emulate target!\n";
-    return EXIT_FAILURE;
-  }
-
-  // FIXME: is it possible to have a lightweight MCLinker pass?
-  if (!InitializeInputs(builder, input_actions)) {
-    mcld::errs() << argv[0] << ": failed to initialize input tree!\n";
-    return EXIT_FAILURE;
-  }
-
-  if (!linker.link(module, builder)) {
-    mcld::errs() << argv[0] << ": failed to link objects!\n";
-    return EXIT_FAILURE;
-  }
-
-  if (!linker.emit(module, module.name())) {
-    mcld::errs() << argv[0] << ": failed to emit output!\n";
-    return EXIT_FAILURE;
-  }
-
-  mcld::Finalize();
-
-  return EXIT_SUCCESS;
-}
diff --git a/unittests/DirIteratorTest.cpp b/unittests/DirIteratorTest.cpp
index 2684466..cc440ca 100644
--- a/unittests/DirIteratorTest.cpp
+++ b/unittests/DirIteratorTest.cpp
@@ -49,8 +49,10 @@
 
   size_t size = 0;
   while (entry != enEnd) {
-    if (0 != entry.path())
+    if (0 != entry.path()) {
       size = entry.path()->native().size();
+      ASSERT_TRUE(size != 0);
+    }
 
     ++entry;
   }
diff --git a/unittests/HashTableTest.cpp b/unittests/HashTableTest.cpp
index 595b1e1..695ccb8 100644
--- a/unittests/HashTableTest.cpp
+++ b/unittests/HashTableTest.cpp
@@ -67,9 +67,7 @@
   HashTableTy* hashTable = new HashTableTy(0);
 
   bool exist;
-  HashTableTy::entry_type* entry = 0;
-
-  entry = hashTable->insert(pA, exist);
+  hashTable->insert(pA, exist);
 
   EXPECT_FALSE(hashTable->empty());
 
@@ -135,9 +133,8 @@
   HashTableTy* hashTable = new HashTableTy(0);
 
   bool exist;
-  HashTableTy::entry_type* entry = 0;
   for (unsigned int key = 0; key < 100; ++key)
-    entry = hashTable->insert(key, exist);
+    hashTable->insert(key, exist);
 
   EXPECT_FALSE(hashTable->empty());
 
@@ -161,9 +158,8 @@
   HashTableTy* hashTable = new HashTableTy(22);
 
   bool exist;
-  HashTableTy::entry_type* entry = 0;
   for (unsigned int key = 0; key < 100; ++key) {
-    entry = hashTable->insert(key, exist);
+    hashTable->insert(key, exist);
   }
 
   hashTable->clear();
@@ -185,9 +181,8 @@
   HashTableTy* hashTable = new HashTableTy();
 
   bool exist;
-  HashTableTy::entry_type* entry = 0;
   for (unsigned int key = 0; key < 100; ++key) {
-    entry = hashTable->insert(key, exist);
+    hashTable->insert(key, exist);
   }
   EXPECT_FALSE(hashTable->empty());
 
@@ -207,7 +202,7 @@
   }
 
   for (unsigned int key = 0; key < 20; ++key) {
-    entry = hashTable->insert(key, exist);
+    hashTable->insert(key, exist);
   }
   EXPECT_TRUE(100 == hashTable->numOfEntries());
   EXPECT_TRUE(197 == hashTable->numOfBuckets());