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