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 const_cast<mcld::LinkerScript&>(*pConfig.getLDScript())); 107 108 mBuilder = new mcld::IRBuilder(*mModule, *mLDConfig); 109 110 mLinker = new mcld::Linker(); 111 112 mLinker->emulate(const_cast<mcld::LinkerScript&>(*pConfig.getLDScript()), 113 const_cast<mcld::LinkerConfig&>(*mLDConfig)); 114 115 return kSuccess; 116 } 117 118 enum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec) { 119 mcld::Input* input = mBuilder->ReadInput(pNameSpec); 120 if (NULL == input) 121 return kFindNameSpec; 122 return kSuccess; 123 } 124 125 /// addObject - Add a object file by the filename. 126 enum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath) { 127 mcld::Input* input = mBuilder->ReadInput(pObjectPath, pObjectPath); 128 if (NULL == input) 129 return kOpenObjectFile; 130 return kSuccess; 131 } 132 133 /// addObject - Add a piece of memory. The memory is of ELF format. 134 enum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize) { 135 mcld::Input* input = mBuilder->ReadInput("NAN", pMemory, pSize); 136 if (NULL == input) 137 return kOpenMemory; 138 return kSuccess; 139 } 140 141 enum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize) { 142 mcld::Input* input = mBuilder->CreateInput("NAN", "NAN", mcld::Input::Object); 143 mcld::LDSection* sect = mBuilder->CreateELFHeader(*input, ".text", 144 llvm::ELF::SHT_PROGBITS, 145 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 146 0x1); 147 mcld::SectionData* data = mBuilder->CreateSectionData(*sect); 148 mcld::Fragment* frag = mBuilder->CreateRegion(pMemory, pSize); 149 mBuilder->AppendFragment(*frag, *data); 150 return kSuccess; 151 } 152 153 enum Linker::ErrorCode Linker::setOutput(const std::string &pPath) { 154 mOutputPath = pPath; 155 return kSuccess; 156 } 157 158 enum Linker::ErrorCode Linker::setOutput(int pFileHandler) { 159 mOutputHandler = pFileHandler; 160 return kSuccess; 161 } 162 163 enum Linker::ErrorCode Linker::link() { 164 mLinker->link(*mModule, *mBuilder); 165 if (!mOutputPath.empty()) { 166 mLinker->emit(mOutputPath); 167 return kSuccess; 168 } 169 170 if (-1 != mOutputHandler) { 171 mLinker->emit(mOutputHandler); 172 return kSuccess; 173 } 174 return kNotSetUpOutput; 175 } 176 177