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>
17f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Support/FileOutputBuffer.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>
27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/LD/ObjectWriter.h>
28d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Fragment/Relocation.h>
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentRef.h>
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <cassert>
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLinker::Linker()
366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : m_pConfig(NULL), m_pIRBuilder(NULL),
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pTarget(NULL), m_pBackend(NULL), m_pObjLinker(NULL) {
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLinker::~Linker()
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  reset();
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// emulate - To set up target-dependent options and default linker script.
46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// Follow GNU ld quirks.
47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::emulate(LinkerScript& pScript, LinkerConfig& pConfig)
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pConfig = &pConfig;
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!initTarget())
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!initBackend())
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
57f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!initOStream())
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!initEmulator(pScript))
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::link(Module& pModule, IRBuilder& pBuilder)
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!normalize(pModule, pBuilder))
69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return false;
70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (!resolve(pModule))
726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return layout();
756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
77f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// normalize - to convert the command line language to the input tree.
78f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::normalize(Module& pModule, IRBuilder& pBuilder)
796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pConfig);
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pIRBuilder = &pBuilder;
83f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  m_pObjLinker = new ObjectLinker(*m_pConfig, *m_pBackend);
85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 2. - initialize ObjectLinker
87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (!m_pObjLinker->initialize(pModule, pBuilder))
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 3. - initialize output's standard sections
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->initStdSections())
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!Diagnose())
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
97a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  // 4.a - add undefined symbols
98a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  //   before reading the inputs, we should add undefined symbols set by -u to
99a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  //   ensure that correspoding objects (e.g. in an archive) will be included
100a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  m_pObjLinker->addUndefinedSymbols();
101a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
102a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  // 4.b - normalize the input tree
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   read out sections and symbol/string tables (from the files) and
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   set them in Module. When reading out the symbol, resolve their symbols
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   immediately and set their ResolveInfo (i.e., Symbol Resolution).
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->normalize();
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_pConfig->options().trace()) {
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    static int counter = 0;
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    mcld::outs() << "** name\ttype\tpath\tsize (" << pModule.getInputTree().size() << ")\n";
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    InputTree::const_dfs_iterator input, inEnd = pModule.getInputTree().dfs_end();
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (input=pModule.getInputTree().dfs_begin(); input!=inEnd; ++input) {
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mcld::outs() << counter++ << " *  " << (*input)->name();
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      switch((*input)->type()) {
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::Archive:
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tarchive\t(";
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::Object:
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tobject\t(";
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::DynObj:
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tshared\t(";
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::Script:
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tscript\t(";
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::External:
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\textern\t(";
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        unreachable(diag::err_cannot_trace_file) << (*input)->type()
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                 << (*input)->name()
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                 << (*input)->path();
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mcld::outs() << (*input)->path() << ")\n";
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 5. - set up code position
1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::DynObj == m_pConfig->codeGenType() ||
1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pConfig->options().isPIE()) {
1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::Independent);
1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (pModule.getLibraryList().empty()) {
1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // If the output is dependent on its loaded address, and it does not need
1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // to call outside functions, then we can treat the output static dependent
1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // and perform better optimizations.
1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::StaticDependent);
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (LinkerConfig::Exec == m_pConfig->codeGenType()) {
151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // Since the output is static dependent, there should not have any undefined
152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // references in the output module.
153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      m_pConfig->options().setNoUndefined();
154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    }
1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::DynamicDependent);
1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->linkable())
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return Diagnose();
16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return true;
164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
166f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::resolve(Module& pModule)
167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(NULL != m_pConfig);
169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(m_pObjLinker != NULL);
170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 6. - read all relocation entries from input files
1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   For all relocation sections of each input file (in the tree),
1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   read out reloc entry info from the object file and accordingly
1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   initiate their reloc entries in SectOrRelocData of LDSection.
175f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //
176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //   To collect all edges in the reference graph.
17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->readRelocations();
17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
179f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
180f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 7. - data stripping optimizations
181f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  m_pObjLinker->dataStrippingOpt();
182f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
183f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 8. - merge all sections
1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Push sections into Module's SectionTable.
1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Merge sections that have the same name.
1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Maintain them as fragments in the section.
187f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //
188f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //   To merge nodes of the reference graph.
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->mergeSections())
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
192f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 9.a - add symbols to output
193f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  //  After all input symbols have been resolved, add them to output symbol
194f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  //  table at once
195f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  m_pObjLinker->addSymbolsToOutput(pModule);
196f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
197f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 9.b - allocateCommonSymbols
1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Allocate fragments for common symbols to the corresponding sections.
1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_pObjLinker->allocateCommonSymbols())
2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
201f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool Linker::layout()
2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pConfig && NULL != m_pObjLinker);
2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
209f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 10. - add standard symbols, target-dependent symbols and script symbols
21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->addStandardSymbols() ||
2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      !m_pObjLinker->addTargetSymbols() ||
2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      !m_pObjLinker->addScriptSymbols())
21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
215f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 11. - scan all relocation entries by output symbols.
2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   reserve GOT space for layout.
2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   the space info is needed by pre-layout to compute the section size
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->scanRelocations();
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
220f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 12.a - init relaxation stuff.
2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pObjLinker->initStubs();
2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
223f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 12.b - pre-layout
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->prelayout();
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
226f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 12.c - linear layout
2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Decide which sections will be left in. Sort the sections according to
2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   a given order. Then, create program header accordingly.
2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Finally, set the offset for sections (@ref LDSection)
2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   according to the new order.
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->layout();
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
233f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 12.d - post-layout (create segment, instruction relaxing)
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->postlayout();
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
236f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 13. - finalize symbol value
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->finalizeSymbolValue();
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
239f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 14. - apply relocations
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->relocation();
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!Diagnose())
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
247f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::emit(FileOutputBuffer& pOutput)
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
249f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 15. - write out output
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->emitOutput(pOutput);
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
252f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 16. - post processing
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->postProcessing(pOutput);
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!Diagnose())
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
261f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::emit(const Module& pModule, const std::string& pPath)
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FileHandle file;
264f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  FileHandle::Permission perm;
265f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  switch (m_pConfig->codeGenType()) {
266f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::Unknown:
267f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::Object:
268f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      perm = mcld::FileHandle::Permission(0x644);
269f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      break;
270f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::DynObj:
271f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::Exec:
272f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::Binary:
273f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      perm = mcld::FileHandle::Permission(0x755);
274f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      break;
275f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    default: assert(0 && "Unknown file type");
276f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
277f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!file.open(pPath,
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            FileHandle::ReadWrite | FileHandle::Truncate | FileHandle::Create,
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            perm)) {
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    error(diag::err_cannot_open_output_file) << "Linker::emit()" << pPath;
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
285a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  std::unique_ptr<FileOutputBuffer> output;
286f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  FileOutputBuffer::create(file,
287f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                           m_pObjLinker->getWriter()->getOutputSize(pModule),
288f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                           output);
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
290f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  bool result = emit(*output.get());
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file.close();
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return result;
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
295f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::emit(const Module& pModule, int pFileDescriptor)
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FileHandle file;
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file.delegate(pFileDescriptor);
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
300a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  std::unique_ptr<FileOutputBuffer> output;
301f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  FileOutputBuffer::create(file,
302f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                           m_pObjLinker->getWriter()->getOutputSize(pModule),
303f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                           output);
304f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
305f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  bool result = emit(*output.get());
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return result;
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::reset()
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pConfig = NULL;
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pIRBuilder = NULL;
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pTarget = NULL;
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
316d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Because llvm::iplist will touch the removed node, we must clear
317d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // RelocData before deleting target backend.
318d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  RelocData::Clear();
319d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  SectionData::Clear();
3206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  EhFrame::Clear();
321d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pBackend;
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pBackend = NULL;
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pObjLinker;
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker = NULL;
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection::Clear();
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol::Clear();
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FragmentRef::Clear();
331d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocation::Clear();
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initTarget()
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pConfig);
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  std::string error;
340f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  llvm::Triple triple(m_pConfig->targets().triple());
341f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
342f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  m_pTarget = mcld::TargetRegistry::lookupTarget(m_pConfig->targets().getArch(),
343f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                                 triple, error);
344f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  m_pConfig->targets().setTriple(triple);
345f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pTarget) {
347f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    fatal(diag::fatal_cannot_init_target) << triple.str() << error;
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initBackend()
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pTarget);
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pBackend = m_pTarget->createLDBackend(*m_pConfig);
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pBackend) {
358d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::fatal_cannot_init_backend) << m_pConfig->targets().triple().str();
35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initOStream()
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pConfig);
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  mcld::outs().setColor(m_pConfig->options().color());
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  mcld::errs().setColor(m_pConfig->options().color());
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
374f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::initEmulator(LinkerScript& pScript)
375f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
376f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(NULL != m_pTarget && NULL != m_pConfig);
377f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return m_pTarget->emulate(pScript, *m_pConfig);
378f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
379f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
380