LIEF: Library to Instrument Executable Formats Version 0.15.0
Loading...
Searching...
No Matches
ELF/Section.hpp
1/* Copyright 2017 - 2024 R. Thomas
2 * Copyright 2017 - 2024 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>
20#include <ostream>
21#include <vector>
22
23#include "LIEF/utils.hpp"
24#include "LIEF/visibility.h"
25#include "LIEF/Abstract/Section.hpp"
26
27#include "LIEF/ELF/enums.hpp"
28#include "LIEF/iterators.hpp"
29
30namespace LIEF {
31namespace ELF {
32
33namespace DataHandler {
34class Handler;
35}
36
37class Segment;
38class Parser;
39class Binary;
40class Builder;
41class ExeLayout;
42class ObjectFileLayout;
43
44
46class LIEF_API Section : public LIEF::Section {
47 friend class Parser;
48 friend class Binary;
49 friend class Builder;
50 friend class ExeLayout;
51 friend class ObjectFileLayout;
52
53 public:
54 using segments_t = std::vector<Segment*>;
57
58 static constexpr uint32_t MAX_SECTION_SIZE = 2_GB;
59
60 enum class TYPE : uint64_t {
61 SHT_NULL = 0,
62 PROGBITS = 1,
63 SYMTAB = 2,
64 STRTAB = 3,
65 RELA = 4,
66 HASH = 5,
67 DYNAMIC = 6,
68 NOTE = 7,
69 NOBITS = 8,
70 REL = 9,
71 SHLIB = 10,
72 DYNSYM = 11,
73 INIT_ARRAY = 14,
74 FINI_ARRAY = 15,
75 PREINIT_ARRAY = 16,
76 GROUP = 17,
77 SYMTAB_SHNDX = 18,
78 RELR = 19,
79
80 ANDROID_REL = 0x60000001,
81 ANDROID_RELA = 0x60000002,
82 LLVM_ADDRSIG = 0x6fff4c03,
83 ANDROID_RELR = 0x6fffff00,
84 GNU_ATTRIBUTES = 0x6ffffff5,
85 GNU_HASH = 0x6ffffff6,
86 GNU_VERDEF = 0x6ffffffd,
87 GNU_VERNEED = 0x6ffffffe,
88 GNU_VERSYM = 0x6fffffff,
90 _ID_SHIFT_ = 32,
91 _ARM_ID_ = 1LLU, _HEX_ID_ = 2LLU, _X86_64_ID_ = 2LLU,
92 _MIPS_ID_ = 3LLU,
93
94 ARM_EXIDX = 0x70000001U + (_ARM_ID_ << _ID_SHIFT_),
95 ARM_PREEMPTMAP = 0x70000002U + (_ARM_ID_ << _ID_SHIFT_),
96 ARM_ATTRIBUTES = 0x70000003U + (_ARM_ID_ << _ID_SHIFT_),
97 ARM_DEBUGOVERLAY = 0x70000004U + (_ARM_ID_ << _ID_SHIFT_),
98 ARM_OVERLAYSECTION = 0x70000005U + (_ARM_ID_ << _ID_SHIFT_),
99
100 HEX_ORDERED = 0x70000000 + (_HEX_ID_ << _ID_SHIFT_),
102 /* this section based on their sizes */
103 X86_64_UNWIND = 0x70000001 + (_X86_64_ID_ << _ID_SHIFT_),
105 MIPS_REGINFO = 0x70000006 + (_MIPS_ID_ << _ID_SHIFT_),
106 MIPS_OPTIONS = 0x7000000d + (_MIPS_ID_ << _ID_SHIFT_),
107 MIPS_ABIFLAGS = 0x7000002a + (_MIPS_ID_ << _ID_SHIFT_),
108 };
109
110 enum class FLAGS : uint64_t {
111 NONE = 0x000000000,
112 WRITE = 0x000000001,
113 ALLOC = 0x000000002,
114 EXECINSTR = 0x000000004,
115 MERGE = 0x000000010,
116 STRINGS = 0x000000020,
117 INFO_LINK = 0x000000040,
118 LINK_ORDER = 0x000000080,
119 OS_NONCONFORMING = 0x000000100,
120 GROUP = 0x000000200,
121 TLS = 0x000000400,
122 COMPRESSED = 0x000000800,
123 GNU_RETAIN = 0x000200000,
124 EXCLUDE = 0x080000000,
125
126 _ID_SHIFT_ = 32,
127 _XCORE_ID_ = 1LLU, _HEX_ID_ = 3LLU, _X86_64_ID_ = 2LLU,
128 _MIPS_ID_ = 4LLU, _ARM_ID_ = 5LLU,
129
130 XCORE_SHF_DP_SECTION = 0x010000000 + (_XCORE_ID_ << _ID_SHIFT_),
131 XCORE_SHF_CP_SECTION = 0x020000000 + (_XCORE_ID_ << _ID_SHIFT_),
132
133 X86_64_LARGE = 0x010000000 + (_X86_64_ID_ << _ID_SHIFT_),
134
135 HEX_GPREL = 0x010000000 + (_HEX_ID_ << _ID_SHIFT_),
136
137 MIPS_NODUPES = 0x010000000 + (_MIPS_ID_ << _ID_SHIFT_),
138 MIPS_NAMES = 0x020000000 + (_MIPS_ID_ << _ID_SHIFT_),
139 MIPS_LOCAL = 0x040000000 + (_MIPS_ID_ << _ID_SHIFT_),
140 MIPS_NOSTRIP = 0x080000000 + (_MIPS_ID_ << _ID_SHIFT_),
141 MIPS_GPREL = 0x010000000 + (_MIPS_ID_ << _ID_SHIFT_),
142 MIPS_MERGE = 0x020000000 + (_MIPS_ID_ << _ID_SHIFT_),
143 MIPS_ADDR = 0x040000000 + (_MIPS_ID_ << _ID_SHIFT_),
144 MIPS_STRING = 0x080000000 + (_MIPS_ID_ << _ID_SHIFT_),
145
146 ARM_PURECODE = 0x020000000 + (_ARM_ID_ << _ID_SHIFT_),
147 };
148
149 static constexpr uint64_t FLAG_MASK = (uint64_t(1) << uint8_t(FLAGS::_ID_SHIFT_)) - 1;
150 static constexpr uint64_t TYPE_MASK = (uint64_t(1) << uint8_t(TYPE::_ID_SHIFT_)) - 1;
151
152 static TYPE type_from(uint32_t value, ARCH arch);
153 static uint32_t to_value(TYPE type) {
154 return static_cast<uint64_t>(type) & TYPE_MASK;
155 }
156
157 Section(const std::string& name, TYPE type = TYPE::PROGBITS) :
158 LIEF::Section(name),
159 type_{type}
160 {}
161
162 Section() = default;
163 ~Section() override = default;
164
165 Section& operator=(Section other) {
166 swap(other);
167 return *this;
168 }
169 Section(const Section& other);
170 void swap(Section& other) noexcept;
171
172 TYPE type() const {
173 return type_;
174 }
175
177 span<const uint8_t> content() const override;
178
180 void content(const std::vector<uint8_t>& data) override;
181
182 void content(std::vector<uint8_t>&& data);
183
185 uint64_t flags() const {
186 return flags_;
187 }
188
190 bool has(FLAGS flag) const;
191
193 bool has(const Segment& segment) const;
194
196 std::vector<FLAGS> flags_list() const;
197
198 uint64_t size() const override {
199 return size_;
200 }
201
202 void size(uint64_t size) override;
203
204 void offset(uint64_t offset) override;
205
206 uint64_t offset() const override {
207 return offset_;
208 }
209
211 uint64_t file_offset() const {
212 return this->offset();
213 }
214
219 uint64_t original_size() const {
220 return original_size_;
221 }
222
224 uint64_t alignment() const {
225 return address_align_;
226 }
227
230 uint64_t information() const {
231 return info_;
232 }
233
236 //
240 uint64_t entry_size() const {
241 return entry_size_;
242 }
243
245 uint32_t link() const {
246 return link_;
247 }
248
250 Section& clear(uint8_t value = 0);
251
253 void add(FLAGS flag);
254
256 void remove(FLAGS flag);
257
258 void type(TYPE type) {
259 type_ = type;
260 }
261
262 void flags(uint64_t flags) {
263 flags_ = flags;
264 }
265
266 void clear_flags() {
267 flags_ = 0;
268 }
269
270 void file_offset(uint64_t offset) {
271 this->offset(offset);
272 }
273
274 void link(uint32_t link) {
275 link_ = link;
276 }
277
278 void information(uint32_t info) {
279 info_ = info;
280 }
281
282 void alignment(uint64_t alignment) {
283 address_align_ = alignment;
284 }
285
286 void entry_size(uint64_t entry_size) {
287 entry_size_ = entry_size;
288 }
289
290 it_segments segments() {
291 return segments_;
292 }
293
294 it_const_segments segments() const {
295 return segments_;
296 }
297
298 Section& as_frame() {
299 is_frame_ = true;
300 return *this;
301 }
302
303 bool is_frame() const {
304 return is_frame_;
305 }
306
307 void accept(Visitor& visitor) const override;
308
309 Section& operator+=(FLAGS c) {
310 add(c);
311 return *this;
312 }
313
314 Section& operator-=(FLAGS c) {
315 remove(c);
316 return *this;
317 }
318
319 LIEF_API friend std::ostream& operator<<(std::ostream& os, const Section& section);
320
321 private:
322 template<class T>
323 LIEF_LOCAL Section(const T& header, ARCH arch);
324
325 span<uint8_t> writable_content();
326 ARCH arch_ = ARCH::NONE;
327 TYPE type_ = TYPE::SHT_NULL;
328 uint64_t flags_ = 0;
329 uint64_t original_size_ = 0;
330 uint32_t link_ = 0;
331 uint32_t info_ = 0;
332 uint64_t address_align_ = 0;
333 uint64_t entry_size_ = 0;
334 segments_t segments_;
335 bool is_frame_ = false;
336 DataHandler::Handler* datahandler_ = nullptr;
337 std::vector<uint8_t> content_c_;
338};
339
340LIEF_API const char* to_string(Section::TYPE e);
341LIEF_API const char* to_string(Section::FLAGS e);
342
343}
344}
345
346ENABLE_BITMASK_OPERATORS(LIEF::ELF::Section::FLAGS)
347
348#endif
Class which represents an ELF binary.
Definition ELF/Binary.hpp:59
Class which takes an ELF::Binary object and reconstructs a valid binary.
Definition ELF/Builder.hpp:51
Class which parses and transforms an ELF file into a ELF::Binary object.
Definition ELF/Parser.hpp:45
Class wich represents an ELF Section.
Definition ELF/Section.hpp:46
void size(uint64_t size) override
Change the section size.
span< const uint8_t > content() const override
Section's content.
uint64_t original_size() const
Original size of the section's data.
Definition ELF/Section.hpp:219
uint64_t flags() const
Section flags.
Definition ELF/Section.hpp:185
void remove(FLAGS flag)
Remove the given ELF_SECTION_FLAGS.
std::vector< FLAGS > flags_list() const
Return section flags as a std::set
uint64_t file_offset() const
Definition ELF/Section.hpp:211
TYPE
Definition ELF/Section.hpp:60
uint32_t link() const
Index to another section.
Definition ELF/Section.hpp:245
uint64_t size() const override
section's size (size in the binary, not the virtual size)
Definition ELF/Section.hpp:198
void content(const std::vector< uint8_t > &data) override
Set section content.
Section & clear(uint8_t value=0)
Clear the content of the section with the given value
bool has(const Segment &segment) const
True if the section is wrapped by the given Segment
FLAGS
Definition ELF/Section.hpp:110
uint64_t information() const
Section information. This meaning of this value depends on the section's type.
Definition ELF/Section.hpp:230
uint64_t offset() const override
Offset in the binary.
Definition ELF/Section.hpp:206
void add(FLAGS flag)
Add the given ELF_SECTION_FLAGS.
uint64_t alignment() const
Section file alignment.
Definition ELF/Section.hpp:224
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:240
Class which represents the ELF segments.
Definition Segment.hpp:44
Class which represents an abstracted section.
Definition Abstract/Section.hpp:29
Iterator which returns reference on container's values.
Definition iterators.hpp:48
ARCH
Machine architectures See current registered ELF machine architectures at: http://www....
Definition ELF/enums.hpp:30
LIEF namespace.
Definition Abstract/Binary.hpp:32