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 HEXAGON_LDBACKEND_H
     10 #define HEXAGON_LDBACKEND_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   Relocator* getRelocator();
     87 
     88   ResolveInfo::Desc getSymDesc(uint16_t shndx) const
     89   {
     90     if (shndx >= llvm::ELF::SHN_HEXAGON_SCOMMON &&
     91         shndx <= llvm::ELF::SHN_HEXAGON_SCOMMON_8)
     92       return ResolveInfo::Common;
     93     return ResolveInfo::NoneDesc;
     94   }
     95 
     96   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
     97 
     98   void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
     99 
    100   bool initBRIslandFactory();
    101 
    102   bool initStubFactory();
    103 
    104   bool mayRelax() { return true; }
    105 
    106   bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
    107 
    108   bool initTargetStubs();
    109 
    110   OutputRelocSection& getRelaDyn();
    111 
    112   const OutputRelocSection& getRelaDyn() const;
    113 
    114   HexagonGOTPLT& getGOTPLT();
    115 
    116   const HexagonGOTPLT& getGOTPLT() const;
    117 
    118   OutputRelocSection& getRelaPLT();
    119 
    120   const OutputRelocSection& getRelaPLT() const;
    121 
    122   /// getTargetSectionOrder - compute the layout order of Hexagon target section
    123   unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
    124 
    125   /// finalizeTargetSymbols - finalize the symbol value
    126   bool finalizeTargetSymbols();
    127 
    128   /// mergeSection - merge target dependent sections
    129   bool mergeSection(Module& pModule, LDSection& pSection);
    130 
    131   /// readSection - read target dependent sections
    132   bool readSection(Input& pInput, SectionData& pSD);
    133 
    134   bool MoveCommonData(SectionData &pFrom, SectionData &pTo);
    135 
    136   bool MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo);
    137 
    138   bool SetSDataSection();
    139 
    140   uint32_t getGP() { return m_psdata->addr(); }
    141 
    142   Relocation::Type getCopyRelType()    const { return m_CopyRel;    }
    143 
    144   virtual uint32_t getGOTSymbolAddr() {
    145     return m_pGOTSymbol->value();
    146   }
    147 
    148 
    149 protected:
    150   void defineGOTSymbol(IRBuilder& pBuilder, Fragment&);
    151 
    152 private:
    153   /// getRelEntrySize - the size in BYTE of rela type relocation
    154   size_t getRelEntrySize()
    155   { return 0; }
    156 
    157   /// getRelaEntrySize - the size in BYTE of rela type relocation
    158   size_t getRelaEntrySize()
    159   { return 12; }
    160 
    161   /// doCreateProgramHdrs - backend can implement this function to create the
    162   /// target-dependent segments
    163   void doCreateProgramHdrs(Module& pModule);
    164 
    165   uint64_t maxBranchOffset() { return ~(~0 << 6); }
    166 
    167   virtual void setGOTSectionSize(IRBuilder& pBuilder);
    168 
    169   virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
    170 
    171   virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
    172 					 const ELFFileFormat* FileFormat) const;
    173 
    174   virtual void setRelaDynSize();
    175   virtual void setRelaPLTSize();
    176 
    177 private:
    178   Relocator* m_pRelocator;
    179   HexagonGOT* m_pGOT;
    180   HexagonGOTPLT* m_pGOTPLT;
    181   HexagonPLT* m_pPLT;
    182   /// m_RelaDyn - dynamic relocation table of .rela.dyn
    183   OutputRelocSection* m_pRelaDyn;
    184   /// m_RelaPLT - dynamic relocation table of .rela.plt
    185   OutputRelocSection* m_pRelaPLT;
    186 
    187   HexagonELFDynamic* m_pDynamic;
    188 
    189   LDSection* m_psdata;
    190   LDSection* m_pscommon_1;
    191   LDSection* m_pscommon_2;
    192   LDSection* m_pscommon_4;
    193   LDSection* m_pscommon_8;
    194   LDSection* m_pstart;
    195   LDSymbol* m_psdabase;
    196 
    197   LDSymbol* m_pGOTSymbol;
    198   LDSymbol* m_pBSSEnd;
    199   Relocation::Type m_CopyRel;
    200 };
    201 } // namespace of mcld
    202 
    203 #endif
    204 
    205