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