summaryrefslogtreecommitdiff
path: root/include/mcld/LD/ELFSegment.h
blob: 312f0a767cec61e06b3599fcd282b500b55144b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//===- ELFSegment.h -------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_ELF_SEGMENT_H
#define MCLD_ELF_SEGMENT_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include <llvm/Support/ELF.h>
#include <llvm/Support/DataTypes.h>
#include <mcld/LD/LDSection.h>
#include <cassert>
#include <vector>

namespace mcld
{

/** \class ELFSegment
 *  \brief decribe the program header for ELF executable or shared object
 */
class ELFSegment
{
public:
  typedef std::vector<LDSection*>::iterator sect_iterator;
  typedef std::vector<LDSection*>::const_iterator const_sect_iterator;
public:
  ELFSegment(uint32_t pType,
             uint32_t pFlag = llvm::ELF::PF_R,
             uint64_t pOffset = 0,
             uint64_t pVaddr = 0,
             uint64_t pPaddr = 0,
             uint64_t pFilesz = 0,
             uint64_t pMemsz = 0,
             uint64_t pAlign = 0);
  ~ELFSegment();

  ///  -----  iterators  -----  ///
  sect_iterator sectBegin()
  { return m_SectionList.begin(); }

  sect_iterator sectEnd()
  { return m_SectionList.end(); }

  const_sect_iterator sectBegin() const
  { return m_SectionList.begin(); }

  const_sect_iterator sectEnd() const
  { return m_SectionList.end(); }

  const LDSection* getFirstSection()
  {
    if (0 == m_SectionList.size())
      return NULL;
    return m_SectionList[0];
  }

  const LDSection* getLastSection()
  {
    size_t size = m_SectionList.size();
    if (0 == size)
      return NULL;
    return m_SectionList[size - 1];
  }

  const LDSection* getFirstSection() const
  {
    if (0 == m_SectionList.size())
      return NULL;
    return m_SectionList[0];
  }

  const LDSection* getLastSection() const
  {
    size_t size = m_SectionList.size();
    if (0 == size)
      return NULL;
    return m_SectionList[size - 1];
  }

  ///  -----  observers  -----  ///
  uint32_t type() const
  { return m_Type; }

  uint64_t offset() const
  { return m_Offset; }

  uint64_t vaddr() const
  { return m_Vaddr; }

  uint64_t paddr() const
  { return m_Paddr; }

  uint64_t filesz() const
  { return m_Filesz; }

  uint64_t memsz() const
  { return m_Memsz; }

  uint32_t flag() const
  { return m_Flag; }

  uint64_t align() const
  { return m_Align; }

  size_t numOfSections() const
  { return m_SectionList.size(); }

  ///  -----  modifiers  -----  ///
  void setOffset(uint64_t pOffset)
  { m_Offset = pOffset; }

  void setVaddr(uint64_t pVaddr)
  { m_Vaddr = pVaddr; }

  void setPaddr(uint64_t pPaddr)
  { m_Paddr = pPaddr; }

  void setFilesz(uint64_t pFilesz)
  { m_Filesz = pFilesz; }

  void setMemsz(uint64_t pMemsz)
  { m_Memsz = pMemsz; }

  void setFlag(uint32_t pFlag)
  { m_Flag = pFlag; }

  void updateFlag(uint32_t pFlag)
  {
    // PT_TLS segment should be PF_R
    if (llvm::ELF::PT_TLS != m_Type)
      m_Flag |= pFlag;
  }

  void setAlign(uint64_t pAlign)
  { m_Align = pAlign; }

  void addSection(LDSection* pSection)
  {
    assert(NULL != pSection);
    m_SectionList.push_back(pSection);
  }

private:
  uint32_t m_Type;    // Type of segment
  uint32_t m_Flag;    // Segment flags
  uint64_t m_Offset;  // File offset where segment is located, in bytes
  uint64_t m_Vaddr;   // Virtual address of beginning of segment
  uint64_t m_Paddr;   // Physical address of beginning of segment (OS-specific)
  uint64_t m_Filesz;  // Num. of bytes in file image of segment (may be zero)
  uint64_t m_Memsz;   // Num. of bytes in mem image of segment (may be zero)
  uint64_t m_Align;   // Segment alignment constraint
  std::vector<LDSection*> m_SectionList;
};

} // namespace of mcld

#endif