15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MCLDDriver.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//===----------------------------------------------------------------------===//
9affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/InputTree.h>
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDDriver.h>
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ArchiveReader.h>
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ObjectReader.h>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/DynObjReader.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ObjectWriter.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/DynObjWriter.h>
18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ExecWriter.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ResolveInfo.h>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/RealPath.h>
21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryAreaFactory.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
24cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/Archive.h>
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace llvm;
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
29cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoMCLDDriver::MCLDDriver(MCLDInfo& pLDInfo,
30cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                       TargetLDBackend& pLDBackend,
31cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                       MemoryAreaFactory& pAreaFactory)
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_LDInfo(pLDInfo),
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_LDBackend(pLDBackend),
34cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    m_pLinker(NULL),
35cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    m_AreaFactory(pAreaFactory) {
36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCLDDriver::~MCLDDriver()
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pLinker)
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pLinker;
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// initMCLinker - initialize MCLinker
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///  Connect all components with MCLinker
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::initMCLinker()
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == m_pLinker)
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pLinker = new MCLinker(m_LDBackend,
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             m_LDInfo,
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             m_SectionMap);
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize the readers and writers
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Because constructor can not be failed, we initalize all readers and
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // writers outside the MCLinker constructors.
57cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (!m_LDBackend.initObjectReader(*m_pLinker) ||
58cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      !m_LDBackend.initArchiveReader(*m_pLinker, m_LDInfo, m_AreaFactory) ||
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      !m_LDBackend.initObjectReader(*m_pLinker) ||
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      !m_LDBackend.initDynObjReader(*m_pLinker) ||
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      !m_LDBackend.initObjectWriter(*m_pLinker) ||
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      !m_LDBackend.initDynObjWriter(*m_pLinker) ||
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      !m_LDBackend.initExecWriter(*m_pLinker))
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // initialize RelocationFactory
67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_LDBackend.initRelocFactory(*m_pLinker);
68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// initStdSections - initialize standard sections
72affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MCLDDriver::initStdSections()
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// initialize section mapping for standard format, target-dependent section,
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// (and user-defined mapping)
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!m_SectionMap.initStdSectionMap() ||
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      !m_LDBackend.initTargetSectionMap(m_SectionMap))
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// A technical debt. We need to initialize section map here because
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// we do not separate output file and temporary data structure. So far,
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// MCLinker directly use output file's LDContext as the temporary data
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// structure. We will create a new data structure mcld::Module to collect
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// all temporary data structures togather.
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_pLinker->initSectionMap();
86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // initialize standard sections
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (m_LDInfo.output().type()) {
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::DynObj: {
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // intialize standard and target-dependent sections
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!m_LDBackend.initDynObjSections(*m_pLinker))
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return false;
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Exec: {
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // intialize standard and target-dependent sections
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!m_LDBackend.initExecSections(*m_pLinker))
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return false;
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Object: {
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("output type is not implemented yet. file: `") +
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               m_LDInfo.output().name() +
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine("'."));
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return false;
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default: {
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("unknown output type of file `") +
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               m_LDInfo.output().name() +
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine("'."));
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       return false;
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end of switch
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // initialize target-dependent sections
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDBackend.initTargetSections(*m_pLinker);
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
121cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaovoid MCLDDriver::normalize()
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
123cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // -----  set up inputs  ----- //
124cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  InputTree::iterator input, inEnd = m_LDInfo.inputs().end();
125cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  for (input = m_LDInfo.inputs().begin(); input!=inEnd; ++input) {
126cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // already got type - for example, bitcode or external OIR (object
127cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // intermediate representation)
128cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if ((*input)->type() == Input::Script ||
129cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        (*input)->type() == Input::Object ||
130cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        (*input)->type() == Input::DynObj  ||
131cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        (*input)->type() == Input::Archive ||
132cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        (*input)->type() == Input::External)
133cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      continue;
134cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
135cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // is a relocatable object file
136cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if (m_LDBackend.getObjectReader()->isMyFormat(**input)) {
137cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      (*input)->setType(Input::Object);
138cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      m_LDBackend.getObjectReader()->readObject(**input);
139cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      m_LDBackend.getObjectReader()->readSections(**input);
140cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      m_LDBackend.getObjectReader()->readSymbols(**input);
141cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    }
142cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // is a shared object file
143cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    else if (m_LDBackend.getDynObjReader()->isMyFormat(**input)) {
144cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      (*input)->setType(Input::DynObj);
145cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      m_LDBackend.getDynObjReader()->readDSO(**input);
146cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      m_LDBackend.getDynObjReader()->readSymbols(**input);
147cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    }
148cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // is an archive
149cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    else if (m_LDBackend.getArchiveReader()->isMyFormat(**input)) {
150cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      (*input)->setType(Input::Archive);
151cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      Archive archive(**input, m_LDInfo.inputFactory());
152cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      m_LDBackend.getArchiveReader()->readArchive(archive);
153cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      if(archive.numOfObjectMember() > 0) {
154cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        m_LDInfo.inputs().merge<InputTree::Inclusive>(input, archive.inputs());
155cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      }
156cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    }
157cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    else {
158cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      fatal(diag::err_unrecognized_input_file) << (*input)->path()
159cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                               << m_LDInfo.triple().str();
160cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    }
161cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  } // end of for
162cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
163cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
164cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool MCLDDriver::linkable() const
165cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
166cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // check we have input and output files
167cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (m_LDInfo.inputs().empty()) {
168cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    error(diag::err_no_inputs);
169cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return false;
170cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  }
171cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
172cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // check all attributes are legal
173cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  mcld::AttributeFactory::const_iterator attr, attrEnd = m_LDInfo.attrFactory().end();
174cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  for (attr=m_LDInfo.attrFactory().begin(); attr!=attrEnd; ++attr) {
175cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if (!m_LDInfo.attrFactory().constraint().isLegal((**attr))) {
176cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      return false;
177cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    }
178cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  }
179cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
180cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // can not mix -static with shared objects
181cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  mcld::InputTree::const_bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
183cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if ((*input)->type() == mcld::Input::DynObj) {
184cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      if((*input)->attribute()->isStatic()) {
185cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        error(diag::err_mixed_shared_static_objects)
186cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                        << (*input)->name() << (*input)->path();
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return false;
188cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      }
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
191cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
192cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // can not mix -r with shared objects
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// mergeSections - put allinput sections into output sections
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::mergeSections()
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: when MCLinker can read other object files, we have to merge
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // sections
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addStandardSymbols - shared object and executable files need some
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// standard symbols
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   @return if there are some input symbols with the same name to the
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   standard symbols, return false
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::addStandardSymbols()
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return m_LDBackend.initStandardSymbols(*m_pLinker, m_LDInfo.output());
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addTargetSymbols - some targets, such as MIPS and ARM, need some
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// target-dependent symbols
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   @return if there are some input symbols with the same name to the
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   target symbols, return false
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::addTargetSymbols()
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_LDBackend.initTargetSymbols(*m_pLinker, m_LDInfo.output());
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// readRelocations - read all relocation entries
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// All symbols should be read and resolved before this function.
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::readRelocations()
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Bitcode is read by the other path. This function reads relocation sections
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // in object files.
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::InputTree::bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if ((*input)->type() == Input::Object) {
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!m_LDBackend.getObjectReader()->readRelocations(**input))
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return false;
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // ignore the other kinds of files.
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// prelayout - help backend to do some modification before layout
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::prelayout()
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDBackend.preLayout(m_LDInfo.output(),
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                        m_LDInfo,
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                        *m_pLinker);
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDBackend.allocateCommonSymbols(m_LDInfo, *m_pLinker);
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// check program interpreter - computer the name size of the runtime dyld
251affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// FIXME: check if we are doing static linking!
252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (m_LDInfo.output().type() == Output::Exec)
253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_LDBackend.sizeInterp(m_LDInfo.output(), m_LDInfo);
254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// measure NamePools - compute the size of name pool sections
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// In ELF, will compute  the size of.symtab, .strtab, .dynsym, .dynstr,
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// and .hash sections.
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dump all symbols and strings from MCLinker and build the format-dependent
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// hash table.
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDBackend.sizeNamePools(m_LDInfo.output(), m_pLinker->getOutputSymbols(), m_LDInfo);
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout - linearly layout all output sections and reserve some space
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// for GOT/PLT
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   Because we do not support instruction relaxing in this early version,
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   if there is a branch can not jump to its target, we return false
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   directly
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::layout()
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pLinker->layout();
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// prelayout - help backend to do some modification after layout
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::postlayout()
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDBackend.postLayout(m_LDInfo.output(),
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         m_LDInfo,
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         *m_pLinker);
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// finalizeSymbolValue - finalize the resolved symbol value.
286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang///   Before relocate(), after layout(), MCLinker should correct value of all
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang///   symbol.
288affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MCLDDriver::finalizeSymbolValue()
289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return m_pLinker->finalizeSymbols();
291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// relocate - applying relocation entries and create relocation
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// section in the output files
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Create relocation section, asking TargetLDBackend to
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// read the relocation information into RelocationEntry
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// and push_back into the relocation section
298affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MCLDDriver::relocation()
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pLinker->applyRelocations();
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitOutput - emit the output file.
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::emitOutput()
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(m_LDInfo.output().type()) {
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Object:
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_LDBackend.getObjectWriter()->writeObject(m_LDInfo.output());
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return true;
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::DynObj:
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_LDBackend.getDynObjWriter()->writeDynObj(m_LDInfo.output());
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return true;
313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::Exec:
314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_LDBackend.getExecWriter()->writeExecutable(m_LDInfo.output());
315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return true;
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// postProcessing - do modification after all processes
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLDDriver::postProcessing()
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pLinker->syncRelocationResult();
324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_LDBackend.postProcessing(m_LDInfo.output(),
326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                             m_LDInfo,
327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                             *m_pLinker);
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
330