Line data Source code
1 : use lief_ffi as ffi;
2 : use std::fmt;
3 : use std::marker::PhantomData;
4 : use bitflags::bitflags;
5 :
6 : use crate::to_slice;
7 : use crate::generic;
8 : use crate::common::FromFFI;
9 : use crate::declare_iterator;
10 :
11 : /// Structure wich represents an ELF Section
12 : pub struct Section<'a> {
13 : ptr: cxx::UniquePtr<ffi::ELF_Section>,
14 : _owner: PhantomData<&'a ()>
15 : }
16 :
17 : impl Section<'_> {
18 : /// Type of the section
19 10240 : pub fn get_type(&self) -> Type {
20 10240 : Type::from(self.ptr.get_type())
21 10240 : }
22 :
23 : /// Sections flags
24 10240 : pub fn flags(&self) -> Flags {
25 10240 : Flags::from_value(self.ptr.flags())
26 10240 : }
27 :
28 : /// Section alignment
29 10240 : pub fn alignment(&self) -> u64 {
30 10240 : self.ptr.alignment()
31 10240 : }
32 :
33 : /// Section information.
34 : /// This meaning of this value depends on the section's type
35 10240 : pub fn information(&self) -> u64 {
36 10240 : self.ptr.information()
37 10240 : }
38 :
39 : /// This function returns the size of an element in the case of a section that contains
40 : /// an array.
41 : ///
42 : /// For instance, the `.dynamic` section contains an array of DynamicEntry. As the
43 : /// size of the raw C structure of this entry is 0x10 (`sizeof(Elf64_Dyn)`)
44 : /// in a ELF64, the `entry_size` is set to this value.
45 10240 : pub fn entry_size(&self) -> u64 {
46 10240 : self.ptr.entry_size()
47 10240 : }
48 :
49 : /// Index to another section
50 10240 : pub fn link(&self) -> u64 {
51 10240 : self.ptr.link()
52 10240 : }
53 :
54 : /// Offset in the file where the content of this section is located
55 10240 : pub fn file_offset(&self) -> u64 {
56 10240 : self.ptr.file_offset()
57 10240 : }
58 :
59 : /// Original size of the section (regardless modifications)
60 10240 : pub fn original_size(&self) -> u64 {
61 10240 : self.ptr.original_size()
62 10240 : }
63 :
64 : /// Content of the section as a slice of bytes
65 2050 : pub fn content(&self) -> &[u8] {
66 2050 : to_slice!(self.ptr.content());
67 2050 : }
68 : }
69 :
70 : #[allow(non_camel_case_types)]
71 10240 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
72 : pub enum Type {
73 : /// No associated section (inactive entry)
74 : SHT_NULL,
75 : /// Program-defined contents.
76 : PROGBITS,
77 : /// Symbol table
78 : SYMTAB,
79 : /// String table
80 : STRTAB,
81 : /// Relocation entries; explicit addends.
82 : RELA,
83 : /// Symbol hash table.
84 : HASH,
85 : /// Information for dynamic linking.
86 : DYNAMIC,
87 : /// Information about the file.
88 : NOTE,
89 : /// Data occupies no space in the file.
90 : NOBITS,
91 : /// Relocation entries; no explicit addends.
92 : REL,
93 : /// Reserved
94 : SHLIB,
95 : /// Symbol table.
96 : DYNSYM,
97 : /// Pointers to initialization functions.
98 : INIT_ARRAY,
99 : /// Pointers to termination functions.
100 : FINI_ARRAY,
101 : /// Pointers to pre-init functions.
102 : PREINIT_ARRAY,
103 : /// Section group.
104 : GROUP,
105 : /// Indices for SHN_XINDEX entries.
106 : SYMTAB_SHNDX,
107 : /// Relocation entries; only offsets.
108 : RELR,
109 : /// Packed relocations (Android specific).
110 : ANDROID_REL,
111 : /// Packed relocations (Android specific).
112 : ANDROID_RELA,
113 : /// This section is used to mark symbols as address-significant.
114 : LLVM_ADDRSIG,
115 : /// New relr relocations (Android specific).
116 : ANDROID_RELR,
117 : /// Object attributes.
118 : GNU_ATTRIBUTES,
119 : /// GNU-style hash table.
120 : GNU_HASH,
121 : /// GNU version definitions.
122 : GNU_VERDEF,
123 : /// GNU version references.
124 : GNU_VERNEED,
125 : /// GNU symbol versions table.
126 : GNU_VERSYM,
127 : /// Exception Index table
128 : ARM_EXIDX,
129 : /// BPABI DLL dynamic linking pre-emption map
130 : ARM_PREEMPTMAP,
131 : /// Object file compatibility attributes
132 : ARM_ATTRIBUTES,
133 : ARM_DEBUGOVERLAY,
134 : ARM_OVERLAYSECTION,
135 : /// Link editor is to sort the entries in this section based on their sizes
136 : HEX_ORDERED,
137 : /// Unwind information
138 : X86_64_UNWIND,
139 : /// Register usage information
140 : MIPS_REGINFO,
141 : /// General options
142 : MIPS_OPTIONS,
143 : /// ABI information
144 : MIPS_ABIFLAGS,
145 : /// RISC-V Attribute
146 : RISCV_ATTRIBUTES,
147 : UNKNOWN(u64),
148 : }
149 :
150 :
151 : impl From<u64> for Type {
152 10240 : fn from(value: u64) -> Self {
153 10240 : match value {
154 70 : 0x00000000 => Type::SHT_NULL,
155 7610 : 0x00000001 => Type::PROGBITS,
156 950 : 0x00000002 => Type::SYMTAB,
157 160 : 0x00000003 => Type::STRTAB,
158 130 : 0x00000004 => Type::RELA,
159 20 : 0x00000005 => Type::HASH,
160 60 : 0x00000006 => Type::DYNAMIC,
161 140 : 0x00000007 => Type::NOTE,
162 660 : 0x00000008 => Type::NOBITS,
163 20 : 0x00000009 => Type::REL,
164 0 : 0x0000000a => Type::SHLIB,
165 50 : 0x0000000b => Type::DYNSYM,
166 90 : 0x0000000e => Type::INIT_ARRAY,
167 40 : 0x0000000f => Type::FINI_ARRAY,
168 0 : 0x00000010 => Type::PREINIT_ARRAY,
169 50 : 0x00000011 => Type::GROUP,
170 0 : 0x00000012 => Type::SYMTAB_SHNDX,
171 0 : 0x00000013 => Type::RELR,
172 0 : 0x60000001 => Type::ANDROID_REL,
173 0 : 0x60000002 => Type::ANDROID_RELA,
174 0 : 0x6fff4c03 => Type::LLVM_ADDRSIG,
175 0 : 0x6fffff00 => Type::ANDROID_RELR,
176 10 : 0x6ffffff5 => Type::GNU_ATTRIBUTES,
177 40 : 0x6ffffff6 => Type::GNU_HASH,
178 10 : 0x6ffffffd => Type::GNU_VERDEF,
179 50 : 0x6ffffffe => Type::GNU_VERNEED,
180 50 : 0x6fffffff => Type::GNU_VERSYM,
181 0 : 0x170000001 => Type::ARM_EXIDX,
182 0 : 0x170000002 => Type::ARM_PREEMPTMAP,
183 0 : 0x170000003 => Type::ARM_ATTRIBUTES,
184 0 : 0x170000004 => Type::ARM_DEBUGOVERLAY,
185 0 : 0x170000005 => Type::ARM_OVERLAYSECTION,
186 0 : 0x270000000 => Type::HEX_ORDERED,
187 0 : 0x270000001 => Type::X86_64_UNWIND,
188 10 : 0x370000006 => Type::MIPS_REGINFO,
189 0 : 0x37000000d => Type::MIPS_OPTIONS,
190 10 : 0x37000002a => Type::MIPS_ABIFLAGS,
191 0 : 0x470000003 => Type::RISCV_ATTRIBUTES,
192 10 : _ => Type::UNKNOWN(value),
193 :
194 : }
195 10240 : }
196 : }
197 : impl From<Type> for u64 {
198 0 : fn from(value: Type) -> u64 {
199 0 : match value {
200 0 : Type::SHT_NULL => 0x00000000,
201 0 : Type::PROGBITS => 0x00000001,
202 0 : Type::SYMTAB => 0x00000002,
203 0 : Type::STRTAB => 0x00000003,
204 0 : Type::RELA => 0x00000004,
205 0 : Type::HASH => 0x00000005,
206 0 : Type::DYNAMIC => 0x00000006,
207 0 : Type::NOTE => 0x00000007,
208 0 : Type::NOBITS => 0x00000008,
209 0 : Type::REL => 0x00000009,
210 0 : Type::SHLIB => 0x0000000a,
211 0 : Type::DYNSYM => 0x0000000b,
212 0 : Type::INIT_ARRAY => 0x0000000e,
213 0 : Type::FINI_ARRAY => 0x0000000f,
214 0 : Type::PREINIT_ARRAY => 0x00000010,
215 0 : Type::GROUP => 0x00000011,
216 0 : Type::SYMTAB_SHNDX => 0x00000012,
217 0 : Type::RELR => 0x00000013,
218 0 : Type::ANDROID_REL => 0x60000001,
219 0 : Type::ANDROID_RELA => 0x60000002,
220 0 : Type::LLVM_ADDRSIG => 0x6fff4c03,
221 0 : Type::ANDROID_RELR => 0x6fffff00,
222 0 : Type::GNU_ATTRIBUTES => 0x6ffffff5,
223 0 : Type::GNU_HASH => 0x6ffffff6,
224 0 : Type::GNU_VERDEF => 0x6ffffffd,
225 0 : Type::GNU_VERNEED => 0x6ffffffe,
226 0 : Type::GNU_VERSYM => 0x6fffffff,
227 0 : Type::ARM_EXIDX => 0x170000001,
228 0 : Type::ARM_PREEMPTMAP => 0x170000002,
229 0 : Type::ARM_ATTRIBUTES => 0x170000003,
230 0 : Type::ARM_DEBUGOVERLAY => 0x170000004,
231 0 : Type::ARM_OVERLAYSECTION => 0x170000005,
232 0 : Type::HEX_ORDERED => 0x270000000,
233 0 : Type::X86_64_UNWIND => 0x270000001,
234 0 : Type::MIPS_REGINFO => 0x370000006,
235 0 : Type::MIPS_OPTIONS => 0x37000000d,
236 0 : Type::MIPS_ABIFLAGS => 0x37000002a,
237 0 : Type::RISCV_ATTRIBUTES => 0x470000003,
238 0 : Type::UNKNOWN(value) => value,
239 : }
240 0 : }
241 : }
242 :
243 0 : bitflags! {
244 10240 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
245 0 : pub struct Flags: u64 {
246 0 : const NONE = 0x0;
247 0 : const WRITE = 0x1;
248 0 : const ALLOC = 0x2;
249 0 : const EXECINSTR = 0x4;
250 0 : const MERGE = 0x10;
251 0 : const STRINGS = 0x20;
252 0 : const INFO_LINK = 0x40;
253 0 : const LINK_ORDER = 0x80;
254 0 : const OS_NONCONFORMING = 0x100;
255 0 : const GROUP = 0x200;
256 0 : const TLS = 0x400;
257 0 : const COMPRESSED = 0x800;
258 0 : const GNU_RETAIN = 0x200000;
259 0 : const EXCLUDE = 0x80000000;
260 0 : const XCORE_SHF_DP_SECTION = 0x110000000;
261 0 : const XCORE_SHF_CP_SECTION = 0x120000000;
262 0 : const X86_64_LARGE = 0x210000000;
263 0 : const HEX_GPREL = 0x310000000;
264 0 : const MIPS_NODUPES = 0x401000000;
265 0 : const MIPS_NAMES = 0x402000000;
266 0 : const MIPS_LOCAL = 0x404000000;
267 0 : const MIPS_NOSTRIP = 0x408000000;
268 0 : const MIPS_GPREL = 0x410000000;
269 0 : const MIPS_MERGE = 0x420000000;
270 0 : const MIPS_ADDR = 0x440000000;
271 0 : const MIPS_STRING = 0x480000000;
272 0 : const ARM_PURECODE = 0x520000000;
273 0 : }
274 0 : }
275 :
276 : impl Flags {
277 10240 : pub fn from_value(value: u64) -> Self {
278 10240 : Flags::from_bits_truncate(value)
279 10240 : }
280 : }
281 :
282 : impl fmt::Debug for Section<'_> {
283 10240 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284 10240 : let base = self as &dyn generic::Section;
285 10240 : f.debug_struct("Section")
286 10240 : .field("base", &base)
287 10240 : .field("type", &self.get_type())
288 10240 : .field("flags", &self.flags())
289 10240 : .field("alignment", &self.alignment())
290 10240 : .field("information", &self.information())
291 10240 : .field("entry_size", &self.entry_size())
292 10240 : .field("link", &self.link())
293 10240 : .field("file_offset", &self.file_offset())
294 10240 : .field("original_size", &self.original_size())
295 10240 : .finish()
296 10240 :
297 10240 : }
298 : }
299 :
300 : impl fmt::Display for Section<'_> {
301 1990 : fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
302 1990 : write!(f, "{}", self.ptr.to_string())
303 1990 : }
304 : }
305 :
306 : impl FromFFI<ffi::ELF_Section> for Section<'_> {
307 10260 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_Section>) -> Self {
308 10260 : Self {
309 10260 : ptr,
310 10260 : _owner: PhantomData
311 10260 : }
312 10260 : }
313 : }
314 :
315 : impl generic::Section for Section<'_> {
316 50980 : fn as_generic(&self) -> &ffi::AbstractSection {
317 50980 : self.ptr.as_ref().unwrap().as_ref()
318 50980 : }
319 : }
320 :
321 1990 : declare_iterator!(Sections, Section<'a>, ffi::ELF_Section, ffi::ELF_Binary, ffi::ELF_Binary_it_sections);
|