LIEF: Library to Instrument Executable Formats Version 1.0.0
Loading...
Searching...
No Matches
Segment.hpp
Go to the documentation of this file.
1/* Copyright 2017 - 2026 R. Thomas
2 * Copyright 2017 - 2026 Quarkslab
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef LIEF_ELF_SEGMENT_H
17#define LIEF_ELF_SEGMENT_H
18
19#include <string>
20#include <vector>
21#include <ostream>
22#include <memory>
23
24#include "LIEF/Object.hpp"
26#include "LIEF/visibility.h"
27#include "LIEF/errors.hpp"
28#include "LIEF/iterators.hpp"
29#include "LIEF/span.hpp"
30
31#include "LIEF/ELF/Header.hpp"
32
33#include "LIEF/ELF/enums.hpp"
34
35namespace LIEF {
36class SpanStream;
37
38namespace ELF {
39namespace DataHandler {
40class Handler;
41}
42
43class Parser;
44class Binary;
45class Section;
46class Builder;
47
49class LIEF_API Segment : public Object {
50
51 friend class Parser;
52 friend class Section;
53 friend class Binary;
54 friend class Builder;
55
56 public:
57 using sections_t = std::vector<Section*>;
60
61 // clang-format off
62 static constexpr uint64_t PT_BIT = 33;
63 static constexpr uint64_t PT_OS_BIT = 53;
64 static constexpr uint64_t PT_MASK = (uint64_t(1) << PT_BIT) - 1;
65
66 static constexpr uint64_t PT_ARM = uint64_t(1) << PT_BIT;
67 static constexpr uint64_t PT_AARCH64 = uint64_t(2) << PT_BIT;
68 static constexpr uint64_t PT_MIPS = uint64_t(3) << PT_BIT;
69 static constexpr uint64_t PT_RISCV = uint64_t(4) << PT_BIT;
70 static constexpr uint64_t PT_IA_64 = uint64_t(5) << PT_BIT;
71
72 static constexpr uint64_t PT_HPUX = uint64_t(1) << PT_OS_BIT;
73
74 enum class TYPE : uint64_t {
75 UNKNOWN = uint64_t(-1),
76 PT_NULL_ = 0,
77 LOAD = 1,
78 DYNAMIC = 2,
79 INTERP = 3,
80 NOTE = 4,
81 SHLIB = 5,
82 PHDR = 6,
83 TLS = 7,
84
85 GNU_EH_FRAME = 0x6474e550,
86
87 GNU_STACK = 0x6474e551,
88 GNU_PROPERTY = 0x6474e553,
89 GNU_RELRO = 0x6474e552,
90 PAX_FLAGS = 0x65041580,
91
92 ARM_ARCHEXT = 0x70000000 | PT_ARM,
93 ARM_EXIDX = 0x70000001 | PT_ARM,
94
95 AARCH64_MEMTAG_MTE = 0x70000002 | PT_AARCH64,
96
97 MIPS_REGINFO = 0x70000000 | PT_MIPS,
98 MIPS_RTPROC = 0x70000001 | PT_MIPS,
99 MIPS_OPTIONS = 0x70000002 | PT_MIPS,
100 MIPS_ABIFLAGS = 0x70000003 | PT_MIPS,
101
102 RISCV_ATTRIBUTES = 0x70000003 | PT_RISCV,
103
104 IA_64_EXT = (0x70000000 + 0x0) | PT_IA_64,
105 IA_64_UNWIND = (0x70000000 + 0x1) | PT_IA_64,
106
107 HP_TLS = (0x60000000 + 0x00) | PT_HPUX,
108 HP_CORE_NONE = (0x60000000 + 0x01) | PT_HPUX,
109 HP_CORE_VERSION = (0x60000000 + 0x02) | PT_HPUX,
110 HP_CORE_KERNEL = (0x60000000 + 0x03) | PT_HPUX,
111 HP_CORE_COMM = (0x60000000 + 0x04) | PT_HPUX,
112 HP_CORE_PROC = (0x60000000 + 0x05) | PT_HPUX,
113 HP_CORE_LOADABLE = (0x60000000 + 0x06) | PT_HPUX,
114 HP_CORE_STACK = (0x60000000 + 0x07) | PT_HPUX,
115 HP_CORE_SHM = (0x60000000 + 0x08) | PT_HPUX,
116 HP_CORE_MMF = (0x60000000 + 0x09) | PT_HPUX,
117 HP_PARALLEL = (0x60000000 + 0x10) | PT_HPUX,
118 HP_FASTBIND = (0x60000000 + 0x11) | PT_HPUX,
119 HP_OPT_ANNOT = (0x60000000 + 0x12) | PT_HPUX,
120 HP_HSL_ANNOT = (0x60000000 + 0x13) | PT_HPUX,
121 HP_STACK = (0x60000000 + 0x14) | PT_HPUX,
122 HP_CORE_UTSNAME = (0x60000000 + 0x15) | PT_HPUX,
123 };
124 // clang-format on
125
126 enum class FLAGS {
127 NONE = 0,
128 X = 1,
129 W = 2,
130 R = 4,
131 };
132
133 static TYPE type_from(uint64_t value, ARCH arch, Header::OS_ABI os);
134 static uint64_t to_value(TYPE type) {
135 return static_cast<uint64_t>(type) & PT_MASK;
136 }
137
138 static result<Segment> from_raw(const uint8_t* ptr, size_t size);
139 static result<Segment> from_raw(const std::vector<uint8_t>& raw) {
140 return from_raw(raw.data(), raw.size());
141 }
142
143 Segment() = default;
144
145 ~Segment() override = default;
146
148 Segment(const Segment& other);
149
150 Segment& operator=(Segment&&) = default;
151 Segment(Segment&&) = default;
152
153 void swap(Segment& other);
154
155 bool is_load() const {
156 return type() == TYPE::LOAD;
157 }
158
159 bool is_interpreter() const {
160 return type() == TYPE::INTERP;
161 }
162
163 bool is_phdr() const {
164 return type() == TYPE::PHDR;
165 }
166
168 TYPE type() const {
169 return type_;
170 }
171
173 FLAGS flags() const {
174 return FLAGS(flags_);
175 }
176
178 uint64_t file_offset() const {
179 return file_offset_;
180 }
181
183 uint64_t virtual_address() const {
184 return virtual_address_;
185 }
186
192 uint64_t physical_address() const {
193 return physical_address_;
194 }
195
197 uint64_t physical_size() const {
198 return size_;
199 }
200
204 uint64_t virtual_size() const {
205 return virtual_size_;
206 }
207
209 uint64_t alignment() const {
210 return alignment_;
211 }
212
215
217 bool has(FLAGS flag) const {
218 return (flags_ & static_cast<uint64_t>(flag)) != 0;
219 }
220
222 bool has(const Section& section) const;
223
225 bool has(const std::string& section_name) const;
226
228 void add(FLAGS flag);
229
231 void remove(FLAGS flag);
232
233 void type(TYPE type) {
234 type_ = type;
235 }
236
238 flags_ = static_cast<uint32_t>(flags);
239 }
240
241 void flags(uint32_t flags) {
242 flags_ = flags;
243 }
244
245 void clear_flags() {
246 flags_ = 0;
247 }
248
249 void file_offset(uint64_t file_offset);
250
252 virtual_address_ = virtual_address;
253 }
254
256 physical_address_ = physical_address;
257 }
258
260
261 void virtual_size(uint64_t virtual_size) {
262 virtual_size_ = virtual_size;
263 }
264
265 void alignment(uint64_t alignment) {
266 alignment_ = alignment;
267 }
268
269 void content(std::vector<uint8_t> content);
270
272 void fill(char c) {
273 span<uint8_t> buffer = writable_content();
274 std::fill(buffer.begin(), buffer.end(), c);
275 }
276
278 void clear() {
279 fill('\0');
280 }
281
282 template<typename T>
283 T get_content_value(size_t offset) const;
284 template<typename T>
285 void set_content_value(size_t offset, T value);
286 size_t get_content_size() const;
287
290 return sections_;
291 }
292
294 return sections_;
295 }
296
297 std::unique_ptr<SpanStream> stream() const;
298
299 void accept(Visitor& visitor) const override;
300
302 add(flag);
303 return *this;
304 }
305
307 remove(flag);
308 return *this;
309 }
310
311 LIEF_API friend std::ostream& operator<<(std::ostream& os,
312 const Segment& segment);
313
314 private:
315 template<class T>
316 LIEF_LOCAL Segment(const T& header, ARCH arch = ARCH::NONE,
318
319 LIEF_LOCAL uint64_t handler_size() const;
320 span<uint8_t> writable_content() LIEF_LIFETIMEBOUND;
321
322 TYPE type_ = TYPE::PT_NULL_;
323 ARCH arch_ = ARCH::NONE;
324 uint32_t flags_ = 0;
325 uint64_t file_offset_ = 0;
326 uint64_t virtual_address_ = 0;
327 uint64_t physical_address_ = 0;
328 uint64_t size_ = 0;
329 uint64_t virtual_size_ = 0;
330 uint64_t alignment_ = 0;
331 uint64_t handler_size_ = 0;
332 sections_t sections_;
333 DataHandler::Handler* datahandler_ = nullptr;
334 std::vector<uint8_t> content_c_;
335};
336
337LIEF_API const char* to_string(Segment::TYPE e);
338LIEF_API const char* to_string(Segment::FLAGS e);
339}
340}
341
342
343ENABLE_BITMASK_OPERATORS(LIEF::ELF::Segment::FLAGS);
344
345#endif /* _ELF_SEGMENT_H */
Class which represents an ELF binary.
Definition ELF/Binary.hpp:60
Class which takes an ELF::Binary object and reconstructs a valid binary.
Definition ELF/Builder.hpp:48
OS_ABI
Match the result Elfxx_Ehdr.e_ident[EI_OSABI].
Definition ELF/Header.hpp:81
@ SYSTEMV
UNIX System V ABI.
Definition ELF/Header.hpp:82
Class which parses and transforms an ELF file into a ELF::Binary object.
Definition ELF/Parser.hpp:44
Class which represents an ELF Section.
Definition ELF/Section.hpp:49
Class which represents the ELF segments.
Definition Segment.hpp:49
uint64_t physical_address() const
The physical address of the segment. This value is not really relevant on systems like Linux or Andro...
Definition Segment.hpp:192
void physical_address(uint64_t physical_address)
Definition Segment.hpp:255
std::vector< Section * > sections_t
Definition Segment.hpp:57
void add(FLAGS flag)
Append the given ELF_SEGMENT_FLAGS.
static constexpr uint64_t PT_ARM
Definition Segment.hpp:66
static result< Segment > from_raw(const std::vector< uint8_t > &raw)
Definition Segment.hpp:139
friend class Section
Definition Segment.hpp:52
void fill(char c)
Fill the content of this segment with the value provided in parameter.
Definition Segment.hpp:272
size_t get_content_size() const
T get_content_value(size_t offset) const
static constexpr uint64_t PT_MASK
Definition Segment.hpp:64
static constexpr uint64_t PT_BIT
Definition Segment.hpp:62
bool is_interpreter() const
Definition Segment.hpp:159
void flags(FLAGS flags)
Definition Segment.hpp:237
void clear()
Clear the content of this segment.
Definition Segment.hpp:278
~Segment() override=default
bool is_phdr() const
Definition Segment.hpp:163
uint64_t physical_size() const
The file size of the data associated with this segment.
Definition Segment.hpp:197
void clear_flags()
Definition Segment.hpp:245
Segment & operator-=(FLAGS flag)
Definition Segment.hpp:306
bool has(const std::string &section_name) const
Check if the current segment wraps the given section's name.
void flags(uint32_t flags)
Definition Segment.hpp:241
Segment & operator+=(FLAGS flag)
Definition Segment.hpp:301
void set_content_value(size_t offset, T value)
void file_offset(uint64_t file_offset)
Segment & operator=(Segment other)
void remove(FLAGS flag)
Remove the given ELF_SEGMENT_FLAGS.
Segment & operator=(Segment &&)=default
void type(TYPE type)
Definition Segment.hpp:233
static constexpr uint64_t PT_MIPS
Definition Segment.hpp:68
uint64_t virtual_address() const
The virtual address of the segment.
Definition Segment.hpp:183
span< const uint8_t > content() const
The raw data associated with this segment.
bool has(FLAGS flag) const
Check if the current segment has the given flag.
Definition Segment.hpp:217
static constexpr uint64_t PT_AARCH64
Definition Segment.hpp:67
void swap(Segment &other)
friend class Builder
Definition Segment.hpp:54
FLAGS
Definition Segment.hpp:126
it_sections sections()
Iterator over the sections wrapped by this segment.
Definition Segment.hpp:289
void virtual_size(uint64_t virtual_size)
Definition Segment.hpp:261
static TYPE type_from(uint64_t value, ARCH arch, Header::OS_ABI os)
TYPE type() const
The segment's type (LOAD, DYNAMIC, ...).
Definition Segment.hpp:168
void content(std::vector< uint8_t > content)
friend class Binary
Definition Segment.hpp:53
void physical_size(uint64_t physical_size)
static constexpr uint64_t PT_RISCV
Definition Segment.hpp:69
bool has(const Section &section) const
Check if the current segment wraps the given ELF::Section.
uint64_t file_offset() const
The file offset of the data associated with this segment.
Definition Segment.hpp:178
bool is_load() const
Definition Segment.hpp:155
it_const_sections sections() const
Definition Segment.hpp:293
friend class Parser
Definition Segment.hpp:51
TYPE
Definition Segment.hpp:74
@ LOAD
Definition Segment.hpp:77
@ PHDR
Definition Segment.hpp:82
@ INTERP
Definition Segment.hpp:79
Segment(const Segment &other)
static constexpr uint64_t PT_IA_64
Definition Segment.hpp:70
uint64_t alignment() const
The offset alignment of the segment.
Definition Segment.hpp:209
static constexpr uint64_t PT_HPUX
Definition Segment.hpp:72
static uint64_t to_value(TYPE type)
Definition Segment.hpp:134
ref_iterator< sections_t & > it_sections
Definition Segment.hpp:58
FLAGS flags() const
The flag permissions associated with this segment.
Definition Segment.hpp:173
void virtual_address(uint64_t virtual_address)
Definition Segment.hpp:251
std::unique_ptr< SpanStream > stream() const
Segment(Segment &&)=default
static constexpr uint64_t PT_OS_BIT
Definition Segment.hpp:63
static result< Segment > from_raw(const uint8_t *ptr, size_t size)
uint64_t virtual_size() const
The in-memory size of this segment. Usually, if the .bss segment is wrapped by this segment then,...
Definition Segment.hpp:204
void alignment(uint64_t alignment)
Definition Segment.hpp:265
void accept(Visitor &visitor) const override
const_ref_iterator< const sections_t & > it_const_sections
Definition Segment.hpp:59
friend std::ostream & operator<<(std::ostream &os, const Segment &segment)
Definition SpanStream.hpp:32
Definition Visitor.hpp:212
Iterator which returns reference on container's values.
Definition iterators.hpp:47
Wrapper that contains an Object (T) or an error.
Definition errors.hpp:78
#define LIEF_LIFETIMEBOUND
Definition compiler_attributes.hpp:72
#define ENABLE_BITMASK_OPERATORS(X)
Definition enums.hpp:24
Definition ELF/Binary.hpp:39
Namespace related to the LIEF's ELF module.
Definition Abstract/Header.hpp:28
const char * to_string(DynamicEntry::TAG e)
ARCH
Definition ELF/enums.hpp:30
@ NONE
Definition ELF/enums.hpp:31
LIEF namespace.
Definition Abstract/Binary.hpp:41
tcb::span< ElementType, Extent > span
Definition span.hpp:22
ref_iterator< CT, U, typename decay_t< CT >::const_iterator > const_ref_iterator
Iterator which returns a const ref on container's values.
Definition iterators.hpp:320
#define LIEF_API
Definition visibility.h:45
#define LIEF_LOCAL
Definition visibility.h:46