122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- ObjectLinker.cpp ---------------------------------------------------===//
222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//                     The MCLinker Project
422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file is distributed under the University of Illinois Open Source
622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// License. See LICENSE.TXT for details.
722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectLinker.h>
1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h>
14d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/IRBuilder.h>
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h>
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h>
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/Archive.h>
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ArchiveReader.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ObjectReader.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/DynObjReader.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/GroupReader.h>
22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/BinaryReader.h>
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ObjectWriter.h>
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ResolveInfo.h>
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h>
26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/Relocator.h>
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/RealPath.h>
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h>
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MsgHandling.h>
30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/DefSymParser.h>
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h>
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/Casting.h>
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace llvm;
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoObjectLinker::ObjectLinker(const LinkerConfig& pConfig,
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           TargetLDBackend& pLDBackend)
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : m_Config(pConfig),
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pLinker(NULL),
446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pModule(NULL),
456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pBuilder(NULL),
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_LDBackend(pLDBackend),
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pObjectReader(NULL),
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pDynObjReader(NULL),
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pArchiveReader(NULL),
50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pGroupReader(NULL),
51d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pBinaryReader(NULL),
526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pWriter(NULL) {
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoObjectLinker::~ObjectLinker()
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pLinker;
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pObjectReader;
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynObjReader;
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pArchiveReader;
61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pGroupReader;
62d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pBinaryReader;
636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pWriter;
646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ObjectLinker::setup(Module& pModule, IRBuilder& pBuilder)
676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pModule = &pModule;
696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pBuilder = &pBuilder;
70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // set up soname
726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_Config.options().soname().empty()) {
736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pModule->setName(m_Config.options().soname());
746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initFragmentLinker - initialize FragmentLinker
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///  Connect all components with FragmentLinker
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::initFragmentLinker()
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pLinker) {
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pLinker = new FragmentLinker(m_Config,
836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   *m_pModule,
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   m_LDBackend);
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // initialize the readers and writers
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Because constructor can not be failed, we initalize all readers and
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // writers outside the FragmentLinker constructors.
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pObjectReader  = m_LDBackend.createObjectReader(*m_pBuilder);
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pArchiveReader = m_LDBackend.createArchiveReader(*m_pModule);
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pDynObjReader  = m_LDBackend.createDynObjReader(*m_pBuilder);
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pBinaryReader  = m_LDBackend.createBinaryReader(*m_pBuilder);
94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  m_pGroupReader   = new GroupReader(*m_pModule, *m_pObjectReader,
95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                         *m_pDynObjReader, *m_pArchiveReader, *m_pBinaryReader);
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pWriter        = m_LDBackend.createWriter();
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
98d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // initialize Relocator
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initRelocator();
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStdSections - initialize standard sections
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::initStdSections()
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ObjectBuilder builder(m_Config, *m_pModule);
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // initialize standard sections
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_LDBackend.initStdSections(builder))
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // initialize target-dependent sections
1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initTargetSections(*m_pModule, builder);
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid ObjectLinker::normalize()
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // -----  set up inputs  ----- //
1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::input_iterator input, inEnd = m_pModule->input_end();
1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (input = m_pModule->input_begin(); input!=inEnd; ++input) {
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // is a group node
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isGroup(input)) {
1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      getGroupReader()->readGroup(input, m_pBuilder->getInputBuilder(), m_Config);
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // already got type - for example, bitcode or external OIR (object
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // intermediate representation)
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*input)->type() == Input::Script ||
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*input)->type() == Input::Archive ||
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*input)->type() == Input::External)
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (Input::Object == (*input)->type()) {
1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getObjectList().push_back(*input);
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (Input::DynObj == (*input)->type()) {
1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getLibraryList().push_back(*input);
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
146d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // read input as a binary file
147d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (m_Config.options().isBinaryInput()) {
148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (*input)->setType(Input::Object);
149d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      getBinaryReader()->readBinary(**input);
1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getObjectList().push_back(*input);
151d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // is a relocatable object file
153d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    else if (getObjectReader()->isMyFormat(**input)) {
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*input)->setType(Input::Object);
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getObjectReader()->readHeader(**input);
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getObjectReader()->readSections(**input);
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getObjectReader()->readSymbols(**input);
1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getObjectList().push_back(*input);
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // is a shared object file
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if (getDynObjReader()->isMyFormat(**input)) {
16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*input)->setType(Input::DynObj);
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getDynObjReader()->readHeader(**input);
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getDynObjReader()->readSymbols(**input);
1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getLibraryList().push_back(*input);
16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // is an archive
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if (getArchiveReader()->isMyFormat(**input)) {
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*input)->setType(Input::Archive);
1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      Archive archive(**input, m_pBuilder->getInputBuilder());
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getArchiveReader()->readArchive(archive);
17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if(archive.numOfObjectMember() > 0) {
1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        m_pModule->getInputTree().merge<InputTree::Inclusive>(input,
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                            archive.inputs());
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else {
17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::err_unrecognized_input_file) << (*input)->path()
179d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                          << m_Config.targets().triple().str();
18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of for
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::linkable() const
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // check we have input and output files
1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_pModule->getInputTree().empty()) {
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    error(diag::err_no_inputs);
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // can not mix -static with shared objects
1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_lib_iterator lib, libEnd = m_pModule->lib_end();
1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (lib = m_pModule->lib_begin(); lib != libEnd; ++lib) {
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if((*lib)->attribute()->isStatic()) {
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      error(diag::err_mixed_shared_static_objects)
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      << (*lib)->name() << (*lib)->path();
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return false;
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // --nmagic and --omagic options lead to static executable program.
2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // These options turn off page alignment of sections. Because the
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // sections are not aligned to pages, these sections can not contain any
2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // exported functions. Also, because the two options disable linking
2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // against shared libraries, the output absolutely does not call outside
2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // functions.
2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Config.options().nmagic() && !m_Config.isCodeStatic()) {
2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    error(diag::err_nmagic_not_static);
2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Config.options().omagic() && !m_Config.isCodeStatic()) {
2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    error(diag::err_omagic_not_static);
2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRelocations - read all relocation entries
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// All symbols should be read and resolved before this function.
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::readRelocations()
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Bitcode is read by the other path. This function reads relocation sections
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // in object files.
2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  mcld::InputTree::bfs_iterator input, inEnd = m_pModule->getInputTree().bfs_end();
2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (input=m_pModule->getInputTree().bfs_begin(); input!=inEnd; ++input) {
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*input)->type() == Input::Object && (*input)->hasMemArea()) {
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!getObjectReader()->readRelocations(**input))
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return false;
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // ignore the other kinds of files.
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// mergeSections - put allinput sections into output sections
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::mergeSections()
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ObjectBuilder builder(m_Config, *m_pModule);
2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::obj_iterator obj, objEnd = m_pModule->obj_end();
2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (obj = m_pModule->obj_begin(); obj != objEnd; ++obj) {
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      switch ((*sect)->kind()) {
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // Some *INPUT sections should not be merged.
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::Ignore:
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::Null:
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::Relocation:
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::NamePool:
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::Group:
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::StackNote:
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          // skip
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::Target:
2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (!m_LDBackend.mergeSection(*m_pModule, **sect)) {
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            error(diag::err_cannot_merge_section) << (*sect)->name()
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  << (*obj)->name();
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            return false;
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::EhFrame: {
26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!(*sect)->hasEhFrame())
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            continue; // skip
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
267f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          LDSection* out_sect = NULL;
268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          if (NULL == (out_sect = builder.MergeSection(**sect))) {
269f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            error(diag::err_cannot_merge_section) << (*sect)->name()
270f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                                  << (*obj)->name();
271f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            return false;
272f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          }
273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
274f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) {
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            error(diag::err_cannot_merge_section) << (*sect)->name()
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  << (*obj)->name();
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            return false;
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        default: {
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!(*sect)->hasSectionData())
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            continue; // skip
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
285f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          LDSection* out_sect = NULL;
286f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          if (NULL == (out_sect = builder.MergeSection(**sect))) {
287f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            error(diag::err_cannot_merge_section) << (*sect)->name()
288f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                                  << (*obj)->name();
289f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            return false;
2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          }
291f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
292f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) {
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            error(diag::err_cannot_merge_section) << (*sect)->name()
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  << (*obj)->name();
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            return false;
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      } // end of switch
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // for each section
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // for each obj
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// addStandardSymbols - shared object and executable files need some
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// standard symbols
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   @return if there are some input symbols with the same name to the
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   standard symbols, return false
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::addStandardSymbols()
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // create and add section symbols for each output section
3126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::iterator iter, iterEnd = m_pModule->end();
3136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (iter = m_pModule->begin(); iter != iterEnd; ++iter) {
3146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pModule->getSectionSymbolSet().add(**iter, m_pModule->getNamePool());
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return m_LDBackend.initStandardSymbols(*m_pBuilder, *m_pModule);
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// addTargetSymbols - some targets, such as MIPS and ARM, need some
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent symbols
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   @return if there are some input symbols with the same name to the
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   target symbols, return false
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::addTargetSymbols()
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initTargetSymbols(*m_pBuilder, *m_pModule);
3276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
3286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// addScriptSymbols - define symbols from the command line option or linker
3316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// scripts.
3326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ObjectLinker::addScriptSymbols()
3336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
334f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  const LinkerScript& script = m_pModule->getScript();
335f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LinkerScript::DefSymMap::const_entry_iterator it;
336f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LinkerScript::DefSymMap::const_entry_iterator ie = script.defSymMap().end();
337f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // go through the entire defSymMap
338f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  for (it = script.defSymMap().begin(); it != ie; ++it) {
339f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    const llvm::StringRef sym =  it.getEntry()->key();
340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    ResolveInfo* old_info = m_pModule->getNamePool().findInfo(sym);
341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // if the symbol does not exist, we can set type to NOTYPE
342f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // else we retain its type, same goes for size - 0 or retain old value
343f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // and visibility - Default or retain
344f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (old_info != NULL) {
345f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      if(!m_pBuilder->AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
346f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             sym,
347f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             static_cast<ResolveInfo::Type>(old_info->type()),
348f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             ResolveInfo::Define,
349f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             ResolveInfo::Absolute,
350f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             old_info->size(),
351f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             0x0,
352f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             FragmentRef::Null(),
353f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             old_info->visibility()))
354f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        return false;
355f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    }
356f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    else {
357f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      if (!m_pBuilder->AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
358f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             sym,
359f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             ResolveInfo::NoType,
360f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             ResolveInfo::Define,
361f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             ResolveInfo::Absolute,
362f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             0x0,
363f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             0x0,
364f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             FragmentRef::Null(),
365f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                             ResolveInfo::Default))
366f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        return false;
367f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    }
368f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::scanRelocations()
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // apply all relocations of all inputs
3756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::obj_iterator input, inEnd = m_pModule->obj_end();
3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (input = m_pModule->obj_begin(); input != inEnd; ++input) {
377f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_LDBackend.getRelocator()->initializeScan(**input);
37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // bypass the reloc section if
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 1. its section kind is changed to Ignore. (The target section is a
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // discarded group section.)
38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 2. it has no reloc data. (All symbols in the input relocs are in the
38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // discarded group sections)
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        Relocation* relocation = llvm::cast<Relocation>(reloc);
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // scan relocation
3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (LinkerConfig::Object != m_Config.codeGenType())
392f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          m_LDBackend.getRelocator()->scanRelocation(
393f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                    *relocation, *m_pBuilder, *m_pModule, **rs);
3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        else
395f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          m_LDBackend.getRelocator()->partialScanRelocation(
396f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                                 *relocation, *m_pModule, **rs);
39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      } // for all relocations
39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // for all relocation section
399f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_LDBackend.getRelocator()->finalizeScan(**input);
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // for all inputs
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// initStubs - initialize stub-related stuff.
4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ObjectLinker::initStubs()
4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // initialize BranchIslandFactory
4086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initBRIslandFactory();
4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // initialize StubFactory
4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initStubFactory();
4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // initialize target stubs
4146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initTargetStubs();
4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// allocateCommonSymobols - allocate fragments for common symbols to the
4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// corresponding sections
4206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ObjectLinker::allocateCommonSymbols()
4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != m_Config.codeGenType() ||
4236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Config.options().isDefineCommon())
4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return m_LDBackend.allocateCommonSymbols(*m_pModule);
4256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
4266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// prelayout - help backend to do some modification before layout
42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::prelayout()
43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // finalize the section symbols, set their fragment reference and push them
43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // into output symbol table
4336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::iterator sect, sEnd = m_pModule->end();
4346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (sect = m_pModule->begin(); sect != sEnd; ++sect) {
435f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pModule->getSectionSymbolSet().finalize(**sect,
436f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        m_pModule->getSymbolTable(),
437f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        m_Config.codeGenType() == LinkerConfig::Object);
43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.preLayout(*m_pModule, *m_pBuilder);
44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// check program interpreter - computer the name size of the runtime dyld
4436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_Config.isCodeStatic() &&
44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (LinkerConfig::Exec == m_Config.codeGenType() ||
44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao       m_Config.options().isPIE() ||
44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao       m_Config.options().hasDyld()))
44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_LDBackend.sizeInterp();
44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
44922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// measure NamePools - compute the size of name pool sections
45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// In ELF, will compute  the size of.symtab, .strtab, .dynsym, .dynstr,
45122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// .hash and .shstrtab sections.
45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ///
45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// dump all symbols and strings from FragmentLinker and build the format-dependent
45422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// hash table.
455f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @note sizeNamePools replies on LinkerConfig::CodePosition. Must determine
456f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// code position model before calling GNULDBackend::sizeNamePools()
457f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  m_LDBackend.sizeNamePools(*m_pModule);
45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
46122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// layout - linearly layout all output sections and reserve some space
46322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// for GOT/PLT
46422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   Because we do not support instruction relaxing in this early version,
46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   if there is a branch can not jump to its target, we return false
46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   directly
46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::layout()
46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.layout(*m_pModule);
470d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return true;
47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// prelayout - help backend to do some modification after layout
47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::postlayout()
47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.postLayout(*m_pModule, *m_pBuilder);
47722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
47822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
48022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// finalizeSymbolValue - finalize the resolved symbol value.
48122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   Before relocate(), after layout(), FragmentLinker should correct value of all
48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   symbol.
48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::finalizeSymbolValue()
48422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
485f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool finalized = m_pLinker->finalizeSymbols() && m_LDBackend.finalizeSymbols();
486f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool scriptSymsAdded = true;
487f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  uint64_t symVal;
488f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  const LinkerScript& script = m_pModule->getScript();
489f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LinkerScript::DefSymMap::const_entry_iterator it;
490f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LinkerScript::DefSymMap::const_entry_iterator ie = script.defSymMap().end();
491f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
492f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  DefSymParser parser(*m_pModule);
493f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  for (it = script.defSymMap().begin(); it != ie; ++it) {
494f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    llvm::StringRef symName =  it.getEntry()->key();
495f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    llvm::StringRef expr =  it.getEntry()->value();
496f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
497f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    LDSymbol* symbol = m_pModule->getNamePool().findSymbol(symName);
498f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    assert(NULL != symbol && "--defsym symbol should be in the name pool");
499f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    scriptSymsAdded &= parser.parse(expr, symVal);
500f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (!scriptSymsAdded)
501f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      break;
502f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    symbol->setValue(symVal);
503f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
504f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return finalized && scriptSymsAdded ;
50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// relocate - applying relocation entries and create relocation
50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// section in the output files
50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// Create relocation section, asking TargetLDBackend to
51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// read the relocation information into RelocationEntry
51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// and push_back into the relocation section
51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::relocation()
51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_pLinker->applyRelocations();
51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitOutput - emit the output file.
51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::emitOutput(MemoryArea& pOutput)
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return llvm::errc::success == getWriter()->writeObject(*m_pModule, pOutput);
52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
523f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// postProcessing - do modification after all processes
52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::postProcessing(MemoryArea& pOutput)
52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pLinker->syncRelocationResult(pOutput);
52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit .eh_frame_hdr
53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // eh_frame_hdr should be emitted after syncRelocation, because eh_frame_hdr
53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // needs FDE PC value, which will be corrected at syncRelocation
5326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.postProcessing(pOutput);
53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
536