Home | History | Annotate | Download | only in LD
      1 //===- ELFSegment.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_SEGMENT_H
     10 #define MCLD_ELF_SEGMENT_H
     11 #ifdef ENABLE_UNITTEST
     12 #include <gtest.h>
     13 #endif
     14 #include <llvm/Support/ELF.h>
     15 #include <llvm/Support/DataTypes.h>
     16 #include <mcld/LD/LDSection.h>
     17 #include <cassert>
     18 #include <vector>
     19 
     20 namespace mcld
     21 {
     22 
     23 /** \class ELFSegment
     24  *  \brief decribe the program header for ELF executable or shared object
     25  */
     26 class ELFSegment
     27 {
     28 public:
     29   typedef std::vector<LDSection*>::iterator sect_iterator;
     30   typedef std::vector<LDSection*>::const_iterator const_sect_iterator;
     31 public:
     32   ELFSegment(uint32_t pType,
     33              uint32_t pFlag = llvm::ELF::PF_R,
     34              uint64_t pOffset = 0,
     35              uint64_t pVaddr = 0,
     36              uint64_t pPaddr = 0,
     37              uint64_t pFilesz = 0,
     38              uint64_t pMemsz = 0,
     39              uint64_t pAlign = 0);
     40   ~ELFSegment();
     41 
     42   ///  -----  iterators  -----  ///
     43   sect_iterator sectBegin()
     44   { return m_SectionList.begin(); }
     45 
     46   sect_iterator sectEnd()
     47   { return m_SectionList.end(); }
     48 
     49   const_sect_iterator sectBegin() const
     50   { return m_SectionList.begin(); }
     51 
     52   const_sect_iterator sectEnd() const
     53   { return m_SectionList.end(); }
     54 
     55   const LDSection* getFirstSection()
     56   {
     57     if (0 == m_SectionList.size())
     58       return NULL;
     59     return m_SectionList[0];
     60   }
     61 
     62   const LDSection* getLastSection()
     63   {
     64     size_t size = m_SectionList.size();
     65     if (0 == size)
     66       return NULL;
     67     return m_SectionList[size - 1];
     68   }
     69 
     70   const LDSection* getFirstSection() const
     71   {
     72     if (0 == m_SectionList.size())
     73       return NULL;
     74     return m_SectionList[0];
     75   }
     76 
     77   const LDSection* getLastSection() const
     78   {
     79     size_t size = m_SectionList.size();
     80     if (0 == size)
     81       return NULL;
     82     return m_SectionList[size - 1];
     83   }
     84 
     85   ///  -----  observers  -----  ///
     86   uint32_t type() const
     87   { return m_Type; }
     88 
     89   uint64_t offset() const
     90   { return m_Offset; }
     91 
     92   uint64_t vaddr() const
     93   { return m_Vaddr; }
     94 
     95   uint64_t paddr() const
     96   { return m_Paddr; }
     97 
     98   uint64_t filesz() const
     99   { return m_Filesz; }
    100 
    101   uint64_t memsz() const
    102   { return m_Memsz; }
    103 
    104   uint32_t flag() const
    105   { return m_Flag; }
    106 
    107   uint64_t align() const
    108   { return m_Align; }
    109 
    110   size_t numOfSections() const
    111   { return m_SectionList.size(); }
    112 
    113   ///  -----  modifiers  -----  ///
    114   void setOffset(uint64_t pOffset)
    115   { m_Offset = pOffset; }
    116 
    117   void setVaddr(uint64_t pVaddr)
    118   { m_Vaddr = pVaddr; }
    119 
    120   void setPaddr(uint64_t pPaddr)
    121   { m_Paddr = pPaddr; }
    122 
    123   void setFilesz(uint64_t pFilesz)
    124   { m_Filesz = pFilesz; }
    125 
    126   void setMemsz(uint64_t pMemsz)
    127   { m_Memsz = pMemsz; }
    128 
    129   void setFlag(uint32_t pFlag)
    130   { m_Flag = pFlag; }
    131 
    132   void updateFlag(uint32_t pFlag)
    133   {
    134     // PT_TLS segment should be PF_R
    135     if (llvm::ELF::PT_TLS != m_Type)
    136       m_Flag |= pFlag;
    137   }
    138 
    139   void setAlign(uint64_t pAlign)
    140   { m_Align = pAlign; }
    141 
    142   void addSection(LDSection* pSection)
    143   {
    144     assert(NULL != pSection);
    145     m_SectionList.push_back(pSection);
    146   }
    147 
    148 private:
    149   uint32_t m_Type;    // Type of segment
    150   uint32_t m_Flag;    // Segment flags
    151   uint64_t m_Offset;  // File offset where segment is located, in bytes
    152   uint64_t m_Vaddr;   // Virtual address of beginning of segment
    153   uint64_t m_Paddr;   // Physical address of beginning of segment (OS-specific)
    154   uint64_t m_Filesz;  // Num. of bytes in file image of segment (may be zero)
    155   uint64_t m_Memsz;   // Num. of bytes in mem image of segment (may be zero)
    156   uint64_t m_Align;   // Segment alignment constraint
    157   std::vector<LDSection*> m_SectionList;
    158 };
    159 
    160 } // namespace of mcld
    161 
    162 #endif
    163