122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- Linker.cpp ---------------------------------------------------------===// 222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// 322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// The MCLinker Project 422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// 522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file is distributed under the University of Illinois Open Source 622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// License. See LICENSE.TXT for details. 722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// 822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Linker.h> 1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MsgHandling.h> 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/TargetRegistry.h> 1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/FileHandle.h> 17f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Support/FileOutputBuffer.h> 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/raw_ostream.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectLinker.h> 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/InputBuilder.h> 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/TargetLDBackend.h> 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h> 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSymbol.h> 25d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/SectionData.h> 26d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/RelocData.h> 27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/LD/ObjectWriter.h> 28d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Fragment/Relocation.h> 2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentRef.h> 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <cassert> 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld; 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLinker::Linker() 366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : m_pConfig(NULL), m_pIRBuilder(NULL), 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pTarget(NULL), m_pBackend(NULL), m_pObjLinker(NULL) { 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLinker::~Linker() 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reset(); 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// emulate - To set up target-dependent options and default linker script. 46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// Follow GNU ld quirks. 47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::emulate(LinkerScript& pScript, LinkerConfig& pConfig) 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pConfig = &pConfig; 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!initTarget()) 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!initBackend()) 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 57f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!initOStream()) 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!initEmulator(pScript)) 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::link(Module& pModule, IRBuilder& pBuilder) 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!normalize(pModule, pBuilder)) 69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!resolve(pModule)) 726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return layout(); 756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 77f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// normalize - to convert the command line language to the input tree. 78f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::normalize(Module& pModule, IRBuilder& pBuilder) 796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pConfig); 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pIRBuilder = &pBuilder; 83f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pObjLinker = new ObjectLinker(*m_pConfig, *m_pBackend); 85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 2. - initialize ObjectLinker 87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!m_pObjLinker->initialize(pModule, pBuilder)) 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 3. - initialize output's standard sections 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_pObjLinker->initStdSections()) 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!Diagnose()) 956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 97a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines // 4.a - add undefined symbols 98a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines // before reading the inputs, we should add undefined symbols set by -u to 99a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines // ensure that correspoding objects (e.g. in an archive) will be included 100a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines m_pObjLinker->addUndefinedSymbols(); 101a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 102a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines // 4.b - normalize the input tree 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // read out sections and symbol/string tables (from the files) and 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set them in Module. When reading out the symbol, resolve their symbols 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // immediately and set their ResolveInfo (i.e., Symbol Resolution). 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->normalize(); 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_pConfig->options().trace()) { 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao static int counter = 0; 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::outs() << "** name\ttype\tpath\tsize (" << pModule.getInputTree().size() << ")\n"; 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao InputTree::const_dfs_iterator input, inEnd = pModule.getInputTree().dfs_end(); 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (input=pModule.getInputTree().dfs_begin(); input!=inEnd; ++input) { 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::outs() << counter++ << " * " << (*input)->name(); 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch((*input)->type()) { 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case Input::Archive: 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::outs() << "\tarchive\t("; 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case Input::Object: 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::outs() << "\tobject\t("; 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case Input::DynObj: 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::outs() << "\tshared\t("; 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case Input::Script: 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::outs() << "\tscript\t("; 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case Input::External: 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::outs() << "\textern\t("; 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao unreachable(diag::err_cannot_trace_file) << (*input)->type() 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*input)->name() 13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*input)->path(); 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::outs() << (*input)->path() << ")\n"; 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // 5. - set up code position 1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::DynObj == m_pConfig->codeGenType() || 1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pConfig->options().isPIE()) { 1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pConfig->setCodePosition(LinkerConfig::Independent); 1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (pModule.getLibraryList().empty()) { 1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // If the output is dependent on its loaded address, and it does not need 1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // to call outside functions, then we can treat the output static dependent 1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // and perform better optimizations. 1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pConfig->setCodePosition(LinkerConfig::StaticDependent); 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LinkerConfig::Exec == m_pConfig->codeGenType()) { 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Since the output is static dependent, there should not have any undefined 152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // references in the output module. 153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pConfig->options().setNoUndefined(); 154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pConfig->setCodePosition(LinkerConfig::DynamicDependent); 1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_pObjLinker->linkable()) 16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Diagnose(); 16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 166f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::resolve(Module& pModule) 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != m_pConfig); 169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_pObjLinker != NULL); 170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 6. - read all relocation entries from input files 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // For all relocation sections of each input file (in the tree), 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // read out reloc entry info from the object file and accordingly 1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initiate their reloc entries in SectOrRelocData of LDSection. 175f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // To collect all edges in the reference graph. 17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->readRelocations(); 17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 179f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 180f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 7. - data stripping optimizations 181f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pObjLinker->dataStrippingOpt(); 182f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 183f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 8. - merge all sections 1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Push sections into Module's SectionTable. 1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Merge sections that have the same name. 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Maintain them as fragments in the section. 187f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 188f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // To merge nodes of the reference graph. 18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_pObjLinker->mergeSections()) 19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 192f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 9.a - add symbols to output 193f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // After all input symbols have been resolved, add them to output symbol 194f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // table at once 195f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pObjLinker->addSymbolsToOutput(pModule); 196f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 197f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 9.b - allocateCommonSymbols 1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Allocate fragments for common symbols to the corresponding sections. 1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pObjLinker->allocateCommonSymbols()) 2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 201f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool Linker::layout() 2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pConfig && NULL != m_pObjLinker); 2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 209f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 10. - add standard symbols, target-dependent symbols and script symbols 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_pObjLinker->addStandardSymbols() || 2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines !m_pObjLinker->addTargetSymbols() || 2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines !m_pObjLinker->addScriptSymbols()) 21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 215f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 11. - scan all relocation entries by output symbols. 2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // reserve GOT space for layout. 2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // the space info is needed by pre-layout to compute the section size 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->scanRelocations(); 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 220f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 12.a - init relaxation stuff. 2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pObjLinker->initStubs(); 2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 223f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 12.b - pre-layout 22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->prelayout(); 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 226f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 12.c - linear layout 2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Decide which sections will be left in. Sort the sections according to 2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // a given order. Then, create program header accordingly. 2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Finally, set the offset for sections (@ref LDSection) 2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // according to the new order. 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->layout(); 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 233f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 12.d - post-layout (create segment, instruction relaxing) 23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->postlayout(); 23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 236f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 13. - finalize symbol value 23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->finalizeSymbolValue(); 23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 239f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 14. - apply relocations 24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->relocation(); 24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!Diagnose()) 24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 247f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::emit(FileOutputBuffer& pOutput) 24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 249f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 15. - write out output 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->emitOutput(pOutput); 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 252f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // 16. - post processing 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker->postProcessing(pOutput); 25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!Diagnose()) 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 261f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::emit(const Module& pModule, const std::string& pPath) 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FileHandle file; 264f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines FileHandle::Permission perm; 265f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines switch (m_pConfig->codeGenType()) { 266f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case mcld::LinkerConfig::Unknown: 267f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case mcld::LinkerConfig::Object: 268f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines perm = mcld::FileHandle::Permission(0x644); 269f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 270f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case mcld::LinkerConfig::DynObj: 271f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case mcld::LinkerConfig::Exec: 272f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case mcld::LinkerConfig::Binary: 273f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines perm = mcld::FileHandle::Permission(0x755); 274f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 275f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines default: assert(0 && "Unknown file type"); 276f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 277f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!file.open(pPath, 27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FileHandle::ReadWrite | FileHandle::Truncate | FileHandle::Create, 28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao perm)) { 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao error(diag::err_cannot_open_output_file) << "Linker::emit()" << pPath; 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 285a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines std::unique_ptr<FileOutputBuffer> output; 286f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines FileOutputBuffer::create(file, 287f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pObjLinker->getWriter()->getOutputSize(pModule), 288f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines output); 28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 290f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines bool result = emit(*output.get()); 29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file.close(); 29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return result; 29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 295f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::emit(const Module& pModule, int pFileDescriptor) 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FileHandle file; 29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file.delegate(pFileDescriptor); 29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 300a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines std::unique_ptr<FileOutputBuffer> output; 301f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines FileOutputBuffer::create(file, 302f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pObjLinker->getWriter()->getOutputSize(pModule), 303f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines output); 304f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 305f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines bool result = emit(*output.get()); 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return result; 30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::reset() 31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pConfig = NULL; 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pIRBuilder = NULL; 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pTarget = NULL; 31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 316d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // Because llvm::iplist will touch the removed node, we must clear 317d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // RelocData before deleting target backend. 318d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao RelocData::Clear(); 319d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao SectionData::Clear(); 3206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines EhFrame::Clear(); 321d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pBackend; 32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pBackend = NULL; 32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pObjLinker; 32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjLinker = NULL; 32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection::Clear(); 32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol::Clear(); 33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Clear(); 331d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao Relocation::Clear(); 33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initTarget() 33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pConfig); 33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao std::string error; 340f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::Triple triple(m_pConfig->targets().triple()); 341f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 342f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pTarget = mcld::TargetRegistry::lookupTarget(m_pConfig->targets().getArch(), 343f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines triple, error); 344f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pConfig->targets().setTriple(triple); 345f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pTarget) { 347f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines fatal(diag::fatal_cannot_init_target) << triple.str() << error; 34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initBackend() 35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pTarget); 35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pBackend = m_pTarget->createLDBackend(*m_pConfig); 35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pBackend) { 358d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::fatal_cannot_init_backend) << m_pConfig->targets().triple().str(); 35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initOStream() 36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pConfig); 36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::outs().setColor(m_pConfig->options().color()); 36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::errs().setColor(m_pConfig->options().color()); 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 374f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::initEmulator(LinkerScript& pScript) 375f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 376f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != m_pTarget && NULL != m_pConfig); 377f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_pTarget->emulate(pScript, *m_pConfig); 378f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 379f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 380