Home | History | Annotate | Download | only in Mips
      1 //===- MipsLDBackend.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 MIPS_LDBACKEND_H
     10 #define MIPS_LDBACKEND_H
     11 #include <mcld/Target/GNULDBackend.h>
     12 #include "MipsELFDynamic.h"
     13 #include "MipsGOT.h"
     14 
     15 namespace mcld {
     16 
     17 class LinkerConfig;
     18 class OutputRelocSection;
     19 class SectionMap;
     20 class MemoryArea;
     21 class MipsGNUInfo;
     22 
     23 //===----------------------------------------------------------------------===//
     24 /// MipsGNULDBackend - linker backend of Mips target of GNU ELF format
     25 ///
     26 class MipsGNULDBackend : public GNULDBackend
     27 {
     28 public:
     29   enum ReservedEntryType {
     30     None          = 0,  // no reserved entry
     31     ReserveRel    = 1,  // reserve a dynamic relocation entry
     32     ReserveGot    = 2,  // reserve a GOT entry
     33     ReserveGpDisp = 8   // reserve _gp_disp symbol
     34   };
     35 
     36 public:
     37   MipsGNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo);
     38   ~MipsGNULDBackend();
     39 
     40 public:
     41   /// initTargetSections - initialize target dependent sections in output
     42   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
     43 
     44   /// initTargetSymbols - initialize target dependent symbols in output.
     45   void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
     46 
     47   /// initRelocator - create and initialize Relocator.
     48   bool initRelocator();
     49 
     50   /// getRelocator - return relocator.
     51   Relocator* getRelocator();
     52 
     53   /// scanRelocation - determine the empty entries are needed or not and
     54   /// create the empty entries if needed.
     55   /// For Mips, the GOT, GP, and dynamic relocation entries are check to create.
     56   void scanRelocation(Relocation& pReloc,
     57                       IRBuilder& pBuilder,
     58                       Module& pModule,
     59                       LDSection& pSection);
     60 
     61   /// preLayout - Backend can do any needed modification before layout
     62   void doPreLayout(IRBuilder& pBuilder);
     63 
     64   /// postLayout - Backend can do any needed modification after layout
     65   void doPostLayout(Module& pModule, IRBuilder& pBuilder);
     66 
     67   /// dynamic - the dynamic section of the target machine.
     68   /// Use co-variant return type to return its own dynamic section.
     69   MipsELFDynamic& dynamic();
     70 
     71   /// dynamic - the dynamic section of the target machine.
     72   /// Use co-variant return type to return its own dynamic section.
     73   const MipsELFDynamic& dynamic() const;
     74 
     75   /// emitSectionData - write out the section data into the memory region.
     76   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
     77   /// call back target backend to emit the data.
     78   ///
     79   /// Backends handle the target-special tables (plt, gp,...) by themselves.
     80   /// Backend can put the data of the tables in SectionData directly
     81   ///  - LDSection.getSectionData can get the section data.
     82   /// Or, backend can put the data into special data structure
     83   ///  - backend can maintain its own map<LDSection, table> to get the table
     84   /// from given LDSection.
     85   ///
     86   /// @param pSection - the given LDSection
     87   /// @param pRegion - the region to write out data
     88   /// @return the size of the table in the file.
     89   uint64_t emitSectionData(const LDSection& pSection,
     90                            MemoryRegion& pRegion) const;
     91 
     92   void sizeNamePools(Module& pModule, bool pIsStaticLink);
     93 
     94   /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
     95   void emitDynNamePools(Module& pModule, MemoryArea& pOut);
     96 
     97 
     98   MipsGOT& getGOT();
     99   const MipsGOT& getGOT() const;
    100 
    101   OutputRelocSection& getRelDyn();
    102   const OutputRelocSection& getRelDyn() const;
    103 
    104   /// getTargetSectionOrder - compute the layout order of ARM target sections
    105   unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
    106 
    107   /// finalizeSymbol - finalize the symbol value
    108   bool finalizeTargetSymbols();
    109 
    110   /// allocateCommonSymbols - allocate common symbols in the corresponding
    111   /// sections.
    112   bool allocateCommonSymbols(Module& pModule);
    113 
    114 private:
    115   void scanLocalReloc(Relocation& pReloc,
    116                       IRBuilder& pBuilder,
    117                       const LDSection& pSection);
    118 
    119   void scanGlobalReloc(Relocation& pReloc,
    120                        IRBuilder& pBuilder,
    121                        const LDSection& pSection);
    122 
    123   void defineGOTSymbol(IRBuilder& pBuilder);
    124 
    125   /// emitSymbol32 - emit an ELF32 symbol, override parent's function
    126   void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32,
    127                     LDSymbol& pSymbol,
    128                     char* pStrtab,
    129                     size_t pStrtabsize,
    130                     size_t pSymtabIdx);
    131 
    132   /// getRelEntrySize - the size in BYTE of rel type relocation
    133   size_t getRelEntrySize()
    134   { return 8; }
    135 
    136   /// getRelEntrySize - the size in BYTE of rela type relocation
    137   size_t getRelaEntrySize()
    138   { return 12; }
    139 
    140   /// doCreateProgramHdrs - backend can implement this function to create the
    141   /// target-dependent segments
    142   void doCreateProgramHdrs(Module& pModule);
    143 
    144 private:
    145   Relocator* m_pRelocator;
    146 
    147   MipsGOT* m_pGOT;                      // .got
    148   OutputRelocSection* m_pRelDyn;        // .rel.dyn
    149 
    150   MipsELFDynamic* m_pDynamic;
    151   LDSymbol* m_pGOTSymbol;
    152   LDSymbol* m_pGpDispSymbol;
    153 
    154   std::vector<LDSymbol*> m_GlobalGOTSyms;
    155 
    156 private:
    157   /// isGlobalGOTSymbol - return true if the symbol is the global GOT entry.
    158   bool isGlobalGOTSymbol(const LDSymbol& pSymbol) const;
    159 
    160 };
    161 
    162 } // namespace of mcld
    163 
    164 #endif
    165 
    166