Linker.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
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#include <mcld/Linker.h> 10#include <mcld/LinkerConfig.h> 11#include <mcld/Module.h> 12#include <mcld/IRBuilder.h> 13 14#include <mcld/Support/MsgHandling.h> 15#include <mcld/Support/TargetRegistry.h> 16#include <mcld/Support/FileHandle.h> 17#include <mcld/Support/MemoryArea.h> 18#include <mcld/Support/raw_ostream.h> 19 20#include <mcld/Object/ObjectLinker.h> 21#include <mcld/MC/InputBuilder.h> 22#include <mcld/Target/TargetLDBackend.h> 23#include <mcld/LD/LDSection.h> 24#include <mcld/LD/LDSymbol.h> 25#include <mcld/LD/SectionData.h> 26#include <mcld/LD/RelocData.h> 27#include <mcld/Fragment/Relocation.h> 28#include <mcld/Fragment/FragmentRef.h> 29 30#include <cassert> 31 32using namespace mcld; 33 34Linker::Linker() 35 : m_pConfig(NULL), m_pIRBuilder(NULL), 36 m_pTarget(NULL), m_pBackend(NULL), m_pObjLinker(NULL) { 37} 38 39Linker::~Linker() 40{ 41 reset(); 42} 43 44bool Linker::config(LinkerConfig& pConfig) 45{ 46 m_pConfig = &pConfig; 47 48 if (!initTarget()) 49 return false; 50 51 if (!initBackend()) 52 return false; 53 54 m_pObjLinker = new ObjectLinker(*m_pConfig, 55 *m_pBackend); 56 57 if (!initEmulator()) 58 return false; 59 60 if (!initOStream()) 61 return false; 62 63 return true; 64} 65 66bool Linker::link(Module& pModule, IRBuilder& pBuilder) 67{ 68 if (!resolve(pModule, pBuilder)) 69 return false; 70 71 return layout(); 72} 73 74bool Linker::resolve(Module& pModule, IRBuilder& pBuilder) 75{ 76 assert(NULL != m_pConfig); 77 78 m_pIRBuilder = &pBuilder; 79 assert(m_pObjLinker!=NULL); 80 m_pObjLinker->setup(pModule, pBuilder); 81 82 // 2. - initialize FragmentLinker 83 if (!m_pObjLinker->initFragmentLinker()) 84 return false; 85 86 // 3. - initialize output's standard sections 87 if (!m_pObjLinker->initStdSections()) 88 return false; 89 90 if (!Diagnose()) 91 return false; 92 93 // 4. - normalize the input tree 94 // read out sections and symbol/string tables (from the files) and 95 // set them in Module. When reading out the symbol, resolve their symbols 96 // immediately and set their ResolveInfo (i.e., Symbol Resolution). 97 m_pObjLinker->normalize(); 98 99 if (m_pConfig->options().trace()) { 100 static int counter = 0; 101 mcld::outs() << "** name\ttype\tpath\tsize (" << pModule.getInputTree().size() << ")\n"; 102 InputTree::const_dfs_iterator input, inEnd = pModule.getInputTree().dfs_end(); 103 for (input=pModule.getInputTree().dfs_begin(); input!=inEnd; ++input) { 104 mcld::outs() << counter++ << " * " << (*input)->name(); 105 switch((*input)->type()) { 106 case Input::Archive: 107 mcld::outs() << "\tarchive\t("; 108 break; 109 case Input::Object: 110 mcld::outs() << "\tobject\t("; 111 break; 112 case Input::DynObj: 113 mcld::outs() << "\tshared\t("; 114 break; 115 case Input::Script: 116 mcld::outs() << "\tscript\t("; 117 break; 118 case Input::External: 119 mcld::outs() << "\textern\t("; 120 break; 121 default: 122 unreachable(diag::err_cannot_trace_file) << (*input)->type() 123 << (*input)->name() 124 << (*input)->path(); 125 } 126 mcld::outs() << (*input)->path() << ")\n"; 127 } 128 } 129 130 // 5. - set up code position 131 if (LinkerConfig::DynObj == m_pConfig->codeGenType() || 132 m_pConfig->options().isPIE()) { 133 m_pConfig->setCodePosition(LinkerConfig::Independent); 134 } 135 else if (pModule.getLibraryList().empty()) { 136 // If the output is dependent on its loaded address, and it does not need 137 // to call outside functions, then we can treat the output static dependent 138 // and perform better optimizations. 139 m_pConfig->setCodePosition(LinkerConfig::StaticDependent); 140 } 141 else { 142 m_pConfig->setCodePosition(LinkerConfig::DynamicDependent); 143 } 144 145 if (!m_pObjLinker->linkable()) 146 return Diagnose(); 147 148 // 6. - read all relocation entries from input files 149 // For all relocation sections of each input file (in the tree), 150 // read out reloc entry info from the object file and accordingly 151 // initiate their reloc entries in SectOrRelocData of LDSection. 152 m_pObjLinker->readRelocations(); 153 154 // 7. - merge all sections 155 // Push sections into Module's SectionTable. 156 // Merge sections that have the same name. 157 // Maintain them as fragments in the section. 158 if (!m_pObjLinker->mergeSections()) 159 return false; 160 161 // 8. - allocateCommonSymbols 162 // Allocate fragments for common symbols to the corresponding sections. 163 if (!m_pObjLinker->allocateCommonSymbols()) 164 return false; 165 return true; 166} 167 168bool Linker::layout() 169{ 170 assert(NULL != m_pConfig && NULL != m_pObjLinker); 171 172 // 9. - add standard symbols, target-dependent symbols and script symbols 173 // m_pObjLinker->addUndefSymbols(); 174 if (!m_pObjLinker->addStandardSymbols() || 175 !m_pObjLinker->addTargetSymbols() || 176 !m_pObjLinker->addScriptSymbols()) 177 return false; 178 179 // 10. - scan all relocation entries by output symbols. 180 // reserve GOT space for layout. 181 // the space info is needed by pre-layout to compute the section size 182 m_pObjLinker->scanRelocations(); 183 184 // 11.a - init relaxation stuff. 185 m_pObjLinker->initStubs(); 186 187 // 11.b - pre-layout 188 m_pObjLinker->prelayout(); 189 190 // 11.c - linear layout 191 // Decide which sections will be left in. Sort the sections according to 192 // a given order. Then, create program header accordingly. 193 // Finally, set the offset for sections (@ref LDSection) 194 // according to the new order. 195 m_pObjLinker->layout(); 196 197 // 11.d - post-layout (create segment, instruction relaxing) 198 m_pObjLinker->postlayout(); 199 200 // 12. - finalize symbol value 201 m_pObjLinker->finalizeSymbolValue(); 202 203 // 13. - apply relocations 204 m_pObjLinker->relocation(); 205 206 if (!Diagnose()) 207 return false; 208 return true; 209} 210 211bool Linker::emit(MemoryArea& pOutput) 212{ 213 // 13. - write out output 214 m_pObjLinker->emitOutput(pOutput); 215 216 // 14. - post processing 217 m_pObjLinker->postProcessing(pOutput); 218 219 if (!Diagnose()) 220 return false; 221 222 return true; 223} 224 225bool Linker::emit(const std::string& pPath) 226{ 227 FileHandle file; 228 FileHandle::Permission perm = 0755; 229 if (!file.open(pPath, 230 FileHandle::ReadWrite | FileHandle::Truncate | FileHandle::Create, 231 perm)) { 232 error(diag::err_cannot_open_output_file) << "Linker::emit()" << pPath; 233 return false; 234 } 235 236 MemoryArea* output = new MemoryArea(file); 237 238 bool result = emit(*output); 239 240 delete output; 241 file.close(); 242 return result; 243} 244 245bool Linker::emit(int pFileDescriptor) 246{ 247 FileHandle file; 248 file.delegate(pFileDescriptor); 249 MemoryArea* output = new MemoryArea(file); 250 251 bool result = emit(*output); 252 253 delete output; 254 file.close(); 255 return result; 256} 257 258bool Linker::reset() 259{ 260 m_pConfig = NULL; 261 m_pIRBuilder = NULL; 262 m_pTarget = NULL; 263 264 // Because llvm::iplist will touch the removed node, we must clear 265 // RelocData before deleting target backend. 266 RelocData::Clear(); 267 SectionData::Clear(); 268 EhFrame::Clear(); 269 270 delete m_pBackend; 271 m_pBackend = NULL; 272 273 delete m_pObjLinker; 274 m_pObjLinker = NULL; 275 276 LDSection::Clear(); 277 LDSymbol::Clear(); 278 FragmentRef::Clear(); 279 Relocation::Clear(); 280 return true; 281} 282 283bool Linker::initTarget() 284{ 285 assert(NULL != m_pConfig); 286 287 std::string error; 288 m_pTarget = mcld::TargetRegistry::lookupTarget(m_pConfig->targets().triple().str(), error); 289 if (NULL == m_pTarget) { 290 fatal(diag::fatal_cannot_init_target) << m_pConfig->targets().triple().str() << error; 291 return false; 292 } 293 return true; 294} 295 296bool Linker::initBackend() 297{ 298 assert(NULL != m_pTarget); 299 m_pBackend = m_pTarget->createLDBackend(*m_pConfig); 300 if (NULL == m_pBackend) { 301 fatal(diag::fatal_cannot_init_backend) << m_pConfig->targets().triple().str(); 302 return false; 303 } 304 return true; 305} 306 307bool Linker::initEmulator() 308{ 309 assert(NULL != m_pTarget && NULL != m_pConfig); 310 bool result = m_pTarget->emulate(m_pConfig->targets().triple().str(), 311 *m_pConfig); 312 313 // Relocation should be set up after emulation. 314 Relocation::SetUp(*m_pConfig); 315 return result; 316} 317 318bool Linker::initOStream() 319{ 320 assert(NULL != m_pConfig); 321 322 mcld::outs().setColor(m_pConfig->options().color()); 323 mcld::errs().setColor(m_pConfig->options().color()); 324 325 return true; 326} 327 328