Home | History | Annotate | Download | only in Hexagon
      1 //===- HexagonLDBackend.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_HEXAGON_HEXAGONLDBACKEND_H_
     10 #define TARGET_HEXAGON_HEXAGONLDBACKEND_H_
     11 
     12 #include "HexagonELFDynamic.h"
     13 #include "HexagonGOT.h"
     14 #include "HexagonPLT.h"
     15 #include "HexagonGOTPLT.h"
     16 #include "mcld/IRBuilder.h"
     17 #include "mcld/LinkerConfig.h"
     18 #include "mcld/LD/LDSection.h"
     19 #include "mcld/Object/ObjectBuilder.h"
     20 #include "mcld/Target/GNULDBackend.h"
     21 #include "mcld/Target/OutputRelocSection.h"
     22 
     23 namespace mcld {
     24 
     25 class HexagonGNUInfo;
     26 class LinkerConfig;
     27 
     28 //===----------------------------------------------------------------------===//
     29 /// HexagonLDBackend - linker backend of Hexagon target of GNU ELF format
     30 ///
     31 class HexagonLDBackend : public GNULDBackend {
     32  public:
     33   HexagonLDBackend(const LinkerConfig& pConfig, HexagonGNUInfo* pInfo);
     34 
     35   ~HexagonLDBackend();
     36 
     37   uint32_t machine() const;
     38 
     39   HexagonGOT& getGOT();
     40 
     41   const HexagonGOT& getGOT() const;
     42 
     43   HexagonPLT& getPLT();
     44 
     45   const HexagonPLT& getPLT() const;
     46 
     47   /// preLayout - Backend can do any needed modification before layout
     48   void doPreLayout(IRBuilder& pBuilder);
     49 
     50   bool allocateCommonSymbols(Module& pModule);
     51 
     52   /// postLayout - Backend can do any needed modification after layout
     53   void doPostLayout(Module& pModule, IRBuilder& pBuilder);
     54 
     55   /// dynamic - the dynamic section of the target machine.
     56   /// Use co-variant return type to return its own dynamic section.
     57   HexagonELFDynamic& dynamic();
     58 
     59   /// dynamic - the dynamic section of the target machine.
     60   /// Use co-variant return type to return its own dynamic section.
     61   const HexagonELFDynamic& dynamic() const;
     62 
     63   /// emitSectionData - write out the section data into the memory region.
     64   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
     65   /// call back target backend to emit the data.
     66   ///
     67   /// Backends handle the target-special tables (plt, gp,...) by themselves.
     68   /// Backend can put the data of the tables in MCSectionData directly
     69   ///  - LDSection.getSectionData can get the section data.
     70   /// Or, backend can put the data into special data structure
     71   ///  - backend can maintain its own map<LDSection, table> to get the table
     72   /// from given LDSection.
     73   ///
     74   /// @param pSection - the given LDSection
     75   /// @param pLayout - for comouting the size of fragment
     76   /// @param pRegion - the region to write out data
     77   /// @return the size of the table in the file.
     78   uint64_t emitSectionData(const LDSection& pSection,
     79                            MemoryRegion& pRegion) const;
     80 
     81   /// initRelocator - create and initialize Relocator.
     82   bool initRelocator();
     83 
     84   /// getRelocator - return relocator.
     85   const Relocator* getRelocator() const;
     86   Relocator* getRelocator();
     87 
     88   ResolveInfo::Desc getSymDesc(uint16_t shndx) const {
     89     if (shndx >= llvm::ELF::SHN_HEXAGON_SCOMMON &&
     90         shndx <= llvm::ELF::SHN_HEXAGON_SCOMMON_8)
     91       return ResolveInfo::Common;
     92     return ResolveInfo::NoneDesc;
     93   }
     94 
     95   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
     96 
     97   void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
     98 
     99   bool initBRIslandFactory();
    100 
    101   bool initStubFactory();
    102 
    103   bool mayRelax() { return true; }
    104 
    105   bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
    106 
    107   bool initTargetStubs();
    108 
    109   OutputRelocSection& getRelaDyn();
    110 
    111   const OutputRelocSection& getRelaDyn() const;
    112 
    113   HexagonGOTPLT& getGOTPLT();
    114 
    115   const HexagonGOTPLT& getGOTPLT() const;
    116 
    117   OutputRelocSection& getRelaPLT();
    118 
    119   const OutputRelocSection& getRelaPLT() const;
    120 
    121   /// getTargetSectionOrder - compute the layout order of Hexagon target section
    122   unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
    123 
    124   /// finalizeTargetSymbols - finalize the symbol value
    125   bool finalizeTargetSymbols();
    126 
    127   /// mergeSection - merge target dependent sections
    128   bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection);
    129 
    130   /// readSection - read target dependent sections
    131   bool readSection(Input& pInput, SectionData& pSD);
    132 
    133   bool MoveCommonData(SectionData& pFrom, SectionData& pTo);
    134 
    135   bool MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo);
    136 
    137   bool SetSDataSection();
    138 
    139   uint32_t getGP() { return m_psdata->addr(); }
    140 
    141   Relocation::Type getCopyRelType() const { return m_CopyRel; }
    142 
    143   virtual uint32_t getGOTSymbolAddr() { return m_pGOTSymbol->value(); }
    144 
    145  protected:
    146   void defineGOTSymbol(IRBuilder& pBuilder, Fragment&);
    147 
    148  private:
    149   /// getRelEntrySize - the size in BYTE of rela type relocation
    150   size_t getRelEntrySize() { return 0; }
    151 
    152   /// getRelaEntrySize - the size in BYTE of rela type relocation
    153   size_t getRelaEntrySize() { return 12; }
    154 
    155   /// doCreateProgramHdrs - backend can implement this function to create the
    156   /// target-dependent segments
    157   void doCreateProgramHdrs(Module& pModule);
    158 
    159   /// maxFwdBranchOffset
    160   int64_t maxFwdBranchOffset() const { return ~(~0U << 6); }
    161 
    162   virtual void setGOTSectionSize(IRBuilder& pBuilder);
    163 
    164   virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
    165 
    166   virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
    167                                          const ELFFileFormat* FileFormat) const;
    168 
    169   virtual void setRelaDynSize();
    170   virtual void setRelaPLTSize();
    171 
    172  private:
    173   Relocator* m_pRelocator;
    174   HexagonGOT* m_pGOT;
    175   HexagonGOTPLT* m_pGOTPLT;
    176   HexagonPLT* m_pPLT;
    177   /// m_RelaDyn - dynamic relocation table of .rela.dyn
    178   OutputRelocSection* m_pRelaDyn;
    179   /// m_RelaPLT - dynamic relocation table of .rela.plt
    180   OutputRelocSection* m_pRelaPLT;
    181 
    182   HexagonELFDynamic* m_pDynamic;
    183 
    184   LDSection* m_psdata;
    185   LDSection* m_pscommon_1;
    186   LDSection* m_pscommon_2;
    187   LDSection* m_pscommon_4;
    188   LDSection* m_pscommon_8;
    189   LDSection* m_pstart;
    190   LDSymbol* m_psdabase;
    191 
    192   LDSymbol* m_pGOTSymbol;
    193   LDSymbol* m_pBSSEnd;
    194   Relocation::Type m_CopyRel;
    195 };
    196 
    197 }  // namespace mcld
    198 
    199 #endif  // TARGET_HEXAGON_HEXAGONLDBACKEND_H_
    200