Linker.cpp revision a6c24dff8b7fa2551a3a885e77a2e814f5b764a2
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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Linker.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FragmentRef.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Relocation.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h"
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h"
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ObjectWriter.h"
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocData.h"
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h"
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/InputBuilder.h"
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectLinker.h"
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileHandle.h"
2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileOutputBuffer.h"
2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h"
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/TargetRegistry.h"
2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/raw_ostream.h"
2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/TargetLDBackend.h"
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <cassert>
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLinker::Linker()
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_pConfig(NULL),
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pIRBuilder(NULL),
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pTarget(NULL),
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pBackend(NULL),
3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pObjLinker(NULL) {
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4237b74a387bb3993387029859c2d9d051c41c724eStephen HinesLinker::~Linker() {
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  reset();
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// emulate - To set up target-dependent options and default linker script.
47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// Follow GNU ld quirks.
4837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::emulate(LinkerScript& pScript, LinkerConfig& pConfig) {
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
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::link(Module& pModule, IRBuilder& pBuilder) {
67f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!normalize(pModule, pBuilder))
68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return false;
69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
7087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!resolve(pModule))
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.
7737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::normalize(Module& pModule, IRBuilder& pBuilder) {
7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(m_pConfig != NULL);
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pIRBuilder = &pBuilder;
81f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
82f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  m_pObjLinker = new ObjectLinker(*m_pConfig, *m_pBackend);
83f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 2. - initialize ObjectLinker
8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!m_pObjLinker->initialize(pModule, pBuilder))
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 3. - initialize output's standard sections
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->initStdSections())
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!Diagnose())
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
950dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  // 4.a - add undefined symbols
960dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  //   before reading the inputs, we should add undefined symbols set by -u to
970dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  //   ensure that correspoding objects (e.g. in an archive) will be included
980dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  m_pObjLinker->addUndefinedSymbols();
990dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
1000dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  // 4.b - normalize the input tree
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   read out sections and symbol/string tables (from the files) and
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   set them in Module. When reading out the symbol, resolve their symbols
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   immediately and set their ResolveInfo (i.e., Symbol Resolution).
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->normalize();
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_pConfig->options().trace()) {
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    static int counter = 0;
10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    mcld::outs() << "** name\ttype\tpath\tsize ("
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                 << pModule.getInputTree().size() << ")\n";
11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    InputTree::const_dfs_iterator input,
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        inEnd = pModule.getInputTree().dfs_end();
11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    for (input = pModule.getInputTree().dfs_begin(); input != inEnd; ++input) {
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mcld::outs() << counter++ << " *  " << (*input)->name();
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      switch ((*input)->type()) {
11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        case Input::Archive:
11737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          mcld::outs() << "\tarchive\t(";
11837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          break;
11937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        case Input::Object:
12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          mcld::outs() << "\tobject\t(";
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          break;
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        case Input::DynObj:
12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          mcld::outs() << "\tshared\t(";
12437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          break;
12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        case Input::Script:
12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          mcld::outs() << "\tscript\t(";
12737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          break;
12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        case Input::External:
12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          mcld::outs() << "\textern\t(";
13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          break;
13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        default:
13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          unreachable(diag::err_cannot_trace_file)
13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines              << (*input)->type() << (*input)->name() << (*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);
14337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else if (pModule.getLibraryList().empty()) {
1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // If the output is dependent on its loaded address, and it does not need
1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // to call outside functions, then we can treat the output static dependent
1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // and perform better optimizations.
1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::StaticDependent);
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (LinkerConfig::Exec == m_pConfig->codeGenType()) {
15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      // Since the output is static dependent, there should not have any
15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      // undefined
152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // references in the output module.
153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      m_pConfig->options().setNoUndefined();
154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    }
15537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pConfig->setCodePosition(LinkerConfig::DynamicDependent);
1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->linkable())
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return Diagnose();
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return true;
163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
16537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::resolve(Module& pModule) {
16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(m_pConfig != NULL);
167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(m_pObjLinker != NULL);
168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // 6. - read all relocation entries from input files
1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   For all relocation sections of each input file (in the tree),
1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   read out reloc entry info from the object file and accordingly
1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   initiate their reloc entries in SectOrRelocData of LDSection.
173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //
174f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  //   To collect all edges in the reference graph.
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->readRelocations();
17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 7. - data stripping optimizations
17887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pObjLinker->dataStrippingOpt();
17987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
18087f34658dec9097d987d254a990ea7f311bfc95fStephen 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
18987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 9.a - add symbols to output
19087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  //  After all input symbols have been resolved, add them to output symbol
19187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  //  table at once
19287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pObjLinker->addSymbolsToOutput(pModule);
19387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
19487f34658dec9097d987d254a990ea7f311bfc95fStephen 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;
19887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
20237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::layout() {
20337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(m_pConfig != NULL && m_pObjLinker != NULL);
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 10. - add standard symbols, target-dependent symbols and script symbols
20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_pObjLinker->addStandardSymbols() ||
20737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      !m_pObjLinker->addTargetSymbols() || !m_pObjLinker->addScriptSymbols())
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
21087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 11. - scan all relocation entries by output symbols.
2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   reserve GOT space for layout.
2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   the space info is needed by pre-layout to compute the section size
21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->scanRelocations();
21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
21587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 12.a - init relaxation stuff.
2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pObjLinker->initStubs();
2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 12.b - pre-layout
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->prelayout();
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 12.c - linear layout
2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Decide which sections will be left in. Sort the sections according to
2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   a given order. Then, create program header accordingly.
2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   Finally, set the offset for sections (@ref LDSection)
2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  //   according to the new order.
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->layout();
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 12.d - post-layout (create segment, instruction relaxing)
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->postlayout();
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 13. - finalize symbol value
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->finalizeSymbolValue();
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 14. - apply relocations
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->relocation();
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!Diagnose())
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::emit(FileOutputBuffer& pOutput) {
24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 15. - write out output
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->emitOutput(pOutput);
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 16. - post processing
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker->postProcessing(pOutput);
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!Diagnose())
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::emit(const Module& pModule, const std::string& pPath) {
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FileHandle file;
25737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  FileHandle::OpenMode open_mode(
25837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FileHandle::ReadWrite | FileHandle::Truncate | FileHandle::Create);
25937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  FileHandle::Permission permission;
26087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  switch (m_pConfig->codeGenType()) {
26187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case mcld::LinkerConfig::Unknown:
26287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case mcld::LinkerConfig::Object:
26337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      permission = FileHandle::Permission(0x644);
26487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
26587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case mcld::LinkerConfig::DynObj:
26687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case mcld::LinkerConfig::Exec:
26787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case mcld::LinkerConfig::Binary:
26837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      permission = FileHandle::Permission(0x755);
26987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
27037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    default:
27137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      assert(0 && "Unknown file type");
27287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
27387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
27437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool result = file.open(sys::fs::Path(pPath), open_mode, permission);
27537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (!result) {
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    error(diag::err_cannot_open_output_file) << "Linker::emit()" << pPath;
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2800dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  std::unique_ptr<FileOutputBuffer> output;
28137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  FileOutputBuffer::create(
28237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      file, m_pObjLinker->getWriter()->getOutputSize(pModule), output);
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
284a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  result = emit(*output);
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file.close();
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return result;
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::emit(const Module& pModule, int pFileDescriptor) {
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FileHandle file;
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file.delegate(pFileDescriptor);
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2930dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  std::unique_ptr<FileOutputBuffer> output;
29437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  FileOutputBuffer::create(
29537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      file, m_pObjLinker->getWriter()->getOutputSize(pModule), output);
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
297a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  return emit(*output);
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::reset() {
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pConfig = NULL;
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pIRBuilder = NULL;
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pTarget = NULL;
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
305d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Because llvm::iplist will touch the removed node, we must clear
306d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // RelocData before deleting target backend.
307d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  RelocData::Clear();
308d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  SectionData::Clear();
3096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  EhFrame::Clear();
310d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pBackend;
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pBackend = NULL;
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pObjLinker;
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pObjLinker = NULL;
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection::Clear();
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol::Clear();
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FragmentRef::Clear();
320d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocation::Clear();
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::initTarget() {
32537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(m_pConfig != NULL);
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  std::string error;
32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::Triple triple(m_pConfig->targets().triple());
32987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
33037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_pTarget = mcld::TargetRegistry::lookupTarget(
33137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pConfig->targets().getArch(), triple, error);
33287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pConfig->targets().setTriple(triple);
33387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
33437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_pTarget == NULL) {
33587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    fatal(diag::fatal_cannot_init_target) << triple.str() << error;
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
34137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::initBackend() {
34237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(m_pTarget != NULL);
34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pBackend = m_pTarget->createLDBackend(*m_pConfig);
34437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_pBackend == NULL) {
34537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    fatal(diag::fatal_cannot_init_backend)
34637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        << m_pConfig->targets().triple().str();
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::initOStream() {
35337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(m_pConfig != NULL);
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  mcld::outs().setColor(m_pConfig->options().color());
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  mcld::errs().setColor(m_pConfig->options().color());
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Linker::initEmulator(LinkerScript& pScript) {
36237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(m_pTarget != NULL && m_pConfig != NULL);
363f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return m_pTarget->emulate(pScript, *m_pConfig);
364f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
365f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
36637b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
367