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: "