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