ObjectLinker.cpp revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
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> 1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h> 14d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/IRBuilder.h> 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h> 1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h> 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/Archive.h> 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ArchiveReader.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ObjectReader.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/DynObjReader.h> 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/GroupReader.h> 22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/BinaryReader.h> 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ObjectWriter.h> 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ResolveInfo.h> 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h> 26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/Relocator.h> 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/RealPath.h> 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h> 2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MsgHandling.h> 30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/DefSymParser.h> 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/TargetLDBackend.h> 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h> 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/Casting.h> 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace llvm; 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld; 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoObjectLinker::ObjectLinker(const LinkerConfig& pConfig, 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao TargetLDBackend& pLDBackend) 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : m_Config(pConfig), 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pLinker(NULL), 446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule(NULL), 456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pBuilder(NULL), 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_LDBackend(pLDBackend), 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjectReader(NULL), 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pDynObjReader(NULL), 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pArchiveReader(NULL), 50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pGroupReader(NULL), 51d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pBinaryReader(NULL), 526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pWriter(NULL) { 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoObjectLinker::~ObjectLinker() 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pLinker; 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pObjectReader; 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynObjReader; 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pArchiveReader; 61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pGroupReader; 62d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pBinaryReader; 636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pWriter; 646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ObjectLinker::setup(Module& pModule, IRBuilder& pBuilder) 676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule = &pModule; 696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pBuilder = &pBuilder; 70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set up soname 726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_Config.options().soname().empty()) { 736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule->setName(m_Config.options().soname()); 746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initFragmentLinker - initialize FragmentLinker 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// Connect all components with FragmentLinker 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::initFragmentLinker() 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pLinker) { 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pLinker = new FragmentLinker(m_Config, 836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *m_pModule, 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_LDBackend); 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize the readers and writers 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Because constructor can not be failed, we initalize all readers and 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // writers outside the FragmentLinker constructors. 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pObjectReader = m_LDBackend.createObjectReader(*m_pBuilder); 916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pArchiveReader = m_LDBackend.createArchiveReader(*m_pModule); 926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynObjReader = m_LDBackend.createDynObjReader(*m_pBuilder); 936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pBinaryReader = m_LDBackend.createBinaryReader(*m_pBuilder); 94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGroupReader = new GroupReader(*m_pModule, *m_pObjectReader, 95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *m_pDynObjReader, *m_pArchiveReader, *m_pBinaryReader); 966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pWriter = m_LDBackend.createWriter(); 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 98d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // initialize Relocator 996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.initRelocator(); 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStdSections - initialize standard sections 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::initStdSections() 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ObjectBuilder builder(m_Config, *m_pModule); 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize standard sections 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_LDBackend.initStdSections(builder)) 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize target-dependent sections 1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.initTargetSections(*m_pModule, builder); 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid ObjectLinker::normalize() 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ----- set up inputs ----- // 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::input_iterator input, inEnd = m_pModule->input_end(); 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (input = m_pModule->input_begin(); input!=inEnd; ++input) { 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is a group node 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (isGroup(input)) { 1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines getGroupReader()->readGroup(input, m_pBuilder->getInputBuilder(), m_Config); 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // already got type - for example, bitcode or external OIR (object 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // intermediate representation) 13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*input)->type() == Input::Script || 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->type() == Input::Archive || 13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->type() == Input::External) 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (Input::Object == (*input)->type()) { 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule->getObjectList().push_back(*input); 13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (Input::DynObj == (*input)->type()) { 1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule->getLibraryList().push_back(*input); 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 146d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // read input as a binary file 147d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().isBinaryInput()) { 148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (*input)->setType(Input::Object); 149d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao getBinaryReader()->readBinary(**input); 1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule->getObjectList().push_back(*input); 151d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is a relocatable object file 153d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (getObjectReader()->isMyFormat(**input)) { 15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->setType(Input::Object); 15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getObjectReader()->readHeader(**input); 15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getObjectReader()->readSections(**input); 15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getObjectReader()->readSymbols(**input); 1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule->getObjectList().push_back(*input); 15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is a shared object file 16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (getDynObjReader()->isMyFormat(**input)) { 16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->setType(Input::DynObj); 16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getDynObjReader()->readHeader(**input); 16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getDynObjReader()->readSymbols(**input); 1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule->getLibraryList().push_back(*input); 16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is an archive 16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (getArchiveReader()->isMyFormat(**input)) { 16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->setType(Input::Archive); 1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Archive archive(**input, m_pBuilder->getInputBuilder()); 17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getArchiveReader()->readArchive(archive); 17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if(archive.numOfObjectMember() > 0) { 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule->getInputTree().merge<InputTree::Inclusive>(input, 17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao archive.inputs()); 17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_unrecognized_input_file) << (*input)->path() 179d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << m_Config.targets().triple().str(); 18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::linkable() const 18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // check we have input and output files 1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_pModule->getInputTree().empty()) { 18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao error(diag::err_no_inputs); 18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // can not mix -static with shared objects 1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_lib_iterator lib, libEnd = m_pModule->lib_end(); 1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (lib = m_pModule->lib_begin(); lib != libEnd; ++lib) { 19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if((*lib)->attribute()->isStatic()) { 19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao error(diag::err_mixed_shared_static_objects) 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*lib)->name() << (*lib)->path(); 19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // --nmagic and --omagic options lead to static executable program. 2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // These options turn off page alignment of sections. Because the 2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // sections are not aligned to pages, these sections can not contain any 2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // exported functions. Also, because the two options disable linking 2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // against shared libraries, the output absolutely does not call outside 2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // functions. 2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Config.options().nmagic() && !m_Config.isCodeStatic()) { 2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines error(diag::err_nmagic_not_static); 2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Config.options().omagic() && !m_Config.isCodeStatic()) { 2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines error(diag::err_omagic_not_static); 2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRelocations - read all relocation entries 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// All symbols should be read and resolved before this function. 22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::readRelocations() 22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Bitcode is read by the other path. This function reads relocation sections 22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // in object files. 2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines mcld::InputTree::bfs_iterator input, inEnd = m_pModule->getInputTree().bfs_end(); 2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (input=m_pModule->getInputTree().bfs_begin(); input!=inEnd; ++input) { 22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*input)->type() == Input::Object && (*input)->hasMemArea()) { 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!getObjectReader()->readRelocations(**input)) 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ignore the other kinds of files. 23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// mergeSections - put allinput sections into output sections 23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::mergeSections() 24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ObjectBuilder builder(m_Config, *m_pModule); 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::obj_iterator obj, objEnd = m_pModule->obj_end(); 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (obj = m_pModule->obj_begin(); obj != objEnd; ++obj) { 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd(); 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) { 24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch ((*sect)->kind()) { 24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Some *INPUT sections should not be merged. 24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Ignore: 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Null: 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::NamePool: 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Group: 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::StackNote: 25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // skip 25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Target: 2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_LDBackend.mergeSection(*m_pModule, **sect)) { 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao error(diag::err_cannot_merge_section) << (*sect)->name() 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*obj)->name(); 26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: { 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!(*sect)->hasEhFrame()) 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; // skip 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 267f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection* out_sect = NULL; 268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL == (out_sect = builder.MergeSection(**sect))) { 269f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines error(diag::err_cannot_merge_section) << (*sect)->name() 270f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines << (*obj)->name(); 271f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 272f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 274f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) { 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao error(diag::err_cannot_merge_section) << (*sect)->name() 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*obj)->name(); 27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: { 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!(*sect)->hasSectionData()) 28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; // skip 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 285f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection* out_sect = NULL; 286f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL == (out_sect = builder.MergeSection(**sect))) { 287f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines error(diag::err_cannot_merge_section) << (*sect)->name() 288f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines << (*obj)->name(); 289f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 291f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 292f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) { 29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao error(diag::err_cannot_merge_section) << (*sect)->name() 29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*obj)->name(); 29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of switch 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for each section 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for each obj 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// addStandardSymbols - shared object and executable files need some 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// standard symbols 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @return if there are some input symbols with the same name to the 30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// standard symbols, return false 30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::addStandardSymbols() 31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create and add section symbols for each output section 3126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::iterator iter, iterEnd = m_pModule->end(); 3136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (iter = m_pModule->begin(); iter != iterEnd; ++iter) { 3146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pModule->getSectionSymbolSet().add(**iter, m_pModule->getNamePool()); 31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_LDBackend.initStandardSymbols(*m_pBuilder, *m_pModule); 31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// addTargetSymbols - some targets, such as MIPS and ARM, need some 32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent symbols 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @return if there are some input symbols with the same name to the 32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target symbols, return false 32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::addTargetSymbols() 32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.initTargetSymbols(*m_pBuilder, *m_pModule); 3276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 3286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// addScriptSymbols - define symbols from the command line option or linker 3316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// scripts. 3326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ObjectLinker::addScriptSymbols() 3336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 334f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const LinkerScript& script = m_pModule->getScript(); 335f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LinkerScript::DefSymMap::const_entry_iterator it; 336f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LinkerScript::DefSymMap::const_entry_iterator ie = script.defSymMap().end(); 337f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // go through the entire defSymMap 338f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (it = script.defSymMap().begin(); it != ie; ++it) { 339f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const llvm::StringRef sym = it.getEntry()->key(); 340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo* old_info = m_pModule->getNamePool().findInfo(sym); 341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // if the symbol does not exist, we can set type to NOTYPE 342f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // else we retain its type, same goes for size - 0 or retain old value 343f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // and visibility - Default or retain 344f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (old_info != NULL) { 345f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if(!m_pBuilder->AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 346f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym, 347f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines static_cast<ResolveInfo::Type>(old_info->type()), 348f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Define, 349f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Absolute, 350f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines old_info->size(), 351f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, 352f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines FragmentRef::Null(), 353f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines old_info->visibility())) 354f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 355f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 356f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 357f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_pBuilder->AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 358f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym, 359f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::NoType, 360f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Define, 361f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Absolute, 362f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, 363f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, 364f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines FragmentRef::Null(), 365f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Default)) 366f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 367f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 368f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::scanRelocations() 37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // apply all relocations of all inputs 3756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::obj_iterator input, inEnd = m_pModule->obj_end(); 3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (input = m_pModule->obj_begin(); input != inEnd; ++input) { 377f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_LDBackend.getRelocator()->initializeScan(**input); 37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // bypass the reloc section if 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. its section kind is changed to Ignore. (The target section is a 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // discarded group section.) 38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. it has no reloc data. (All symbols in the input relocs are in the 38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // discarded group sections) 38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Relocation* relocation = llvm::cast<Relocation>(reloc); 39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // scan relocation 3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != m_Config.codeGenType()) 392f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_LDBackend.getRelocator()->scanRelocation( 393f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *relocation, *m_pBuilder, *m_pModule, **rs); 3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 395f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_LDBackend.getRelocator()->partialScanRelocation( 396f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *relocation, *m_pModule, **rs); 39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all relocations 39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all relocation section 399f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_LDBackend.getRelocator()->finalizeScan(**input); 40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all inputs 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// initStubs - initialize stub-related stuff. 4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ObjectLinker::initStubs() 4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize BranchIslandFactory 4086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.initBRIslandFactory(); 4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize StubFactory 4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.initStubFactory(); 4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize target stubs 4146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.initTargetStubs(); 4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// allocateCommonSymobols - allocate fragments for common symbols to the 4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// corresponding sections 4206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ObjectLinker::allocateCommonSymbols() 4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != m_Config.codeGenType() || 4236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_Config.options().isDefineCommon()) 4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_LDBackend.allocateCommonSymbols(*m_pModule); 4256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 4266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// prelayout - help backend to do some modification before layout 42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::prelayout() 43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // finalize the section symbols, set their fragment reference and push them 43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // into output symbol table 4336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::iterator sect, sEnd = m_pModule->end(); 4346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (sect = m_pModule->begin(); sect != sEnd; ++sect) { 435f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pModule->getSectionSymbolSet().finalize(**sect, 436f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pModule->getSymbolTable(), 437f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_Config.codeGenType() == LinkerConfig::Object); 43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.preLayout(*m_pModule, *m_pBuilder); 44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// check program interpreter - computer the name size of the runtime dyld 4436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_Config.isCodeStatic() && 44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (LinkerConfig::Exec == m_Config.codeGenType() || 44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Config.options().isPIE() || 44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Config.options().hasDyld())) 44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_LDBackend.sizeInterp(); 44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// measure NamePools - compute the size of name pool sections 45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// In ELF, will compute the size of.symtab, .strtab, .dynsym, .dynstr, 45122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// .hash and .shstrtab sections. 45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// 45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// dump all symbols and strings from FragmentLinker and build the format-dependent 45422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// hash table. 455f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// @note sizeNamePools replies on LinkerConfig::CodePosition. Must determine 456f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// code position model before calling GNULDBackend::sizeNamePools() 457f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_LDBackend.sizeNamePools(*m_pModule); 45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 46122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// layout - linearly layout all output sections and reserve some space 46322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// for GOT/PLT 46422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// Because we do not support instruction relaxing in this early version, 46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// if there is a branch can not jump to its target, we return false 46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// directly 46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::layout() 46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.layout(*m_pModule); 470d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return true; 47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// prelayout - help backend to do some modification after layout 47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::postlayout() 47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.postLayout(*m_pModule, *m_pBuilder); 47722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 47822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 48022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// finalizeSymbolValue - finalize the resolved symbol value. 48122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// Before relocate(), after layout(), FragmentLinker should correct value of all 48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbol. 48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::finalizeSymbolValue() 48422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 485f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool finalized = m_pLinker->finalizeSymbols() && m_LDBackend.finalizeSymbols(); 486f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool scriptSymsAdded = true; 487f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t symVal; 488f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const LinkerScript& script = m_pModule->getScript(); 489f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LinkerScript::DefSymMap::const_entry_iterator it; 490f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LinkerScript::DefSymMap::const_entry_iterator ie = script.defSymMap().end(); 491f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 492f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines DefSymParser parser(*m_pModule); 493f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (it = script.defSymMap().begin(); it != ie; ++it) { 494f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::StringRef symName = it.getEntry()->key(); 495f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::StringRef expr = it.getEntry()->value(); 496f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 497f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSymbol* symbol = m_pModule->getNamePool().findSymbol(symName); 498f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != symbol && "--defsym symbol should be in the name pool"); 499f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines scriptSymsAdded &= parser.parse(expr, symVal); 500f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!scriptSymsAdded) 501f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 502f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines symbol->setValue(symVal); 503f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 504f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return finalized && scriptSymsAdded ; 50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// relocate - applying relocation entries and create relocation 50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// section in the output files 50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// Create relocation section, asking TargetLDBackend to 51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// read the relocation information into RelocationEntry 51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// and push_back into the relocation section 51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::relocation() 51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pLinker->applyRelocations(); 51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitOutput - emit the output file. 51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::emitOutput(MemoryArea& pOutput) 51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return llvm::errc::success == getWriter()->writeObject(*m_pModule, pOutput); 52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 523f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// postProcessing - do modification after all processes 52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ObjectLinker::postProcessing(MemoryArea& pOutput) 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pLinker->syncRelocationResult(pOutput); 52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit .eh_frame_hdr 53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // eh_frame_hdr should be emitted after syncRelocation, because eh_frame_hdr 53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // needs FDE PC value, which will be corrected at syncRelocation 5326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_LDBackend.postProcessing(pOutput); 53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 536