Home | History | Annotate | Download | only in Target
      1 //===- ELFDynamic.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 MCLD_TARGET_ELFDYNAMIC_H_
     10 #define MCLD_TARGET_ELFDYNAMIC_H_
     11 
     12 #include "mcld/LD/LDSection.h"
     13 #include "mcld/Support/FileOutputBuffer.h"
     14 #include <llvm/Support/ELF.h>
     15 #include <vector>
     16 #include <cstring>
     17 
     18 namespace mcld {
     19 
     20 class ELFFileFormat;
     21 class GNULDBackend;
     22 class LinkerConfig;
     23 
     24 namespace elf_dynamic {
     25 
     26 /** \class EntryIF
     27 *  \brief EntryIF provides a common interface for one entry in the dynamic
     28 *  section
     29 */
     30 class EntryIF {
     31  protected:
     32   EntryIF();
     33 
     34  public:
     35   virtual ~EntryIF();
     36 
     37   virtual EntryIF* clone() const = 0;
     38   virtual size_t size() const = 0;
     39   virtual size_t symbolSize() const = 0;
     40   virtual size_t relSize() const = 0;
     41   virtual size_t relaSize() const = 0;
     42   virtual size_t emit(uint8_t* pAddress) const = 0;
     43   virtual void setValue(uint64_t pTag, uint64_t pValue) = 0;
     44 };
     45 
     46 template <size_t BITNUMBER, bool LITTLEENDIAN>
     47 class Entry {};
     48 
     49 template <>
     50 class Entry<32, true> : public EntryIF {
     51  public:
     52   typedef llvm::ELF::Elf32_Dyn Pair;
     53   typedef llvm::ELF::Elf32_Sym Symbol;
     54   typedef llvm::ELF::Elf32_Rel Rel;
     55   typedef llvm::ELF::Elf32_Rela Rela;
     56 
     57  public:
     58   inline Entry();
     59 
     60   inline ~Entry();
     61 
     62   Entry* clone() const { return new Entry(); }
     63 
     64   size_t size() const { return sizeof(Pair); }
     65 
     66   size_t symbolSize() const { return sizeof(Symbol); }
     67 
     68   size_t relSize() const { return sizeof(Rel); }
     69 
     70   size_t relaSize() const { return sizeof(Rela); }
     71 
     72   inline void setValue(uint64_t pTag, uint64_t pValue);
     73 
     74   inline size_t emit(uint8_t* pAddress) const;
     75 
     76  private:
     77   Pair m_Pair;
     78 };
     79 
     80 template <>
     81 class Entry<64, true> : public EntryIF {
     82  public:
     83   typedef llvm::ELF::Elf64_Dyn Pair;
     84   typedef llvm::ELF::Elf64_Sym Symbol;
     85   typedef llvm::ELF::Elf64_Rel Rel;
     86   typedef llvm::ELF::Elf64_Rela Rela;
     87 
     88  public:
     89   inline Entry();
     90 
     91   inline ~Entry();
     92 
     93   Entry* clone() const { return new Entry(); }
     94 
     95   size_t size() const { return sizeof(Pair); }
     96 
     97   size_t symbolSize() const { return sizeof(Symbol); }
     98 
     99   size_t relSize() const { return sizeof(Rel); }
    100 
    101   size_t relaSize() const { return sizeof(Rela); }
    102 
    103   inline void setValue(uint64_t pTag, uint64_t pValue);
    104 
    105   inline size_t emit(uint8_t* pAddress) const;
    106 
    107  private:
    108   Pair m_Pair;
    109 };
    110 
    111 #include "ELFDynamic.tcc"
    112 
    113 }  // namespace elf_dynamic
    114 
    115 /** \class ELFDynamic
    116  *  \brief ELFDynamic is the .dynamic section in ELF shared and executable
    117  *  files.
    118  */
    119 class ELFDynamic {
    120  public:
    121   typedef std::vector<elf_dynamic::EntryIF*> EntryListType;
    122   typedef EntryListType::iterator iterator;
    123   typedef EntryListType::const_iterator const_iterator;
    124 
    125  public:
    126   ELFDynamic(const GNULDBackend& pBackend, const LinkerConfig& pConfig);
    127 
    128   virtual ~ELFDynamic();
    129 
    130   size_t size() const;
    131 
    132   size_t entrySize() const;
    133 
    134   size_t numOfBytes() const;
    135 
    136   /// reserveEntries - reserve entries
    137   void reserveEntries(const ELFFileFormat& pFormat);
    138 
    139   /// reserveNeedEntry - reserve on DT_NEED entry.
    140   void reserveNeedEntry();
    141 
    142   /// applyEntries - apply entries
    143   void applyEntries(const ELFFileFormat& pFormat);
    144 
    145   void applySoname(uint64_t pStrTabIdx);
    146 
    147   const_iterator needBegin() const { return m_NeedList.begin(); }
    148   iterator needBegin() { return m_NeedList.begin(); }
    149 
    150   const_iterator needEnd() const { return m_NeedList.end(); }
    151   iterator needEnd() { return m_NeedList.end(); }
    152 
    153   /// emit
    154   void emit(const LDSection& pSection, MemoryRegion& pRegion) const;
    155 
    156  protected:
    157   /// reserveTargetEntries - reserve target dependent entries
    158   virtual void reserveTargetEntries(const ELFFileFormat& pFormat) = 0;
    159 
    160   /// applyTargetEntries - apply target-dependant
    161   virtual void applyTargetEntries(const ELFFileFormat& pFormat) = 0;
    162 
    163  protected:
    164   void reserveOne(uint64_t pTag);
    165 
    166   void applyOne(uint64_t pTag, uint64_t pValue);
    167 
    168   size_t symbolSize() const;
    169 
    170   const LinkerConfig& config() const { return m_Config; }
    171 
    172  private:
    173   EntryListType m_EntryList;
    174   EntryListType m_NeedList;
    175   elf_dynamic::EntryIF* m_pEntryFactory;
    176   const GNULDBackend& m_Backend;
    177   const LinkerConfig& m_Config;
    178 
    179   // The entry reserved and the entry being applied are not must matched.
    180   // For better performance, we use a simple counter and apply entry one-by-one
    181   // by the counter. m_Idx is the counter indicating to the entry being applied.
    182   size_t m_Idx;
    183 };
    184 
    185 }  // namespace mcld
    186 
    187 #endif  // MCLD_TARGET_ELFDYNAMIC_H_
    188