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