1 //===- Linker.cpp ---------------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "alone/Linker.h" 11 #include "alone/Support/LinkerConfig.h" 12 #include "alone/Support/Log.h" 13 14 #include <llvm/Support/ELF.h> 15 16 #include <mcld/Module.h> 17 #include <mcld/IRBuilder.h> 18 #include <mcld/MC/MCLDInput.h> 19 #include <mcld/Linker.h> 20 #include <mcld/LD/LDSection.h> 21 #include <mcld/LD/LDContext.h> 22 #include <mcld/Support/Path.h> 23 24 using namespace alone; 25 26 const char* Linker::GetErrorString(enum Linker::ErrorCode pErrCode) { 27 static const char* ErrorString[] = { 28 /* kSuccess */ 29 "Successfully compiled.", 30 /* kDoubleConfig */ 31 "Configure Linker twice.", 32 /* kDelegateLDInfo */ 33 "Cannot get linker information", 34 /* kFindNameSpec */ 35 "Cannot find -lnamespec", 36 /* kOpenObjectFile */ 37 "Cannot open object file", 38 /* kNotConfig */ 39 "Linker::config() is not called", 40 /* kNotSetUpOutput */ 41 "Linker::setOutput() is not called before add input files", 42 /* kOpenOutput */ 43 "Cannot open output file", 44 /* kReadSections */ 45 "Cannot read sections", 46 /* kReadSymbols */ 47 "Cannot read symbols", 48 /* kAddAdditionalSymbols */ 49 "Cannot add standard and target symbols", 50 /* kMaxErrorCode */ 51 "(Unknown error code)" 52 }; 53 54 if (pErrCode > kMaxErrorCode) { 55 pErrCode = kMaxErrorCode; 56 } 57 58 return ErrorString[ static_cast<size_t>(pErrCode) ]; 59 } 60 61 //===----------------------------------------------------------------------===// 62 // Linker 63 //===----------------------------------------------------------------------===// 64 Linker::Linker() 65 : mLDConfig(NULL), mModule(NULL), mLinker(NULL), mBuilder(NULL), 66 mOutputHandler(-1) { 67 } 68 69 Linker::Linker(const LinkerConfig& pConfig) 70 : mLDConfig(NULL), mModule(NULL), mLinker(NULL), mBuilder(NULL), 71 mOutputHandler(-1) { 72 73 const std::string &triple = pConfig.getTriple(); 74 75 enum ErrorCode err = config(pConfig); 76 if (kSuccess != err) { 77 ALOGE("%s (%s)", GetErrorString(err), triple.c_str()); 78 return; 79 } 80 81 return; 82 } 83 84 Linker::~Linker() { 85 delete mModule; 86 delete mLinker; 87 delete mBuilder; 88 } 89 90 enum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig) { 91 mLDConfig = pConfig.getLDConfig(); 92 if (mLDConfig == NULL) { 93 return kDelegateLDInfo; 94 } 95 return kSuccess; 96 } 97 98 enum Linker::ErrorCode Linker::config(const LinkerConfig& pConfig) { 99 if (mLDConfig != NULL) { 100 return kDoubleConfig; 101 } 102 103 extractFiles(pConfig); 104 105 mModule = new mcld::Module(mLDConfig->options().soname()); 106 107 mBuilder = new mcld::IRBuilder(*mModule, *mLDConfig); 108 109 mLinker = new mcld::Linker(); 110 111 mLinker->config(const_cast<mcld::LinkerConfig&>(*mLDConfig)); 112 113 return kSuccess; 114 } 115 116 enum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec) { 117 mcld::Input* input = mBuilder->ReadInput(pNameSpec); 118 if (NULL == input) 119 return kFindNameSpec; 120 return kSuccess; 121 } 122 123 /// addObject - Add a object file by the filename. 124 enum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath) { 125 mcld::Input* input = mBuilder->ReadInput(pObjectPath, pObjectPath); 126 if (NULL == input) 127 return kOpenObjectFile; 128 return kSuccess; 129 } 130 131 /// addObject - Add a piece of memory. The memory is of ELF format. 132 enum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize) { 133 mcld::Input* input = mBuilder->ReadInput("NAN", pMemory, pSize); 134 if (NULL == input) 135 return kOpenMemory; 136 return kSuccess; 137 } 138 139 enum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize) { 140 mcld::Input* input = mBuilder->CreateInput("NAN", "NAN", mcld::Input::Object); 141 mcld::LDSection* sect = mBuilder->CreateELFHeader(*input, ".text", 142 llvm::ELF::SHT_PROGBITS, 143 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 144 0x1); 145 mcld::SectionData* data = mBuilder->CreateSectionData(*sect); 146 mcld::Fragment* frag = mBuilder->CreateRegion(pMemory, pSize); 147 mBuilder->AppendFragment(*frag, *data); 148 return kSuccess; 149 } 150 151 enum Linker::ErrorCode Linker::setOutput(const std::string &pPath) { 152 mOutputPath = pPath; 153 return kSuccess; 154 } 155 156 enum Linker::ErrorCode Linker::setOutput(int pFileHandler) { 157 mOutputHandler = pFileHandler; 158 return kSuccess; 159 } 160 161 enum Linker::ErrorCode Linker::link() { 162 mLinker->link(*mModule, *mBuilder); 163 if (!mOutputPath.empty()) { 164 mLinker->emit(mOutputPath); 165 return kSuccess; 166 } 167 168 if (-1 != mOutputHandler) { 169 mLinker->emit(mOutputHandler); 170 return kSuccess; 171 } 172 return kNotSetUpOutput; 173 } 174 175