15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ARMLDBackend.cpp ---------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 9cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "ARM.h" 10d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "ARMGNUInfo.h" 1187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include "ARMELFAttributeData.h" 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "ARMELFDynamic.h" 13b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "ARMException.h" 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "ARMLDBackend.h" 15d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "ARMRelocator.h" 1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "ARMToARMStub.h" 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "ARMToTHMStub.h" 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "THMToTHMStub.h" 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "THMToARMStub.h" 20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 23b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/ADT/ilist_sort.h" 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/AlignFragment.h" 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h" 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/NullFragment.h" 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/RegionFragment.h" 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Stub.h" 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/BranchIslandFactory.h" 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h" 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegment.h" 32b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/LD/ELFSegmentFactory.h" 33b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/LD/LDContext.h" 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/StubFactory.h" 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h" 3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryArea.h" 3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryRegion.h" 3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/TargetRegistry.h" 4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFAttribute.h" 4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNUInfo.h" 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 430dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <llvm/ADT/StringRef.h> 440dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <llvm/ADT/Triple.h> 450dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <llvm/ADT/Twine.h> 460dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <llvm/Support/Casting.h> 4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/ELF.h> 480dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 490dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <cstring> 50b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include <vector> 510dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 54b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines/// Fragment data for EXIDX_CANTUNWIND. 55b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesstatic const char g_CantUnwindEntry[8] = { 56b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Relocation to text section. 57b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 0, 0, 0, 0, 58b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // EXIDX_CANTUNWIND (little endian.) 59b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1, 0, 0, 0, 60b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines}; 61b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 62b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines/// Helper function to create a local symbol at the end of the fragment. 63b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesstatic mcld::ResolveInfo* 64b0d0eb206527b43c771933602e147bbd7b471082Stephen HinesCreateLocalSymbolToFragmentEnd(mcld::Module& pModule, mcld::Fragment& pFrag) { 65b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Create and add symbol to the name pool. 66b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines mcld::ResolveInfo* resolveInfo = 67b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pModule.getNamePool().createSymbol(/* pName */"", 68b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines /* pIsDyn */false, 69b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines mcld::ResolveInfo::Section, 70b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines mcld::ResolveInfo::Define, 71b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines mcld::ResolveInfo::Local, 72b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines /* pSize */0, 73b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines mcld::ResolveInfo::Hidden); 74b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (resolveInfo == nullptr) { 75b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return nullptr; 76b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 77b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 78b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Create input symbol. 79b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines mcld::LDSymbol* inputSym = mcld::LDSymbol::Create(*resolveInfo); 80b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (inputSym == nullptr) { 81b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return nullptr; 82b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 83b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 84b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines inputSym->setFragmentRef(mcld::FragmentRef::Create(pFrag, pFrag.size())); 85b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines inputSym->setValue(/* pValue */0); 86b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 87b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // The output symbol is simply an alias to the input symbol. 88b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines resolveInfo->setSymPtr(inputSym); 89b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 90b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return resolveInfo; 91b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 92b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 93b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines/// Comparator to sort .ARM.exidx fragments according to the address of the 94b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines/// corresponding .text fragment. 95b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesclass ExIdxFragmentComparator { 96b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines private: 97b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const ARMExData& m_pExData; 98b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 99b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines public: 100b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines explicit ExIdxFragmentComparator(const ARMExData& pExData) 101b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines : m_pExData(pExData) { 102b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 103b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 104b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines bool operator()(const Fragment& a, const Fragment& b) { 105b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ARMExSectionTuple* tupleA = m_pExData.getTupleByExIdx(&a); 106b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ARMExSectionTuple* tupleB = m_pExData.getTupleByExIdx(&b); 107b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 108b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* textFragA = tupleA->getTextFragment(); 109b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* textFragB = tupleB->getTextFragment(); 110b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 111b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t addrA = textFragA->getParent()->getSection().addr() + 112b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines textFragA->getOffset(); 113b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t addrB = textFragB->getParent()->getSection().addr() + 114b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines textFragB->getOffset(); 115b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return (addrA < addrB); 116b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 117b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines}; 118b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 119cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 120cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// ARMGNULDBackend 121cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo) 12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines : GNULDBackend(pConfig, pInfo), 12437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelocator(NULL), 12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOT(NULL), 12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pPLT(NULL), 12737b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelDyn(NULL), 12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelPLT(NULL), 12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pAttrData(NULL), 13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pDynamic(NULL), 13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol(NULL), 13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEXIDXStart(NULL), 13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEXIDXEnd(NULL), 13437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEXIDX(NULL), 13537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEXTAB(NULL), 13637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pAttributes(NULL) { 13737b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 13937b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMGNULDBackend::~ARMGNULDBackend() { 140d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pRelocator; 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pGOT; 14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pPLT; 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelDyn; 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelPLT; 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynamic; 14687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete m_pAttrData; 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGNULDBackend::initTargetSections(Module& pModule, 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder& pBuilder) { 15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines // FIXME: Currently we set exidx and extab to "Exception" and directly emit 15237b74a387bb3993387029859c2d9d051c41c724eStephen Hines // them from input 15337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEXIDX = 15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.CreateSection(".ARM.exidx", 15537b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDFileFormat::Target, 15637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHT_ARM_EXIDX, 15737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER, 15837b74a387bb3993387029859c2d9d051c41c724eStephen Hines config().targets().bitclass() / 8); 15937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEXTAB = pBuilder.CreateSection(".ARM.extab", 16037b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDFileFormat::Target, 16137b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHT_PROGBITS, 16237b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHF_ALLOC, 16337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x1); 16437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pAttributes = pBuilder.CreateSection(".ARM.attributes", 16537b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDFileFormat::Target, 16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHT_ARM_ATTRIBUTES, 16737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, 16837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x1); 16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 17087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize "aeabi" attributes subsection 17187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pAttrData = new ARMELFAttributeData(); 17287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines attribute().registerAttributeData(*m_pAttrData); 17387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got 17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& got = file_format->getGOT(); 17922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT = new ARMGOT(got); 18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .plt 18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& plt = file_format->getPLT(); 18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pPLT = new ARMPLT(plt, *m_pGOT); 18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .rel.plt 18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& relplt = file_format->getRelPlt(); 18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relplt.setLink(&plt); 18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create SectionData and ARMRelDynSection 189d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelPLT = new OutputRelocSection(pModule, relplt); 19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .rel.dyn 19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 193d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn = new OutputRelocSection(pModule, reldyn); 19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 19737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) { 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 200f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 20137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol = 20237b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 20337b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 20437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 20537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 20637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 20737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 20837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 20937b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), 21037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 211f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 21237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pEXIDX != NULL && m_pEXIDX->size() != 0x0) { 2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef* exidx_start = 21437b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 0x0); 21537b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef* exidx_end = FragmentRef::Create( 21637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEXIDX->getSectionData()->front(), m_pEXIDX->size()); 2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pEXIDXStart = 21837b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 21937b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__exidx_start", 22037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 22137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 22237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 22337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 22437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 22537b74a387bb3993387029859c2d9d051c41c724eStephen Hines exidx_start, // FragRef 22637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 22737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 22837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEXIDXEnd = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 22937b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__exidx_end", 23037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 23137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 23237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 23337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 23437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 23537b74a387bb3993387029859c2d9d051c41c724eStephen Hines exidx_end, // FragRef 23637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // change __exidx_start/_end to local dynamic category 23837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pEXIDXStart != NULL) 239f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*m_pEXIDXStart); 24037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pEXIDXEnd != NULL) 241f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*m_pEXIDXEnd); 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pEXIDXStart = 24437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 24537b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__exidx_start", 24637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 24737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 24837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 24937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 25037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 25137b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), 25237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 25337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 25437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEXIDXEnd = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 25537b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__exidx_end", 25637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 25737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 25837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 25937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 26037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 26137b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), 26237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMGNULDBackend::initRelocator() { 26737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pRelocator == NULL) { 268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new ARMRelocator(*this, config()); 269d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 270d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return true; 271d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 272d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 27337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst Relocator* ARMGNULDBackend::getRelocator() const { 27437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 2750dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return m_pRelocator; 2760dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 2770dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 27837b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocator* ARMGNULDBackend::getRelocator() { 27937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 280d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return m_pRelocator; 281d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 282d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 28337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGNULDBackend::doPreLayout(IRBuilder& pBuilder) { 2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .dynamic data 28537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!config().isCodeStatic() && m_pDynamic == NULL) 2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynamic = new ARMELFDynamic(*this, config()); 2876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 28887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set attribute section size 28987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pAttributes->setSize(attribute().sizeOutput()); 29087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .got size 29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // when building shared object, the .got section is must 29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 29437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (LinkerConfig::DynObj == config().codeGenType() || m_pGOT->hasGOT1() || 29537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol != NULL) { 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->finalizeSectionSize(); 2976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder); 29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .plt size 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_pPLT->hasPLT1()) 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pPLT->finalizeSectionSize(); 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 304d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .rel.dyn size 3066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelDyn->empty()) { 30737b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 30837b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 30937b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 31037b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelDyn().setSize(m_pRelDyn->numOfRelocs() * 31137b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelEntrySize()); 3126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .rel.plt size 3156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelPLT->empty()) { 31637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 31737b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 31837b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 31937b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelPlt().setSize(m_pRelPLT->numOfRelocs() * 32037b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelEntrySize()); 3216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 32537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) { 32637b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFFileFormat* file_format = getOutputFormat(); 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // apply PLT 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (file_format->hasPLT()) { 3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Since we already have the size of LDSection PLT, m_pPLT should not be 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // NULL. 33237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL); 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT0(); 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT1(); 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // apply GOT 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (file_format->hasGOT()) { 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Since we already have the size of GOT, m_pGOT should not be NULL. 34037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL); 34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->applyGOT0(file_format->getDynamic().addr()); 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // executable file and object file? should fill with zero. 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->applyGOT0(0); 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 35237b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMELFDynamic& ARMGNULDBackend::dynamic() { 35337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 35937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst ARMELFDynamic& ARMGNULDBackend::dynamic() const { 36037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 36437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) { 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pGOTSymbol != NULL) { 3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 36837b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 36937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 37037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 37137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 37237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 37337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 37437b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(*(m_pGOT->begin()), 0x0), 37537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 37637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 37837b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 37937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 38037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 38137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 38237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 38337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 38437b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(*(m_pGOT->begin()), 0x0), 38537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection, 39037b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 39587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = m_pPLT->emit(pRegion); 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 40087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = m_pGOT->emit(pRegion); 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 40487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 40587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (&pSection == m_pAttributes) { 40687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return attribute().emit(pRegion); 40787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 40887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 40987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab 41087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // directly from the input file. 41187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const SectionData* sect_data = pSection.getSectionData(); 41287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 41387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint8_t* out_offset = pRegion.begin(); 41487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 41587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines size_t size = frag_iter->size(); 41637b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (frag_iter->getKind()) { 41787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Fragment::Fillment: { 41837b74a387bb3993387029859c2d9d051c41c724eStephen Hines const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter); 41937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (fill_frag.getValueSize() == 0) { 42087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // virtual fillment, ignore it. 42187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 42287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 42387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 42487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines memset(out_offset, fill_frag.getValue(), fill_frag.size()); 42587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 42687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 42787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Fragment::Region: { 42887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const RegionFragment& region_frag = 42937b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::cast<RegionFragment>(*frag_iter); 43087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const char* start = region_frag.getRegion().begin(); 43187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines memcpy(out_offset, start, size); 43287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 43387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 43487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Fragment::Alignment: { 43587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); 43687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t count = size / align_frag.getValueSize(); 43787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (align_frag.getValueSize()) { 43887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case 1u: 43987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::memset(out_offset, align_frag.getValue(), count); 44087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 44187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: 44287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::report_fatal_error( 44337b74a387bb3993387029859c2d9d051c41c724eStephen Hines "unsupported value size for align fragment emission yet.\n"); 44487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 44537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end switch 44687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 44787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 44887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Fragment::Null: { 44987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(0x0 == size); 45087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 45187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: 45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::report_fatal_error("unsupported fragment type.\n"); 45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 45537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end switch 45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_offset += size; 45737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end for 45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return pRegion.size(); 4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 46237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMGNULDBackend::finalizeTargetSymbols() { 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 466a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 467a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines/// preMergeSections - hooks to be executed before merging sections 468a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesvoid ARMGNULDBackend::preMergeSections(Module& pModule) { 469b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Since the link relationship between .text and .ARM.exidx will be discarded 470b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // after merging sections, we have to build the exception handling section 471b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // mapping before section merge. 472b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_pExData = ARMExData::create(pModule); 473a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines} 474a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 475a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines/// postMergeSections - hooks to be executed after merging sections 476a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesvoid ARMGNULDBackend::postMergeSections(Module& pModule) { 477a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (m_pEXIDX->hasSectionData()) { 478a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Append the NullFragment so that __exidx_end can be correctly inserted. 479a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines NullFragment* null = new NullFragment(m_pEXIDX->getSectionData()); 480a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines null->setOffset(m_pEXIDX->size()); 481a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 482a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines} 483a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 48487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool ARMGNULDBackend::mergeSection(Module& pModule, 48587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const Input& pInput, 48637b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDSection& pSection) { 48722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (pSection.type()) { 48822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::SHT_ARM_ATTRIBUTES: { 48987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return attribute().merge(pInput, pSection); 49087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 491a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 49287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case llvm::ELF::SHT_ARM_EXIDX: { 49337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(pSection.getLink() != NULL); 49437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if ((pSection.getLink()->kind() == LDFileFormat::Ignore) || 49537b74a387bb3993387029859c2d9d051c41c724eStephen Hines (pSection.getLink()->kind() == LDFileFormat::Folded)) { 49687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // if the target section of the .ARM.exidx is Ignore, then it should be 49787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // ignored as well 49887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSection.setKind(LDFileFormat::Ignore); 49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 50087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 501a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 502a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (!m_pEXIDX->hasSectionData()) { 503a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Create SectionData for m_pEXIDX. 504a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData* sectData = IRBuilder::CreateSectionData(*m_pEXIDX); 505a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 506a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Initialize the alignment of m_pEXIDX. 507a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines const size_t alignExIdx = 4; 508a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines m_pEXIDX->setAlign(alignExIdx); 509a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 510a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Insert an AlignFragment to the beginning of m_pEXIDX. 511a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines AlignFragment* frag = 512a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines new AlignFragment(/*alignment*/alignExIdx, 513a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines /*the filled value*/0x0, 514a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines /*the size of filled value*/1u, 515a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines /*max bytes to emit*/alignExIdx - 1); 516a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines frag->setOffset(0); 517a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines frag->setParent(sectData); 518a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines sectData->getFragmentList().push_back(frag); 519a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines m_pEXIDX->setSize(frag->size()); 520a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 521a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 522a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Move RegionFragment from pSection to m_pEXIDX. 523a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines uint64_t offset = m_pEXIDX->size(); 524a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData::FragmentListType& src = 525a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines pSection.getSectionData()->getFragmentList(); 526a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData::FragmentListType& dst = 527a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines m_pEXIDX->getSectionData()->getFragmentList(); 528a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData::FragmentListType::iterator frag = src.begin(); 529a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData::FragmentListType::iterator fragEnd = src.end(); 530a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines while (frag != fragEnd) { 531a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (frag->getKind() != Fragment::Region) { 532a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ++frag; 533a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } else { 534a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines frag->setParent(m_pEXIDX->getSectionData()); 535a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines frag->setOffset(offset); 536a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines offset += frag->size(); 537a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines dst.splice(dst.end(), src, frag++); 538a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 539a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 540a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 541a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Update the size of m_pEXIDX. 542a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines m_pEXIDX->setSize(offset); 543a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines return true; 54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 545a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: { 547533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines ObjectBuilder builder(pModule); 54887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines builder.MergeSection(pInput, pSection); 54987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 55137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 55322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 55537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGNULDBackend::setUpReachedSectionsForGC( 55637b74a387bb3993387029859c2d9d051c41c724eStephen Hines const Module& pModule, 55737b74a387bb3993387029859c2d9d051c41c724eStephen Hines GarbageCollection::SectionReachedListMap& pSectReachedListMap) const { 55887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // traverse all the input relocations to find the relocation sections applying 55987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // .ARM.exidx sections 56087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Module::const_obj_iterator input, inEnd = pModule.obj_end(); 56187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (input = pModule.obj_begin(); input != inEnd; ++input) { 56287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDContext::const_sect_iterator rs, 56337b74a387bb3993387029859c2d9d051c41c724eStephen Hines rsEnd = (*input)->context()->relocSectEnd(); 56487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 56587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // bypass the discarded relocation section 56687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1. its section kind is changed to Ignore. (The target section is a 56787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // discarded group section.) 56887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2. it has no reloc data. (All symbols in the input relocs are in the 56987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // discarded group sections) 57087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* reloc_sect = *rs; 57187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* apply_sect = reloc_sect->getLink(); 57287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((LDFileFormat::Ignore == reloc_sect->kind()) || 57387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (!reloc_sect->hasRelocData())) 57487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 57587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 57687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::ELF::SHT_ARM_EXIDX == apply_sect->type()) { 57787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1. set up the reference according to relocations 57887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool add_first = false; 57987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines GarbageCollection::SectionListTy* reached_sects = NULL; 58087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines RelocData::iterator reloc_it, rEnd = reloc_sect->getRelocData()->end(); 58187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (reloc_it = reloc_sect->getRelocData()->begin(); reloc_it != rEnd; 58237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++reloc_it) { 58387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation* reloc = llvm::cast<Relocation>(reloc_it); 58487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo* sym = reloc->symInfo(); 58587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // only the target symbols defined in the input fragments can make the 58687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // reference 58737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (sym == NULL) 58887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 58987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!sym->isDefine() || !sym->outSymbol()->hasFragRef()) 59087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 59187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 59287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // only the target symbols defined in the concerned sections can make 59387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // the reference 59487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const LDSection* target_sect = 59537b74a387bb3993387029859c2d9d051c41c724eStephen Hines &sym->outSymbol()->fragRef()->frag()->getParent()->getSection(); 5960dea6bc96bb52346737966839ac68644f7939f58Stephen Hines if (target_sect->kind() != LDFileFormat::TEXT && 5970dea6bc96bb52346737966839ac68644f7939f58Stephen Hines target_sect->kind() != LDFileFormat::DATA && 59887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines target_sect->kind() != LDFileFormat::BSS) 59987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 60087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 60187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // setup the reached list, if we first add the element to reached list 60287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // of this section, create an entry in ReachedSections map 60387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!add_first) { 60487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines reached_sects = &pSectReachedListMap.getReachedList(*apply_sect); 60587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines add_first = true; 60687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 60787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines reached_sects->insert(target_sect); 60887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 60987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines reached_sects = NULL; 61087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines add_first = false; 61187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2. set up the reference from XXX to .ARM.exidx.XXX 61287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(apply_sect->getLink() != NULL); 61387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSectReachedListMap.addReference(*apply_sect->getLink(), *apply_sect); 61487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 61587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 61687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 61787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 61887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 61937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD) { 620cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = NULL; 62122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 62222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t size = pSD.getSection().size(); 62322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 62487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef region = pInput.memArea()->request(offset, size); 62587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (region.size() == 0) { 626affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // If the input section's size is zero, we got a NULL region. 627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // use a virtual fill fragment 628cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag = new FillFragment(0x0, 0, 0); 62937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 63087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag = new RegionFragment(region); 63122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 63322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ObjectBuilder::AppendFragment(*frag, pSD); 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 63737b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMGOT& ARMGNULDBackend::getGOT() { 63837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL && "GOT section not exist"); 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 64237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst ARMGOT& ARMGNULDBackend::getGOT() const { 64337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL && "GOT section not exist"); 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 64737b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMPLT& ARMGNULDBackend::getPLT() { 64837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL && "PLT section not exist"); 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 65237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst ARMPLT& ARMGNULDBackend::getPLT() const { 65337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL && "PLT section not exist"); 6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 65737b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& ARMGNULDBackend::getRelDyn() { 65837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelDyn != NULL && ".rel.dyn section not exist"); 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 66237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& ARMGNULDBackend::getRelDyn() const { 66337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelDyn != NULL && ".rel.dyn section not exist"); 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 66737b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& ARMGNULDBackend::getRelPLT() { 66837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelPLT != NULL && ".rel.plt section not exist"); 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 67237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& ARMGNULDBackend::getRelPLT() const { 67337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelPLT != NULL && ".rel.plt section not exist"); 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 67737b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMELFAttributeData& ARMGNULDBackend::getAttributeData() { 67837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pAttrData != NULL && ".ARM.attributes section not exist"); 67987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pAttrData; 68087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 68187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 68237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst ARMELFAttributeData& ARMGNULDBackend::getAttributeData() const { 68337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pAttrData != NULL && ".ARM.attributes section not exist"); 68487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pAttrData; 68587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 68687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 68737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned int ARMGNULDBackend::getTargetSectionOrder( 68837b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSection& pSectHdr) const { 68922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 69187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 69222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasNow()) 693affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO_LAST; 6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 69787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_PLT; 6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSectHdr == m_pEXIDX || &pSectHdr == m_pEXTAB) { 701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // put ARM.exidx and ARM.extab in the same order of .eh_frame 702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_EXCEPTION; 703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 708b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesvoid ARMGNULDBackend::rewriteARMExIdxSection(Module& pModule) { 709b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!m_pEXIDX->hasSectionData()) { 710b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Return if this is empty section. 711b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return; 712b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 713b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 714b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData* sectData = m_pEXIDX->getSectionData(); 715b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData::FragmentListType& list = sectData->getFragmentList(); 716b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 717b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Move the first fragment (align fragment) and last fragment (null fragment) 718b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // to temporary list because we would only like to sort the region fragment. 719b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData::FragmentListType tmp; 720b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines { 721b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData::iterator first = sectData->begin(); 722b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData::iterator last = sectData->end(); 723b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines --last; 724b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 725b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(first->getKind() == Fragment::Alignment); 726b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(last->getKind() == Fragment::Null); 727b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 728b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines tmp.splice(tmp.end(), list, first); 729b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines tmp.splice(tmp.end(), list, last); 730b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 731b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 732b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Sort the region fragments in the .ARM.exidx output section. 733b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sort(list, ExIdxFragmentComparator(*m_pExData)); 734b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 735b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Fix the coverage of the .ARM.exidx table. 736b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::StringRef cantUnwindRegion(g_CantUnwindEntry, 737b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sizeof(g_CantUnwindEntry)); 738b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 739b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData::FragmentListType::iterator it = list.begin(); 740b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (it != list.end()) { 741b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* prevTextFrag = m_pExData->getTupleByExIdx(&*it)->getTextFragment(); 742b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t prevTextEnd = prevTextFrag->getParent()->getSection().addr() + 743b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines prevTextFrag->getOffset() + 744b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines prevTextFrag->size(); 745b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++it; 746b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines while (it != list.end()) { 747b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* currTextFrag = 748b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_pExData->getTupleByExIdx(&*it)->getTextFragment(); 749b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t currTextBegin = currTextFrag->getParent()->getSection().addr() + 750b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines currTextFrag->getOffset(); 751b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 752b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (currTextBegin > prevTextEnd) { 753b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Found a gap. Insert a can't unwind entry. 754b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr); 755b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines frag->setParent(sectData); 756b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines list.insert(it, frag); 757b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 758b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Add PREL31 reference to the beginning of the uncovered region. 759b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Relocation* reloc = 760b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31), 761b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines *FragmentRef::Create(*frag, /* pOffset */0), 762b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines /* pAddend */0); 763b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines reloc->setSymInfo( 764b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag)); 765b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines addExtraRelocation(reloc); 766b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 767b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 768b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines prevTextEnd = currTextBegin + currTextFrag->size(); 769b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines prevTextFrag = currTextFrag; 770b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++it; 771b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 772b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 773b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Add a can't unwind entry to terminate .ARM.exidx section. 774b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr); 775b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines frag->setParent(sectData); 776b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines list.push_back(frag); 777b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 778b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Add PREL31 reference to the end of the .text section. 779b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Relocation* reloc = 780b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31), 781b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines *FragmentRef::Create(*frag, /* pOffset */0), 782b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines /* pAddend */0); 783b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines reloc->setSymInfo(CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag)); 784b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines addExtraRelocation(reloc); 785b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 786b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 787b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Add the first and the last fragment back. 788b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines list.splice(list.begin(), tmp, tmp.begin()); 789b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines list.splice(list.end(), tmp, tmp.begin()); 790b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 791b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Update the fragment offsets. 792b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t offset = 0; 793b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (SectionData::iterator it = sectData->begin(), end = sectData->end(); 794b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines it != end; ++it) { 795b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines it->setOffset(offset); 796b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines offset += it->size(); 797b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 798b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 799b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Update the section size. 800b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_pEXIDX->setSize(offset); 801b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 802b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Rebuild the section header. 803b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines setOutputSectionAddress(pModule); 804b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 805b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 806a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines/// relax - the relaxation pass 807a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesbool ARMGNULDBackend::relax(Module& pModule, IRBuilder& pBuilder) { 80804c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines if (!GNULDBackend::relax(pModule, pBuilder)) { 80904c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines return false; 81004c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines } 811a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines rewriteARMExIdxSection(pModule); 81204c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines return true; 813a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines} 814a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 81522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doRelax 81637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMGNULDBackend::doRelax(Module& pModule, 81737b74a387bb3993387029859c2d9d051c41c724eStephen Hines IRBuilder& pBuilder, 81837b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool& pFinished) { 81937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(getStubFactory() != NULL && getBRIslandFactory() != NULL); 82022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 82122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isRelaxed = false; 82222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 82322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // check branch relocs and create the related stubs if needed 82422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::obj_iterator input, inEnd = pModule.obj_end(); 82522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (input = pModule.obj_begin(); input != inEnd; ++input) { 82622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 82722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 82822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 82922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 83022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 83122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 83222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Relocation* relocation = llvm::cast<Relocation>(reloc); 83322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 83422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (relocation->type()) { 835f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_ARM_PC24: 83622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_CALL: 83722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_JUMP24: 83822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_PLT32: 83922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_THM_CALL: 84022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_THM_XPC22: 84122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_THM_JUMP24: 84287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case llvm::ELF::R_ARM_THM_JUMP19: { 84322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // calculate the possible symbol value 84422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t sym_value = 0x0; 84522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = relocation->symInfo()->outSymbol(); 84622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbol->hasFragRef()) { 84722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t value = symbol->fragRef()->getOutputOffset(); 84822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t addr = 84937b74a387bb3993387029859c2d9d051c41c724eStephen Hines symbol->fragRef()->frag()->getParent()->getSection().addr(); 85022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sym_value = addr + value; 85122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 85237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if ((relocation->symInfo()->reserved() & 85337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ARMRelocator::ReservePLT) != 0x0) { 85437b74a387bb3993387029859c2d9d051c41c724eStephen Hines // FIXME: we need to find out the address of the specific plt 85537b74a387bb3993387029859c2d9d051c41c724eStephen Hines // entry 85622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(file_format->hasPLT()); 85722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sym_value = file_format->getPLT().addr(); 85822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 85937b74a387bb3993387029859c2d9d051c41c724eStephen Hines Stub* stub = getStubFactory()->create(*relocation, // relocation 86037b74a387bb3993387029859c2d9d051c41c724eStephen Hines sym_value, // symbol value 8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder, 86222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *getBRIslandFactory()); 86337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (stub != NULL) { 864b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(stub->symInfo() != NULL); 865b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // reset the branch target of the reloc to this stub instead 866b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines relocation->setSymInfo(stub->symInfo()); 867b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 86887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (config().options().getStripSymbolMode()) { 8692bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar case GeneralOptions::StripSymbolMode::StripAllSymbols: 8702bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar case GeneralOptions::StripSymbolMode::StripLocals: 87187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 87287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: { 87387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // a stub symbol should be local 87437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(stub->symInfo() != NULL && stub->symInfo()->isLocal()); 87587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& symtab = file_format->getSymTab(); 87687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& strtab = file_format->getStrTab(); 87787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 87887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // increase the size of .symtab and .strtab if needed 879b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 88087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab.setInfo(symtab.getInfo() + 1); 88137b74a387bb3993387029859c2d9d051c41c724eStephen Hines strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 88237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1); 88387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 88437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 88522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isRelaxed = true; 88622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 88722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 88822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 88987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case llvm::ELF::R_ARM_V4BX: 89087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /* FIXME: bypass R_ARM_V4BX relocation now */ 89187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 89222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 89322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 89437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 89537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for all relocations 89637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for all relocation section 89737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for all inputs 89822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 89922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // find the first fragment w/ invalid offset due to stub insertion 900b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines std::vector<Fragment*> invalid_frags; 90122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pFinished = true; 90222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 90337b74a387bb3993387029859c2d9d051c41c724eStephen Hines island_end = getBRIslandFactory()->end(); 90437b74a387bb3993387029859c2d9d051c41c724eStephen Hines island != island_end; 90537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++island) { 906b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((*island).size() > stubGroupSize()) { 907b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines error(diag::err_no_space_to_place_stubs) << stubGroupSize(); 908b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 909b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 910b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 911b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((*island).numOfStubs() == 0) { 912b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 913b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 914b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 915b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* exit = &*(*island).end(); 9162a0b905c72a5b9554c9eeb0bda6fbdea49bcddffPirama Arumuga Nainar if (exit == &*(*island).begin()->getParent()->end()) { 917b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 918b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 91922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 92022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (((*island).offset() + (*island).size()) > exit->getOffset()) { 921b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (invalid_frags.empty() || 922b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines (invalid_frags.back()->getParent() != (*island).getParent())) { 923b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid_frags.push_back(exit); 924b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pFinished = false; 925b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 926b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 92722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 92822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 92922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 93022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // reset the offset of invalid fragments 931b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie; 932b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++it) { 933b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* invalid = *it; 934b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines while (invalid != NULL) { 935b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid->setOffset(invalid->getPrevNode()->getOffset() + 936b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid->getPrevNode()->size()); 937b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid = invalid->getNextNode(); 938b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 93922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 94022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 941b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // reset the size of section that has stubs inserted. 94222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (isRelaxed) { 943b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData* prev = NULL; 944b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 945b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines island_end = getBRIslandFactory()->end(); 946b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines island != island_end; 947b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++island) { 948b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData* sd = (*island).begin()->getParent(); 949b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((*island).numOfStubs() != 0) { 950b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (sd != prev) { 951b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sd->getSection().setSize(sd->back().getOffset() + sd->back().size()); 952b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 953b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 954b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines prev = sd; 955b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 95622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 95722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return isRelaxed; 95822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 95922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 96022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initTargetStubs 96137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMGNULDBackend::initTargetStubs() { 96237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (getStubFactory() != NULL) { 9636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines getStubFactory()->addPrototype(new ARMToARMStub(config().isCodeIndep())); 9646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines getStubFactory()->addPrototype(new ARMToTHMStub(config().isCodeIndep())); 9650dea6bc96bb52346737966839ac68644f7939f58Stephen Hines getStubFactory()->addPrototype( 9660dea6bc96bb52346737966839ac68644f7939f58Stephen Hines new THMToTHMStub(config().isCodeIndep(), m_pAttrData->usingThumb2())); 9670dea6bc96bb52346737966839ac68644f7939f58Stephen Hines getStubFactory()->addPrototype( 9680dea6bc96bb52346737966839ac68644f7939f58Stephen Hines new THMToARMStub(config().isCodeIndep(), m_pAttrData->usingThumb2())); 96922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 97022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 97122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 97222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 97322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9740dea6bc96bb52346737966839ac68644f7939f58Stephen Hines/// maxFwdBranchOffset 975b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesint64_t ARMGNULDBackend::maxFwdBranchOffset() const { 9760dea6bc96bb52346737966839ac68644f7939f58Stephen Hines if (m_pAttrData->usingThumb2()) { 9770dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return THM2_MAX_FWD_BRANCH_OFFSET; 9780dea6bc96bb52346737966839ac68644f7939f58Stephen Hines } else { 9790dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return THM_MAX_FWD_BRANCH_OFFSET; 9800dea6bc96bb52346737966839ac68644f7939f58Stephen Hines } 9810dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 9820dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 9830dea6bc96bb52346737966839ac68644f7939f58Stephen Hines/// maxBwdBranchOffset 984b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesint64_t ARMGNULDBackend::maxBwdBranchOffset() const { 9850dea6bc96bb52346737966839ac68644f7939f58Stephen Hines if (m_pAttrData->usingThumb2()) { 9860dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return THM2_MAX_BWD_BRANCH_OFFSET; 9870dea6bc96bb52346737966839ac68644f7939f58Stephen Hines } else { 9880dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return THM_MAX_BWD_BRANCH_OFFSET; 9890dea6bc96bb52346737966839ac68644f7939f58Stephen Hines } 9900dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 9910dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 99222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the 99322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments 99437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGNULDBackend::doCreateProgramHdrs(Module& pModule) { 99537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pEXIDX != NULL && m_pEXIDX->size() != 0x0) { 99637b74a387bb3993387029859c2d9d051c41c724eStephen Hines // make PT_ARM_EXIDX 99737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFSegment* exidx_seg = 99837b74a387bb3993387029859c2d9d051c41c724eStephen Hines elfSegmentTable().produce(llvm::ELF::PT_ARM_EXIDX, llvm::ELF::PF_R); 99937b74a387bb3993387029859c2d9d051c41c724eStephen Hines exidx_seg->append(m_pEXIDX); 100037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 100122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 100222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10030dea6bc96bb52346737966839ac68644f7939f58Stephen Hines/// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe 10040dea6bc96bb52346737966839ac68644f7939f58Stephen Hines/// function pointer access 100537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMGNULDBackend::mayHaveUnsafeFunctionPointerAccess( 100637b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSection& pSection) const { 10070dea6bc96bb52346737966839ac68644f7939f58Stephen Hines llvm::StringRef name(pSection.name()); 100837b74a387bb3993387029859c2d9d051c41c724eStephen Hines return !name.startswith(".ARM.exidx") && !name.startswith(".ARM.extab") && 10090dea6bc96bb52346737966839ac68644f7939f58Stephen Hines GNULDBackend::mayHaveUnsafeFunctionPointerAccess(pSection); 10100dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 10110dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 10135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createARMLDBackend - the help funtion to create corresponding ARMLDBackend 10145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 101537b74a387bb3993387029859c2d9d051c41c724eStephen HinesTargetLDBackend* createARMLDBackend(const LinkerConfig& pConfig) { 1016d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSDarwin()) { 10175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 10195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new ARMMachOLDBackend(createARMMachOArchiveReader, 10205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createARMMachOObjectReader, 10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createARMMachOObjectWriter); 10225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 10235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1024d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSWindows()) { 10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 10265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 10275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new ARMCOFFLDBackend(createARMCOFFArchiveReader, 10285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createARMCOFFObjectReader, 10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createARMCOFFObjectWriter); 10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 10315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 103237b74a387bb3993387029859c2d9d051c41c724eStephen Hines return new ARMGNULDBackend(pConfig, 103337b74a387bb3993387029859c2d9d051c41c724eStephen Hines new ARMGNUInfo(pConfig.targets().triple())); 10345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 103637b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 10375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 103822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 10395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 104022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 104122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeARMLDBackend() { 10425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 104337b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheARMTarget, 104437b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::createARMLDBackend); 104537b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheThumbTarget, 104637b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::createARMLDBackend); 10475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1048