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" 11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "ARMELFDynamic.h" 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "ARMLDBackend.h" 13d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "ARMRelocator.h" 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "ARMToARMStub.h" 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "ARMToTHMStub.h" 1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "THMToTHMStub.h" 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include "THMToARMStub.h" 18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 19cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstring> 20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Twine.h> 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h> 24cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h> 2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/AlignFragment.h> 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/RegionFragment.h> 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h> 33affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h> 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/Stub.h> 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/BranchIslandFactory.h> 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/StubFactory.h> 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/NullFragment.h> 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h> 41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Target/GNUInfo.h> 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 45cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 46cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// ARMGNULDBackend 47cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 48d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo) 49d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao : GNULDBackend(pConfig, pInfo), 50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelocator(NULL), 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT(NULL), 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT(NULL), 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic(NULL), 5667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao m_pGOTSymbol(NULL), 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pEXIDXStart(NULL), 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pEXIDXEnd(NULL), 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pEXIDX(NULL), 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pEXTAB(NULL), 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pAttributes(NULL) { 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGNULDBackend::~ARMGNULDBackend() 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 66d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pRelocator; 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pGOT; 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pPLT; 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelDyn; 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelPLT; 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynamic; 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid ARMGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder) 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: Currently we set exidx and extab to "Exception" and directly emit 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // them from input 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pEXIDX = pBuilder.CreateSection(".ARM.exidx", 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDFileFormat::Target, 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::SHT_ARM_EXIDX, 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER, 82d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass() / 8); 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pEXTAB = pBuilder.CreateSection(".ARM.extab", 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDFileFormat::Target, 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::SHT_PROGBITS, 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::SHF_ALLOC, 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x1); 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pAttributes = pBuilder.CreateSection(".ARM.attributes", 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDFileFormat::Target, 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::SHT_ARM_ATTRIBUTES, 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x1); 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& got = file_format->getGOT(); 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT = new ARMGOT(got); 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .plt 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& plt = file_format->getPLT(); 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pPLT = new ARMPLT(plt, *m_pGOT); 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .rel.plt 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& relplt = file_format->getRelPlt(); 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relplt.setLink(&plt); 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create SectionData and ARMRelDynSection 109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelPLT = new OutputRelocSection(pModule, relplt); 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .rel.dyn 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn = new OutputRelocSection(pModule, reldyn); 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 121f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 122f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_GLOBAL_OFFSET_TABLE_", 1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Object, 1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Define, 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Local, 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Null(), 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Hidden); 131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) { 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef* exidx_start = 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 0x0); 1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef* exidx_end = 1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pEXIDX->size()); 1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pEXIDXStart = 1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__exidx_start", 1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Object, 1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Define, 1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Local, 1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // size 1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // value 1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines exidx_start, // FragRef 1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Default); 1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pEXIDXEnd = 1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__exidx_end", 1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Object, 1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Define, 1546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Local, 1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // size 1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // value 1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines exidx_end, // FragRef 1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Default); 1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // change __exidx_start/_end to local dynamic category 1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL != m_pEXIDXStart) 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*m_pEXIDXStart); 1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL != m_pEXIDXEnd) 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*m_pEXIDXEnd); 1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pEXIDXStart = 1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__exidx_start", 1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::NoType, 1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Define, 1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Absolute, 1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // size 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // value 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Null(), 1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Default); 1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pEXIDXEnd = 1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__exidx_end", 1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::NoType, 1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Define, 1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Absolute, 1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // size 1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // value 1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Null(), 1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Default); 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ARMGNULDBackend::initRelocator() 190d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (NULL == m_pRelocator) { 192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new ARMRelocator(*this, config()); 193d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 194d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return true; 195d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 196d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 197d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocator* ARMGNULDBackend::getRelocator() 198d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 199d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao assert(NULL != m_pRelocator); 200d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return m_pRelocator; 201d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 202d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::doPreLayout(IRBuilder& pBuilder) 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .dynamic data 2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().isCodeStatic() && NULL == m_pDynamic) 2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynamic = new ARMELFDynamic(*this, config()); 2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .got size 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // when building shared object, the .got section is must 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->hasGOT1() || 21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao NULL != m_pGOTSymbol) { 21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->finalizeSectionSize(); 2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder); 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .plt size 22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_pPLT->hasPLT1()) 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pPLT->finalizeSectionSize(); 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 223d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .rel.dyn size 2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelDyn->empty()) { 2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(!config().isCodeStatic() && 2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "static linkage should not result in a dynamic relocation section"); 228d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao file_format->getRelDyn().setSize( 229d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn->numOfRelocs() * getRelEntrySize()); 2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .rel.plt size 2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelPLT->empty()) { 2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(!config().isCodeStatic() && 2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "static linkage should not result in a dynamic relocation section"); 236d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao file_format->getRelPlt().setSize( 237d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelPLT->numOfRelocs() * getRelEntrySize()); 2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat *file_format = getOutputFormat(); 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // apply PLT 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (file_format->hasPLT()) { 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Since we already have the size of LDSection PLT, m_pPLT should not be 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // NULL. 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT); 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT0(); 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT1(); 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // apply GOT 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (file_format->hasGOT()) { 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Since we already have the size of GOT, m_pGOT should not be NULL. 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->applyGOT0(file_format->getDynamic().addr()); 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // executable file and object file? should fill with zero. 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->applyGOT0(0); 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMELFDynamic& ARMGNULDBackend::dynamic() 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst ARMELFDynamic& ARMGNULDBackend::dynamic() const 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) 2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pGOTSymbol != NULL) { 2886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Create(*(m_pGOT->begin()), 0x0), 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 2996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Create(*(m_pGOT->begin()), 0x0), 3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection, 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSection == m_pAttributes || 320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSection == m_pEXIDX || 321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSection == m_pEXTAB) { 322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab 323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // directly from the input file. 324cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const SectionData* sect_data = pSection.getSectionData(); 325cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint8_t* out_offset = pRegion.start(); 327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t size = frag_iter->size(); 329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang switch(frag_iter->getKind()) { 33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case Fragment::Fillment: { 33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const FillFragment& fill_frag = 33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::cast<FillFragment>(*frag_iter); 33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == fill_frag.getValueSize()) { 33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // virtual fillment, ignore it. 33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao memset(out_offset, fill_frag.getValue(), fill_frag.size()); 33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 341cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Region: { 342cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const RegionFragment& region_frag = 343cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao llvm::cast<RegionFragment>(*frag_iter); 344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const uint8_t* start = region_frag.getRegion().start(); 345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang memcpy(out_offset, start, size); 346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 347affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 348cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Alignment: { 3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); 350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t count = size / align_frag.getValueSize(); 351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang switch (align_frag.getValueSize()) { 352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case 1u: 353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang std::memset(out_offset, align_frag.getValue(), count); 354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::report_fatal_error( 357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "unsupported value size for align fragment emission yet.\n"); 358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } // end switch 360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case Fragment::Null: { 36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(0x0 == size); 36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::report_fatal_error("unsupported fragment type.\n"); 368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } // end switch 370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang out_offset += size; 371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } // end for 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pRegion.size(); 373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } // end if 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(file_format->getPLT())) { 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = m_pPLT->emit(pRegion); 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(file_format->getGOT())) { 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = m_pGOT->emit(pRegion); 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unrecognized_output_sectoin) 387affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pSection.name() 388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ARMGNULDBackend::finalizeTargetSymbols() 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ARMGNULDBackend::mergeSection(Module& pModule, LDSection& pSection) 39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (pSection.type()) { 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::SHT_ARM_ATTRIBUTES: { 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: (Luba) 40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Handle ARM attributes in the right way. 4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // In current milestone, we goes through the shortcut. 40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // It reads input's ARM attributes and copies the first ARM attributes 40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // into the output file. The correct way is merge these sections, not 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // just copy. 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 != m_pAttributes->size()) 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // First time we meet a ARM attributes section. 41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* sd = IRBuilder::CreateSectionData(*m_pAttributes); 41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ObjectBuilder::MoveSectionData(*pSection.getSectionData(), *sd); 41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: { 41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ObjectBuilder builder(config(), pModule); 41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return builder.MergeSection(pSection); 41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of switch 42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD) 42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 426cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = NULL; 42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t size = pSD.getSection().size(); 42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* region = pInput.memArea()->request(offset, size); 431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == region) { 432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // If the input section's size is zero, we got a NULL region. 433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // use a virtual fill fragment 434cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag = new FillFragment(0x0, 0, 0); 435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 437cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag = new RegionFragment(*region); 43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ObjectBuilder::AppendFragment(*frag, pSD); 4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT& ARMGNULDBackend::getGOT() 4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT && "GOT section not exist"); 4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst ARMGOT& ARMGNULDBackend::getGOT() const 4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT && "GOT section not exist"); 4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMPLT& ARMGNULDBackend::getPLT() 4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst ARMPLT& ARMGNULDBackend::getPLT() const 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& ARMGNULDBackend::getRelDyn() 4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& ARMGNULDBackend::getRelDyn() const 4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& ARMGNULDBackend::getRelPLT() 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& ARMGNULDBackend::getRelPLT() const 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoARMGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 49522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSectHdr == &file_format->getGOT()) { 49822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasNow()) 499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO_LAST; 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getPLT()) 5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_PLT; 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSectHdr == m_pEXIDX || &pSectHdr == m_pEXTAB) { 507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // put ARM.exidx and ARM.extab in the same order of .eh_frame 508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_EXCEPTION; 509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doRelax 5156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool 5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesARMGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) 51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); 51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isRelaxed = false; 52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // check branch relocs and create the related stubs if needed 52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::obj_iterator input, inEnd = pModule.obj_end(); 52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (input = pModule.obj_begin(); input != inEnd; ++input) { 52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Relocation* relocation = llvm::cast<Relocation>(reloc); 53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (relocation->type()) { 534f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_ARM_PC24: 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_CALL: 53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_JUMP24: 53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_PLT32: 53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_THM_CALL: 53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_THM_XPC22: 54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_THM_JUMP24: 54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_THM_JUMP19: 54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_ARM_V4BX: { 54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // calculate the possible symbol value 54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t sym_value = 0x0; 54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = relocation->symInfo()->outSymbol(); 54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbol->hasFragRef()) { 54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t value = symbol->fragRef()->getOutputOffset(); 54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t addr = 54922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symbol->fragRef()->frag()->getParent()->getSection().addr(); 55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sym_value = addr + value; 55122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (relocation->symInfo()->isGlobal() && 553f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (relocation->symInfo()->reserved() & ARMRelocator::ReservePLT) != 0x0) { 55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: we need to find out the address of the specific plt entry 55522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(file_format->hasPLT()); 55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sym_value = file_format->getPLT().addr(); 55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Stub* stub = getStubFactory()->create(*relocation, // relocation 56022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sym_value, // symbol value 5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder, 56222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *getBRIslandFactory()); 56322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != stub) { 5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // a stub symbol should be local 5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != stub->symInfo() && stub->symInfo()->isLocal()); 56622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& symtab = file_format->getSymTab(); 56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& strtab = file_format->getStrTab(); 5686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // increase the size of .symtab and .strtab if needed 570d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 57122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 57222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 57322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf64_Sym)); 5746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symtab.setInfo(symtab.getInfo() + 1); 57522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 57622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 57722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isRelaxed = true; 57822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 57922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 58022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 58122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 58222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 58322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of switch 58422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 58522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all relocations 58622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all relocation section 58722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all inputs 58822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 58922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // find the first fragment w/ invalid offset due to stub insertion 59022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Fragment* invalid = NULL; 59122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pFinished = true; 59222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 59322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao island_end = getBRIslandFactory()->end(); island != island_end; ++island) { 59422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*island).end() == file_format->getText().getSectionData()->end()) 59522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 59622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 59722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Fragment* exit = (*island).end(); 59822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (((*island).offset() + (*island).size()) > exit->getOffset()) { 59922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao invalid = exit; 60022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pFinished = false; 60122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 60222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 60322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 60422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 60522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // reset the offset of invalid fragments 60622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao while (NULL != invalid) { 60722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao invalid->setOffset(invalid->getPrevNode()->getOffset() + 60822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao invalid->getPrevNode()->size()); 60922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao invalid = invalid->getNextNode(); 61022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 61122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 61222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // reset the size of .text 61322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (isRelaxed) { 61422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getText().setSize( 61522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getText().getSectionData()->back().getOffset() + 61622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getText().getSectionData()->back().size()); 61722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 61822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return isRelaxed; 61922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 62022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 62122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initTargetStubs 6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ARMGNULDBackend::initTargetStubs() 62322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 62422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != getStubFactory()) { 6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines getStubFactory()->addPrototype(new ARMToARMStub(config().isCodeIndep())); 6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines getStubFactory()->addPrototype(new ARMToTHMStub(config().isCodeIndep())); 6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines getStubFactory()->addPrototype(new THMToTHMStub(config().isCodeIndep())); 6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines getStubFactory()->addPrototype(new THMToARMStub(config().isCodeIndep())); 62922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 63022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 63122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 63222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 63322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 63422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the 63522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments 6366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ARMGNULDBackend::doCreateProgramHdrs(Module& pModule) 63722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 63822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) { 63922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // make PT_ARM_EXIDX 64086036a3bd999904d071826b2f0a84023e28aeebcShih-wei Liao ELFSegment* exidx_seg = elfSegmentTable().produce(llvm::ELF::PT_ARM_EXIDX, 64122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::PF_R); 64222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao exidx_seg->addSection(m_pEXIDX); 64322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 64422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 64522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createARMLDBackend - the help funtion to create corresponding ARMLDBackend 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createARMLDBackend(const llvm::Target& pTarget, 65222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LinkerConfig& pConfig) 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 654d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSDarwin()) { 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new ARMMachOLDBackend(createARMMachOArchiveReader, 6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createARMMachOObjectReader, 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createARMMachOObjectWriter); 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 662d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSWindows()) { 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new ARMCOFFLDBackend(createARMCOFFArchiveReader, 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createARMCOFFObjectReader, 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createARMCOFFObjectWriter); 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 670d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ARMGNULDBackend(pConfig, new ARMGNUInfo(pConfig.targets().triple())); 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 67522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 67722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 67822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeARMLDBackend() { 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(TheARMTarget, createARMLDBackend); 681affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::TargetRegistry::RegisterTargetLDBackend(TheThumbTarget, createARMLDBackend); 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 684