1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===- ARMLDBackend.cpp ---------------------------------------------------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The MCLinker Project 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ARM.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ARMGNUInfo.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ARMELFAttributeData.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ARMELFDynamic.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ARMLDBackend.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ARMRelocator.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ARMToARMStub.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ARMToTHMStub.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "THMToTHMStub.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "THMToARMStub.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/IRBuilder.h> 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <mcld/LinkerConfig.h> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/Fragment/FillFragment.h> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/Fragment/AlignFragment.h> 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <mcld/Fragment/RegionFragment.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/Fragment/Stub.h> 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <mcld/Fragment/NullFragment.h> 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <mcld/Support/MemoryRegion.h> 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <mcld/Support/MemoryArea.h> 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <mcld/Support/MsgHandling.h> 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <mcld/Support/TargetRegistry.h> 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <mcld/LD/BranchIslandFactory.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/LD/StubFactory.h> 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/LD/LDContext.h> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/LD/ELFFileFormat.h> 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/LD/ELFSegmentFactory.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/LD/ELFSegment.h> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/Target/ELFAttribute.h> 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <mcld/Target/GNUInfo.h> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mcld/Object/ObjectBuilder.h> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <llvm/ADT/StringRef.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <llvm/ADT/Triple.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <llvm/ADT/Twine.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <llvm/Support/ELF.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <llvm/Support/Casting.h> 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstring> 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using namespace mcld; 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//===----------------------------------------------------------------------===// 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// ARMGNULDBackend 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//===----------------------------------------------------------------------===// 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)ARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo) 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : GNULDBackend(pConfig, pInfo), 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pRelocator(NULL), 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pGOT(NULL), 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pPLT(NULL), 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_pRelDyn(NULL), 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_pRelPLT(NULL), 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_pAttrData(NULL), 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_pDynamic(NULL), 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_pGOTSymbol(NULL), 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_pEXIDXStart(NULL), 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pEXIDXEnd(NULL), 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pEXIDX(NULL), 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch m_pEXTAB(NULL), 68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch m_pAttributes(NULL) { 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)ARMGNULDBackend::~ARMGNULDBackend() 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete m_pRelocator; 74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch delete m_pGOT; 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete m_pPLT; 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete m_pRelDyn; 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete m_pRelPLT; 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete m_pDynamic; 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete m_pAttrData; 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ARMGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder) 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // FIXME: Currently we set exidx and extab to "Exception" and directly emit 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // them from input 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pEXIDX = pBuilder.CreateSection(".ARM.exidx", 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDFileFormat::Target, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::ELF::SHT_ARM_EXIDX, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config().targets().bitclass() / 8); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pEXTAB = pBuilder.CreateSection(".ARM.extab", 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDFileFormat::Target, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::ELF::SHT_PROGBITS, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::ELF::SHF_ALLOC, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x1); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pAttributes = pBuilder.CreateSection(".ARM.attributes", 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDFileFormat::Target, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::ELF::SHT_ARM_ATTRIBUTES, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x1); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize "aeabi" attributes subsection 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pAttrData = new ARMELFAttributeData(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attribute().registerAttributeData(*m_pAttrData); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LinkerConfig::Object != config().codeGenType()) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ELFFileFormat* file_format = getOutputFormat(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize .got 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDSection& got = file_format->getGOT(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pGOT = new ARMGOT(got); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize .plt 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDSection& plt = file_format->getPLT(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pPLT = new ARMPLT(plt, *m_pGOT); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize .rel.plt 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDSection& relplt = file_format->getRelPlt(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) relplt.setLink(&plt); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // create SectionData and ARMRelDynSection 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pRelPLT = new OutputRelocSection(pModule, relplt); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize .rel.dyn 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDSection& reldyn = file_format->getRelDyn(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pRelDyn = new OutputRelocSection(pModule, reldyn); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ARMGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // same name in input 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LinkerConfig::Object != config().codeGenType()) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "_GLOBAL_OFFSET_TABLE_", 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Object, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Define, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Local, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // size 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // value 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FragmentRef::Null(), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Hidden); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FragmentRef* exidx_start = 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 0x0); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FragmentRef* exidx_end = 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pEXIDX->size()); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pEXIDXStart = 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "__exidx_start", 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Object, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Define, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Local, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // size 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // value 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exidx_start, // FragRef 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Default); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pEXIDXEnd = 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "__exidx_end", 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Object, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Define, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Local, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // size 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // value 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exidx_end, // FragRef 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Default); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change __exidx_start/_end to local dynamic category 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != m_pEXIDXStart) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pModule.getSymbolTable().changeToDynamic(*m_pEXIDXStart); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != m_pEXIDXEnd) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pModule.getSymbolTable().changeToDynamic(*m_pEXIDXEnd); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pEXIDXStart = 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "__exidx_start", 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::NoType, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Define, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Absolute, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // size 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // value 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FragmentRef::Null(), 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Default); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pEXIDXEnd = 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "__exidx_end", 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::NoType, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Define, 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResolveInfo::Absolute, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // size 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0x0, // value 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FragmentRef::Null(), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo::Default); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ARMGNULDBackend::initRelocator() 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (NULL == m_pRelocator) { 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pRelocator = new ARMRelocator(*this, config()); 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const Relocator* ARMGNULDBackend::getRelocator() const 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) assert(NULL != m_pRelocator); 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return m_pRelocator; 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Relocator* ARMGNULDBackend::getRelocator() 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) assert(NULL != m_pRelocator); 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return m_pRelocator; 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ARMGNULDBackend::doPreLayout(IRBuilder& pBuilder) 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize .dynamic data 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!config().isCodeStatic() && NULL == m_pDynamic) 22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pDynamic = new ARMELFDynamic(*this, config()); 22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // set attribute section size 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_pAttributes->setSize(attribute().sizeOutput()); 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // set .got size 231e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // when building shared object, the .got section is must 232e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (LinkerConfig::Object != config().codeGenType()) { 233e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (LinkerConfig::DynObj == config().codeGenType() || 234e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch m_pGOT->hasGOT1() || 235e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch NULL != m_pGOTSymbol) { 236e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch m_pGOT->finalizeSectionSize(); 237e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch defineGOTSymbol(pBuilder); 238e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // set .plt size 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (m_pPLT->hasPLT1()) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) m_pPLT->finalizeSectionSize(); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ELFFileFormat* file_format = getOutputFormat(); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // set .rel.dyn size 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!m_pRelDyn->empty()) { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(!config().isCodeStatic() && 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "static linkage should not result in a dynamic relocation section"); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_format->getRelDyn().setSize( 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pRelDyn->numOfRelocs() * getRelEntrySize()); 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // set .rel.plt size 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!m_pRelPLT->empty()) { 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) assert(!config().isCodeStatic() && 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "static linkage should not result in a dynamic relocation section"); 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) file_format->getRelPlt().setSize( 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pRelPLT->numOfRelocs() * getRelEntrySize()); 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ARMGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ELFFileFormat *file_format = getOutputFormat(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // apply PLT 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (file_format->hasPLT()) { 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Since we already have the size of LDSection PLT, m_pPLT should not be 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NULL. 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) assert(NULL != m_pPLT); 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pPLT->applyPLT0(); 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m_pPLT->applyPLT1(); 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // apply GOT 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (file_format->hasGOT()) { 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Since we already have the size of GOT, m_pGOT should not be NULL. 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) assert(NULL != m_pGOT); 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (LinkerConfig::DynObj == config().codeGenType()) 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m_pGOT->applyGOT0(file_format->getDynamic().addr()); 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else { 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // executable file and object file? should fill with zero. 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m_pGOT->applyGOT0(0); 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/// dynamic - the dynamic section of the target machine. 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/// Use co-variant return type to return its own dynamic section. 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)ARMELFDynamic& ARMGNULDBackend::dynamic() 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) assert(NULL != m_pDynamic); 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return *m_pDynamic; 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// dynamic - the dynamic section of the target machine. 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// Use co-variant return type to return its own dynamic section. 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const ARMELFDynamic& ARMGNULDBackend::dynamic() const 30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pDynamic); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pDynamic; 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ARMGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (m_pGOTSymbol != NULL) { 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "_GLOBAL_OFFSET_TABLE_", 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResolveInfo::Object, 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ResolveInfo::Define, 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResolveInfo::Local, 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 0x0, // size 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0x0, // value 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FragmentRef::Create(*(m_pGOT->begin()), 0x0), 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResolveInfo::Hidden); 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else { 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "_GLOBAL_OFFSET_TABLE_", 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResolveInfo::Object, 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ResolveInfo::Define, 32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ResolveInfo::Local, 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 0x0, // size 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0, // value 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FragmentRef::Create(*(m_pGOT->begin()), 0x0), 32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ResolveInfo::Hidden); 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)uint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection, 33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MemoryRegion& pRegion) const 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(pRegion.size() && "Size of MemoryRegion is zero!"); 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ELFFileFormat* file_format = getOutputFormat(); 33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint64_t result = m_pPLT->emit(pRegion); 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return result; 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { 34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint64_t result = m_pGOT->emit(pRegion); 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return result; 34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (&pSection == m_pAttributes) { 35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return attribute().emit(pRegion); 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // directly from the input file. 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SectionData* sect_data = pSection.getSectionData(); 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint8_t* out_offset = pRegion.begin(); 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t size = frag_iter->size(); 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch(frag_iter->getKind()) { 36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case Fragment::Fillment: { 36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const FillFragment& fill_frag = 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) llvm::cast<FillFragment>(*frag_iter); 36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (0 == fill_frag.getValueSize()) { 36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // virtual fillment, ignore it. 36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) memset(out_offset, fill_frag.getValue(), fill_frag.size()); 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case Fragment::Region: { 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const RegionFragment& region_frag = 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) llvm::cast<RegionFragment>(*frag_iter); 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char* start = region_frag.getRegion().begin(); 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) memcpy(out_offset, start, size); 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case Fragment::Alignment: { 38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); 38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint64_t count = size / align_frag.getValueSize(); 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (align_frag.getValueSize()) { 38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case 1u: 38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::memset(out_offset, align_frag.getValue(), count); 38690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 38790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) llvm::report_fatal_error( 38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "unsupported value size for align fragment emission yet.\n"); 39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } // end switch 39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case Fragment::Null: { 39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) assert(0x0 == size); 39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::report_fatal_error("unsupported fragment type.\n"); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } // end switch 40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) out_offset += size; 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } // end for 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return pRegion.size(); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// finalizeSymbol - finalize the symbol value 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool ARMGNULDBackend::finalizeTargetSymbols() 40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ARMGNULDBackend::mergeSection(Module& pModule, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Input& pInput, 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDSection& pSection) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (pSection.type()) { 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case llvm::ELF::SHT_ARM_ATTRIBUTES: { 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return attribute().merge(pInput, pSection); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case llvm::ELF::SHT_ARM_EXIDX: { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != pSection.getLink()); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LDFileFormat::Ignore == pSection.getLink()->kind()) { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the target section of the .ARM.exidx is Ignore, then it should be 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ignored as well 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pSection.setKind(LDFileFormat::Ignore); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** fall through **/ 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObjectBuilder builder(pModule); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) builder.MergeSection(pInput, pSection); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } // end of switch 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ARMGNULDBackend::setUpReachedSectionsForGC(const Module& pModule, 44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GarbageCollection::SectionReachedListMap& pSectReachedListMap) const 44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // traverse all the input relocations to find the relocation sections applying 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // .ARM.exidx sections 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Module::const_obj_iterator input, inEnd = pModule.obj_end(); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (input = pModule.obj_begin(); input != inEnd; ++input) { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDContext::const_sect_iterator rs, 44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) rsEnd = (*input)->context()->relocSectEnd(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bypass the discarded relocation section 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1. its section kind is changed to Ignore. (The target section is a 45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // discarded group section.) 45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 2. it has no reloc data. (All symbols in the input relocs are in the 45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // discarded group sections) 45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LDSection* reloc_sect = *rs; 45690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LDSection* apply_sect = reloc_sect->getLink(); 45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if ((LDFileFormat::Ignore == reloc_sect->kind()) || 45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (!reloc_sect->hasRelocData())) 45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (llvm::ELF::SHT_ARM_EXIDX == apply_sect->type()) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1. set up the reference according to relocations 46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool add_first = false; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GarbageCollection::SectionListTy* reached_sects = NULL; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RelocData::iterator reloc_it, rEnd = reloc_sect->getRelocData()->end(); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (reloc_it = reloc_sect->getRelocData()->begin(); reloc_it != rEnd; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++reloc_it) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Relocation* reloc = llvm::cast<Relocation>(reloc_it); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveInfo* sym = reloc->symInfo(); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only the target symbols defined in the input fragments can make the 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == sym) 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sym->isDefine() || !sym->outSymbol()->hasFragRef()) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only the target symbols defined in the concerned sections can make 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the reference 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LDSection* target_sect = 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &sym->outSymbol()->fragRef()->frag()->getParent()->getSection(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_sect->kind() != LDFileFormat::TEXT && 48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) target_sect->kind() != LDFileFormat::DATA && 48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) target_sect->kind() != LDFileFormat::BSS) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // setup the reached list, if we first add the element to reached list 48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // of this section, create an entry in ReachedSections map 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!add_first) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reached_sects = &pSectReachedListMap.getReachedList(*apply_sect); 49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) add_first = true; 49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reached_sects->insert(target_sect); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reached_sects = NULL; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_first = false; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2. set up the reference from XXX to .ARM.exidx.XXX 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(apply_sect->getLink() != NULL); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pSectReachedListMap.addReference(*apply_sect->getLink(), *apply_sect); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fragment* frag = NULL; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t size = pSD.getSection().size(); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::StringRef region = pInput.memArea()->request(offset, size); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (region.size() == 0) { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the input section's size is zero, we got a NULL region. 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use a virtual fill fragment 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frag = new FillFragment(0x0, 0, 0); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frag = new RegionFragment(region); 5181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObjectBuilder::AppendFragment(*frag, pSD); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ARMGOT& ARMGNULDBackend::getGOT() 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pGOT && "GOT section not exist"); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pGOT; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ARMGOT& ARMGNULDBackend::getGOT() const 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pGOT && "GOT section not exist"); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pGOT; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ARMPLT& ARMGNULDBackend::getPLT() 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pPLT && "PLT section not exist"); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pPLT; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ARMPLT& ARMGNULDBackend::getPLT() const 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pPLT && "PLT section not exist"); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pPLT; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OutputRelocSection& ARMGNULDBackend::getRelDyn() 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pRelDyn; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const OutputRelocSection& ARMGNULDBackend::getRelDyn() const 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pRelDyn; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OutputRelocSection& ARMGNULDBackend::getRelPLT() 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pRelPLT; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const OutputRelocSection& ARMGNULDBackend::getRelPLT() const 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pRelPLT; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ARMELFAttributeData& ARMGNULDBackend::getAttributeData() 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pAttrData && ".ARM.attributes section not exist"); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pAttrData; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ARMELFAttributeData& ARMGNULDBackend::getAttributeData() const 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != m_pAttrData && ".ARM.attributes section not exist"); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *m_pAttrData; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned int 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ARMGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ELFFileFormat* file_format = getOutputFormat(); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (config().options().hasNow()) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SHO_RELRO_LAST; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SHO_DATA; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SHO_PLT; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (&pSectHdr == m_pEXIDX || &pSectHdr == m_pEXTAB) { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // put ARM.exidx and ARM.extab in the same order of .eh_frame 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SHO_EXCEPTION; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SHO_UNDEFINED; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// doRelax 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ARMGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool isRelaxed = false; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ELFFileFormat* file_format = getOutputFormat(); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check branch relocs and create the related stubs if needed 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Module::obj_iterator input, inEnd = pModule.obj_end(); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (input = pModule.obj_begin(); input != inEnd; ++input) { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Relocation* relocation = llvm::cast<Relocation>(reloc); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (relocation->type()) { 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case llvm::ELF::R_ARM_PC24: 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case llvm::ELF::R_ARM_CALL: 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case llvm::ELF::R_ARM_JUMP24: 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case llvm::ELF::R_ARM_PLT32: 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case llvm::ELF::R_ARM_THM_CALL: 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case llvm::ELF::R_ARM_THM_XPC22: 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case llvm::ELF::R_ARM_THM_JUMP24: 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case llvm::ELF::R_ARM_THM_JUMP19: { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // calculate the possible symbol value 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t sym_value = 0x0; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDSymbol* symbol = relocation->symInfo()->outSymbol(); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbol->hasFragRef()) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t value = symbol->fragRef()->getOutputOffset(); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t addr = 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbol->fragRef()->frag()->getParent()->getSection().addr(); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sym_value = addr + value; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (relocation->symInfo()->isGlobal() && 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (relocation->symInfo()->reserved() & ARMRelocator::ReservePLT) != 0x0) { 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: we need to find out the address of the specific plt entry 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(file_format->hasPLT()); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sym_value = file_format->getPLT().addr(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stub* stub = getStubFactory()->create(*relocation, // relocation 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sym_value, // symbol value 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pBuilder, 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *getBRIslandFactory()); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != stub) { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (config().options().getStripSymbolMode()) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GeneralOptions::StripAllSymbols: 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GeneralOptions::StripLocals: 6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 65990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a stub symbol should be local 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(NULL != stub->symInfo() && stub->symInfo()->isLocal()); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDSection& symtab = file_format->getSymTab(); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LDSection& strtab = file_format->getStrTab(); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // increase the size of .symtab and .strtab if needed 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (config().targets().is32Bits()) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf64_Sym)); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symtab.setInfo(symtab.getInfo() + 1); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } // end of switch 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isRelaxed = true; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case llvm::ELF::R_ARM_V4BX: 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* FIXME: bypass R_ARM_V4BX relocation now */ 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } // end of switch 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } // for all relocations 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } // for all relocation section 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } // for all inputs 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // find the first fragment w/ invalid offset due to stub insertion 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fragment* invalid = NULL; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pFinished = true; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) island_end = getBRIslandFactory()->end(); island != island_end; ++island) { 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*island).end() == file_format->getText().getSectionData()->end()) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fragment* exit = (*island).end(); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((*island).offset() + (*island).size()) > exit->getOffset()) { 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid = exit; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pFinished = false; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reset the offset of invalid fragments 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (NULL != invalid) { 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid->setOffset(invalid->getPrevNode()->getOffset() + 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid->getPrevNode()->size()); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid = invalid->getNextNode(); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reset the size of .text 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isRelaxed) { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_format->getText().setSize( 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_format->getText().getSectionData()->back().getOffset() + 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_format->getText().getSectionData()->back().size()); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return isRelaxed; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// initTargetStubs 722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ARMGNULDBackend::initTargetStubs() 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != getStubFactory()) { 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getStubFactory()->addPrototype(new ARMToARMStub(config().isCodeIndep())); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getStubFactory()->addPrototype(new ARMToTHMStub(config().isCodeIndep())); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getStubFactory()->addPrototype( 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new THMToTHMStub(config().isCodeIndep(), m_pAttrData->usingThumb2())); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getStubFactory()->addPrototype( 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new THMToARMStub(config().isCodeIndep(), m_pAttrData->usingThumb2())); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// maxFwdBranchOffset 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64_t ARMGNULDBackend::maxFwdBranchOffset() 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m_pAttrData->usingThumb2()) { 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return THM2_MAX_FWD_BRANCH_OFFSET; 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return THM_MAX_FWD_BRANCH_OFFSET; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// maxBwdBranchOffset 747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64_t ARMGNULDBackend::maxBwdBranchOffset() 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m_pAttrData->usingThumb2()) { 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return THM2_MAX_BWD_BRANCH_OFFSET; 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return THM_MAX_BWD_BRANCH_OFFSET; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// doCreateProgramHdrs - backend can implement this function to create the 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// target-dependent segments 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ARMGNULDBackend::doCreateProgramHdrs(Module& pModule) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) { 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make PT_ARM_EXIDX 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ELFSegment* exidx_seg = elfSegmentTable().produce(llvm::ELF::PT_ARM_EXIDX, 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::ELF::PF_R); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exidx_seg->append(m_pEXIDX); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// function pointer access 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ARMGNULDBackend::mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const 7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) llvm::StringRef name(pSection.name()); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !name.startswith(".ARM.exidx") && 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !name.startswith(".ARM.extab") && 777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GNULDBackend::mayHaveUnsafeFunctionPointerAccess(pSection); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace mcld { 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// createARMLDBackend - the help funtion to create corresponding ARMLDBackend 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TargetLDBackend* createARMLDBackend(const LinkerConfig& pConfig) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pConfig.targets().triple().isOSDarwin()) { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(0 && "MachO linker is not supported yet"); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ARMMachOLDBackend(createARMMachOArchiveReader, 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) createARMMachOObjectReader, 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) createARMMachOObjectWriter); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) **/ 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pConfig.targets().triple().isOSWindows()) { 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(0 && "COFF linker is not supported yet"); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ARMCOFFLDBackend(createARMCOFFArchiveReader, 8001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci createARMCOFFObjectReader, 8011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci createARMCOFFObjectWriter); 8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci **/ 8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return new ARMGNULDBackend(pConfig, new ARMGNUInfo(pConfig.targets().triple())); 8051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 8061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace of mcld 8081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===----------------------------------------------------------------------===// 8101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Force static initialization. 8111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===----------------------------------------------------------------------===// 8121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciextern "C" void MCLDInitializeARMLDBackend() { 8131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Register the linker backend 8141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mcld::TargetRegistry::RegisterTargetLDBackend(TheARMTarget, createARMLDBackend); 8151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mcld::TargetRegistry::RegisterTargetLDBackend(TheThumbTarget, createARMLDBackend); 8161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 8171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci