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