Linker.cpp revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- Linker.cpp ---------------------------------------------------------===//
222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//                     The MCLinker Project
422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file is distributed under the University of Illinois Open Source
622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// License. See LICENSE.TXT for details.
722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Linker.h>
1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MsgHandling.h>
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/TargetRegistry.h>
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/FileHandle.h>
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h>
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/raw_ostream.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectLinker.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/InputBuilder.h>
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h>
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSymbol.h>
25d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/SectionData.h>
26d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/RelocData.h>
27d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Fragment/Relocation.h>
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentRef.h>
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <cassert>
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLinker::Linker()
356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : m_pConfig(NULL), m_pIRBuilder(NULL),
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pTarget(NULL), m_pBackend(NULL), m_pObjLinker(NULL) {
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLinker::~Linker()
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  reset();
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
44f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// emulate - To set up target-dependent options and default linker script.
45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// Follow GNU ld quirks.
46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::emulate(LinkerScript& pScript, LinkerConfig& pConfig)
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pConfig = &pConfig;
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!initTarget())
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!initBackend())
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
56f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!initOStream())
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!initEmulator(pScript))
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::link(Module& pModule, IRBuilder& pBuilder)
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
67f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!normalize(pModule, pBuilder))
68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return false;
69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!resolve())
716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return layout();
746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
76f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// normalize - to convert the command line language to the input tree.
77f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::normalize(Module& pModule, IRBuilder& pBuilder)
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pConfig);
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pIRBuilder = &pBuilder;
82f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
83f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  m_pObjLinker = new ObjectLinker(*m_pConfig, *m_pBackend);
84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pObjLinker->setup(pModule, pBuilder);
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 2. - initialize FragmentLinker
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->initFragmentLinker())
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 3. - initialize output's standard sections
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->initStdSections())
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!Diagnose())
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 4. - normalize the input tree
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   read out sections and symbol/string tables (from the files) and
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   set them in Module. When reading out the symbol, resolve their symbols
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   immediately and set their ResolveInfo (i.e., Symbol Resolution).
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->normalize();
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_pConfig->options().trace()) {
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    static int counter = 0;
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    mcld::outs() << "** name\ttype\tpath\tsize (" << pModule.getInputTree().size() << ")\n";
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    InputTree::const_dfs_iterator input, inEnd = pModule.getInputTree().dfs_end();
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (input=pModule.getInputTree().dfs_begin(); input!=inEnd; ++input) {
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mcld::outs() << counter++ << " *  " << (*input)->name();
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      switch((*input)->type()) {
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::Archive:
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tarchive\t(";
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::Object:
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tobject\t(";
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::DynObj:
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tshared\t(";
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::Script:
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tscript\t(";
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::External:
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\textern\t(";
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        unreachable(diag::err_cannot_trace_file) << (*input)->type()
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                 << (*input)->name()
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                 << (*input)->path();
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mcld::outs() << (*input)->path() << ")\n";
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 5. - set up code position
1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::DynObj == m_pConfig->codeGenType() ||
1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pConfig->options().isPIE()) {
1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::Independent);
1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (pModule.getLibraryList().empty()) {
1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // If the output is dependent on its loaded address, and it does not need
1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // to call outside functions, then we can treat the output static dependent
1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // and perform better optimizations.
1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::StaticDependent);
145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (LinkerConfig::Exec == m_pConfig->codeGenType()) {
147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // Since the output is static dependent, there should not have any undefined
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // references in the output module.
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      m_pConfig->options().setNoUndefined();
150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    }
1516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::DynamicDependent);
1546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->linkable())
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return Diagnose();
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return true;
160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::resolve()
163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(NULL != m_pConfig);
165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(m_pObjLinker != NULL);
166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 6. - read all relocation entries from input files
1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   For all relocation sections of each input file (in the tree),
1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   read out reloc entry info from the object file and accordingly
1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   initiate their reloc entries in SectOrRelocData of LDSection.
171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //
172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //   To collect all edges in the reference graph.
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->readRelocations();
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 7. - merge all sections
1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Push sections into Module's SectionTable.
1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Merge sections that have the same name.
1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Maintain them as fragments in the section.
179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //
180f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //   To merge nodes of the reference graph.
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->mergeSections())
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 8. - allocateCommonSymbols
1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Allocate fragments for common symbols to the corresponding sections.
1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_pObjLinker->allocateCommonSymbols())
1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
1886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
1906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool Linker::layout()
1926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pConfig && NULL != m_pObjLinker);
1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 9. - add standard symbols, target-dependent symbols and script symbols
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // m_pObjLinker->addUndefSymbols();
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->addStandardSymbols() ||
1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      !m_pObjLinker->addTargetSymbols() ||
1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      !m_pObjLinker->addScriptSymbols())
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 10. - scan all relocation entries by output symbols.
2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   reserve GOT space for layout.
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   the space info is needed by pre-layout to compute the section size
20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->scanRelocations();
20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 11.a - init relaxation stuff.
2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pObjLinker->initStubs();
2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 11.b - pre-layout
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->prelayout();
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 11.c - linear layout
2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Decide which sections will be left in. Sort the sections according to
2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   a given order. Then, create program header accordingly.
2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Finally, set the offset for sections (@ref LDSection)
2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   according to the new order.
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->layout();
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 11.d - post-layout (create segment, instruction relaxing)
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->postlayout();
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 12. - finalize symbol value
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->finalizeSymbolValue();
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 13. - apply relocations
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->relocation();
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!Diagnose())
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::emit(MemoryArea& pOutput)
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 13. - write out output
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->emitOutput(pOutput);
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 14. - post processing
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->postProcessing(pOutput);
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!Diagnose())
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::emit(const std::string& pPath)
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FileHandle file;
251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  FileHandle::Permission perm = FileHandle::Permission(0x755);
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!file.open(pPath,
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            FileHandle::ReadWrite | FileHandle::Truncate | FileHandle::Create,
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            perm)) {
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    error(diag::err_cannot_open_output_file) << "Linker::emit()" << pPath;
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryArea* output = new MemoryArea(file);
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool result = emit(*output);
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete output;
26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file.close();
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return result;
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::emit(int pFileDescriptor)
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FileHandle file;
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file.delegate(pFileDescriptor);
27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryArea* output = new MemoryArea(file);
27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool result = emit(*output);
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete output;
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file.close();
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return result;
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::reset()
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pConfig = NULL;
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pIRBuilder = NULL;
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pTarget = NULL;
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
287d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Because llvm::iplist will touch the removed node, we must clear
288d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // RelocData before deleting target backend.
289d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  RelocData::Clear();
290d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  SectionData::Clear();
2916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  EhFrame::Clear();
292d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pBackend;
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pBackend = NULL;
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pObjLinker;
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker = NULL;
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection::Clear();
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol::Clear();
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FragmentRef::Clear();
302d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocation::Clear();
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initTarget()
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pConfig);
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  std::string error;
311d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_pTarget = mcld::TargetRegistry::lookupTarget(m_pConfig->targets().triple().str(), error);
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pTarget) {
313d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::fatal_cannot_init_target) << m_pConfig->targets().triple().str() << error;
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initBackend()
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pTarget);
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pBackend = m_pTarget->createLDBackend(*m_pConfig);
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pBackend) {
324d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::fatal_cannot_init_backend) << m_pConfig->targets().triple().str();
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initOStream()
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pConfig);
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  mcld::outs().setColor(m_pConfig->options().color());
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  mcld::errs().setColor(m_pConfig->options().color());
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::initEmulator(LinkerScript& pScript)
341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
342f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(NULL != m_pTarget && NULL != m_pConfig);
343f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return m_pTarget->emulate(pScript, *m_pConfig);
344f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
345f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
346