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