LIEF: Library to Instrument Executable Formats Version 2.0.0
Loading...
Searching...
No Matches
ELF/Section.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_SECTION_H
17#define LIEF_ELF_SECTION_H
18
19#include <string_view>
20#include <memory>
21#include <ostream>
22#include <string>
23#include <vector>
24
27#include "LIEF/utils.hpp"
28#include "LIEF/visibility.h"
29
30#include "LIEF/ELF/enums.hpp"
31#include "LIEF/iterators.hpp"
32
33namespace LIEF {
34class SpanStream;
35namespace ELF {
36
37namespace DataHandler {
38class Handler;
39}
40
41class Segment;
42class Parser;
43class Binary;
44class Builder;
45class ExeLayout;
46class ObjectFileLayout;
47
48
51 friend class Parser;
52 friend class Binary;
53 friend class Builder;
54 friend class ExeLayout;
55 friend class ObjectFileLayout;
56
57 public:
58 using segments_t = std::vector<Segment*>;
61
62 static constexpr uint32_t MAX_SECTION_SIZE = 2_GB;
63
64 // clang-format off
65 enum class TYPE : uint64_t {
66 SHT_NULL_ = 0,
67 PROGBITS = 1,
68 SYMTAB = 2,
69 STRTAB = 3,
70 RELA = 4,
71 HASH = 5,
72 DYNAMIC = 6,
73 NOTE = 7,
74 NOBITS = 8,
75 REL = 9,
76 SHLIB = 10,
77 DYNSYM = 11,
78 INIT_ARRAY = 14,
79 FINI_ARRAY = 15,
80 PREINIT_ARRAY = 16,
81 GROUP = 17,
82 SYMTAB_SHNDX = 18,
83 RELR = 19,
84
85 ANDROID_REL = 0x60000001,
86 ANDROID_RELA = 0x60000002,
87
88 LLVM_ADDRSIG = 0x6fff4c03,
90
91 ANDROID_RELR = 0x6fffff00,
92 GNU_ATTRIBUTES = 0x6ffffff5,
93 GNU_HASH = 0x6ffffff6,
94 GNU_VERDEF = 0x6ffffffd,
95 GNU_VERNEED = 0x6ffffffe,
96 GNU_VERSYM = 0x6fffffff,
97
98 _ID_SHIFT_ = 32,
99 _ARM_ID_ = 1LLU,
100 _HEX_ID_ = 2LLU,
101 _X86_64_ID_ = 2LLU,
102 _MIPS_ID_ = 3LLU,
103 _RISCV_ID_ = 4LLU,
104 _AARCH64_ID_ = 5LLU,
105
106 ARM_EXIDX = 0x70000001U + (_ARM_ID_ << _ID_SHIFT_),
107 ARM_PREEMPTMAP = 0x70000002U + (_ARM_ID_ << _ID_SHIFT_),
108 ARM_ATTRIBUTES = 0x70000003U + (_ARM_ID_ << _ID_SHIFT_),
109 ARM_DEBUGOVERLAY = 0x70000004U + (_ARM_ID_ << _ID_SHIFT_),
110 ARM_OVERLAYSECTION = 0x70000005U + (_ARM_ID_ << _ID_SHIFT_),
111
112 HEX_ORDERED = 0x70000000 + (_HEX_ID_ << _ID_SHIFT_),
114
115 /* this section based on their sizes */
116 X86_64_UNWIND = 0x70000001 + (_X86_64_ID_ << _ID_SHIFT_),
117
118 MIPS_LIBLIST = 0x70000000 + (_MIPS_ID_ << _ID_SHIFT_),
119 MIPS_MSYM = 0x70000001 + (_MIPS_ID_ << _ID_SHIFT_),
120 MIPS_CONFLICT = 0x70000002 + (_MIPS_ID_ << _ID_SHIFT_),
121 MIPS_GPTAB = 0x70000003 + (_MIPS_ID_ << _ID_SHIFT_),
122 MIPS_UCODE = 0x70000004 + (_MIPS_ID_ << _ID_SHIFT_),
123 MIPS_DEBUG = 0x70000005 + (_MIPS_ID_ << _ID_SHIFT_),
124 MIPS_REGINFO = 0x70000006 + (_MIPS_ID_ << _ID_SHIFT_),
125 MIPS_PACKAGE = 0x70000007 + (_MIPS_ID_ << _ID_SHIFT_),
126 MIPS_PACKSYM = 0x70000008 + (_MIPS_ID_ << _ID_SHIFT_),
127 MIPS_RELD = 0x70000009 + (_MIPS_ID_ << _ID_SHIFT_),
128 MIPS_IFACE = 0x7000000b + (_MIPS_ID_ << _ID_SHIFT_),
129 MIPS_CONTENT = 0x7000000c + (_MIPS_ID_ << _ID_SHIFT_),
130 MIPS_OPTIONS = 0x7000000d + (_MIPS_ID_ << _ID_SHIFT_),
131 MIPS_SHDR = 0x70000010 + (_MIPS_ID_ << _ID_SHIFT_),
132 MIPS_FDESC = 0x70000011 + (_MIPS_ID_ << _ID_SHIFT_),
133 MIPS_EXTSYM = 0x70000012 + (_MIPS_ID_ << _ID_SHIFT_),
134 MIPS_DENSE = 0x70000013 + (_MIPS_ID_ << _ID_SHIFT_),
135 MIPS_PDESC = 0x70000014 + (_MIPS_ID_ << _ID_SHIFT_),
136 MIPS_LOCSYM = 0x70000015 + (_MIPS_ID_ << _ID_SHIFT_),
137 MIPS_AUXSYM = 0x70000016 + (_MIPS_ID_ << _ID_SHIFT_),
138 MIPS_OPTSYM = 0x70000017 + (_MIPS_ID_ << _ID_SHIFT_),
139 MIPS_LOCSTR = 0x70000018 + (_MIPS_ID_ << _ID_SHIFT_),
140 MIPS_LINE = 0x70000019 + (_MIPS_ID_ << _ID_SHIFT_),
141 MIPS_RFDESC = 0x7000001a + (_MIPS_ID_ << _ID_SHIFT_),
142 MIPS_DELTASYM = 0x7000001b + (_MIPS_ID_ << _ID_SHIFT_),
143 MIPS_DELTAINST = 0x7000001c + (_MIPS_ID_ << _ID_SHIFT_),
144 MIPS_DELTACLASS = 0x7000001d + (_MIPS_ID_ << _ID_SHIFT_),
145 MIPS_DWARF = 0x7000001e + (_MIPS_ID_ << _ID_SHIFT_),
146 MIPS_DELTADECL = 0x7000001f + (_MIPS_ID_ << _ID_SHIFT_),
147 MIPS_SYMBOL_LIB = 0x70000020 + (_MIPS_ID_ << _ID_SHIFT_),
148 MIPS_EVENTS = 0x70000021 + (_MIPS_ID_ << _ID_SHIFT_),
149 MIPS_TRANSLATE = 0x70000022 + (_MIPS_ID_ << _ID_SHIFT_),
150 MIPS_PIXIE = 0x70000023 + (_MIPS_ID_ << _ID_SHIFT_),
151 MIPS_XLATE = 0x70000024 + (_MIPS_ID_ << _ID_SHIFT_),
152 MIPS_XLATE_DEBUG = 0x70000025 + (_MIPS_ID_ << _ID_SHIFT_),
153 MIPS_WHIRL = 0x70000026 + (_MIPS_ID_ << _ID_SHIFT_),
154 MIPS_EH_REGION = 0x70000027 + (_MIPS_ID_ << _ID_SHIFT_),
155 MIPS_XLATE_OLD = 0x70000028 + (_MIPS_ID_ << _ID_SHIFT_),
156 MIPS_PDR_EXCEPTION = 0x70000029 + (_MIPS_ID_ << _ID_SHIFT_),
157 MIPS_ABIFLAGS = 0x7000002a + (_MIPS_ID_ << _ID_SHIFT_),
158 MIPS_XHASH = 0x7000002b + (_MIPS_ID_ << _ID_SHIFT_),
159
160 RISCV_ATTRIBUTES = 0x70000003 + (_RISCV_ID_ << _ID_SHIFT_),
161
162 AARCH64_ATTRIBUTES = 0x70000003 + (_AARCH64_ID_ << _ID_SHIFT_),
163 AARCH64_AUTH_RELR = 0x70000004 + (_AARCH64_ID_ << _ID_SHIFT_),
164 AARCH64_MEMTAG_GLOBALS_STATIC = 0x70000007 + (_AARCH64_ID_ << _ID_SHIFT_),
165 AARCH64_MEMTAG_GLOBALS_DYNAMIC = 0x70000008 + (_AARCH64_ID_ << _ID_SHIFT_),
166 };
167
168 enum class FLAGS : uint64_t {
169 NONE = 0x000000000,
170 WRITE = 0x000000001,
171 ALLOC = 0x000000002,
172 EXECINSTR = 0x000000004,
173 MERGE = 0x000000010,
174 STRINGS = 0x000000020,
175 INFO_LINK = 0x000000040,
176 LINK_ORDER = 0x000000080,
177 OS_NONCONFORMING = 0x000000100,
178 GROUP = 0x000000200,
179 TLS = 0x000000400,
180 COMPRESSED = 0x000000800,
181 GNU_RETAIN = 0x000200000,
182 EXCLUDE = 0x080000000,
183
184 _ID_SHIFT_ = 32,
185 _XCORE_ID_ = 1LLU,
186 _HEX_ID_ = 3LLU,
187 _X86_64_ID_ = 2LLU,
188 _MIPS_ID_ = 4LLU,
189 _ARM_ID_ = 5LLU,
190 _AARCH64_ID_ = 6LLU,
191
192 XCORE_SHF_DP_SECTION = 0x010000000 + (_XCORE_ID_ << _ID_SHIFT_),
193 XCORE_SHF_CP_SECTION = 0x020000000 + (_XCORE_ID_ << _ID_SHIFT_),
194
195 X86_64_LARGE = 0x010000000 + (_X86_64_ID_ << _ID_SHIFT_),
196
197 HEX_GPREL = 0x010000000 + (_HEX_ID_ << _ID_SHIFT_),
198
199 MIPS_NODUPES = 0x001000000 + (_MIPS_ID_ << _ID_SHIFT_),
200 MIPS_NAMES = 0x002000000 + (_MIPS_ID_ << _ID_SHIFT_),
201 MIPS_LOCAL = 0x004000000 + (_MIPS_ID_ << _ID_SHIFT_),
202 MIPS_NOSTRIP = 0x008000000 + (_MIPS_ID_ << _ID_SHIFT_),
203 MIPS_GPREL = 0x010000000 + (_MIPS_ID_ << _ID_SHIFT_),
204 MIPS_MERGE = 0x020000000 + (_MIPS_ID_ << _ID_SHIFT_),
205 MIPS_ADDR = 0x040000000 + (_MIPS_ID_ << _ID_SHIFT_),
206 MIPS_STRING = 0x080000000 + (_MIPS_ID_ << _ID_SHIFT_),
207
208 ARM_PURECODE = 0x020000000 + (_ARM_ID_ << _ID_SHIFT_),
209
210 AARCH64_PURECODE = 0x020000000 + (_AARCH64_ID_ << _ID_SHIFT_),
211 };
212 // clang-format on
213
214 static constexpr uint64_t FLAG_MASK =
215 (uint64_t(1) << uint8_t(FLAGS::_ID_SHIFT_)) - 1;
216 static constexpr uint64_t TYPE_MASK =
217 (uint64_t(1) << uint8_t(TYPE::_ID_SHIFT_)) - 1;
218
219 static TYPE type_from(uint32_t value, ARCH arch);
220 static uint32_t to_value(TYPE type) {
221 return static_cast<uint64_t>(type) & TYPE_MASK;
222 }
223
224 Section(std::string_view name, TYPE type = TYPE::PROGBITS) :
225 LIEF::Section(std::string(name)),
226 type_{type} {}
227
228 Section() = default;
229 ~Section() override = default;
230
232 swap(other);
233 return *this;
234 }
235 Section(const Section& other);
236 void swap(Section& other) noexcept;
237
238 TYPE type() const {
239 return type_;
240 }
241
244
246 void content(const std::vector<uint8_t>& data) override;
247
248 void content(std::vector<uint8_t>&& data);
249
251 uint64_t flags() const {
252 return flags_;
253 }
254
256 bool has(FLAGS flag) const;
257
259 bool has(const Segment& segment) const;
260
262 std::vector<FLAGS> flags_list() const;
263
264 uint64_t size() const override {
265 return size_;
266 }
267
268 void size(uint64_t size) override;
269
270 void offset(uint64_t offset) override;
271
272 uint64_t offset() const override {
273 return offset_;
274 }
275
277 uint64_t file_offset() const {
278 return this->offset();
279 }
280
285 uint64_t original_size() const {
286 return original_size_;
287 }
288
290 uint64_t alignment() const {
291 return address_align_;
292 }
293
296 uint64_t information() const {
297 return info_;
298 }
299
306 uint64_t entry_size() const {
307 return entry_size_;
308 }
309
311 uint32_t link() const {
312 return link_;
313 }
314
316 Section& clear(uint8_t value = 0) LIEF_LIFETIMEBOUND;
317
319 void add(FLAGS flag);
320
322 void remove(FLAGS flag);
323
324 void type(TYPE type) {
325 type_ = type;
326 }
327
328 void flags(uint64_t flags) {
329 flags_ = flags;
330 }
331
332 void clear_flags() {
333 flags_ = 0;
334 }
335
336 void file_offset(uint64_t offset) {
337 this->offset(offset);
338 }
339
340 void link(uint32_t link) {
341 link_ = link;
342 }
343
344 void information(uint32_t info) {
345 info_ = info;
346 }
347
348 void alignment(uint64_t alignment) {
349 address_align_ = alignment;
350 }
351
352 void entry_size(uint64_t entry_size) {
353 entry_size_ = entry_size;
354 }
355
357 return segments_;
358 }
359
361 return segments_;
362 }
363
365 is_frame_ = true;
366 return *this;
367 }
368
369 bool is_frame() const {
370 return is_frame_;
371 }
372
373 void accept(Visitor& visitor) const override;
374
376 add(c);
377 return *this;
378 }
379
381 remove(c);
382 return *this;
383 }
384
386 std::unique_ptr<SpanStream> stream() const;
387
388 LIEF_API friend std::ostream& operator<<(std::ostream& os,
389 const Section& section);
390
391 private:
392 template<class T>
393 LIEF_LOCAL Section(const T& header, ARCH arch);
394
396 ARCH arch_ = ARCH::NONE;
397 TYPE type_ = TYPE::SHT_NULL_;
398 uint64_t flags_ = 0;
399 uint64_t original_size_ = 0;
400 uint32_t link_ = 0;
401 uint32_t info_ = 0;
402 uint64_t address_align_ = 0;
403 uint64_t entry_size_ = 0;
404 segments_t segments_;
405 bool is_frame_ = false;
406 DataHandler::Handler* datahandler_ = nullptr;
407 std::vector<uint8_t> content_c_;
408};
409
410LIEF_API const char* to_string(Section::TYPE e);
411LIEF_API const char* to_string(Section::FLAGS e);
412
413}
414}
415
416ENABLE_BITMASK_OPERATORS(LIEF::ELF::Section::FLAGS);
417
418#endif
Class which represents an ELF binary.
Definition ELF/Binary.hpp:61
Class which takes an ELF::Binary object and reconstructs a valid binary.
Definition ELF/Builder.hpp:48
Class which parses and transforms an ELF file into a ELF::Binary object.
Definition ELF/Parser.hpp:47
Class which represents an ELF Section.
Definition ELF/Section.hpp:50
friend class ObjectFileLayout
Definition ELF/Section.hpp:55
void size(uint64_t size) override
Change the section size.
static TYPE type_from(uint32_t value, ARCH arch)
ref_iterator< segments_t & > it_segments
Definition ELF/Section.hpp:59
span< const uint8_t > content() const override
Section's content.
it_segments segments()
Definition ELF/Section.hpp:356
uint64_t original_size() const
Original size of the section's data.
Definition ELF/Section.hpp:285
friend class ExeLayout
Definition ELF/Section.hpp:54
Section & operator+=(FLAGS c)
Definition ELF/Section.hpp:375
void clear_flags()
Definition ELF/Section.hpp:332
uint64_t flags() const
Section flags.
Definition ELF/Section.hpp:251
std::vector< Segment * > segments_t
Definition ELF/Section.hpp:58
static constexpr uint64_t TYPE_MASK
Definition ELF/Section.hpp:216
Section & as_frame()
Definition ELF/Section.hpp:364
void offset(uint64_t offset) override
static constexpr uint64_t FLAG_MASK
Definition ELF/Section.hpp:214
friend std::ostream & operator<<(std::ostream &os, const Section &section)
void remove(FLAGS flag)
Remove the given ELF_SECTION_FLAGS.
std::vector< FLAGS > flags_list() const
Return section flags as a std::set.
bool is_frame() const
Definition ELF/Section.hpp:369
uint64_t file_offset() const
Definition ELF/Section.hpp:277
~Section() override=default
void alignment(uint64_t alignment)
Definition ELF/Section.hpp:348
void information(uint32_t info)
Definition ELF/Section.hpp:344
static uint32_t to_value(TYPE type)
Definition ELF/Section.hpp:220
std::unique_ptr< SpanStream > stream() const
Return a stream over the content of this section.
Section(const Section &other)
const_ref_iterator< const segments_t & > it_const_segments
Definition ELF/Section.hpp:60
TYPE type() const
Definition ELF/Section.hpp:238
friend class Builder
Definition ELF/Section.hpp:53
TYPE
Definition ELF/Section.hpp:65
@ _ID_SHIFT_
Definition ELF/Section.hpp:98
@ PROGBITS
Definition ELF/Section.hpp:67
Section & operator-=(FLAGS c)
Definition ELF/Section.hpp:380
uint32_t link() const
Index to another section.
Definition ELF/Section.hpp:311
uint64_t size() const override
Section's size (size in the binary, not the virtual size).
Definition ELF/Section.hpp:264
friend class Binary
Definition ELF/Section.hpp:52
Section & clear(uint8_t value=0)
Clear the content of the section with the given value.
void accept(Visitor &visitor) const override
void swap(Section &other) noexcept
bool has(const Segment &segment) const
True if the section is wrapped by the given Segment
void entry_size(uint64_t entry_size)
Definition ELF/Section.hpp:352
friend class Parser
Definition ELF/Section.hpp:51
FLAGS
Definition ELF/Section.hpp:168
@ _ID_SHIFT_
Definition ELF/Section.hpp:184
uint64_t information() const
Section information. The meaning of this value depends on the section's type.
Definition ELF/Section.hpp:296
Section(std::string_view name, TYPE type=TYPE::PROGBITS)
Definition ELF/Section.hpp:224
uint64_t offset() const override
Offset in the binary.
Definition ELF/Section.hpp:272
static constexpr uint32_t MAX_SECTION_SIZE
Definition ELF/Section.hpp:62
void link(uint32_t link)
Definition ELF/Section.hpp:340
void add(FLAGS flag)
Add the given ELF_SECTION_FLAGS.
Section & operator=(Section other)
Definition ELF/Section.hpp:231
uint64_t alignment() const
Section file alignment.
Definition ELF/Section.hpp:290
it_const_segments segments() const
Definition ELF/Section.hpp:360
bool has(FLAGS flag) const
True if the section has the given flag
uint64_t entry_size() const
This function returns the size of an element in the case of a section that contains an array.
Definition ELF/Section.hpp:306
void file_offset(uint64_t offset)
Definition ELF/Section.hpp:336
void flags(uint64_t flags)
Definition ELF/Section.hpp:328
Class which represents the ELF segments.
Definition Segment.hpp:49
Class which represents an abstracted section.
Definition Abstract/Section.hpp:31
virtual std::string_view name() const
Section's name.
Definition Abstract/Section.hpp:45
Definition SpanStream.hpp:32
Definition Visitor.hpp:212
Iterator which returns reference on container's values.
Definition iterators.hpp:121
#define LIEF_LIFETIMEBOUND
Definition compiler_attributes.hpp:72
#define ENABLE_BITMASK_OPERATORS(X)
Definition enums.hpp:24
Definition ELF/Binary.hpp:40
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:28
@ NONE
Definition ELF/enums.hpp:29
LIEF namespace.
Definition Abstract/Binary.hpp:42
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:386
#define LIEF_API
Definition visibility.h:45
#define LIEF_LOCAL
Definition visibility.h:46