15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- SectLinker.cpp -----------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file implements the SectLinker class. 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/FileHandle.h> 14affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/InputTree.h> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDDriver.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/FileSystem.h> 17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/FileHandle.h> 19affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/raw_ostream.h> 20affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryAreaFactory.h> 21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/DerivedPositionDependentOptions.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/TargetLDBackend.h> 23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/CodeGen/SectLinker.h> 24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/CodeGen/SectLinkerOption.h> 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Module.h> 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <algorithm> 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stack> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string> 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace llvm; 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Forward declarations 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaochar SectLinker::m_ID = 0; 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic bool CompareOption(const PositionDependentOption* X, 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const PositionDependentOption* Y); 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// SectLinker 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoSectLinker::SectLinker(SectLinkerOption &pOption, 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao TargetLDBackend& pLDBackend) 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : MachineFunctionPass(m_ID), 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pOption(&pOption), 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pLDBackend(&pLDBackend), 48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pLDDriver(NULL), 49affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pMemAreaFactory(NULL) 50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pMemAreaFactory = new MemoryAreaFactory(32); 52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoSectLinker::~SectLinker() 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pLDDriver; 57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: current implementation can not change the order of delete. 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Instance of TargetLDBackend was created outside and is not managed by 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // SectLinker. It should not be destroyed here and by SectLinker. However, in 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // order to follow the LLVM convention - that is, the pass manages all the 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // objects it used during the processing, we destroy the object of 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TargetLDBackend here. 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pLDBackend; 66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang delete m_pMemAreaFactory; 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool SectLinker::doInitialization(Module &pM) 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLDInfo &info = m_pOption->info(); 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // ----- convert position dependent options into tree of input files ----- // 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao PositionDependentOptions &PosDepOpts = m_pOption->pos_dep_options(); 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::stable_sort(PosDepOpts.begin(), PosDepOpts.end(), CompareOption); 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao initializeInputTree(PosDepOpts); 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang initializeInputOutput(info); 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Now, all input arguments are prepared well, send it into MCLDDriver 80cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao m_pLDDriver = new MCLDDriver(info, *m_pLDBackend, *memAreaFactory()); 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool SectLinker::doFinalization(Module &pM) 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo &info = m_pOption->info(); 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2. - initialize MCLinker 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!m_pLDDriver->initMCLinker()) 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 3. - initialize output's standard sections 94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!m_pLDDriver->initStdSections()) 95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 4. - normalize the input tree 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pLDDriver->normalize(); 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (info.options().trace()) { 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static int counter = 0; 102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::outs() << "** name\ttype\tpath\tsize (" << info.inputs().size() << ")\n"; 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao InputTree::const_dfs_iterator input, inEnd = info.inputs().dfs_end(); 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (input=info.inputs().dfs_begin(); input!=inEnd; ++input) { 105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::outs() << counter++ << " * " << (*input)->name(); 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch((*input)->type()) { 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Input::Archive: 108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::outs() << "\tarchive\t("; 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Input::Object: 111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::outs() << "\tobject\t("; 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Input::DynObj: 114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::outs() << "\tshared\t("; 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Input::Script: 117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::outs() << "\tscript\t("; 118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case Input::External: 120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::outs() << "\textern\t("; 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang unreachable(diag::err_cannot_trace_file) << (*input)->type() 124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << (*input)->name() 125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << (*input)->path(); 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::outs() << (*input)->path() << ")\n"; 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 5. - check if we can do static linking and if we use split-stack. 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!m_pLDDriver->linkable()) 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 136cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // 6. - merge all sections 137cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (!m_pLDDriver->mergeSections()) 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 140cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // 7. - add standard symbols and target-dependent symbols 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // m_pLDDriver->addUndefSymbols(); 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!m_pLDDriver->addStandardSymbols() || 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao !m_pLDDriver->addTargetSymbols()) 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 8. - read all relocation entries from input files 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pLDDriver->readRelocations(); 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 9. - pre-layout 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pLDDriver->prelayout(); 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 10. - linear layout 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pLDDriver->layout(); 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 155cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // 10.b - post-layout (create segment, instruction relaxing) 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pLDDriver->postlayout(); 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 11. - finalize symbol value 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pLDDriver->finalizeSymbolValue(); 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 12. - apply relocations 162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pLDDriver->relocation(); 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 13. - write out output 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pLDDriver->emitOutput(); 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 14. - post processing 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pLDDriver->postProcessing(); 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool SectLinker::runOnMachineFunction(MachineFunction& pF) 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // basically, linkers do nothing during function is generated. 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 178affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid SectLinker::initializeInputOutput(MCLDInfo &pLDInfo) 179affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- initialize output file ----- // 181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang FileHandle::Permission perm; 182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Output::Object == pLDInfo.output().type()) 183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang perm = 0544; 184affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 185affc150dc44fab1911775a49636d0ce85333b634Zonr Chang perm = 0755; 186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang MemoryArea* out_area = memAreaFactory()->produce(pLDInfo.output().path(), 188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang FileHandle::ReadWrite, 189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang perm); 190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!out_area->handler()->isGood()) { 192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // make sure output is openend successfully. 193affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::err_cannot_open_output_file) << pLDInfo.output().name() 194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pLDInfo.output().path(); 195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLDInfo.output().setMemArea(out_area); 198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLDInfo.output().setContext(pLDInfo.contextFactory().produce()); 199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- initialize input files ----- // 201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang InputTree::dfs_iterator input, inEnd = pLDInfo.inputs().dfs_end(); 202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (input = pLDInfo.inputs().dfs_begin(); input!=inEnd; ++input) { 203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // already got type - for example, bitcode 204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if ((*input)->type() == Input::Script || 205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*input)->type() == Input::Object || 206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*input)->type() == Input::DynObj || 207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*input)->type() == Input::Archive) 208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang continue; 209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang MemoryArea *input_memory = 211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang memAreaFactory()->produce((*input)->path(), FileHandle::ReadOnly); 212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (input_memory->handler()->isGood()) { 214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*input)->setMemArea(input_memory); 215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang error(diag::err_cannot_open_input) << (*input)->name() << (*input)->path(); 218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDContext *input_context = 222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLDInfo.contextFactory().produce((*input)->path()); 223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*input)->setContext(input_context); 225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid SectLinker::initializeInputTree(const PositionDependentOptions &pPosDepOptions) const 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pPosDepOptions.empty()) 231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::err_no_inputs); 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLDInfo &info = m_pOption->info(); 234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang PositionDependentOptions::const_iterator option = pPosDepOptions.begin(); 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (1 == pPosDepOptions.size() && 236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ((*option)->type() != PositionDependentOption::INPUT_FILE && 237affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*option)->type() != PositionDependentOption::NAMESPEC) && 238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*option)->type() != PositionDependentOption::BITCODE) { 239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if we only have one positional options, and the option is 240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // not an input file, then emit error message. 241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::err_no_inputs); 242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- Input tree insertion algorithm ----- // 245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // The type of the previsou node indicates the direction of the current 246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // insertion. 247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // root : the parent node who being inserted. 249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // mover : the direcion of current movement. 250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 251affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // for each positional options: 252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // insert the options in current root. 253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // calculate the next movement 254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 255affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Initialization 256affc150dc44fab1911775a49636d0ce85333b634Zonr Chang InputTree::Mover *move = &InputTree::Downward; 257affc150dc44fab1911775a49636d0ce85333b634Zonr Chang InputTree::iterator root = info.inputs().root(); 258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang PositionDependentOptions::const_iterator optionEnd = pPosDepOptions.end(); 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::stack<InputTree::iterator> returnStack; 260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang while (option != optionEnd ) { 262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang switch ((*option)->type()) { 264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /** bitcode **/ 265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case PositionDependentOption::BITCODE: { 266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const BitcodeOption *bitcode_option = 268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang static_cast<const BitcodeOption*>(*option); 269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // threat bitcode as an external IR in this version. 271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang info.inputs().insert(root, *move, 272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bitcode_option->path()->native(), 273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang *(bitcode_option->path()), 274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Input::External); 275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang info.setBitcode(**root); 277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // move root on the new created node. 279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang move->move(root); 280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // the next file is appended after bitcode file. 282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang move = &InputTree::Afterward; 283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /** input object file **/ 287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case PositionDependentOption::INPUT_FILE: { 288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const InputFileOption *input_file_option = 289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang static_cast<const InputFileOption*>(*option); 290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang info.inputs().insert(root, *move, 292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang input_file_option->path()->native(), 293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang *(input_file_option->path())); 294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // move root on the new created node. 296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang move->move(root); 297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // the next file is appended after object file. 299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang move = &InputTree::Afterward; 300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /** -lnamespec **/ 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::NAMESPEC: { 305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang sys::fs::Path* path = NULL; 3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const NamespecOption *namespec_option = 307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang static_cast<const NamespecOption*>(*option); 308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // find out the real path of the namespec. 310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (info.attrFactory().constraint().isSharedSystem()) { 311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // In the system with shared object support, we can find both archive 312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // and shared object. 313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (info.attrFactory().last().isStatic()) { 315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // with --static, we must search an archive. 316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang path = info.options().directories().find(namespec_option->namespec(), 317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Input::Archive); 318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // otherwise, with --Bdynamic, we can find either an archive or a 321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // shared object. 322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang path = info.options().directories().find(namespec_option->namespec(), 323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Input::DynObj); 324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // In the system without shared object support, we only look for an 328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // archive. 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao path = info.options().directories().find(namespec_option->namespec(), 330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Input::Archive); 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 333affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == path) 334affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::err_cannot_find_namespec) << namespec_option->namespec(); 335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 336affc150dc44fab1911775a49636d0ce85333b634Zonr Chang info.inputs().insert(root, *move, 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao namespec_option->namespec(), 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *path); 339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // iterate root on the new created node. 341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang move->move(root); 342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // the file after a namespec must be appended afterward. 344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang move = &InputTree::Afterward; 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 347affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 348affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /** start group **/ 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::START_GROUP: 350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang info.inputs().enterGroup(root, *move); 351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang move->move(root); 352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang returnStack.push(root); 353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang move = &InputTree::Downward; 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /** end group **/ 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::END_GROUP: 357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang root = returnStack.top(); 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao returnStack.pop(); 359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang move = &InputTree::Afterward; 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::WHOLE_ARCHIVE: 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info.attrFactory().last().setWholeArchive(); 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::NO_WHOLE_ARCHIVE: 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info.attrFactory().last().unsetWholeArchive(); 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::AS_NEEDED: 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info.attrFactory().last().setAsNeeded(); 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::NO_AS_NEEDED: 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info.attrFactory().last().unsetAsNeeded(); 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::ADD_NEEDED: 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info.attrFactory().last().setAddNeeded(); 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::NO_ADD_NEEDED: 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info.attrFactory().last().unsetAddNeeded(); 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::BSTATIC: 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info.attrFactory().last().setStatic(); 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case PositionDependentOption::BDYNAMIC: 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info.attrFactory().last().setDynamic(); 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::err_cannot_identify_option) << (*option)->position() 387affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << (uint32_t)(*option)->type(); 388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } // end of switch 389affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ++option; 390affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } // end of while 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!returnStack.empty()) { 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao report_fatal_error("no matched --start-group and --end-group"); 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Non-member functions 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic bool CompareOption(const PositionDependentOption* X, 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const PositionDependentOption* Y) 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return (X->position() < Y->position()); 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 405