ObjectLinker.cpp revision 0dea6bc96bb52346737966839ac68644f7939f58
122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- ObjectLinker.cpp ---------------------------------------------------===//
222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//                     The MCLinker Project
422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file is distributed under the University of Illinois Open Source
622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// License. See LICENSE.TXT for details.
722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectLinker.h>
1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
1287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LinkerScript.h>
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h>
15d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/IRBuilder.h>
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h>
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h>
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/Archive.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ArchiveReader.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ObjectReader.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/DynObjReader.h>
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/GroupReader.h>
23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/BinaryReader.h>
2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/GarbageCollection.h>
250dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <mcld/LD/IdenticalCodeFolding.h>
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ObjectWriter.h>
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ResolveInfo.h>
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h>
29f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/Relocator.h>
3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/SectionData.h>
3187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/BranchIslandFactory.h>
3287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/ScriptFile.h>
3387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/ScriptReader.h>
3487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/Assignment.h>
3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/Operand.h>
3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/RpnEvaluator.h>
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/RealPath.h>
3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Support/FileOutputBuffer.h>
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MsgHandling.h>
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Fragment/Relocation.h>
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/Casting.h>
4587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Host.h>
460dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <system_error>
476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace llvm;
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===//
5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// ObjectLinker
5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===//
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoObjectLinker::ObjectLinker(const LinkerConfig& pConfig,
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           TargetLDBackend& pLDBackend)
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : m_Config(pConfig),
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pModule(NULL),
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pBuilder(NULL),
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_LDBackend(pLDBackend),
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pObjectReader(NULL),
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pDynObjReader(NULL),
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pArchiveReader(NULL),
63d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pGroupReader(NULL),
64d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pBinaryReader(NULL),
6587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    m_pScriptReader(NULL),
666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pWriter(NULL) {
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoObjectLinker::~ObjectLinker()
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pObjectReader;
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynObjReader;
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pArchiveReader;
74d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pGroupReader;
75d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pBinaryReader;
7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  delete m_pScriptReader;
776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pWriter;
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool ObjectLinker::initialize(Module& pModule, IRBuilder& pBuilder)
816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pModule = &pModule;
836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pBuilder = &pBuilder;
84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // initialize the readers and writers
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pObjectReader  = m_LDBackend.createObjectReader(*m_pBuilder);
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pArchiveReader = m_LDBackend.createArchiveReader(*m_pModule);
886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pDynObjReader  = m_LDBackend.createDynObjReader(*m_pBuilder);
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pBinaryReader  = m_LDBackend.createBinaryReader(*m_pBuilder);
90f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  m_pGroupReader   = new GroupReader(*m_pModule, *m_pObjectReader,
91f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                         *m_pDynObjReader, *m_pArchiveReader, *m_pBinaryReader);
9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pScriptReader  = new ScriptReader(*m_pGroupReader);
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_pWriter        = m_LDBackend.createWriter();
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
95d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // initialize Relocator
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initRelocator();
9787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStdSections - initialize standard sections
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::initStdSections()
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
104533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  ObjectBuilder builder(*m_pModule);
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // initialize standard sections
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!m_LDBackend.initStdSections(builder))
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // initialize target-dependent sections
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initTargetSections(*m_pModule, builder);
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1160dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesvoid ObjectLinker::addUndefinedSymbols()
1170dea6bc96bb52346737966839ac68644f7939f58Stephen Hines{
1180dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  // Add the symbol set by -u as an undefind global symbol into symbol pool
1190dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  GeneralOptions::const_undef_sym_iterator usym;
1200dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  GeneralOptions::const_undef_sym_iterator usymEnd =
1210dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                             m_Config.options().undef_sym_end();
1220dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  for (usym = m_Config.options().undef_sym_begin(); usym != usymEnd; ++usym) {
1230dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    Resolver::Result result;
1240dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    m_pModule->getNamePool().insertSymbol(*usym, // name
1250dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                          false, // isDyn
1260dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                          ResolveInfo::NoType,
1270dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                          ResolveInfo::Undefined,
1280dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                          ResolveInfo::Global,
1290dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                          0x0, // size
1300dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                          0x0, // value
1310dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                          ResolveInfo::Default,
1320dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                          NULL,
1330dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                                          result);
1340dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
1350dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    LDSymbol* output_sym = result.info->outSymbol();
1360dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    bool has_output_sym = (NULL != output_sym);
1370dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
1380dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    // create the output symbol if it dose not have one
1390dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    if (!result.existent || !has_output_sym) {
1400dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      output_sym = LDSymbol::Create(*result.info);
1410dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      result.info->setSymPtr(output_sym);
1420dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      output_sym->setFragmentRef(FragmentRef::Null());
1430dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    }
1440dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  }
1450dea6bc96bb52346737966839ac68644f7939f58Stephen Hines}
1460dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid ObjectLinker::normalize()
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // -----  set up inputs  ----- //
1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::input_iterator input, inEnd = m_pModule->input_end();
1516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (input = m_pModule->input_begin(); input!=inEnd; ++input) {
15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // is a group node
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isGroup(input)) {
15487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      getGroupReader()->readGroup(input, inEnd, m_pBuilder->getInputBuilder(),
15587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  m_Config);
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // already got type - for example, bitcode or external OIR (object
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // intermediate representation)
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*input)->type() == Input::Script ||
16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*input)->type() == Input::Archive ||
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*input)->type() == Input::External)
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (Input::Object == (*input)->type()) {
1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getObjectList().push_back(*input);
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (Input::DynObj == (*input)->type()) {
1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getLibraryList().push_back(*input);
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    bool doContinue = false;
177d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // read input as a binary file
17887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (getBinaryReader()->isMyFormat(**input, doContinue)) {
179d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (*input)->setType(Input::Object);
180d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      getBinaryReader()->readBinary(**input);
1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getObjectList().push_back(*input);
182d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // is a relocatable object file
18487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    else if (doContinue && getObjectReader()->isMyFormat(**input, doContinue)) {
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*input)->setType(Input::Object);
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getObjectReader()->readHeader(**input);
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getObjectReader()->readSections(**input);
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getObjectReader()->readSymbols(**input);
1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getObjectList().push_back(*input);
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // is a shared object file
19287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    else if (doContinue && getDynObjReader()->isMyFormat(**input, doContinue)) {
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*input)->setType(Input::DynObj);
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getDynObjReader()->readHeader(**input);
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      getDynObjReader()->readSymbols(**input);
1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_pModule->getLibraryList().push_back(*input);
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // is an archive
19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    else if (doContinue && getArchiveReader()->isMyFormat(**input, doContinue)) {
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*input)->setType(Input::Archive);
2010dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      if (m_Config.options().isInExcludeLIBS(**input)) {
2020dea6bc96bb52346737966839ac68644f7939f58Stephen Hines        (*input)->setNoExport();
2030dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      }
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      Archive archive(**input, m_pBuilder->getInputBuilder());
20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      getArchiveReader()->readArchive(m_Config, archive);
20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if(archive.numOfObjectMember() > 0) {
2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        m_pModule->getInputTree().merge<InputTree::Inclusive>(input,
20887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                              archive.inputs());
20987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
21087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // try to parse input as a linker script
21287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    else if (doContinue && getScriptReader()->isMyFormat(**input, doContinue)) {
21387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      ScriptFile script(ScriptFile::LDScript, **input,
21487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                        m_pBuilder->getInputBuilder());
21587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (getScriptReader()->readScript(m_Config, script)) {
21687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*input)->setType(Input::Script);
21787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        script.activate(*m_pModule);
21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (script.inputs().size() > 0) {
21987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          m_pModule->getInputTree().merge<InputTree::Inclusive>(input,
22087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            script.inputs());
22187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else {
22587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (m_Config.options().warnMismatch())
22687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        warning(diag::warn_unrecognized_input_file) << (*input)->path()
22787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          << m_Config.targets().triple().str();
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of for
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::linkable() const
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // check we have input and output files
2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_pModule->getInputTree().empty()) {
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    error(diag::err_no_inputs);
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // can not mix -static with shared objects
2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_lib_iterator lib, libEnd = m_pModule->lib_end();
2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (lib = m_pModule->lib_begin(); lib != libEnd; ++lib) {
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if((*lib)->attribute()->isStatic()) {
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      error(diag::err_mixed_shared_static_objects)
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      << (*lib)->name() << (*lib)->path();
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return false;
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // --nmagic and --omagic options lead to static executable program.
2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // These options turn off page alignment of sections. Because the
2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // sections are not aligned to pages, these sections can not contain any
2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // exported functions. Also, because the two options disable linking
2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // against shared libraries, the output absolutely does not call outside
2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // functions.
2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Config.options().nmagic() && !m_Config.isCodeStatic()) {
2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    error(diag::err_nmagic_not_static);
2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Config.options().omagic() && !m_Config.isCodeStatic()) {
2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    error(diag::err_omagic_not_static);
2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid ObjectLinker::dataStrippingOpt()
26987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
27087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // Garbege collection
27187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (m_Config.options().GCSections()) {
27287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    GarbageCollection GC(m_Config, m_LDBackend, *m_pModule);
27387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    GC.run();
27487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
2750dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
2760dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  // Identical code folding
2770dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  if (m_Config.options().getICFMode() != GeneralOptions::ICF_None) {
2780dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    IdenticalCodeFolding icf(m_Config, m_LDBackend, *m_pModule);
2790dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    icf.foldIdenticalCode();
2800dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  }
28187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return;
28287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
28387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRelocations - read all relocation entries
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// All symbols should be read and resolved before this function.
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::readRelocations()
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Bitcode is read by the other path. This function reads relocation sections
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // in object files.
2916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  mcld::InputTree::bfs_iterator input, inEnd = m_pModule->getInputTree().bfs_end();
2926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (input=m_pModule->getInputTree().bfs_begin(); input!=inEnd; ++input) {
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*input)->type() == Input::Object && (*input)->hasMemArea()) {
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!getObjectReader()->readRelocations(**input))
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return false;
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // ignore the other kinds of files.
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// mergeSections - put allinput sections into output sections
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::mergeSections()
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
305533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  ObjectBuilder builder(*m_pModule);
3066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::obj_iterator obj, objEnd = m_pModule->obj_end();
3076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (obj = m_pModule->obj_begin(); obj != objEnd; ++obj) {
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      switch ((*sect)->kind()) {
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // Some *INPUT sections should not be merged.
3120dea6bc96bb52346737966839ac68644f7939f58Stephen Hines        case LDFileFormat::Folded:
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::Ignore:
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::Null:
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::NamePool:
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::Group:
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::StackNote:
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          // skip
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
32087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        case LDFileFormat::Relocation: {
32187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (!(*sect)->hasRelocData())
32287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            continue; // skip
32387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
3240dea6bc96bb52346737966839ac68644f7939f58Stephen Hines          if ((*sect)->getLink()->kind() == LDFileFormat::Ignore ||
3250dea6bc96bb52346737966839ac68644f7939f58Stephen Hines              (*sect)->getLink()->kind() == LDFileFormat::Folded)
32687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            (*sect)->setKind(LDFileFormat::Ignore);
32787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          break;
32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::Target:
33087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (!m_LDBackend.mergeSection(*m_pModule, **obj, **sect)) {
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            error(diag::err_cannot_merge_section) << (*sect)->name()
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  << (*obj)->name();
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            return false;
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        case LDFileFormat::EhFrame: {
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!(*sect)->hasEhFrame())
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            continue; // skip
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          LDSection* out_sect = NULL;
34187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (NULL != (out_sect = builder.MergeSection(**obj, **sect))) {
34287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) {
34387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines              error(diag::err_cannot_merge_section) << (*sect)->name()
34487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    << (*obj)->name();
34587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines              return false;
34687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            }
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        default: {
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!(*sect)->hasSectionData())
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            continue; // skip
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
354f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          LDSection* out_sect = NULL;
35587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (NULL != (out_sect = builder.MergeSection(**obj, **sect))) {
35687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) {
35787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines              error(diag::err_cannot_merge_section) << (*sect)->name()
35887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    << (*obj)->name();
35987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines              return false;
36087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            }
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      } // end of switch
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // for each section
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // for each obj
36787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
36887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  RpnEvaluator evaluator(*m_pModule, m_LDBackend);
36987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap::iterator out, outBegin, outEnd;
37087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outBegin = m_pModule->getScript().sectionMap().begin();
37187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outEnd = m_pModule->getScript().sectionMap().end();
37287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out) {
37387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    uint64_t out_align = 0x0, in_align = 0x0;
37487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    LDSection* out_sect = (*out)->getSection();
37587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SectionMap::Output::iterator in, inBegin, inEnd;
37687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    inBegin = (*out)->begin();
37787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    inEnd = (*out)->end();
37887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
37987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // force input alignment from ldscript if any
38087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->prolog().hasSubAlign()) {
38187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      evaluator.eval((*out)->prolog().subAlign(), in_align);
38287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
38387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
38487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (in = inBegin; in != inEnd; ++in) {
38587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      LDSection* in_sect = (*in)->getSection();
38687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*out)->prolog().hasSubAlign())
38787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        in_sect->setAlign(in_align);
38887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
38987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (builder.MoveSectionData(*in_sect->getSectionData(),
39087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  *out_sect->getSectionData())) {
39187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        builder.UpdateSectionAlign(*out_sect, *in_sect);
39287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        m_LDBackend.updateSectionFlags(*out_sect, *in_sect);
39387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
39487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } // for each input section description
39587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
39687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // force output alignment from ldscript if any
39787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->prolog().hasAlign()) {
39887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      evaluator.eval((*out)->prolog().align(), out_align);
39987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      out_sect->setAlign(out_align);
40087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
40187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
40287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->hasContent()) {
40387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      LDSection* target = m_pModule->getSection((*out)->name());
40487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      assert(target != NULL && target->hasSectionData());
40587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (builder.MoveSectionData(*out_sect->getSectionData(),
40687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  *target->getSectionData())) {
40787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        builder.UpdateSectionAlign(*target, *out_sect);
40887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        m_LDBackend.updateSectionFlags(*target, *out_sect);
40987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
41087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
41187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for each output section description
41287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
41687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid ObjectLinker::addSymbolToOutput(ResolveInfo& pInfo, Module& pModule)
41787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
41887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // section symbols will be defined by linker later, we should not add section
41987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // symbols to output here
42087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (ResolveInfo::Section == pInfo.type() || NULL == pInfo.outSymbol())
42187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return;
42287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
42387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // if the symbols defined in the Ignore sections (e.g. discared by GC), then
42487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // not to put them to output
42587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pInfo.outSymbol()->hasFragRef() && LDFileFormat::Ignore ==
42687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        pInfo.outSymbol()->fragRef()->frag()->getParent()->getSection().kind())
42787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return;
42887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
42987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pInfo.shouldForceLocal(m_Config))
43087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pModule.getSymbolTable().forceLocal(*pInfo.outSymbol());
43187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else
43287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pModule.getSymbolTable().add(*pInfo.outSymbol());
43387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
43487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
43587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid ObjectLinker::addSymbolsToOutput(Module& pModule)
43687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
43787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // Traverse all the free ResolveInfo and add the output symobols to output
43887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  NamePool::freeinfo_iterator free_it,
43987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              free_end = pModule.getNamePool().freeinfo_end();
44087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (free_it = pModule.getNamePool().freeinfo_begin(); free_it != free_end;
44187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                                      ++free_it)
44287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    addSymbolToOutput(**free_it, pModule);
44387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
44487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
44587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // Traverse all the resolveInfo and add the output symbol to output
44687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  NamePool::syminfo_iterator info_it,
44787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                             info_end = pModule.getNamePool().syminfo_end();
44887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (info_it = pModule.getNamePool().syminfo_begin(); info_it != info_end;
44987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                                      ++info_it)
45087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    addSymbolToOutput(*info_it.getEntry(), pModule);
45187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
45422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// addStandardSymbols - shared object and executable files need some
45522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// standard symbols
45622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   @return if there are some input symbols with the same name to the
45722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   standard symbols, return false
45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::addStandardSymbols()
45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // create and add section symbols for each output section
4616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::iterator iter, iterEnd = m_pModule->end();
4626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (iter = m_pModule->begin(); iter != iterEnd; ++iter) {
4636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pModule->getSectionSymbolSet().add(**iter, m_pModule->getNamePool());
46422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return m_LDBackend.initStandardSymbols(*m_pBuilder, *m_pModule);
46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
46922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// addTargetSymbols - some targets, such as MIPS and ARM, need some
47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent symbols
47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   @return if there are some input symbols with the same name to the
47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   target symbols, return false
47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::addTargetSymbols()
47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initTargetSymbols(*m_pBuilder, *m_pModule);
4766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
4776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// addScriptSymbols - define symbols from the command line option or linker
4806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// scripts.
4816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ObjectLinker::addScriptSymbols()
4826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
48387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript& script = m_pModule->getScript();
48487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript::Assignments::iterator it, ie = script.assignments().end();
48587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // go through the entire symbol assignments
48687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (it = script.assignments().begin(); it != ie; ++it) {
48787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    LDSymbol* symbol = NULL;
48887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    assert((*it).second.symbol().type() == Operand::SYMBOL);
48987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    const llvm::StringRef symName =  (*it).second.symbol().name();
49087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ResolveInfo::Type       type = ResolveInfo::NoType;
49187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ResolveInfo::Visibility vis  = ResolveInfo::Default;
49287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    size_t size = 0;
49387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ResolveInfo* old_info = m_pModule->getNamePool().findInfo(symName);
494f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // if the symbol does not exist, we can set type to NOTYPE
495f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // else we retain its type, same goes for size - 0 or retain old value
496f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // and visibility - Default or retain
497f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (old_info != NULL) {
49887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      type = static_cast<ResolveInfo::Type>(old_info->type());
49987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      vis = old_info->visibility();
50087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      size = old_info->size();
501f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    }
50287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
50387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // Add symbol and refine the visibility if needed
50487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // FIXME: bfd linker would change the binding instead, but currently
50587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    //        ABS is also a kind of Binding in ResolveInfo.
50687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    switch ((*it).second.type()) {
50787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case Assignment::HIDDEN:
50887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      vis = ResolveInfo::Hidden;
50987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // Fall through
51087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case Assignment::DEFAULT:
51187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      symbol =
51287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        m_pBuilder->AddSymbol<IRBuilder::Force,
51387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              IRBuilder::Unresolve>(symName,
51487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    type,
51587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    ResolveInfo::Define,
51687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    ResolveInfo::Absolute,
51787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    size,
51887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    0x0,
51987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    FragmentRef::Null(),
52087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    vis);
52187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
52287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case Assignment::PROVIDE_HIDDEN:
52387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      vis = ResolveInfo::Hidden;
52487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // Fall through
52587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case Assignment::PROVIDE:
52687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      symbol =
52787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        m_pBuilder->AddSymbol<IRBuilder::AsReferred,
52887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              IRBuilder::Unresolve>(symName,
52987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    type,
53087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    ResolveInfo::Define,
53187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    ResolveInfo::Absolute,
53287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    size,
53387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    0x0,
53487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    FragmentRef::Null(),
53587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                                    vis);
53687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
537f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    }
53887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // Set symbol of this assignment.
53987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    (*it).first = symbol;
540f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::scanRelocations()
54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // apply all relocations of all inputs
5476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::obj_iterator input, inEnd = m_pModule->obj_end();
5486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (input = m_pModule->obj_begin(); input != inEnd; ++input) {
549f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_LDBackend.getRelocator()->initializeScan(**input);
55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
55122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // bypass the reloc section if
55322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 1. its section kind is changed to Ignore. (The target section is a
55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // discarded group section.)
55522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 2. it has no reloc data. (All symbols in the input relocs are in the
55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // discarded group sections)
55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
56022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
56122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        Relocation* relocation = llvm::cast<Relocation>(reloc);
56287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
56387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // bypass the reloc if the symbol is in the discarded input section
56487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        ResolveInfo* info = relocation->symInfo();
56587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (!info->outSymbol()->hasFragRef() &&
56687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            ResolveInfo::Section == info->type() &&
56787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            ResolveInfo::Undefined == info->desc())
56887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines           continue;
56987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
57022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // scan relocation
5716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (LinkerConfig::Object != m_Config.codeGenType())
572f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          m_LDBackend.getRelocator()->scanRelocation(
57387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                    *relocation, *m_pBuilder, *m_pModule, **rs, **input);
5746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        else
575f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          m_LDBackend.getRelocator()->partialScanRelocation(
576f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                                 *relocation, *m_pModule, **rs);
57722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      } // for all relocations
57822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // for all relocation section
579f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_LDBackend.getRelocator()->finalizeScan(**input);
58022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // for all inputs
58122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
58222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
58322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// initStubs - initialize stub-related stuff.
5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ObjectLinker::initStubs()
5866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // initialize BranchIslandFactory
5886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initBRIslandFactory();
5896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // initialize StubFactory
5916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initStubFactory();
5926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // initialize target stubs
5946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.initTargetStubs();
5956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
5966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// allocateCommonSymobols - allocate fragments for common symbols to the
5996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// corresponding sections
6006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ObjectLinker::allocateCommonSymbols()
6016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != m_Config.codeGenType() ||
6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Config.options().isDefineCommon())
6046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return m_LDBackend.allocateCommonSymbols(*m_pModule);
6056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
6066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
6076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
60822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// prelayout - help backend to do some modification before layout
60922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::prelayout()
61022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
61122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // finalize the section symbols, set their fragment reference and push them
61222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // into output symbol table
6136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::iterator sect, sEnd = m_pModule->end();
6146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (sect = m_pModule->begin(); sect != sEnd; ++sect) {
615f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pModule->getSectionSymbolSet().finalize(**sect,
616f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        m_pModule->getSymbolTable(),
617f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        m_Config.codeGenType() == LinkerConfig::Object);
61822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
61922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.preLayout(*m_pModule, *m_pBuilder);
62122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
62222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// check program interpreter - computer the name size of the runtime dyld
6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!m_Config.isCodeStatic() &&
62422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (LinkerConfig::Exec == m_Config.codeGenType() ||
62522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao       m_Config.options().isPIE() ||
62622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao       m_Config.options().hasDyld()))
62722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_LDBackend.sizeInterp();
62822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
62922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// measure NamePools - compute the size of name pool sections
63022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// In ELF, will compute  the size of.symtab, .strtab, .dynsym, .dynstr,
63122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// .hash and .shstrtab sections.
63222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ///
63387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// dump all symbols and strings from ObjectLinker and build the format-dependent
63422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// hash table.
635f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @note sizeNamePools replies on LinkerConfig::CodePosition. Must determine
636f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// code position model before calling GNULDBackend::sizeNamePools()
637f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  m_LDBackend.sizeNamePools(*m_pModule);
63822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
63987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // Do this after backend prelayout since it may add eh_frame entries.
64087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* eh_frame_sect = m_pModule->getSection(".eh_frame");
64187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (eh_frame_sect && eh_frame_sect->hasEhFrame())
64287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    eh_frame_sect->getEhFrame()->computeOffsetSize();
64387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_LDBackend.createAndSizeEhFrameHdr(*m_pModule);
64487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
64522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
64622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
64722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
64822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// layout - linearly layout all output sections and reserve some space
64922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// for GOT/PLT
65022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   Because we do not support instruction relaxing in this early version,
65122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   if there is a branch can not jump to its target, we return false
65222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   directly
65322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::layout()
65422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
6556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.layout(*m_pModule);
656d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return true;
65722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
65822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
65922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// prelayout - help backend to do some modification after layout
66022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::postlayout()
66122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
6626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.postLayout(*m_pModule, *m_pBuilder);
66322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
66422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
66522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
66622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// finalizeSymbolValue - finalize the resolved symbol value.
66787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines///   Before relocate(), after layout(), ObjectLinker should correct value of all
66822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///   symbol.
66922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::finalizeSymbolValue()
67022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
67187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Module::sym_iterator symbol, symEnd = m_pModule->sym_end();
67287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (symbol = m_pModule->sym_begin(); symbol != symEnd; ++symbol) {
67387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
67487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*symbol)->resolveInfo()->isAbsolute() ||
67587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*symbol)->resolveInfo()->type() == ResolveInfo::File) {
67687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // absolute symbols should just use its value directly (i.e., the result
67787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // of symbol resolution)
67887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      continue;
67987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
68087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
68187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*symbol)->resolveInfo()->type() == ResolveInfo::ThreadLocal) {
68287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      m_LDBackend.finalizeTLSSymbol(**symbol);
68387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      continue;
68487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
68587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
68687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*symbol)->hasFragRef()) {
68787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // set the virtual address of the symbol. If the output file is
68887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // relocatable object file, the section's virtual address becomes zero.
68987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // And the symbol's value become section relative offset.
69087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      uint64_t value = (*symbol)->fragRef()->getOutputOffset();
69187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      assert(NULL != (*symbol)->fragRef()->frag());
69287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      uint64_t addr =
69387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*symbol)->fragRef()->frag()->getParent()->getSection().addr();
69487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*symbol)->setValue(value + addr);
69587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      continue;
69687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
697f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
69887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
69987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  RpnEvaluator evaluator(*m_pModule, m_LDBackend);
70087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool finalized = m_LDBackend.finalizeSymbols();
70187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool scriptSymsFinalized = true;
70287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript& script = m_pModule->getScript();
70387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript::Assignments::iterator assign, assignEnd;
70487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assignEnd = script.assignments().end();
70587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (assign = script.assignments().begin(); assign != assignEnd; ++assign) {
70687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    LDSymbol* symbol = (*assign).first;
70787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    Assignment& assignment = (*assign).second;
70887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
70987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (symbol == NULL)
71087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      continue;
71187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
71287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    scriptSymsFinalized &= assignment.assign(evaluator);
71387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (!scriptSymsFinalized)
71487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
71587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
71687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    symbol->setValue(assignment.symbol().value());
71787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for each script symbol assignment
71887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
71987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool assertionsPassed = true;
72087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript::Assertions::iterator assert, assertEnd;
72187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assertEnd = script.assertions().end();
72287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (assert = script.assertions().begin(); assert != assertEnd; ++assert) {
72387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    uint64_t res = 0x0;
72487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    evaluator.eval((*assert).getRpnExpr(), res);
72587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (res == 0x0)
72687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      fatal(diag::err_assert_failed) << (*assert).message();
72787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for each assertion in ldscript
72887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
72987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return finalized && scriptSymsFinalized && assertionsPassed;
73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
73122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
73222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// relocate - applying relocation entries and create relocation
73322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// section in the output files
73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// Create relocation section, asking TargetLDBackend to
73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// read the relocation information into RelocationEntry
73622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// and push_back into the relocation section
73722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::relocation()
73822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
73987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // when producing relocatables, no need to apply relocation
74087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (LinkerConfig::Object == m_Config.codeGenType())
74187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return true;
74287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
74387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // apply all relocations of all inputs
74487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Module::obj_iterator input, inEnd = m_pModule->obj_end();
74587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (input = m_pModule->obj_begin(); input != inEnd; ++input) {
74687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    m_LDBackend.getRelocator()->initializeApply(**input);
74787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
74887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
74987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // bypass the reloc section if
75087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // 1. its section kind is changed to Ignore. (The target section is a
75187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // discarded group section.)
75287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // 2. it has no reloc data. (All symbols in the input relocs are in the
75387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // discarded group sections)
75487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
75587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        continue;
75687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
75787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
75887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        Relocation* relocation = llvm::cast<Relocation>(reloc);
75987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
76087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // bypass the reloc if the symbol is in the discarded input section
76187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        ResolveInfo* info = relocation->symInfo();
76287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (!info->outSymbol()->hasFragRef() &&
76387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            ResolveInfo::Section == info->type() &&
76487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            ResolveInfo::Undefined == info->desc())
76587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          continue;
76687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
76787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        relocation->apply(*m_LDBackend.getRelocator());
76887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } // for all relocations
76987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } // for all relocation section
77087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    m_LDBackend.getRelocator()->finalizeApply(**input);
77187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for all inputs
77287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
77387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // apply relocations created by relaxation
77487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  BranchIslandFactory* br_factory = m_LDBackend.getBRIslandFactory();
77587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  BranchIslandFactory::iterator facIter, facEnd = br_factory->end();
77687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (facIter = br_factory->begin(); facIter != facEnd; ++facIter) {
77787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    BranchIsland& island = *facIter;
77887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    BranchIsland::reloc_iterator iter, iterEnd = island.reloc_end();
77987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (iter = island.reloc_begin(); iter != iterEnd; ++iter)
78087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*iter)->apply(*m_LDBackend.getRelocator());
78187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
78287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return true;
78322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
78422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
78522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitOutput - emit the output file.
78687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool ObjectLinker::emitOutput(FileOutputBuffer& pOutput)
78722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
7880dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  return std::error_code() == getWriter()->writeObject(*m_pModule, pOutput);
78922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
79022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
791f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
79222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// postProcessing - do modification after all processes
79387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool ObjectLinker::postProcessing(FileOutputBuffer& pOutput)
79422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
79587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (LinkerConfig::Object != m_Config.codeGenType())
79687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    normalSyncRelocationResult(pOutput);
79787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else
79887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    partialSyncRelocationResult(pOutput);
79922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
80022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit .eh_frame_hdr
80122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // eh_frame_hdr should be emitted after syncRelocation, because eh_frame_hdr
80222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // needs FDE PC value, which will be corrected at syncRelocation
8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_LDBackend.postProcessing(pOutput);
80422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
80522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
80622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
80787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid ObjectLinker::normalSyncRelocationResult(FileOutputBuffer& pOutput)
80887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
80987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint8_t* data = pOutput.getBufferStart();
81087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
81187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // sync all relocations of all inputs
81287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Module::obj_iterator input, inEnd = m_pModule->obj_end();
81387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (input = m_pModule->obj_begin(); input != inEnd; ++input) {
81487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
81587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
81687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // bypass the reloc section if
81787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // 1. its section kind is changed to Ignore. (The target section is a
81887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // discarded group section.)
81987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // 2. it has no reloc data. (All symbols in the input relocs are in the
82087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // discarded group sections)
82187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
82287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        continue;
82387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
82487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
82587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        Relocation* relocation = llvm::cast<Relocation>(reloc);
82687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
82787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // bypass the reloc if the symbol is in the discarded input section
82887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        ResolveInfo* info = relocation->symInfo();
82987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (!info->outSymbol()->hasFragRef() &&
83087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            ResolveInfo::Section == info->type() &&
83187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            ResolveInfo::Undefined == info->desc())
83287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          continue;
83387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
83487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // bypass the relocation with NONE type. This is to avoid overwrite the
83587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // target result by NONE type relocation if there is a place which has
83687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // two relocations to apply to, and one of it is NONE type. The result
83787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // we want is the value of the other relocation result. For example,
83887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to
83987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // the same place
84087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (0x0 == relocation->type())
84187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          continue;
84287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        writeRelocationResult(*relocation, data);
84387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } // for all relocations
84487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } // for all relocation section
84587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for all inputs
84687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
84787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // sync relocations created by relaxation
84887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  BranchIslandFactory* br_factory = m_LDBackend.getBRIslandFactory();
84987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  BranchIslandFactory::iterator facIter, facEnd = br_factory->end();
85087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (facIter = br_factory->begin(); facIter != facEnd; ++facIter) {
85187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    BranchIsland& island = *facIter;
85287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    BranchIsland::reloc_iterator iter, iterEnd = island.reloc_end();
85387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (iter = island.reloc_begin(); iter != iterEnd; ++iter) {
85487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      Relocation* reloc = *iter;
85587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      writeRelocationResult(*reloc, data);
85687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
85787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
85887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
85987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
86087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid ObjectLinker::partialSyncRelocationResult(FileOutputBuffer& pOutput)
86187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
86287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint8_t* data = pOutput.getBufferStart();
86387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
86487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // traverse outputs' LDSection to get RelocData
86587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Module::iterator sectIter, sectEnd = m_pModule->end();
86687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (sectIter = m_pModule->begin(); sectIter != sectEnd; ++sectIter) {
86787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (LDFileFormat::Relocation != (*sectIter)->kind())
86887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      continue;
86987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
87087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    RelocData* reloc_data = (*sectIter)->getRelocData();
87187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    RelocData::iterator relocIter, relocEnd = reloc_data->end();
87287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (relocIter = reloc_data->begin(); relocIter != relocEnd; ++relocIter) {
87387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      Relocation* reloc = llvm::cast<Relocation>(relocIter);
87487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
87587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // bypass the relocation with NONE type. This is to avoid overwrite the
87687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // target result by NONE type relocation if there is a place which has
87787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // two relocations to apply to, and one of it is NONE type. The result
87887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // we want is the value of the other relocation result. For example,
87987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to
88087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // the same place
88187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (0x0 == reloc->type())
88287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        continue;
88387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      writeRelocationResult(*reloc, data);
88487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
88587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
88687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
88787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
88887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid ObjectLinker::writeRelocationResult(Relocation& pReloc, uint8_t* pOutput)
88987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
89087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // get output file offset
89187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t out_offset =
89287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                 pReloc.targetRef().frag()->getParent()->getSection().offset() +
89387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                 pReloc.targetRef().getOutputOffset();
89487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
89587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint8_t* target_addr = pOutput + out_offset;
89687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // byte swapping if target and host has different endian, and then write back
89787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if(llvm::sys::IsLittleEndianHost != m_Config.targets().isLittleEndian()) {
89887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines     uint64_t tmp_data = 0;
89987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
90087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines     switch(pReloc.size(*m_LDBackend.getRelocator())) {
90187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       case 8u:
90287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         std::memcpy(target_addr, &pReloc.target(), 1);
90387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         break;
90487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
90587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       case 16u:
90687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         tmp_data = mcld::bswap16(pReloc.target());
90787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         std::memcpy(target_addr, &tmp_data, 2);
90887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         break;
90987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
91087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       case 32u:
91187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         tmp_data = mcld::bswap32(pReloc.target());
91287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         std::memcpy(target_addr, &tmp_data, 4);
91387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         break;
91487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
91587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       case 64u:
91687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         tmp_data = mcld::bswap64(pReloc.target());
91787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         std::memcpy(target_addr, &tmp_data, 8);
91887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         break;
91987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
92087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       default:
92187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines         break;
92287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
92387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
92487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else
92587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    std::memcpy(target_addr, &pReloc.target(),
92687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                      pReloc.size(*m_LDBackend.getRelocator())/8);
92787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
92887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
929