Home | History | Annotate | Download | only in AArch64
      1 //===- AArch64LDBackend.h -------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #ifndef TARGET_AARCH64_AARCH64LDBACKEND_H_
     10 #define TARGET_AARCH64_AARCH64LDBACKEND_H_
     11 
     12 #include "AArch64ELFDynamic.h"
     13 #include "AArch64GOT.h"
     14 #include "AArch64PLT.h"
     15 #include "mcld/LD/LDSection.h"
     16 #include "mcld/Target/GNULDBackend.h"
     17 #include "mcld/Target/OutputRelocSection.h"
     18 
     19 namespace mcld {
     20 
     21 class LinkerConfig;
     22 class GNUInfo;
     23 
     24 //===----------------------------------------------------------------------===//
     25 /// AArch64GNULDBackend - linker backend of AArch64 target of GNU ELF format
     26 ///
     27 class AArch64GNULDBackend : public GNULDBackend {
     28  public:
     29   static constexpr int64_t MAX_FWD_BRANCH_OFFSET = (((1 << 25) - 1) << 2);
     30   static constexpr int64_t MAX_BWD_BRANCH_OFFSET = (-((1 << 25) << 2));
     31 
     32   static constexpr int64_t MAX_ADRP_IMM = (1 << 20) - 1;
     33   static constexpr int64_t MIN_ADRP_IMM = -(1 << 20);
     34 
     35  public:
     36   AArch64GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
     37   ~AArch64GNULDBackend();
     38 
     39  public:
     40   /// initTargetSections - initialize target dependent sections in output.
     41   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
     42 
     43   /// initTargetSymbols - initialize target dependent symbols in output.
     44   void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
     45 
     46   /// initRelocator - create and initialize Relocator.
     47   bool initRelocator();
     48 
     49   /// getRelocator - return relocator.
     50   const Relocator* getRelocator() const;
     51   Relocator* getRelocator();
     52 
     53   /// doPreLayout - Backend can do any needed modification before layout
     54   void doPreLayout(IRBuilder& pBuilder);
     55 
     56   /// doPostLayout -Backend can do any needed modification after layout
     57   void doPostLayout(Module& pModule, IRBuilder& pBuilder);
     58 
     59   /// dynamic - the dynamic section of the target machine.
     60   /// Use co-variant return type to return its own dynamic section.
     61   AArch64ELFDynamic& dynamic();
     62 
     63   /// dynamic - the dynamic section of the target machine.
     64   /// Use co-variant return type to return its own dynamic section.
     65   const AArch64ELFDynamic& dynamic() const;
     66 
     67   /// emitSectionData - write out the section data into the memory region.
     68   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
     69   /// call back target backend to emit the data.
     70   ///
     71   /// Backends handle the target-special tables (plt, gp,...) by themselves.
     72   /// Backend can put the data of the tables in SectionData directly
     73   ///  - LDSection.getSectionData can get the section data.
     74   /// Or, backend can put the data into special data structure
     75   ///  - backend can maintain its own map<LDSection, table> to get the table
     76   /// from given LDSection.
     77   ///
     78   /// @param pSection - the given LDSection
     79   /// @param pConfig - all options in the command line.
     80   /// @param pRegion - the region to write out data
     81   /// @return the size of the table in the file.
     82   uint64_t emitSectionData(const LDSection& pSection,
     83                            MemoryRegion& pRegion) const;
     84 
     85   AArch64GOT& getGOT();
     86   const AArch64GOT& getGOT() const;
     87 
     88   AArch64GOT& getGOTPLT();
     89   const AArch64GOT& getGOTPLT() const;
     90 
     91   AArch64PLT& getPLT();
     92   const AArch64PLT& getPLT() const;
     93 
     94   OutputRelocSection& getRelaDyn();
     95   const OutputRelocSection& getRelaDyn() const;
     96 
     97   OutputRelocSection& getRelaPLT();
     98   const OutputRelocSection& getRelaPLT() const;
     99 
    100   LDSymbol* getGOTSymbol() { return m_pGOTSymbol; }
    101   const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; }
    102 
    103   /// getTargetSectionOrder - compute the layout order of AArch64 target
    104   /// sections
    105   unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
    106 
    107   /// finalizeTargetSymbols - finalize the symbol value
    108   bool finalizeTargetSymbols();
    109 
    110   /// mergeSection - merge target dependent sections
    111   bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection);
    112 
    113   /// readSection - read target dependent sections
    114   bool readSection(Input& pInput, SectionData& pSD);
    115 
    116  private:
    117   void defineGOTSymbol(IRBuilder& pBuilder);
    118 
    119   int64_t maxFwdBranchOffset() const { return MAX_FWD_BRANCH_OFFSET; }
    120   int64_t maxBwdBranchOffset() const { return MAX_BWD_BRANCH_OFFSET; }
    121 
    122   void scanErrata(Module& pModule,
    123                   IRBuilder& pBuilder,
    124                   size_t& num_new_stubs,
    125                   size_t& stubs_strlen);
    126 
    127   /// mayRelax - Backends should override this function if they need relaxation
    128   bool mayRelax() { return true; }
    129 
    130   /// doRelax - Backend can orevride this function to add its relaxation
    131   /// implementation. Return true if the output (e.g., .text) is "relaxed"
    132   /// (i.e. layout is changed), and set pFinished to true if everything is fit,
    133   /// otherwise set it to false.
    134   bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
    135 
    136   /// initTargetStubs
    137   bool initTargetStubs();
    138 
    139   /// getRelEntrySize - the size in BYTE of rel type relocation
    140   size_t getRelEntrySize() { return 16; }
    141 
    142   /// getRelEntrySize - the size in BYTE of rela type relocation
    143   size_t getRelaEntrySize() { return 24; }
    144 
    145   /// doCreateProgramHdrs - backend can implement this function to create the
    146   /// target-dependent segments
    147   virtual void doCreateProgramHdrs(Module& pModule);
    148 
    149  private:
    150   Relocator* m_pRelocator;
    151 
    152   AArch64GOT* m_pGOT;
    153   AArch64GOT* m_pGOTPLT;
    154   AArch64PLT* m_pPLT;
    155   /// m_RelDyn - dynamic relocation table of .rel.dyn
    156   OutputRelocSection* m_pRelaDyn;
    157   /// m_RelPLT - dynamic relocation table of .rel.plt
    158   OutputRelocSection* m_pRelaPLT;
    159 
    160   /// m_pAttrData - attribute data in public ("aeabi") attribute subsection
    161   // AArch64ELFAttributeData* m_pAttrData;
    162 
    163   AArch64ELFDynamic* m_pDynamic;
    164   LDSymbol* m_pGOTSymbol;
    165 
    166   //     variable name           :  ELF
    167   // LDSection* m_pAttributes;      // .ARM.attributes
    168   // LDSection* m_pPreemptMap;      // .AArch64.preemptmap
    169   // LDSection* m_pDebugOverlay;    // .AArch64.debug_overlay
    170   // LDSection* m_pOverlayTable;    // .AArch64.overlay_table
    171 };
    172 
    173 }  // namespace mcld
    174 
    175 #endif  // TARGET_AARCH64_AARCH64LDBACKEND_H_
    176