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