Linker.cpp revision f33f6de54db174aa679a4b6d1e040d37e95541c0
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
31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/ADT/OwningPtr.h>
32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <cassert>
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLinker::Linker()
386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : m_pConfig(NULL), m_pIRBuilder(NULL),
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pTarget(NULL), m_pBackend(NULL), m_pObjLinker(NULL) {
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLinker::~Linker()
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  reset();
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// emulate - To set up target-dependent options and default linker script.
48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// Follow GNU ld quirks.
49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::emulate(LinkerScript& pScript, LinkerConfig& pConfig)
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pConfig = &pConfig;
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!initTarget())
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!initBackend())
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!initOStream())
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
62f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!initEmulator(pScript))
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::link(Module& pModule, IRBuilder& pBuilder)
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!normalize(pModule, pBuilder))
71f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return false;
72f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (!resolve(pModule))
746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return layout();
776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
79f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// normalize - to convert the command line language to the input tree.
80f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::normalize(Module& pModule, IRBuilder& pBuilder)
816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pConfig);
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pIRBuilder = &pBuilder;
85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
86f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  m_pObjLinker = new ObjectLinker(*m_pConfig, *m_pBackend);
87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
88f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 2. - initialize ObjectLinker
89f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (!m_pObjLinker->initialize(pModule, pBuilder))
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 3. - initialize output's standard sections
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->initStdSections())
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!Diagnose())
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 4. - normalize the input tree
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   read out sections and symbol/string tables (from the files) and
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   set them in Module. When reading out the symbol, resolve their symbols
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   immediately and set their ResolveInfo (i.e., Symbol Resolution).
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->normalize();
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_pConfig->options().trace()) {
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    static int counter = 0;
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    mcld::outs() << "** name\ttype\tpath\tsize (" << pModule.getInputTree().size() << ")\n";
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    InputTree::const_dfs_iterator input, inEnd = pModule.getInputTree().dfs_end();
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (input=pModule.getInputTree().dfs_begin(); input!=inEnd; ++input) {
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mcld::outs() << counter++ << " *  " << (*input)->name();
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      switch((*input)->type()) {
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::Archive:
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tarchive\t(";
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::Object:
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tobject\t(";
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::DynObj:
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tshared\t(";
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::Script:
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\tscript\t(";
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case Input::External:
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mcld::outs() << "\textern\t(";
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        unreachable(diag::err_cannot_trace_file) << (*input)->type()
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                 << (*input)->name()
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                 << (*input)->path();
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mcld::outs() << (*input)->path() << ")\n";
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // 5. - set up code position
1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::DynObj == m_pConfig->codeGenType() ||
1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pConfig->options().isPIE()) {
1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::Independent);
1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (pModule.getLibraryList().empty()) {
1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // If the output is dependent on its loaded address, and it does not need
1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // to call outside functions, then we can treat the output static dependent
1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // and perform better optimizations.
1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::StaticDependent);
146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (LinkerConfig::Exec == m_pConfig->codeGenType()) {
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // Since the output is static dependent, there should not have any undefined
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // references in the output module.
150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      m_pConfig->options().setNoUndefined();
151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    }
1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
1546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::DynamicDependent);
1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->linkable())
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return Diagnose();
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return true;
161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
163f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::resolve(Module& pModule)
164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(NULL != m_pConfig);
166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(m_pObjLinker != NULL);
167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 6. - read all relocation entries from input files
1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   For all relocation sections of each input file (in the tree),
1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   read out reloc entry info from the object file and accordingly
1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   initiate their reloc entries in SectOrRelocData of LDSection.
172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //
173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //   To collect all edges in the reference graph.
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->readRelocations();
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
176f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
177f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 7. - data stripping optimizations
178f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  m_pObjLinker->dataStrippingOpt();
179f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
180f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 8. - merge all sections
1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Push sections into Module's SectionTable.
1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Merge sections that have the same name.
1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Maintain them as fragments in the section.
184f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //
185f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //   To merge nodes of the reference graph.
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->mergeSections())
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
189f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 9.a - add symbols to output
190f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  //  After all input symbols have been resolved, add them to output symbol
191f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  //  table at once
192f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  m_pObjLinker->addSymbolsToOutput(pModule);
193f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
194f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 9.b - allocateCommonSymbols
1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Allocate fragments for common symbols to the corresponding sections.
1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_pObjLinker->allocateCommonSymbols())
1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
198f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool Linker::layout()
2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != m_pConfig && NULL != m_pObjLinker);
2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
206f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 10. - add standard symbols, target-dependent symbols and script symbols
20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // m_pObjLinker->addUndefSymbols();
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->addStandardSymbols() ||
2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      !m_pObjLinker->addTargetSymbols() ||
2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      !m_pObjLinker->addScriptSymbols())
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
213f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 11. - scan all relocation entries by output symbols.
2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   reserve GOT space for layout.
2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   the space info is needed by pre-layout to compute the section size
21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->scanRelocations();
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
218f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 12.a - init relaxation stuff.
2196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pObjLinker->initStubs();
2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
221f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 12.b - pre-layout
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->prelayout();
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
224f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 12.c - linear layout
2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Decide which sections will be left in. Sort the sections according to
2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   a given order. Then, create program header accordingly.
2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Finally, set the offset for sections (@ref LDSection)
2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   according to the new order.
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->layout();
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
231f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 12.d - post-layout (create segment, instruction relaxing)
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->postlayout();
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
234f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 13. - finalize symbol value
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->finalizeSymbolValue();
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
237f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 14. - apply relocations
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->relocation();
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!Diagnose())
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
245f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::emit(FileOutputBuffer& pOutput)
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
247f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 15. - write out output
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->emitOutput(pOutput);
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
250f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // 16. - post processing
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->postProcessing(pOutput);
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!Diagnose())
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
259f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::emit(const Module& pModule, const std::string& pPath)
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FileHandle file;
262f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  FileHandle::Permission perm;
263f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  switch (m_pConfig->codeGenType()) {
264f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::Unknown:
265f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::Object:
266f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      perm = mcld::FileHandle::Permission(0x644);
267f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      break;
268f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::DynObj:
269f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::Exec:
270f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    case mcld::LinkerConfig::Binary:
271f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      perm = mcld::FileHandle::Permission(0x755);
272f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      break;
273f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    default: assert(0 && "Unknown file type");
274f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
275f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!file.open(pPath,
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            FileHandle::ReadWrite | FileHandle::Truncate | FileHandle::Create,
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            perm)) {
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    error(diag::err_cannot_open_output_file) << "Linker::emit()" << pPath;
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
283f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  llvm::OwningPtr<FileOutputBuffer> output;
284f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  FileOutputBuffer::create(file,
285f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                           m_pObjLinker->getWriter()->getOutputSize(pModule),
286f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                           output);
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
288f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  bool result = emit(*output.get());
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file.close();
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return result;
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
293f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Linker::emit(const Module& pModule, int pFileDescriptor)
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FileHandle file;
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file.delegate(pFileDescriptor);
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
298f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  llvm::OwningPtr<FileOutputBuffer> output;
299f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  FileOutputBuffer::create(file,
300f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                           m_pObjLinker->getWriter()->getOutputSize(pModule),
301f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                           output);
302f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
303f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  bool result = emit(*output.get());
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return result;
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::reset()
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pConfig = NULL;
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pIRBuilder = NULL;
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pTarget = NULL;
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
314d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Because llvm::iplist will touch the removed node, we must clear
315d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // RelocData before deleting target backend.
316d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  RelocData::Clear();
317d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  SectionData::Clear();
3186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  EhFrame::Clear();
319d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pBackend;
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pBackend = NULL;
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pObjLinker;
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker = NULL;
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection::Clear();
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol::Clear();
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FragmentRef::Clear();
329d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocation::Clear();
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initTarget()
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pConfig);
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  std::string error;
338f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  llvm::Triple triple(m_pConfig->targets().triple());
339f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
340f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  m_pTarget = mcld::TargetRegistry::lookupTarget(m_pConfig->targets().getArch(),
341f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                                 triple, error);
342f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  m_pConfig->targets().setTriple(triple);
343f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pTarget) {
345f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    fatal(diag::fatal_cannot_init_target) << triple.str() << error;
34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initBackend()
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pTarget);
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pBackend = m_pTarget->createLDBackend(*m_pConfig);
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pBackend) {
356d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::fatal_cannot_init_backend) << m_pConfig->targets().triple().str();
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool Linker::initOStream()
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pConfig);
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  mcld::outs().setColor(m_pConfig->options().color());
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  mcld::errs().setColor(m_pConfig->options().color());
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
372f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool Linker::initEmulator(LinkerScript& pScript)
373f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
374f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(NULL != m_pTarget && NULL != m_pConfig);
375f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return m_pTarget->emulate(pScript, *m_pConfig);
376f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
377f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
378