Apply changes to migrate on MCLinker 2.0.2-1.

Change-Id: I8b25ad23c257e8a98069611dde525cc6d37e06e9
diff --git a/include/bcc/Linker.h b/include/bcc/Linker.h
index 6d824b4..43a8839 100644
--- a/include/bcc/Linker.h
+++ b/include/bcc/Linker.h
@@ -22,16 +22,11 @@
 namespace mcld {
 
 class Module;
-class TargetLDBackend;
-class ObjectLinker;
-class ContextFactory;
+class IRBuilder;
 class LinkerConfig;
-class TreeIteratorBase;
+class Linker;
 class Input;
-class InputFactory;
-class InputBuilder;
 class MemoryArea;
-class MemoryAreaFactory;
 
 namespace sys { namespace fs {
 
@@ -50,11 +45,10 @@
   enum ErrorCode {
     kSuccess,
     kDoubleConfig,
-    kCreateBackend,
     kDelegateLDInfo,
     kFindNameSpec,
-    kOpenNameSpec,
     kOpenObjectFile,
+    kOpenMemory,
     kNotConfig,
     kNotSetUpOutput,
     kOpenOutput,
@@ -69,15 +63,11 @@
 private:
   const mcld::LinkerConfig *mLDConfig;
   mcld::Module *mModule;
-  mcld::TargetLDBackend *mBackend;
-  mcld::ObjectLinker *mObjLinker;
-  mcld::InputFactory *mInputFactory;
-  mcld::MemoryAreaFactory *mMemAreaFactory;
-  mcld::ContextFactory *mContextFactory;
-  mcld::InputBuilder *mBuilder;
-  mcld::TreeIteratorBase *mRoot;
+  mcld::Linker *mLinker;
+  mcld::IRBuilder *mBuilder;
   std::string mSOName;
-  mcld::MemoryArea* mOutput;
+  std::string mOutputPath;
+  int mOutputHandler;
 
 public:
   Linker();
@@ -104,12 +94,6 @@
 
 private:
   enum ErrorCode extractFiles(const LinkerConfig& pConfig);
-
-  enum ErrorCode openFile(const mcld::sys::fs::Path& pPath,
-                          enum ErrorCode pCode,
-                          mcld::Input& pInput);
-
-  void advanceRoot();
 };
 
 } // end namespace bcc
diff --git a/include/bcc/Support/LinkerConfig.h b/include/bcc/Support/LinkerConfig.h
index dfd2d91..09a08ec 100644
--- a/include/bcc/Support/LinkerConfig.h
+++ b/include/bcc/Support/LinkerConfig.h
@@ -93,6 +93,8 @@
 
   void setBsymbolic(bool pEnable = true);
 
+  void setDefineCommon(bool pEnable = true);
+
   void setSOName(const std::string &pSOName);
 
   void setDyld(const std::string &pDyld);
diff --git a/lib/Core/Linker.cpp b/lib/Core/Linker.cpp
index 775be70..87bc389 100644
--- a/lib/Core/Linker.cpp
+++ b/lib/Core/Linker.cpp
@@ -22,20 +22,11 @@
 
 #include <mcld/Module.h>
 #include <mcld/IRBuilder.h>
-#include <mcld/InputTree.h>
-#include <mcld/Object/ObjectLinker.h>
-#include <mcld/Fragment/FragmentLinker.h>
-#include <mcld/MC/InputFactory.h>
-#include <mcld/MC/ContextFactory.h>
-#include <mcld/MC/InputBuilder.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/Linker.h>
 #include <mcld/LD/LDSection.h>
 #include <mcld/LD/LDContext.h>
-#include <mcld/Target/TargetLDBackend.h>
 #include <mcld/Support/Path.h>
-#include <mcld/Support/MemoryArea.h>
-#include <mcld/Support/FileHandle.h>
-#include <mcld/Support/MemoryAreaFactory.h>
-#include <mcld/Support/TargetRegistry.h>
 
 using namespace bcc;
 
@@ -45,14 +36,10 @@
     "Successfully compiled.",
     /* kDoubleConfig */
     "Configure Linker twice.",
-    /* kCreateBackend */
-    "Cannot create backend.",
     /* kDelegateLDInfo */
     "Cannot get linker information",
     /* kFindNameSpec */
     "Cannot find -lnamespec",
-    /* kOpenNameSpec */
-    "Cannot open -lnamespec",
     /* kOpenObjectFile */
     "Cannot open object file",
     /* kNotConfig */
@@ -82,15 +69,13 @@
 // Linker
 //===----------------------------------------------------------------------===//
 Linker::Linker()
-  : mLDConfig(NULL), mModule(NULL), mBackend(NULL), mObjLinker(NULL),
-    mInputFactory(NULL), mMemAreaFactory(NULL), mContextFactory(NULL),
-    mBuilder(NULL), mRoot(NULL), mOutput(NULL) {
+  : mLDConfig(NULL), mModule(NULL), mLinker(NULL), mBuilder(NULL),
+    mOutputHandler(-1) {
 }
 
 Linker::Linker(const LinkerConfig& pConfig)
-  : mLDConfig(NULL), mModule(NULL), mBackend(NULL), mObjLinker(NULL),
-    mInputFactory(NULL), mMemAreaFactory(NULL), mContextFactory(NULL),
-    mBuilder(NULL), mRoot(NULL), mOutput(NULL) {
+  : mLDConfig(NULL), mModule(NULL), mLinker(NULL), mBuilder(NULL),
+    mOutputHandler(-1) {
 
   const std::string &triple = pConfig.getTriple();
 
@@ -105,14 +90,8 @@
 
 Linker::~Linker() {
   delete mModule;
-  delete mObjLinker;
-  // FIXME: current implementation can not change the order of deleting
-  // ObjectLinker and TargetLDBackend. Because the deletion of relocation list
-  // in FragmentLinker (FragmentLinker is deleted by ObjectLinker) depends on
-  // RelocationFactory in TargetLDBackend
-  delete mBackend;
+  delete mLinker;
   delete mBuilder;
-  delete mRoot;
 }
 
 enum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig) {
@@ -130,229 +109,73 @@
 
   extractFiles(pConfig);
 
-  mBackend = pConfig.getTarget()->createLDBackend(*mLDConfig);
-  if (mBackend == NULL) {
-    return kCreateBackend;
-  }
-
-  mInputFactory = new mcld::InputFactory(32, *mLDConfig);
-
-  mContextFactory = new mcld::ContextFactory(32);
-    /* 32 is a magic number, the estimated number of input files **/
-
-  mMemAreaFactory = new mcld::MemoryAreaFactory(32);
-
-  mBuilder = new mcld::InputBuilder(*mLDConfig,
-                                    *mInputFactory,
-                                    *mContextFactory,
-                                    *mMemAreaFactory,
-                                    true); // delegated
-
   mModule = new mcld::Module(mLDConfig->options().soname());
 
-  mRoot = new mcld::InputTree::iterator(mModule->getInputTree().root());
+  mBuilder = new mcld::IRBuilder(*mModule, *mLDConfig);
 
-  mObjLinker = new mcld::ObjectLinker(*mLDConfig, *mModule, *mBuilder, *mBackend);
+  mLinker = new mcld::Linker();
 
-  mObjLinker->initFragmentLinker();
+  mLinker->config(const_cast<mcld::LinkerConfig&>(*mLDConfig));
 
   return kSuccess;
 }
 
-void Linker::advanceRoot() {
-  if (mRoot->isRoot()) {
-    mRoot->move<mcld::TreeIteratorBase::Leftward>();
-  } else {
-    mRoot->move<mcld::TreeIteratorBase::Rightward>();
-  }
-  return;
-}
-
-enum Linker::ErrorCode Linker::openFile(const mcld::sys::fs::Path& pPath,
-                                        enum Linker::ErrorCode pCode,
-                                        mcld::Input& pInput) {
-  mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pPath,
-                                                    mcld::FileHandle::ReadOnly);
-
-  if (input_memory->handler()->isGood()) {
-    pInput.setMemArea(input_memory);
-  } else {
-    return pCode;
-  }
-
-  mBuilder->setContext(pInput);
-  return kSuccess;
-}
-
 enum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec) {
-  const mcld::sys::fs::Path* path = NULL;
-  // find out the real path of the namespec.
-  if (mLDConfig->attribute().constraint().isSharedSystem()) {
-    // In the system with shared object support, we can find both archive
-    // and shared object.
-
-    if (mInputFactory->attr().isStatic()) {
-      // with --static, we must search an archive.
-      path = mLDConfig->options().directories().find(pNameSpec,
-                                                     mcld::Input::Archive);
-    }
-    else {
-      // otherwise, with --Bdynamic, we can find either an archive or a
-      // shared object.
-      path = mLDConfig->options().directories().find(pNameSpec,
-                                                     mcld::Input::DynObj);
-    }
-  }
-  else {
-    // In the system without shared object support, we only look for an
-    // archive.
-    path = mLDConfig->options().directories().find(pNameSpec,
-                                                 mcld::Input::Archive);
-  }
-
-  if (NULL == path)
+  mcld::Input* input = mBuilder->ReadInput(pNameSpec);
+  if (NULL == input)
     return kFindNameSpec;
-
-  mcld::Input* input = mInputFactory->produce(pNameSpec, *path,
-                                              mcld::Input::Unknown);
-  mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
-
-  advanceRoot();
-
-  return openFile(*path, kOpenNameSpec, *input);
+  return kSuccess;
 }
 
 /// addObject - Add a object file by the filename.
 enum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath) {
-  mcld::Input* input = mInputFactory->produce(pObjectPath,
-                                              pObjectPath,
-                                              mcld::Input::Unknown);
-
-  mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
-
-  advanceRoot();
-
-  return openFile(pObjectPath, kOpenObjectFile, *input);
+  mcld::Input* input = mBuilder->ReadInput(pObjectPath, pObjectPath);
+  if (NULL == input)
+    return kOpenObjectFile;
+  return kSuccess;
 }
 
 /// addObject - Add a piece of memory. The memory is of ELF format.
 enum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize) {
-
-  mcld::Input* input = mInputFactory->produce("memory object", "NAN",
-                                              mcld::Input::Unknown);
-
-  mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
-
-  advanceRoot();
-
-  mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize);
-  input->setMemArea(input_memory);
-
-  mcld::LDContext *input_context = mContextFactory->produce();
-  input->setContext(input_context);
-
+  mcld::Input* input = mBuilder->ReadInput("NAN", pMemory, pSize);
+  if (NULL == input)
+    return kOpenMemory;
   return kSuccess;
 }
 
 enum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize) {
-  mcld::Input* input = mInputFactory->produce("code object", "NAN",
-                                              mcld::Input::External);
-
-  mModule->getInputTree().insert<mcld::InputTree::Positional>(*mRoot, *input);
-
-  advanceRoot();
-
-  mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize);
-  input->setMemArea(input_memory);
-
-  mcld::LDContext *input_context = mContextFactory->produce();
-  input->setContext(input_context);
-
-  // FIXME: So far, FragmentLinker must set up output before add input files.
-  // set up LDContext
-  if (mObjLinker->hasInitLinker()) {
-    return kNotConfig;
-  }
-
-  // create NULL section
-  mcld::LDSection* null = mcld::IRBuilder::CreateELFHeader(*input, "",
-                              llvm::ELF::SHT_NULL, 0, 0);
-  null->setSize(0);
-  null->setOffset(0);
-  null->setInfo(0);
-
-  // create .text section
-  mcld::LDSection* text = mcld::IRBuilder::CreateELFHeader(*input, ".text",
-                              llvm::ELF::SHT_PROGBITS,
-                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
-                              1);
-
-  text->setSize(pSize);
-  text->setOffset(0x0);
-  text->setInfo(0);
-
+  mcld::Input* input = mBuilder->CreateInput("NAN", "NAN", mcld::Input::Object);
+  mcld::LDSection* sect = mBuilder->CreateELFHeader(*input, ".text",
+                                llvm::ELF::SHT_PROGBITS,
+                                llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
+                                0x1);
+  mcld::SectionData* data = mBuilder->CreateSectionData(*sect);
+  mcld::Fragment* frag = mBuilder->CreateRegion(pMemory, pSize);
+  mBuilder->AppendFragment(*frag, *data);
   return kSuccess;
 }
 
 enum Linker::ErrorCode Linker::setOutput(const std::string &pPath) {
-  // -----  initialize output file  ----- //
-  mcld::FileHandle::Permission perm = 0755;
-
-  mOutput = mMemAreaFactory->produce(
-                      pPath,
-                      mcld::FileHandle::ReadWrite |
-                        mcld::FileHandle::Truncate |
-                        mcld::FileHandle::Create,
-                      perm);
-
-  if (!mOutput->handler()->isGood()) {
-    return kOpenOutput;
-  }
-
+  mOutputPath = pPath;
   return kSuccess;
 }
 
 enum Linker::ErrorCode Linker::setOutput(int pFileHandler) {
-  mOutput = mMemAreaFactory->produce(pFileHandler, mcld::FileHandle::ReadWrite);
-
-  if (!mOutput->handler()->isGood()) {
-    return kOpenOutput;
-  }
-
+  mOutputHandler = pFileHandler;
   return kSuccess;
 }
 
 enum Linker::ErrorCode Linker::link() {
-  if (NULL == mOutput)
-    return kNotSetUpOutput;
-
-  if (!mObjLinker->hasInitLinker()) {
-    return kNotConfig;
+  mLinker->link(*mModule, *mBuilder);
+  if (!mOutputPath.empty()) {
+    mLinker->emit(mOutputPath);
+    return kSuccess;
   }
 
-  mObjLinker->initStdSections();
-
-  mObjLinker->normalize();
-
-  if (!mObjLinker->readRelocations())
-    return kReadSections;
-
-  if (!mObjLinker->mergeSections())
-    return kReadSections;
-
-  if (!mObjLinker->addStandardSymbols() || !mObjLinker->addTargetSymbols()) {
-    return kAddAdditionalSymbols;
+  if (-1 != mOutputHandler) {
+    mLinker->emit(mOutputHandler);
+    return kSuccess;
   }
-
-  mObjLinker->scanRelocations();
-  mObjLinker->prelayout();
-  mObjLinker->layout();
-  mObjLinker->postlayout();
-  mObjLinker->finalizeSymbolValue();
-  mObjLinker->relocation();
-  mObjLinker->emitOutput(*mOutput);
-  mObjLinker->postProcessing(*mOutput);
-
-  return kSuccess;
+  return kNotSetUpOutput;
 }
 
diff --git a/lib/Support/LinkerConfig.cpp b/lib/Support/LinkerConfig.cpp
index 70ba64f..a4ede97 100644
--- a/lib/Support/LinkerConfig.cpp
+++ b/lib/Support/LinkerConfig.cpp
@@ -164,6 +164,11 @@
   return;
 }
 
+void LinkerConfig::setDefineCommon(bool pEnable) {
+  mLDConfig->options().setDefineCommon(pEnable);
+  return;
+}
+
 void LinkerConfig::setSOName(const std::string &pSOName) {
   mLDConfig->options().setSOName(pSOName);
   return;
diff --git a/lib/Support/TargetLinkerConfigs.cpp b/lib/Support/TargetLinkerConfigs.cpp
index 38febb6..d7e6163 100644
--- a/lib/Support/TargetLinkerConfigs.cpp
+++ b/lib/Support/TargetLinkerConfigs.cpp
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
+
 #include "bcc/Config/Config.h"
 #include "bcc/Support/TargetLinkerConfigs.h"
 
+#include <mcld/TargetOptions.h>
 #include <mcld/MC/InputFactory.h>
+#include <mcld/Fragment/Relocation.h>
 
 using namespace bcc;
 
@@ -35,6 +38,10 @@
 #if defined(PROVIDE_ARM_CODEGEN)
 ARMLinkerConfig::ARMLinkerConfig() : LinkerConfig(DEFAULT_ARM_TRIPLE_STRING) {
 
+  // set up target-dependent options
+  getLDConfig()->targets().setEndian(mcld::TargetOptions::Little);
+  getLDConfig()->targets().setBitClass(32);
+
   // set up target-dependent constraints of attributes
   getLDConfig()->attribute().constraint().enableWholeArchive();
   getLDConfig()->attribute().constraint().disableAsNeeded();
@@ -60,6 +67,9 @@
     getLDConfig()->scripts().sectionMap().append(".ARM.extab", ".ARM.extab", exist);
     getLDConfig()->scripts().sectionMap().append(".ARM.attributes", ".ARM.attributes", exist);
   }
+
+  // set up relocation factory
+  mcld::Relocation::SetUp(*getLDConfig());
 }
 #endif // defined(PROVIDE_ARM_CODEGEN)
 
@@ -70,6 +80,10 @@
 MipsLinkerConfig::MipsLinkerConfig()
   : LinkerConfig(DEFAULT_MIPS_TRIPLE_STRING) {
 
+  // set up target-dependent options
+  getLDConfig()->targets().setEndian(mcld::TargetOptions::Little);
+  getLDConfig()->targets().setBitClass(32);
+
   // set up target-dependent constraints of attibutes
   getLDConfig()->attribute().constraint().enableWholeArchive();
   getLDConfig()->attribute().constraint().disableAsNeeded();
@@ -87,6 +101,9 @@
   if (!getLDConfig()->options().hasDyld()) {
     getLDConfig()->options().setDyld(gDefaultDyld);
   }
+
+  // set up relocation factory
+  mcld::Relocation::SetUp(*getLDConfig());
 }
 #endif // defined(PROVIDE_MIPS_CODEGEN)
 
@@ -96,6 +113,10 @@
 #if defined(PROVIDE_X86_CODEGEN)
 X86FamilyLinkerConfigBase::X86FamilyLinkerConfigBase(const std::string& pTriple)
   : LinkerConfig(pTriple) {
+  // set up target-dependent options
+  getLDConfig()->targets().setEndian(mcld::TargetOptions::Little);
+  getLDConfig()->targets().setBitClass(32);
+
   // set up target-dependent constraints of attibutes
   getLDConfig()->attribute().constraint().enableWholeArchive();
   getLDConfig()->attribute().constraint().disableAsNeeded();
@@ -113,6 +134,9 @@
   if (!getLDConfig()->options().hasDyld()) {
     getLDConfig()->options().setDyld(gDefaultDyld);
   }
+
+  // set up relocation factory
+  mcld::Relocation::SetUp(*getLDConfig());
 }
 
 X86_32LinkerConfig::X86_32LinkerConfig()
@@ -130,6 +154,11 @@
 //===----------------------------------------------------------------------===//
 GeneralLinkerConfig::GeneralLinkerConfig(const std::string& pTriple)
   : LinkerConfig(pTriple) {
+
+  // set up target-dependent options
+  getLDConfig()->targets().setEndian(mcld::TargetOptions::Little);
+  getLDConfig()->targets().setBitClass(32);
+
   // set up target-dependent constraints of attributes
   getLDConfig()->attribute().constraint().enableWholeArchive();
   getLDConfig()->attribute().constraint().disableAsNeeded();
@@ -140,12 +169,15 @@
   getLDConfig()->attribute().predefined().setDynamic();
 
   // set up section map
-  if (llvm::Triple::arm == getLDConfig()->triple().getArch() &&
+  if (llvm::Triple::arm == getLDConfig()->targets().triple().getArch() &&
       getLDConfig()->codeGenType() != mcld::LinkerConfig::Object) {
     bool exist = false;
     getLDConfig()->scripts().sectionMap().append(".ARM.exidx", ".ARM.exidx", exist);
     getLDConfig()->scripts().sectionMap().append(".ARM.extab", ".ARM.extab", exist);
     getLDConfig()->scripts().sectionMap().append(".ARM.attributes", ".ARM.attributes", exist);
   }
+
+  // set up relocation factory
+  mcld::Relocation::SetUp(*getLDConfig());
 }
 #endif // defined(TARGET_BUILD)
diff --git a/tools/mcld/Main.cpp b/tools/mcld/Main.cpp
index c87a393..ac4772e 100644
--- a/tools/mcld/Main.cpp
+++ b/tools/mcld/Main.cpp
@@ -104,6 +104,33 @@
         llvm::cl::desc("Set the name of the dynamic linker."),
         llvm::cl::value_desc("Program"));
 
+static llvm::cl::opt<bool>
+OptRelocatable("relocatable",
+               llvm::cl::desc("Generate relocatable output"),
+               llvm::cl::init(false));
+
+static llvm::cl::alias
+OptRelocatableAlias("r",
+                    llvm::cl::desc("alias for --relocatable"),
+                    llvm::cl::aliasopt(OptRelocatable));
+
+static llvm::cl::opt<bool>
+OptDefineCommon("d",
+                llvm::cl::ZeroOrMore,
+                llvm::cl::desc("Define common symbol"),
+                llvm::cl::init(false));
+
+static llvm::cl::alias
+OptDefineCommonAlias1("dc",
+                      llvm::cl::desc("alias for -d"),
+                      llvm::cl::aliasopt(OptDefineCommon));
+
+static llvm::cl::alias
+OptDefineCommonAlias2("dp",
+                      llvm::cl::desc("alias for -d"),
+                      llvm::cl::aliasopt(OptDefineCommon));
+
+
 //===----------------------------------------------------------------------===//
 // Inputs
 //===----------------------------------------------------------------------===//
@@ -243,6 +270,9 @@
   // 8. Set up -Bsymbolic.
   config->setBsymbolic(OptBsymbolic);
 
+  // 9. Set up -d (define common symbols)
+  config->setDefineCommon(OptDefineCommon);
+
   Linker::ErrorCode result = pLinker.config(*config);
   if (Linker::kSuccess != result) {
     llvm::errs() << "Failed to configure the linker! (detail: "