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 MCLinker;
     18 class OutputRelocSection;
     19 class SectionMap;
     20 
     21 //===----------------------------------------------------------------------===//
     22 /// MipsGNULDBackend - linker backend of Mips target of GNU ELF format
     23 ///
     24 class MipsGNULDBackend : public GNULDBackend
     25 {
     26 public:
     27   enum ReservedEntryType {
     28     None          = 0,  // no reserved entry
     29     ReserveRel    = 1,  // reserve a dynamic relocation entry
     30     ReserveGot    = 2,  // reserve a GOT entry
     31     ReserveGpDisp = 8   // reserve _gp_disp symbol
     32   };
     33 
     34 public:
     35   MipsGNULDBackend();
     36   ~MipsGNULDBackend();
     37 
     38 public:
     39   /// initTargetSectionMap - initialize target dependent section mapping.
     40   bool initTargetSectionMap(SectionMap& pSectionMap);
     41 
     42   /// initTargetSections - initialize target dependent sections in output
     43   void initTargetSections(MCLinker& pLinker);
     44 
     45   /// initTargetSymbols - initialize target dependent symbols in output.
     46   void initTargetSymbols(MCLinker& pLinker);
     47 
     48   /// initRelocFactory - create and initialize RelocationFactory.
     49   bool initRelocFactory(const MCLinker& pLinker);
     50 
     51   /// getRelocFactory - return relocation factory.
     52   RelocationFactory* getRelocFactory();
     53 
     54   /// scanRelocation - determine the empty entries are needed or not and
     55   /// create the empty entries if needed.
     56   /// For Mips, the GOT, GP, and dynamic relocation entries are check to create.
     57   void scanRelocation(Relocation& pReloc,
     58                       const LDSymbol& pInputSym,
     59                       MCLinker& pLinker,
     60                       const MCLDInfo& pLDInfo,
     61                       const Output& pOutput);
     62 
     63   uint32_t machine() const;
     64 
     65   /// OSABI - the value of e_ident[EI_OSABI]
     66   uint8_t OSABI() const;
     67 
     68   /// ABIVersion - the value of e_ident[EI_ABIVRESION]
     69   uint8_t ABIVersion() const;
     70 
     71   /// flags - the value of ElfXX_Ehdr::e_flags
     72   uint64_t flags() const;
     73 
     74   bool isLittleEndian() const;
     75 
     76   unsigned int bitclass() const;
     77 
     78   /// preLayout - Backend can do any needed modification before layout
     79   void doPreLayout(const Output& pOutput,
     80                    const MCLDInfo& pInfo,
     81                    MCLinker& pLinker);
     82 
     83   /// postLayout -Backend can do any needed modification after layout
     84   void doPostLayout(const Output& pOutput,
     85                     const MCLDInfo& pInfo,
     86                     MCLinker& pLinker);
     87 
     88   /// dynamic - the dynamic section of the target machine.
     89   /// Use co-variant return type to return its own dynamic section.
     90   MipsELFDynamic& dynamic();
     91 
     92   /// dynamic - the dynamic section of the target machine.
     93   /// Use co-variant return type to return its own dynamic section.
     94   const MipsELFDynamic& dynamic() const;
     95 
     96   /// emitSectionData - write out the section data into the memory region.
     97   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
     98   /// call back target backend to emit the data.
     99   ///
    100   /// Backends handle the target-special tables (plt, gp,...) by themselves.
    101   /// Backend can put the data of the tables in MCSectionData directly
    102   ///  - LDSection.getSectionData can get the section data.
    103   /// Or, backend can put the data into special data structure
    104   ///  - backend can maintain its own map<LDSection, table> to get the table
    105   /// from given LDSection.
    106   ///
    107   /// @param pOutput - the output file
    108   /// @param pSection - the given LDSection
    109   /// @param pInfo - all options in the command line.
    110   /// @param pRegion - the region to write out data
    111   /// @return the size of the table in the file.
    112   uint64_t emitSectionData(const Output& pOutput,
    113                            const LDSection& pSection,
    114                            const MCLDInfo& pInfo,
    115                            MemoryRegion& pRegion) const;
    116 
    117   /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
    118   virtual void emitDynNamePools(Output& pOutput,
    119                                 SymbolCategory& pSymbols,
    120                                 const Layout& pLayout,
    121                                 const MCLDInfo& pLDInfo);
    122 
    123   MipsGOT& getGOT();
    124   const MipsGOT& getGOT() const;
    125 
    126   OutputRelocSection& getRelDyn();
    127   const OutputRelocSection& getRelDyn() const;
    128 
    129   /// getTargetSectionOrder - compute the layout order of ARM target sections
    130   unsigned int getTargetSectionOrder(const Output& pOutput,
    131                                      const LDSection& pSectHdr) const;
    132 
    133   /// finalizeSymbol - finalize the symbol value
    134   /// If the symbol's reserved field is not zero, MCLinker will call back this
    135   /// function to ask the final value of the symbol
    136   bool finalizeSymbol(LDSymbol& pSymbol) const;
    137 
    138   /// allocateCommonSymbols - allocate common symbols in the corresponding
    139   /// sections.
    140   bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
    141 
    142 private:
    143   void scanLocalReloc(Relocation& pReloc,
    144                       const LDSymbol& pInputSym,
    145                       MCLinker& pLinker,
    146                       const MCLDInfo& pLDInfo,
    147                       const Output& pOutput);
    148 
    149   void scanGlobalReloc(Relocation& pReloc,
    150                       const LDSymbol& pInputSym,
    151                       MCLinker& pLinker,
    152                       const MCLDInfo& pLDInfo,
    153                       const Output& pOutput);
    154 
    155   bool isSymbolNeedsPLT(ResolveInfo& pSym, const Output& pOutput) const;
    156   bool isSymbolNeedsDynRel(ResolveInfo& pSym, const Output& pOutput) const;
    157 
    158   void createGOT(MCLinker& pLinker, const Output& pOutput);
    159   void createRelDyn(MCLinker& pLinker, const Output& pOutput);
    160 
    161   ELFFileFormat* getOutputFormat(const Output& pOutput) const;
    162 
    163   /// updateAddend - update addend value of the relocation if the
    164   /// the target symbol is a section symbol. Addend is the offset
    165   /// in the section. This value should be updated after section
    166   /// merged.
    167   void updateAddend(Relocation& pReloc,
    168                     const LDSymbol& pInputSym,
    169                     const Layout& pLayout) const;
    170 
    171 private:
    172   RelocationFactory* m_pRelocFactory;
    173 
    174   MipsGOT* m_pGOT;                      // .got
    175   OutputRelocSection* m_pRelDyn;        // .rel.dyn
    176 
    177   MipsELFDynamic* m_pDynamic;
    178   LDSymbol* m_pGOTSymbol;
    179   LDSymbol* m_pGpDispSymbol;
    180 
    181   std::vector<LDSymbol*> m_LocalGOTSyms;
    182   std::vector<LDSymbol*> m_GlobalGOTSyms;
    183 
    184 private:
    185   /// isGOTSymbol - return true if the symbol is the GOT entry.
    186   bool isGOTSymbol(const LDSymbol& pSymbol) const;
    187   /// emitDynamicSymbol - emit dynamic symbol.
    188   void emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
    189                          Output& pOutput,
    190                          LDSymbol& pSymbol,
    191                          const Layout& pLayout,
    192                          char* strtab,
    193                          size_t strtabsize,
    194                          size_t symtabIdx);
    195 };
    196 
    197 } // namespace of mcld
    198 
    199 #endif
    200