1551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===- AArch64LDBackend.cpp -----------------------------------------------===// 2551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// 3551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// The MCLinker Project 4551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// 5551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// This file is distributed under the University of Illinois Open Source 6551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// License. See LICENSE.TXT for details. 7551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// 8551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===// 9551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include "AArch64.h" 10b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "AArch64CA53Erratum835769Stub.h" 11b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "AArch64CA53Erratum843419Stub.h" 12b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "AArch64CA53Erratum843419Stub2.h" 13551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include "AArch64ELFDynamic.h" 14551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include "AArch64GNUInfo.h" 15b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "AArch64InsnHelpers.h" 16551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include "AArch64LDBackend.h" 17b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "AArch64LongBranchStub.h" 18551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include "AArch64Relocator.h" 19551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h" 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/AlignFragment.h" 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h" 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/NullFragment.h" 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/RegionFragment.h" 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Stub.h" 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/BranchIslandFactory.h" 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h" 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegment.h" 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegmentFactory.h" 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h" 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/StubFactory.h" 3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryRegion.h" 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryArea.h" 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/TargetRegistry.h" 3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFAttribute.h" 3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNUInfo.h" 3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h" 40551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 41551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include <llvm/ADT/Triple.h> 42551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include <llvm/ADT/Twine.h> 43551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include <llvm/Support/Casting.h> 4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/ELF.h> 4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <cstring> 47551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 4837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 49551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 50551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===// 51551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// AArch64GNULDBackend 52551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===// 53551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen HinesAArch64GNULDBackend::AArch64GNULDBackend(const LinkerConfig& pConfig, 54551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines GNUInfo* pInfo) 5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines : GNULDBackend(pConfig, pInfo), 5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelocator(NULL), 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOT(NULL), 5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTPLT(NULL), 5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pPLT(NULL), 6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelaDyn(NULL), 6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelaPLT(NULL), 6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pDynamic(NULL), 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol(NULL) { 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 6637b74a387bb3993387029859c2d9d051c41c724eStephen HinesAArch64GNULDBackend::~AArch64GNULDBackend() { 67551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pRelocator != NULL) 68551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines delete m_pRelocator; 69551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pGOT == m_pGOTPLT) { 70551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pGOT != NULL) 71551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines delete m_pGOT; 72551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } else { 73551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pGOT != NULL) 74551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines delete m_pGOT; 75551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pGOTPLT != NULL) 76551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines delete m_pGOTPLT; 77551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 78551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pPLT != NULL) 79551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines delete m_pPLT; 80551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pRelaDyn != NULL) 81551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines delete m_pRelaDyn; 82551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pRelaPLT != NULL) 83551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines delete m_pRelaPLT; 84551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pDynamic != NULL) 85551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines delete m_pDynamic; 86551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 87551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 88551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesvoid AArch64GNULDBackend::initTargetSections(Module& pModule, 8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder& pBuilder) { 90551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 91551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 92551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 93551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // initialize .got 94551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines LDSection& got = file_format->getGOT(); 95551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOT = new AArch64GOT(got); 96551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (config().options().hasNow()) { 97551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // when -z now is given, there will be only one .got section (contains 98551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // both GOTPLT and normal GOT entries), create GOT0 for .got section and 99551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // set m_pGOTPLT to the same .got 100551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOT->createGOT0(); 101551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOTPLT = m_pGOT; 10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 103551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // Otherwise, got should be seperated to two sections, .got and .got.plt 104551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // initialize .got.plt 105551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines LDSection& gotplt = file_format->getGOTPLT(); 106551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOTPLT = new AArch64GOT(gotplt); 107551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOTPLT->createGOT0(); 108551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 109551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 110551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // initialize .plt 111551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines LDSection& plt = file_format->getPLT(); 112551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT = new AArch64PLT(plt, *m_pGOTPLT); 113551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 114551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // initialize .rela.plt 115551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines LDSection& relaplt = file_format->getRelaPlt(); 116551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines relaplt.setLink(&plt); 117551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pRelaPLT = new OutputRelocSection(pModule, relaplt); 118551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 119551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // initialize .rela.dyn 120551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines LDSection& reladyn = file_format->getRelaDyn(); 121551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pRelaDyn = new OutputRelocSection(pModule, reladyn); 122551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 123551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 124551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 125551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesvoid AArch64GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, 12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines Module& pModule) { 127551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 128551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // same name in input 129551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol = 13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 13437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 13537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 13637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 13737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), 13937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 140551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 141551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 142551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 14337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool AArch64GNULDBackend::initRelocator() { 14437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pRelocator == NULL) { 145551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pRelocator = new AArch64Relocator(*this, config()); 146551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 147551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return true; 148551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 149551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst Relocator* AArch64GNULDBackend::getRelocator() const { 15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 1520dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return m_pRelocator; 1530dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 1540dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 15537b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocator* AArch64GNULDBackend::getRelocator() { 15637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 157551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return m_pRelocator; 158551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 159551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 16037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid AArch64GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) { 161551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 162551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pGOTSymbol != NULL) { 163551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 16437b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 16537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 16737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 16837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 17037b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0), 17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 17237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 173551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 17537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 17737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 17837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 17937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 18037b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0), 18137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 182551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 183551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 184551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 18537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid AArch64GNULDBackend::doPreLayout(IRBuilder& pBuilder) { 186551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // initialize .dynamic data 18737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!config().isCodeStatic() && m_pDynamic == NULL) 188551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pDynamic = new AArch64ELFDynamic(*this, config()); 189551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 190551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 191551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // set .got size 192551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (config().options().hasNow()) { 193551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // when building shared object, the GOTPLT section is must 19437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (LinkerConfig::DynObj == config().codeGenType() || m_pGOT->hasGOT1() || 19537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol != NULL) { 196551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOT->finalizeSectionSize(); 197551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines defineGOTSymbol(pBuilder); 198551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 19937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 200551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // when building shared object, the GOTPLT section is must 201551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (LinkerConfig::DynObj == config().codeGenType() || 20237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTPLT->hasGOT1() || m_pGOTSymbol != NULL) { 203551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOTPLT->finalizeSectionSize(); 204551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines defineGOTSymbol(pBuilder); 205551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 206551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pGOT->hasGOT1()) 207551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOT->finalizeSectionSize(); 208551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 209551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 210551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // set .plt size 211551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (m_pPLT->hasPLT1()) 212551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT->finalizeSectionSize(); 213551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 214551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 215551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // set .rela.dyn size 216551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (!m_pRelaDyn->empty()) { 21737b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 21837b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 21937b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 22037b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelaDyn().setSize(m_pRelaDyn->numOfRelocs() * 22137b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelaEntrySize()); 222551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 223551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 224551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // set .rela.plt size 225551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (!m_pRelaPLT->empty()) { 22637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 22737b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 22837b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 22937b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelaPlt().setSize(m_pRelaPLT->numOfRelocs() * 23037b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelaEntrySize()); 231551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 232551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 233551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 234551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 23537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid AArch64GNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) { 23637b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFFileFormat* file_format = getOutputFormat(); 237551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 238551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // apply PLT 239551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (file_format->hasPLT()) { 24037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL); 241551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT->applyPLT0(); 242551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT->applyPLT1(); 243551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 244551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 245551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // apply GOTPLT 246551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if ((config().options().hasNow() && file_format->hasGOT()) || 24737b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->hasGOTPLT()) { 24837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL); 249551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (LinkerConfig::DynObj == config().codeGenType()) 250551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOTPLT->applyGOT0(file_format->getDynamic().addr()); 251551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines else { 252551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // executable file and object file? should fill with zero. 253551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pGOTPLT->applyGOT0(0); 254551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 255551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 256551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 257551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 25837b74a387bb3993387029859c2d9d051c41c724eStephen HinesAArch64ELFDynamic& AArch64GNULDBackend::dynamic() { 25937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 260551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pDynamic; 261551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 262551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 26337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst AArch64ELFDynamic& AArch64GNULDBackend::dynamic() const { 26437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 265551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pDynamic; 266551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 267551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 268551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesuint64_t AArch64GNULDBackend::emitSectionData(const LDSection& pSection, 26937b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 270551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines assert(pRegion.size() && "Size of MemoryRegion is zero!"); 271551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 272551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const ELFFileFormat* file_format = getOutputFormat(); 273551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 274551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { 275551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines uint64_t result = m_pPLT->emit(pRegion); 276551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return result; 277551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 278551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 279551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { 280551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines uint64_t result = m_pGOT->emit(pRegion); 281551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return result; 282551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 283551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 284551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) { 285551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines uint64_t result = m_pGOT->emit(pRegion); 286551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return result; 287551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 288551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 289551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return pRegion.size(); 290551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 291551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 29237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned int AArch64GNULDBackend::getTargetSectionOrder( 29337b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSection& pSectHdr) const { 294551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const ELFFileFormat* file_format = getOutputFormat(); 295551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 296551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 297551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (config().options().hasNow()) 298551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return SHO_RELRO; 299551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return SHO_RELRO_LAST; 300551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 301551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 302551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) 303551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return SHO_NON_RELRO_FIRST; 304551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 305551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 306551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return SHO_PLT; 307551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 308551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return SHO_UNDEFINED; 309551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 310551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 311b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesvoid AArch64GNULDBackend::scanErrata(Module& pModule, 312b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines IRBuilder& pBuilder, 313b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines size_t& num_new_stubs, 314b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines size_t& stubs_strlen) { 315b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // TODO: Implement AArch64 ErrataStubFactory to create the specific erratum 316b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // stub and simplify the logics. 317b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (Module::iterator sect = pModule.begin(), sectEnd = pModule.end(); 318b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sect != sectEnd; ++sect) { 319b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (((*sect)->kind() == LDFileFormat::TEXT) && (*sect)->hasSectionData()) { 320b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData* sd = (*sect)->getSectionData(); 321b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (SectionData::iterator it = sd->begin(), ie = sd->end(); it != ie; 322b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++it) { 323b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* frag = llvm::dyn_cast<RegionFragment>(it); 324b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (frag != NULL) { 325b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines FragmentRef* frag_ref = FragmentRef::Create(*frag, 0); 326b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (unsigned offset = 0; offset < frag->size(); 327b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines offset += AArch64InsnHelpers::InsnSize) { 328b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Stub* stub = getStubFactory()->create(*frag_ref, 329b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pBuilder, 330b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines *getBRIslandFactory()); 331b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (stub != NULL) { 332b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // A stub symbol should be local 333b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(stub->symInfo() != NULL && stub->symInfo()->isLocal()); 334b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const AArch64CA53ErratumStub* erratum_stub = 335b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines reinterpret_cast<const AArch64CA53ErratumStub*>(stub); 336b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(erratum_stub != NULL); 337b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Rewrite the erratum instruction as a branch to the stub. 338b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t offset = frag_ref->offset() + 339b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines erratum_stub->getErratumInsnOffset(); 340b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Relocation* reloc = 341b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Relocation::Create(llvm::ELF::R_AARCH64_JUMP26, 342b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines *(FragmentRef::Create(*frag, offset)), 343b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines /* pAddend */0); 344b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines reloc->setSymInfo(stub->symInfo()); 345b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines reloc->target() = AArch64InsnHelpers::buildBranchInsn(); 346b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines addExtraRelocation(reloc); 347b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 348b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++num_new_stubs; 349b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines stubs_strlen += stub->symInfo()->nameSize() + 1; 350b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 351b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 352b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines frag_ref->assign(*frag, offset + AArch64InsnHelpers::InsnSize); 353b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // for each INSN 354b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 355b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // for each FRAGMENT 356b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 357b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // for each TEXT section 358b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 359b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 360551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesbool AArch64GNULDBackend::doRelax(Module& pModule, 361551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines IRBuilder& pBuilder, 36237b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool& pFinished) { 363b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(getStubFactory() != NULL && getBRIslandFactory() != NULL); 364b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 365b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Number of new stubs added 366b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines size_t num_new_stubs = 0; 367b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // String lengh to hold new stub symbols 368b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines size_t stubs_strlen = 0; 369b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 370b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (config().targets().fixCA53Erratum835769() || 371b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines config().targets().fixCA53Erratum843419()) { 372b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines scanErrata(pModule, pBuilder, num_new_stubs, stubs_strlen); 373b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 374b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 375b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 376b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // check branch relocs and create the related stubs if needed 377b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Module::obj_iterator input, inEnd = pModule.obj_end(); 378b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (input = pModule.obj_begin(); input != inEnd; ++input) { 379b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 380b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 381b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 382b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 383b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 384b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 385b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Relocation* relocation = llvm::cast<Relocation>(reloc); 386b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 387b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines switch (relocation->type()) { 388b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::R_AARCH64_CALL26: 389b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::R_AARCH64_JUMP26: { 390b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // calculate the possible symbol value 391b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t sym_value = 0x0; 392b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines LDSymbol* symbol = relocation->symInfo()->outSymbol(); 393b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (symbol->hasFragRef()) { 394b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t value = symbol->fragRef()->getOutputOffset(); 395b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t addr = 396b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines symbol->fragRef()->frag()->getParent()->getSection().addr(); 397b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sym_value = addr + value; 398b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 399b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((relocation->symInfo()->reserved() & 400b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines AArch64Relocator::ReservePLT) != 0x0) { 401b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // FIXME: we need to find out the address of the specific plt 402b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // entry 403b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(file_format->hasPLT()); 404b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sym_value = file_format->getPLT().addr(); 405b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 406b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Stub* stub = getStubFactory()->create(*relocation, // relocation 407b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sym_value, // symbol value 408b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pBuilder, 409b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines *getBRIslandFactory()); 410b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (stub != NULL) { 411b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // a stub symbol should be local 412b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(stub->symInfo() != NULL && stub->symInfo()->isLocal()); 413b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // reset the branch target of the reloc to this stub instead 414b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines relocation->setSymInfo(stub->symInfo()); 415b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 416b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++num_new_stubs; 417b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines stubs_strlen += stub->symInfo()->nameSize() + 1; 418b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 419b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 420b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 421b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines default: { 422b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 423b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 424b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // end of switch 425b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // for all relocations 426b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // for all relocation section 427b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // for all inputs 428b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 429b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Find the first fragment w/ invalid offset due to stub insertion. 430b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines std::vector<Fragment*> invalid_frags; 431b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pFinished = true; 432b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 433b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines island_end = getBRIslandFactory()->end(); 434b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines island != island_end; 435b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++island) { 436b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((*island).size() > stubGroupSize()) { 437b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines error(diag::err_no_space_to_place_stubs) << stubGroupSize(); 438b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 439b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 440b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 441b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((*island).numOfStubs() == 0) { 442b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 443b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 444b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 445b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* exit = &*(*island).end(); 4462a0b905c72a5b9554c9eeb0bda6fbdea49bcddffPirama Arumuga Nainar if (exit == &*(*island).begin()->getParent()->end()) { 447b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 448b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 449b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 450b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (((*island).offset() + (*island).size()) > exit->getOffset()) { 451b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (invalid_frags.empty() || 452b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines (invalid_frags.back()->getParent() != (*island).getParent())) { 453b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid_frags.push_back(exit); 454b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pFinished = false; 455b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 456b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 457b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 458b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 459b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 460b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Reset the offset of invalid fragments. 461b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie; 462b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++it) { 463b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* invalid = *it; 464b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines while (invalid != NULL) { 465b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid->setOffset(invalid->getPrevNode()->getOffset() + 466b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid->getPrevNode()->size()); 467b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid = invalid->getNextNode(); 468b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 469b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 470b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 471b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Fix up the size of .symtab, .strtab, and TEXT sections 472b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (num_new_stubs == 0) { 473b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 474b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } else { 475b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines switch (config().options().getStripSymbolMode()) { 476b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case GeneralOptions::StripSymbolMode::StripAllSymbols: 477b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case GeneralOptions::StripSymbolMode::StripLocals: 478b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 479b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines default: { 480b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines LDSection& symtab = file_format->getSymTab(); 481b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines LDSection& strtab = file_format->getStrTab(); 482b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 483b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines symtab.setSize(symtab.size() + 484b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sizeof(llvm::ELF::Elf64_Sym) * num_new_stubs); 485b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines symtab.setInfo(symtab.getInfo() + num_new_stubs); 486b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines strtab.setSize(strtab.size() + stubs_strlen); 487b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 488b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // switch (config().options().getStripSymbolMode()) 489b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 490b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData* prev = NULL; 491b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 492b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines island_end = getBRIslandFactory()->end(); 493b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines island != island_end; 494b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++island) { 495b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData* sd = (*island).begin()->getParent(); 496b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((*island).numOfStubs() != 0) { 497b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (sd != prev) { 498b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sd->getSection().setSize(sd->back().getOffset() + sd->back().size()); 499b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 500b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 501b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines prev = sd; 502b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 503b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 504b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // if (num_new_stubs == 0) 505551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 506551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 50737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool AArch64GNULDBackend::initTargetStubs() { 508b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines StubFactory* factory = getStubFactory(); 509b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (factory != NULL) { 510b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines factory->addPrototype(new AArch64LongBranchStub(config().isCodeIndep())); 511b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (config().targets().fixCA53Erratum835769()) { 512b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines factory->addPrototype(new AArch64CA53Erratum835769Stub()); 513b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 514b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (config().targets().fixCA53Erratum843419()) { 515b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines factory->addPrototype(new AArch64CA53Erratum843419Stub()); 516b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines factory->addPrototype(new AArch64CA53Erratum843419Stub2()); 517b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 518b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 519b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 520b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 521551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 522551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 52337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid AArch64GNULDBackend::doCreateProgramHdrs(Module& pModule) { 524551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 525551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 52637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool AArch64GNULDBackend::finalizeTargetSymbols() { 527551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return true; 528551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 529551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 530551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesbool AArch64GNULDBackend::mergeSection(Module& pModule, 531551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const Input& pInput, 53237b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDSection& pSection) { 533551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return true; 534551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 535551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 53637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool AArch64GNULDBackend::readSection(Input& pInput, SectionData& pSD) { 537551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return true; 538551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 539551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 54037b74a387bb3993387029859c2d9d051c41c724eStephen HinesAArch64GOT& AArch64GNULDBackend::getGOT() { 54137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL && "GOT section not exist"); 542551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pGOT; 543551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 544551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 54537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst AArch64GOT& AArch64GNULDBackend::getGOT() const { 54637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL && "GOT section not exist"); 547551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pGOT; 548551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 549551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 55037b74a387bb3993387029859c2d9d051c41c724eStephen HinesAArch64GOT& AArch64GNULDBackend::getGOTPLT() { 55137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL && "GOTPLT section not exist"); 552551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pGOTPLT; 553551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 554551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 55537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst AArch64GOT& AArch64GNULDBackend::getGOTPLT() const { 55637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL && "GOTPLT section not exist"); 557551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pGOTPLT; 558551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 559551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 56037b74a387bb3993387029859c2d9d051c41c724eStephen HinesAArch64PLT& AArch64GNULDBackend::getPLT() { 56137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL && "PLT section not exist"); 562551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pPLT; 563551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 564551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 56537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst AArch64PLT& AArch64GNULDBackend::getPLT() const { 56637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL && "PLT section not exist"); 567551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pPLT; 568551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 569551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 57037b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& AArch64GNULDBackend::getRelaDyn() { 57137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelaDyn != NULL && ".rela.dyn section not exist"); 572551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pRelaDyn; 573551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 574551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 57537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& AArch64GNULDBackend::getRelaDyn() const { 57637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelaDyn != NULL && ".rela.dyn section not exist"); 577551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pRelaDyn; 578551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 579551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 58037b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& AArch64GNULDBackend::getRelaPLT() { 58137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelaPLT != NULL && ".rela.plt section not exist"); 582551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pRelaPLT; 583551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 584551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 58537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& AArch64GNULDBackend::getRelaPLT() const { 58637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelaPLT != NULL && ".rela.plt section not exist"); 587551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return *m_pRelaPLT; 588551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 589551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 590551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===// 591551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// createAArch64LDBackend - the help funtion to create corresponding 592551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// AArch64LDBackend 593551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===// 59437b74a387bb3993387029859c2d9d051c41c724eStephen HinesTargetLDBackend* createAArch64LDBackend(const LinkerConfig& pConfig) { 595551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (pConfig.targets().triple().isOSDarwin()) { 596551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines assert(0 && "MachO linker is not supported yet"); 597551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /** 598551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return new AArch64MachOLDBackend(createAArch64MachOArchiveReader, 599551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines createAArch64MachOObjectReader, 600551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines createAArch64MachOObjectWriter); 601551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines **/ 602551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 603551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (pConfig.targets().triple().isOSWindows()) { 604551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines assert(0 && "COFF linker is not supported yet"); 605551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /** 606551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return new AArch64COFFLDBackend(createAArch64COFFArchiveReader, 607551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines createAArch64COFFObjectReader, 608551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines createAArch64COFFObjectWriter); 609551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines **/ 610551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 61137b74a387bb3993387029859c2d9d051c41c724eStephen Hines return new AArch64GNULDBackend( 61237b74a387bb3993387029859c2d9d051c41c724eStephen Hines pConfig, new AArch64GNUInfo(pConfig.targets().triple())); 613551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 614551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 61537b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 616551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 617551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===// 618551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// Force static initialization. 619551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===// 620551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesextern "C" void MCLDInitializeAArch64LDBackend() { 621551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // Register the linker backend 62237b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheAArch64Target, 62337b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::createAArch64LDBackend); 624551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines} 625