1551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===- AArch64LDBackend.h -------------------------------------------------===// 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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef TARGET_AARCH64_AARCH64LDBACKEND_H_ 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define TARGET_AARCH64_AARCH64LDBACKEND_H_ 11551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 12551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include "AArch64ELFDynamic.h" 13551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include "AArch64GOT.h" 14551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include "AArch64PLT.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/OutputRelocSection.h" 18551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 19551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesnamespace mcld { 20551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 21551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesclass LinkerConfig; 22551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesclass GNUInfo; 23551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 24551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===// 25551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines/// AArch64GNULDBackend - linker backend of AArch64 target of GNU ELF format 26551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines/// 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass AArch64GNULDBackend : public GNULDBackend { 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 29b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines static constexpr int64_t MAX_FWD_BRANCH_OFFSET = (((1 << 25) - 1) << 2); 30b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines static constexpr int64_t MAX_BWD_BRANCH_OFFSET = (-((1 << 25) << 2)); 31b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 32b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines static constexpr int64_t MAX_ADRP_IMM = (1 << 20) - 1; 33b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines static constexpr int64_t MIN_ADRP_IMM = -(1 << 20); 340dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 36551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines AArch64GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 37551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ~AArch64GNULDBackend(); 38551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 40551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// initTargetSections - initialize target dependent sections in output. 41551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 42551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 43551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// initTargetSymbols - initialize target dependent symbols in output. 44551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 45551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 46551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// initRelocator - create and initialize Relocator. 47551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines bool initRelocator(); 48551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 49551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// getRelocator - return relocator. 500dea6bc96bb52346737966839ac68644f7939f58Stephen Hines const Relocator* getRelocator() const; 51551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines Relocator* getRelocator(); 52551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 53551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// doPreLayout - Backend can do any needed modification before layout 54551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines void doPreLayout(IRBuilder& pBuilder); 55551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 56551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// doPostLayout -Backend can do any needed modification after layout 57551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines void doPostLayout(Module& pModule, IRBuilder& pBuilder); 58551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 59551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// dynamic - the dynamic section of the target machine. 60551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// Use co-variant return type to return its own dynamic section. 61551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines AArch64ELFDynamic& dynamic(); 62551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 63551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// dynamic - the dynamic section of the target machine. 64551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// Use co-variant return type to return its own dynamic section. 65551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const AArch64ELFDynamic& dynamic() const; 66551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 67551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// emitSectionData - write out the section data into the memory region. 68551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 69551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// call back target backend to emit the data. 70551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// 71551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// Backends handle the target-special tables (plt, gp,...) by themselves. 72551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// Backend can put the data of the tables in SectionData directly 73551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// - LDSection.getSectionData can get the section data. 74551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// Or, backend can put the data into special data structure 75551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// - backend can maintain its own map<LDSection, table> to get the table 76551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// from given LDSection. 77551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// 78551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// @param pSection - the given LDSection 79551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// @param pConfig - all options in the command line. 80551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// @param pRegion - the region to write out data 81551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// @return the size of the table in the file. 82551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines uint64_t emitSectionData(const LDSection& pSection, 83551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines MemoryRegion& pRegion) const; 84551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 85551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines AArch64GOT& getGOT(); 86551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const AArch64GOT& getGOT() const; 87551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 88551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines AArch64GOT& getGOTPLT(); 89551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const AArch64GOT& getGOTPLT() const; 90551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 91551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines AArch64PLT& getPLT(); 92551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const AArch64PLT& getPLT() const; 93551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 94551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines OutputRelocSection& getRelaDyn(); 95551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const OutputRelocSection& getRelaDyn() const; 96551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 97551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines OutputRelocSection& getRelaPLT(); 98551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const OutputRelocSection& getRelaPLT() const; 99551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDSymbol* getGOTSymbol() { return m_pGOTSymbol; } 101551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; } 102551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines /// getTargetSectionOrder - compute the layout order of AArch64 target 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines /// sections 105551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 106551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 107551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// finalizeTargetSymbols - finalize the symbol value 108551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines bool finalizeTargetSymbols(); 109551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 110551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// mergeSection - merge target dependent sections 111551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection); 112551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 113551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// readSection - read target dependent sections 114551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines bool readSection(Input& pInput, SectionData& pSD); 115551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines private: 117551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines void defineGOTSymbol(IRBuilder& pBuilder); 118551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 119b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines int64_t maxFwdBranchOffset() const { return MAX_FWD_BRANCH_OFFSET; } 120b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines int64_t maxBwdBranchOffset() const { return MAX_BWD_BRANCH_OFFSET; } 121b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 122b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines void scanErrata(Module& pModule, 123b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines IRBuilder& pBuilder, 124b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines size_t& num_new_stubs, 125b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines size_t& stubs_strlen); 126551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 127551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// mayRelax - Backends should override this function if they need relaxation 128551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines bool mayRelax() { return true; } 129551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 130551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// doRelax - Backend can orevride this function to add its relaxation 131551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// implementation. Return true if the output (e.g., .text) is "relaxed" 132551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// (i.e. layout is changed), and set pFinished to true if everything is fit, 133551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// otherwise set it to false. 134551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished); 135551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 136551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// initTargetStubs 137551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines bool initTargetStubs(); 138551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 139551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// getRelEntrySize - the size in BYTE of rel type relocation 14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t getRelEntrySize() { return 16; } 141551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 142551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// getRelEntrySize - the size in BYTE of rela type relocation 14337b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t getRelaEntrySize() { return 24; } 144551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 145551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// doCreateProgramHdrs - backend can implement this function to create the 146551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// target-dependent segments 147551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines virtual void doCreateProgramHdrs(Module& pModule); 148551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines private: 150551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines Relocator* m_pRelocator; 151551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 152551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines AArch64GOT* m_pGOT; 153551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines AArch64GOT* m_pGOTPLT; 154551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines AArch64PLT* m_pPLT; 155551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// m_RelDyn - dynamic relocation table of .rel.dyn 156551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines OutputRelocSection* m_pRelaDyn; 157551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// m_RelPLT - dynamic relocation table of .rel.plt 158551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines OutputRelocSection* m_pRelaPLT; 159551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 160551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines /// m_pAttrData - attribute data in public ("aeabi") attribute subsection 161551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // AArch64ELFAttributeData* m_pAttrData; 162551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 163551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines AArch64ELFDynamic* m_pDynamic; 164551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines LDSymbol* m_pGOTSymbol; 165551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 166551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // variable name : ELF 167533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines // LDSection* m_pAttributes; // .ARM.attributes 168533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines // LDSection* m_pPreemptMap; // .AArch64.preemptmap 169533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines // LDSection* m_pDebugOverlay; // .AArch64.debug_overlay 170533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines // LDSection* m_pOverlayTable; // .AArch64.overlay_table 171551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}; 172551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 174551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 17537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif // TARGET_AARCH64_AARCH64LDBACKEND_H_ 176