Line data Source code
1 : use std::marker::PhantomData;
2 :
3 : use bitflags::bitflags;
4 : use lief_ffi as ffi;
5 : use std::pin::Pin;
6 :
7 : use crate::common::FromFFI;
8 : use crate::declare_iterator;
9 :
10 : #[allow(non_camel_case_types)]
11 2496 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
12 : pub enum Tag {
13 : DT_NULL_,
14 : NEEDED,
15 : PLTRELSZ,
16 : PLTGOT,
17 : HASH,
18 : STRTAB,
19 : SYMTAB,
20 : RELA,
21 : RELASZ,
22 : RELAENT,
23 : STRSZ,
24 : SYMENT,
25 : INIT,
26 : FINI,
27 : SONAME,
28 : RPATH,
29 : SYMBOLIC,
30 : REL,
31 : RELSZ,
32 : RELENT,
33 : PLTREL,
34 : DEBUG_TAG,
35 : TEXTREL,
36 : JMPREL,
37 : BIND_NOW,
38 : INIT_ARRAY,
39 : FINI_ARRAY,
40 : INIT_ARRAYSZ,
41 : FINI_ARRAYSZ,
42 : RUNPATH,
43 : FLAGS,
44 : PREINIT_ARRAY,
45 : PREINIT_ARRAYSZ,
46 : SYMTAB_SHNDX,
47 : RELRSZ,
48 : RELR,
49 : RELRENT,
50 : GNU_HASH,
51 : TLSDESC_PLT,
52 : TLSDESC_GOT,
53 : RELACOUNT,
54 : RELCOUNT,
55 : FLAGS_1,
56 : VERSYM,
57 : VERDEF,
58 : VERDEFNUM,
59 : VERNEED,
60 : VERNEEDNUM,
61 : AUXILIARY,
62 : FILTER,
63 : ANDROID_REL_OFFSET,
64 : ANDROID_REL_SIZE,
65 : ANDROID_REL,
66 : ANDROID_RELSZ,
67 : ANDROID_RELA,
68 : ANDROID_RELASZ,
69 : ANDROID_RELR,
70 : ANDROID_RELRSZ,
71 : ANDROID_RELRENT,
72 : ANDROID_RELRCOUNT,
73 : MIPS_RLD_VERSION,
74 : MIPS_TIME_STAMP,
75 : MIPS_ICHECKSUM,
76 : MIPS_IVERSION,
77 : MIPS_FLAGS,
78 : MIPS_BASE_ADDRESS,
79 : MIPS_MSYM,
80 : MIPS_CONFLICT,
81 : MIPS_LIBLIST,
82 : MIPS_LOCAL_GOTNO,
83 : MIPS_CONFLICTNO,
84 : MIPS_LIBLISTNO,
85 : MIPS_SYMTABNO,
86 : MIPS_UNREFEXTNO,
87 : MIPS_GOTSYM,
88 : MIPS_HIPAGENO,
89 : MIPS_RLD_MAP,
90 : MIPS_DELTA_CLASS,
91 : MIPS_DELTA_CLASS_NO,
92 : MIPS_DELTA_INSTANCE,
93 : MIPS_DELTA_INSTANCE_NO,
94 : MIPS_DELTA_RELOC,
95 : MIPS_DELTA_RELOC_NO,
96 : MIPS_DELTA_SYM,
97 : MIPS_DELTA_SYM_NO,
98 : MIPS_DELTA_CLASSSYM,
99 : MIPS_DELTA_CLASSSYM_NO,
100 : MIPS_CXX_FLAGS,
101 : MIPS_PIXIE_INIT,
102 : MIPS_SYMBOL_LIB,
103 : MIPS_LOCALPAGE_GOTIDX,
104 : MIPS_LOCAL_GOTIDX,
105 : MIPS_HIDDEN_GOTIDX,
106 : MIPS_PROTECTED_GOTIDX,
107 : MIPS_OPTIONS,
108 : MIPS_INTERFACE,
109 : MIPS_DYNSTR_ALIGN,
110 : MIPS_INTERFACE_SIZE,
111 : MIPS_RLD_TEXT_RESOLVE_ADDR,
112 : MIPS_PERF_SUFFIX,
113 : MIPS_COMPACT_SIZE,
114 : MIPS_GP_VALUE,
115 : MIPS_AUX_DYNAMIC,
116 : MIPS_PLTGOT,
117 : MIPS_RWPLT,
118 : MIPS_RLD_MAP_REL,
119 : MIPS_XHASH,
120 : AARCH64_BTI_PLT,
121 : AARCH64_PAC_PLT,
122 : AARCH64_VARIANT_PCS,
123 : AARCH64_MEMTAG_MODE,
124 : AARCH64_MEMTAG_HEAP,
125 : AARCH64_MEMTAG_STACK,
126 : AARCH64_MEMTAG_GLOBALS,
127 : AARCH64_MEMTAG_GLOBALSSZ,
128 : HEXAGON_SYMSZ,
129 : HEXAGON_VER,
130 : HEXAGON_PLT,
131 : PPC_GOT,
132 : PPC_OPT,
133 : PPC64_GLINK,
134 : PPC64_OPT,
135 : RISCV_VARIANT_CC,
136 : X86_64_PLT,
137 : X86_64_PLTSZ,
138 : X86_64_PLTENT,
139 : IA_64_PLT_RESERVE,
140 : IA_64_VMS_SUBTYPE,
141 : IA_64_VMS_IMGIOCNT,
142 : IA_64_VMS_LNKFLAGS,
143 : IA_64_VMS_VIR_MEM_BLK_SIZ,
144 : IA_64_VMS_IDENT,
145 : IA_64_VMS_NEEDED_IDENT,
146 : IA_64_VMS_IMG_RELA_CNT,
147 : IA_64_VMS_SEG_RELA_CNT,
148 : IA_64_VMS_FIXUP_RELA_CNT,
149 : IA_64_VMS_FIXUP_NEEDED,
150 : IA_64_VMS_SYMVEC_CNT,
151 : IA_64_VMS_XLATED,
152 : IA_64_VMS_STACKSIZE,
153 : IA_64_VMS_UNWINDSZ,
154 : IA_64_VMS_UNWIND_CODSEG,
155 : IA_64_VMS_UNWIND_INFOSEG,
156 : IA_64_VMS_LINKTIME,
157 : IA_64_VMS_SEG_NO,
158 : IA_64_VMS_SYMVEC_OFFSET,
159 : IA_64_VMS_SYMVEC_SEG,
160 : IA_64_VMS_UNWIND_OFFSET,
161 : IA_64_VMS_UNWIND_SEG,
162 : IA_64_VMS_STRTAB_OFFSET,
163 : IA_64_VMS_SYSVER_OFFSET,
164 : IA_64_VMS_IMG_RELA_OFF,
165 : IA_64_VMS_SEG_RELA_OFF,
166 : IA_64_VMS_FIXUP_RELA_OFF,
167 : IA_64_VMS_PLTGOT_OFFSET,
168 : IA_64_VMS_PLTGOT_SEG,
169 : IA_64_VMS_FPMODE,
170 : UNKNOWN(u64),
171 : }
172 :
173 : impl From<u64> for Tag {
174 2496 : fn from(value: u64) -> Self {
175 2496 : match value {
176 91 : 0x00000000 => Tag::DT_NULL_,
177 260 : 0x00000001 => Tag::NEEDED,
178 65 : 0x00000002 => Tag::PLTRELSZ,
179 65 : 0x00000003 => Tag::PLTGOT,
180 26 : 0x00000004 => Tag::HASH,
181 91 : 0x00000005 => Tag::STRTAB,
182 91 : 0x00000006 => Tag::SYMTAB,
183 78 : 0x00000007 => Tag::RELA,
184 78 : 0x00000008 => Tag::RELASZ,
185 78 : 0x00000009 => Tag::RELAENT,
186 91 : 0x0000000a => Tag::STRSZ,
187 91 : 0x0000000b => Tag::SYMENT,
188 91 : 0x0000000c => Tag::INIT,
189 91 : 0x0000000d => Tag::FINI,
190 13 : 0x0000000e => Tag::SONAME,
191 13 : 0x0000000f => Tag::RPATH,
192 13 : 0x00000010 => Tag::SYMBOLIC,
193 13 : 0x00000011 => Tag::REL,
194 13 : 0x00000012 => Tag::RELSZ,
195 13 : 0x00000013 => Tag::RELENT,
196 65 : 0x00000014 => Tag::PLTREL,
197 52 : 0x00000015 => Tag::DEBUG_TAG,
198 0 : 0x00000016 => Tag::TEXTREL,
199 65 : 0x00000017 => Tag::JMPREL,
200 0 : 0x00000018 => Tag::BIND_NOW,
201 78 : 0x00000019 => Tag::INIT_ARRAY,
202 65 : 0x0000001a => Tag::FINI_ARRAY,
203 78 : 0x0000001b => Tag::INIT_ARRAYSZ,
204 65 : 0x0000001c => Tag::FINI_ARRAYSZ,
205 13 : 0x0000001d => Tag::RUNPATH,
206 13 : 0x0000001e => Tag::FLAGS,
207 0 : 0x00000020 => Tag::PREINIT_ARRAY,
208 0 : 0x00000021 => Tag::PREINIT_ARRAYSZ,
209 0 : 0x00000022 => Tag::SYMTAB_SHNDX,
210 0 : 0x00000023 => Tag::RELRSZ,
211 0 : 0x00000024 => Tag::RELR,
212 0 : 0x00000025 => Tag::RELRENT,
213 78 : 0x6ffffef5 => Tag::GNU_HASH,
214 0 : 0x6ffffef6 => Tag::TLSDESC_PLT,
215 0 : 0x6ffffef7 => Tag::TLSDESC_GOT,
216 52 : 0x6ffffff9 => Tag::RELACOUNT,
217 0 : 0x6ffffffa => Tag::RELCOUNT,
218 13 : 0x6ffffffb => Tag::FLAGS_1,
219 91 : 0x6ffffff0 => Tag::VERSYM,
220 13 : 0x6ffffffc => Tag::VERDEF,
221 13 : 0x6ffffffd => Tag::VERDEFNUM,
222 91 : 0x6ffffffe => Tag::VERNEED,
223 91 : 0x6fffffff => Tag::VERNEEDNUM,
224 26 : 0x7ffffffd => Tag::AUXILIARY,
225 13 : 0x7fffffff => Tag::FILTER,
226 0 : 0x6000000d => Tag::ANDROID_REL_OFFSET,
227 0 : 0x6000000e => Tag::ANDROID_REL_SIZE,
228 0 : 0x6000000f => Tag::ANDROID_REL,
229 0 : 0x60000010 => Tag::ANDROID_RELSZ,
230 0 : 0x60000011 => Tag::ANDROID_RELA,
231 0 : 0x60000012 => Tag::ANDROID_RELASZ,
232 0 : 0x6fffe000 => Tag::ANDROID_RELR,
233 0 : 0x6fffe001 => Tag::ANDROID_RELRSZ,
234 0 : 0x6fffe003 => Tag::ANDROID_RELRENT,
235 0 : 0x6fffe005 => Tag::ANDROID_RELRCOUNT,
236 13 : 0x170000001 => Tag::MIPS_RLD_VERSION,
237 0 : 0x170000002 => Tag::MIPS_TIME_STAMP,
238 0 : 0x170000003 => Tag::MIPS_ICHECKSUM,
239 0 : 0x170000004 => Tag::MIPS_IVERSION,
240 13 : 0x170000005 => Tag::MIPS_FLAGS,
241 13 : 0x170000006 => Tag::MIPS_BASE_ADDRESS,
242 0 : 0x170000007 => Tag::MIPS_MSYM,
243 0 : 0x170000008 => Tag::MIPS_CONFLICT,
244 0 : 0x170000009 => Tag::MIPS_LIBLIST,
245 13 : 0x17000000a => Tag::MIPS_LOCAL_GOTNO,
246 0 : 0x17000000b => Tag::MIPS_CONFLICTNO,
247 0 : 0x170000010 => Tag::MIPS_LIBLISTNO,
248 13 : 0x170000011 => Tag::MIPS_SYMTABNO,
249 13 : 0x170000012 => Tag::MIPS_UNREFEXTNO,
250 13 : 0x170000013 => Tag::MIPS_GOTSYM,
251 0 : 0x170000014 => Tag::MIPS_HIPAGENO,
252 13 : 0x170000016 => Tag::MIPS_RLD_MAP,
253 0 : 0x170000017 => Tag::MIPS_DELTA_CLASS,
254 0 : 0x170000018 => Tag::MIPS_DELTA_CLASS_NO,
255 0 : 0x170000019 => Tag::MIPS_DELTA_INSTANCE,
256 0 : 0x17000001a => Tag::MIPS_DELTA_INSTANCE_NO,
257 0 : 0x17000001b => Tag::MIPS_DELTA_RELOC,
258 0 : 0x17000001c => Tag::MIPS_DELTA_RELOC_NO,
259 0 : 0x17000001d => Tag::MIPS_DELTA_SYM,
260 0 : 0x17000001e => Tag::MIPS_DELTA_SYM_NO,
261 0 : 0x170000020 => Tag::MIPS_DELTA_CLASSSYM,
262 0 : 0x170000021 => Tag::MIPS_DELTA_CLASSSYM_NO,
263 0 : 0x170000022 => Tag::MIPS_CXX_FLAGS,
264 0 : 0x170000023 => Tag::MIPS_PIXIE_INIT,
265 0 : 0x170000024 => Tag::MIPS_SYMBOL_LIB,
266 0 : 0x170000025 => Tag::MIPS_LOCALPAGE_GOTIDX,
267 0 : 0x170000026 => Tag::MIPS_LOCAL_GOTIDX,
268 0 : 0x170000027 => Tag::MIPS_HIDDEN_GOTIDX,
269 0 : 0x170000028 => Tag::MIPS_PROTECTED_GOTIDX,
270 0 : 0x170000029 => Tag::MIPS_OPTIONS,
271 0 : 0x17000002a => Tag::MIPS_INTERFACE,
272 0 : 0x17000002b => Tag::MIPS_DYNSTR_ALIGN,
273 0 : 0x17000002c => Tag::MIPS_INTERFACE_SIZE,
274 0 : 0x17000002d => Tag::MIPS_RLD_TEXT_RESOLVE_ADDR,
275 0 : 0x17000002e => Tag::MIPS_PERF_SUFFIX,
276 0 : 0x17000002f => Tag::MIPS_COMPACT_SIZE,
277 0 : 0x170000030 => Tag::MIPS_GP_VALUE,
278 0 : 0x170000031 => Tag::MIPS_AUX_DYNAMIC,
279 13 : 0x170000032 => Tag::MIPS_PLTGOT,
280 0 : 0x170000034 => Tag::MIPS_RWPLT,
281 13 : 0x170000035 => Tag::MIPS_RLD_MAP_REL,
282 0 : 0x170000036 => Tag::MIPS_XHASH,
283 0 : 0x270000001 => Tag::AARCH64_BTI_PLT,
284 0 : 0x270000003 => Tag::AARCH64_PAC_PLT,
285 0 : 0x270000005 => Tag::AARCH64_VARIANT_PCS,
286 0 : 0x270000009 => Tag::AARCH64_MEMTAG_MODE,
287 0 : 0x27000000b => Tag::AARCH64_MEMTAG_HEAP,
288 0 : 0x27000000c => Tag::AARCH64_MEMTAG_STACK,
289 0 : 0x27000000d => Tag::AARCH64_MEMTAG_GLOBALS,
290 0 : 0x27000000f => Tag::AARCH64_MEMTAG_GLOBALSSZ,
291 0 : 0x370000000 => Tag::HEXAGON_SYMSZ,
292 0 : 0x370000001 => Tag::HEXAGON_VER,
293 0 : 0x370000002 => Tag::HEXAGON_PLT,
294 0 : 0x470000000 => Tag::PPC_GOT,
295 0 : 0x470000001 => Tag::PPC_OPT,
296 0 : 0x570000000 => Tag::PPC64_GLINK,
297 0 : 0x570000003 => Tag::PPC64_OPT,
298 0 : 0x670000003 => Tag::RISCV_VARIANT_CC,
299 0 : 0x770000000 => Tag::X86_64_PLT,
300 0 : 0x770000001 => Tag::X86_64_PLTSZ,
301 0 : 0x770000003 => Tag::X86_64_PLTENT,
302 0 : 0x870000000 => Tag::IA_64_PLT_RESERVE,
303 0 : 0x860000000 => Tag::IA_64_VMS_SUBTYPE,
304 0 : 0x860000002 => Tag::IA_64_VMS_IMGIOCNT,
305 0 : 0x860000008 => Tag::IA_64_VMS_LNKFLAGS,
306 0 : 0x86000000a => Tag::IA_64_VMS_VIR_MEM_BLK_SIZ,
307 0 : 0x86000000c => Tag::IA_64_VMS_IDENT,
308 0 : 0x860000010 => Tag::IA_64_VMS_NEEDED_IDENT,
309 0 : 0x860000012 => Tag::IA_64_VMS_IMG_RELA_CNT,
310 0 : 0x860000014 => Tag::IA_64_VMS_SEG_RELA_CNT,
311 0 : 0x860000016 => Tag::IA_64_VMS_FIXUP_RELA_CNT,
312 0 : 0x860000018 => Tag::IA_64_VMS_FIXUP_NEEDED,
313 0 : 0x86000001a => Tag::IA_64_VMS_SYMVEC_CNT,
314 0 : 0x86000001e => Tag::IA_64_VMS_XLATED,
315 0 : 0x860000020 => Tag::IA_64_VMS_STACKSIZE,
316 0 : 0x860000022 => Tag::IA_64_VMS_UNWINDSZ,
317 0 : 0x860000024 => Tag::IA_64_VMS_UNWIND_CODSEG,
318 0 : 0x860000026 => Tag::IA_64_VMS_UNWIND_INFOSEG,
319 0 : 0x860000028 => Tag::IA_64_VMS_LINKTIME,
320 0 : 0x86000002a => Tag::IA_64_VMS_SEG_NO,
321 0 : 0x86000002c => Tag::IA_64_VMS_SYMVEC_OFFSET,
322 0 : 0x86000002e => Tag::IA_64_VMS_SYMVEC_SEG,
323 0 : 0x860000030 => Tag::IA_64_VMS_UNWIND_OFFSET,
324 0 : 0x860000032 => Tag::IA_64_VMS_UNWIND_SEG,
325 0 : 0x860000034 => Tag::IA_64_VMS_STRTAB_OFFSET,
326 0 : 0x860000036 => Tag::IA_64_VMS_SYSVER_OFFSET,
327 0 : 0x860000038 => Tag::IA_64_VMS_IMG_RELA_OFF,
328 0 : 0x86000003a => Tag::IA_64_VMS_SEG_RELA_OFF,
329 0 : 0x86000003c => Tag::IA_64_VMS_FIXUP_RELA_OFF,
330 0 : 0x86000003e => Tag::IA_64_VMS_PLTGOT_OFFSET,
331 0 : 0x860000040 => Tag::IA_64_VMS_PLTGOT_SEG,
332 0 : 0x860000042 => Tag::IA_64_VMS_FPMODE,
333 26 : _ => Tag::UNKNOWN(value),
334 : }
335 2496 : }
336 : }
337 :
338 : impl From<Tag> for u64 {
339 390 : fn from(value: Tag) -> u64 {
340 390 : match value {
341 0 : Tag::DT_NULL_ => 0x00000000,
342 0 : Tag::NEEDED => 0x00000001,
343 0 : Tag::PLTRELSZ => 0x00000002,
344 0 : Tag::PLTGOT => 0x00000003,
345 0 : Tag::HASH => 0x00000004,
346 0 : Tag::STRTAB => 0x00000005,
347 0 : Tag::SYMTAB => 0x00000006,
348 0 : Tag::RELA => 0x00000007,
349 0 : Tag::RELASZ => 0x00000008,
350 0 : Tag::RELAENT => 0x00000009,
351 0 : Tag::STRSZ => 0x0000000a,
352 0 : Tag::SYMENT => 0x0000000b,
353 0 : Tag::INIT => 0x0000000c,
354 0 : Tag::FINI => 0x0000000d,
355 0 : Tag::SONAME => 0x0000000e,
356 0 : Tag::RPATH => 0x0000000f,
357 0 : Tag::SYMBOLIC => 0x00000010,
358 0 : Tag::REL => 0x00000011,
359 0 : Tag::RELSZ => 0x00000012,
360 0 : Tag::RELENT => 0x00000013,
361 0 : Tag::PLTREL => 0x00000014,
362 0 : Tag::DEBUG_TAG => 0x00000015,
363 0 : Tag::TEXTREL => 0x00000016,
364 0 : Tag::JMPREL => 0x00000017,
365 0 : Tag::BIND_NOW => 0x00000018,
366 130 : Tag::INIT_ARRAY => 0x00000019,
367 130 : Tag::FINI_ARRAY => 0x0000001a,
368 0 : Tag::INIT_ARRAYSZ => 0x0000001b,
369 0 : Tag::FINI_ARRAYSZ => 0x0000001c,
370 0 : Tag::RUNPATH => 0x0000001d,
371 0 : Tag::FLAGS => 0x0000001e,
372 130 : Tag::PREINIT_ARRAY => 0x00000020,
373 0 : Tag::PREINIT_ARRAYSZ => 0x00000021,
374 0 : Tag::SYMTAB_SHNDX => 0x00000022,
375 0 : Tag::RELRSZ => 0x00000023,
376 0 : Tag::RELR => 0x00000024,
377 0 : Tag::RELRENT => 0x00000025,
378 0 : Tag::GNU_HASH => 0x6ffffef5,
379 0 : Tag::TLSDESC_PLT => 0x6ffffef6,
380 0 : Tag::TLSDESC_GOT => 0x6ffffef7,
381 0 : Tag::RELACOUNT => 0x6ffffff9,
382 0 : Tag::RELCOUNT => 0x6ffffffa,
383 0 : Tag::FLAGS_1 => 0x6ffffffb,
384 0 : Tag::VERSYM => 0x6ffffff0,
385 0 : Tag::VERDEF => 0x6ffffffc,
386 0 : Tag::VERDEFNUM => 0x6ffffffd,
387 0 : Tag::VERNEED => 0x6ffffffe,
388 0 : Tag::VERNEEDNUM => 0x6fffffff,
389 0 : Tag::AUXILIARY => 0x7ffffffd,
390 0 : Tag::FILTER => 0x7fffffff,
391 0 : Tag::ANDROID_REL_OFFSET => 0x6000000d,
392 0 : Tag::ANDROID_REL_SIZE => 0x6000000e,
393 0 : Tag::ANDROID_REL => 0x6000000f,
394 0 : Tag::ANDROID_RELSZ => 0x60000010,
395 0 : Tag::ANDROID_RELA => 0x60000011,
396 0 : Tag::ANDROID_RELASZ => 0x60000012,
397 0 : Tag::ANDROID_RELR => 0x6fffe000,
398 0 : Tag::ANDROID_RELRSZ => 0x6fffe001,
399 0 : Tag::ANDROID_RELRENT => 0x6fffe003,
400 0 : Tag::ANDROID_RELRCOUNT => 0x6fffe005,
401 0 : Tag::MIPS_RLD_VERSION => 0x170000001,
402 0 : Tag::MIPS_TIME_STAMP => 0x170000002,
403 0 : Tag::MIPS_ICHECKSUM => 0x170000003,
404 0 : Tag::MIPS_IVERSION => 0x170000004,
405 0 : Tag::MIPS_FLAGS => 0x170000005,
406 0 : Tag::MIPS_BASE_ADDRESS => 0x170000006,
407 0 : Tag::MIPS_MSYM => 0x170000007,
408 0 : Tag::MIPS_CONFLICT => 0x170000008,
409 0 : Tag::MIPS_LIBLIST => 0x170000009,
410 0 : Tag::MIPS_LOCAL_GOTNO => 0x17000000a,
411 0 : Tag::MIPS_CONFLICTNO => 0x17000000b,
412 0 : Tag::MIPS_LIBLISTNO => 0x170000010,
413 0 : Tag::MIPS_SYMTABNO => 0x170000011,
414 0 : Tag::MIPS_UNREFEXTNO => 0x170000012,
415 0 : Tag::MIPS_GOTSYM => 0x170000013,
416 0 : Tag::MIPS_HIPAGENO => 0x170000014,
417 0 : Tag::MIPS_RLD_MAP => 0x170000016,
418 0 : Tag::MIPS_DELTA_CLASS => 0x170000017,
419 0 : Tag::MIPS_DELTA_CLASS_NO => 0x170000018,
420 0 : Tag::MIPS_DELTA_INSTANCE => 0x170000019,
421 0 : Tag::MIPS_DELTA_INSTANCE_NO => 0x17000001a,
422 0 : Tag::MIPS_DELTA_RELOC => 0x17000001b,
423 0 : Tag::MIPS_DELTA_RELOC_NO => 0x17000001c,
424 0 : Tag::MIPS_DELTA_SYM => 0x17000001d,
425 0 : Tag::MIPS_DELTA_SYM_NO => 0x17000001e,
426 0 : Tag::MIPS_DELTA_CLASSSYM => 0x170000020,
427 0 : Tag::MIPS_DELTA_CLASSSYM_NO => 0x170000021,
428 0 : Tag::MIPS_CXX_FLAGS => 0x170000022,
429 0 : Tag::MIPS_PIXIE_INIT => 0x170000023,
430 0 : Tag::MIPS_SYMBOL_LIB => 0x170000024,
431 0 : Tag::MIPS_LOCALPAGE_GOTIDX => 0x170000025,
432 0 : Tag::MIPS_LOCAL_GOTIDX => 0x170000026,
433 0 : Tag::MIPS_HIDDEN_GOTIDX => 0x170000027,
434 0 : Tag::MIPS_PROTECTED_GOTIDX => 0x170000028,
435 0 : Tag::MIPS_OPTIONS => 0x170000029,
436 0 : Tag::MIPS_INTERFACE => 0x17000002a,
437 0 : Tag::MIPS_DYNSTR_ALIGN => 0x17000002b,
438 0 : Tag::MIPS_INTERFACE_SIZE => 0x17000002c,
439 0 : Tag::MIPS_RLD_TEXT_RESOLVE_ADDR => 0x17000002d,
440 0 : Tag::MIPS_PERF_SUFFIX => 0x17000002e,
441 0 : Tag::MIPS_COMPACT_SIZE => 0x17000002f,
442 0 : Tag::MIPS_GP_VALUE => 0x170000030,
443 0 : Tag::MIPS_AUX_DYNAMIC => 0x170000031,
444 0 : Tag::MIPS_PLTGOT => 0x170000032,
445 0 : Tag::MIPS_RWPLT => 0x170000034,
446 0 : Tag::MIPS_RLD_MAP_REL => 0x170000035,
447 0 : Tag::MIPS_XHASH => 0x170000036,
448 0 : Tag::AARCH64_BTI_PLT => 0x270000001,
449 0 : Tag::AARCH64_PAC_PLT => 0x270000003,
450 0 : Tag::AARCH64_VARIANT_PCS => 0x270000005,
451 0 : Tag::AARCH64_MEMTAG_MODE => 0x270000009,
452 0 : Tag::AARCH64_MEMTAG_HEAP => 0x27000000b,
453 0 : Tag::AARCH64_MEMTAG_STACK => 0x27000000c,
454 0 : Tag::AARCH64_MEMTAG_GLOBALS => 0x27000000d,
455 0 : Tag::AARCH64_MEMTAG_GLOBALSSZ => 0x27000000f,
456 0 : Tag::HEXAGON_SYMSZ => 0x370000000,
457 0 : Tag::HEXAGON_VER => 0x370000001,
458 0 : Tag::HEXAGON_PLT => 0x370000002,
459 0 : Tag::PPC_GOT => 0x470000000,
460 0 : Tag::PPC_OPT => 0x470000001,
461 0 : Tag::PPC64_GLINK => 0x570000000,
462 0 : Tag::PPC64_OPT => 0x570000003,
463 0 : Tag::RISCV_VARIANT_CC => 0x670000003,
464 0 : Tag::X86_64_PLT => 0x770000000,
465 0 : Tag::X86_64_PLTSZ => 0x770000001,
466 0 : Tag::X86_64_PLTENT => 0x770000003,
467 0 : Tag::IA_64_PLT_RESERVE => 0x870000000,
468 0 : Tag::IA_64_VMS_SUBTYPE => 0x860000000,
469 0 : Tag::IA_64_VMS_IMGIOCNT => 0x860000002,
470 0 : Tag::IA_64_VMS_LNKFLAGS => 0x860000008,
471 0 : Tag::IA_64_VMS_VIR_MEM_BLK_SIZ => 0x86000000a,
472 0 : Tag::IA_64_VMS_IDENT => 0x86000000c,
473 0 : Tag::IA_64_VMS_NEEDED_IDENT => 0x860000010,
474 0 : Tag::IA_64_VMS_IMG_RELA_CNT => 0x860000012,
475 0 : Tag::IA_64_VMS_SEG_RELA_CNT => 0x860000014,
476 0 : Tag::IA_64_VMS_FIXUP_RELA_CNT => 0x860000016,
477 0 : Tag::IA_64_VMS_FIXUP_NEEDED => 0x860000018,
478 0 : Tag::IA_64_VMS_SYMVEC_CNT => 0x86000001a,
479 0 : Tag::IA_64_VMS_XLATED => 0x86000001e,
480 0 : Tag::IA_64_VMS_STACKSIZE => 0x860000020,
481 0 : Tag::IA_64_VMS_UNWINDSZ => 0x860000022,
482 0 : Tag::IA_64_VMS_UNWIND_CODSEG => 0x860000024,
483 0 : Tag::IA_64_VMS_UNWIND_INFOSEG => 0x860000026,
484 0 : Tag::IA_64_VMS_LINKTIME => 0x860000028,
485 0 : Tag::IA_64_VMS_SEG_NO => 0x86000002a,
486 0 : Tag::IA_64_VMS_SYMVEC_OFFSET => 0x86000002c,
487 0 : Tag::IA_64_VMS_SYMVEC_SEG => 0x86000002e,
488 0 : Tag::IA_64_VMS_UNWIND_OFFSET => 0x860000030,
489 0 : Tag::IA_64_VMS_UNWIND_SEG => 0x860000032,
490 0 : Tag::IA_64_VMS_STRTAB_OFFSET => 0x860000034,
491 0 : Tag::IA_64_VMS_SYSVER_OFFSET => 0x860000036,
492 0 : Tag::IA_64_VMS_IMG_RELA_OFF => 0x860000038,
493 0 : Tag::IA_64_VMS_SEG_RELA_OFF => 0x86000003a,
494 0 : Tag::IA_64_VMS_FIXUP_RELA_OFF => 0x86000003c,
495 0 : Tag::IA_64_VMS_PLTGOT_OFFSET => 0x86000003e,
496 0 : Tag::IA_64_VMS_PLTGOT_SEG => 0x860000040,
497 0 : Tag::IA_64_VMS_FPMODE => 0x860000042,
498 0 : Tag::UNKNOWN(value) => value,
499 : }
500 390 : }
501 : }
502 :
503 2496 : #[derive(Debug)]
504 : /// Enum that represents the different variants of a dynamic entry
505 : pub enum Entries<'a> {
506 : /// Entry for `DT_NEEDED`
507 : Library(Library<'a>),
508 :
509 : /// Entry for `DT_INIT_ARRAY, DT_FINI_ARRAY`, ...
510 : Array(Array<'a>),
511 :
512 : /// Entry for `DT_RPATH`
513 : Rpath(Rpath<'a>),
514 :
515 : /// Entry for `DT_RUNPATH`
516 : RunPath(RunPath<'a>),
517 :
518 : /// Entry for `DT_SONAME`
519 : SharedObject(SharedObject<'a>),
520 :
521 : /// Entry for `DT_AUXILIARY`
522 : Auxiliary(Auxiliary<'a>),
523 :
524 : /// Entry for `DT_FILTER`
525 : Filter(Filter<'a>),
526 :
527 : /// Entry for `DT_FLAGS` and `DT_FLAGS_1`
528 : Flags(Flags<'a>),
529 :
530 : /// Generic value
531 : Generic(Generic<'a>),
532 : }
533 :
534 : impl Entries<'_> {
535 : /// Create a new dynamic entry with the given Tag
536 0 : pub fn with_tag(tag: Tag) -> Entries<'static> {
537 0 : Entries::from_ffi(lief_ffi::ELF_DynamicEntry::create(tag.into()))
538 0 : }
539 : }
540 :
541 : /// Trait shared by all the [`Entries`]
542 : pub trait DynamicEntry {
543 : #[doc(hidden)]
544 : fn as_base(&self) -> &ffi::ELF_DynamicEntry;
545 :
546 : #[doc(hidden)]
547 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry>;
548 :
549 : /// Dynamic TAG associated with the entry
550 192 : fn tag(&self) -> Tag {
551 192 : Tag::from(self.as_base().tag())
552 192 : }
553 :
554 : /// Raw value which should be interpreted according to the [`DynamicEntry::tag`]
555 184 : fn value(&self) -> u64 {
556 184 : self.as_base().value()
557 184 : }
558 :
559 0 : fn set_value(&mut self, value: u64) {
560 0 : self.as_mut_base().set_value(value);
561 0 : }
562 : }
563 :
564 : impl std::fmt::Display for &dyn DynamicEntry {
565 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
566 0 : write!(f, "{}", self.as_base().to_string())
567 0 : }
568 : }
569 :
570 : impl DynamicEntry for Entries<'_> {
571 0 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
572 0 : match &self {
573 0 : Entries::Library(entry) => entry.as_base(),
574 :
575 0 : Entries::Array(entry) => entry.as_base(),
576 :
577 0 : Entries::Rpath(entry) => entry.as_base(),
578 :
579 0 : Entries::RunPath(entry) => entry.as_base(),
580 :
581 0 : Entries::SharedObject(entry) => entry.as_base(),
582 :
583 0 : Entries::Auxiliary(entry) => entry.as_base(),
584 :
585 0 : Entries::Filter(entry) => entry.as_base(),
586 :
587 0 : Entries::Flags(entry) => entry.as_base(),
588 :
589 0 : Entries::Generic(entry) => entry.as_base(),
590 : }
591 0 : }
592 :
593 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
594 0 : match self {
595 0 : Entries::Library(entry) => entry.as_mut_base(),
596 :
597 0 : Entries::Array(entry) => entry.as_mut_base(),
598 :
599 0 : Entries::Rpath(entry) => entry.as_mut_base(),
600 :
601 0 : Entries::RunPath(entry) => entry.as_mut_base(),
602 :
603 0 : Entries::SharedObject(entry) => entry.as_mut_base(),
604 :
605 0 : Entries::Auxiliary(entry) => entry.as_mut_base(),
606 :
607 0 : Entries::Filter(entry) => entry.as_mut_base(),
608 :
609 0 : Entries::Flags(entry) => entry.as_mut_base(),
610 :
611 0 : Entries::Generic(entry) => entry.as_mut_base(),
612 : }
613 0 : }
614 : }
615 :
616 : impl FromFFI<ffi::ELF_DynamicEntry> for Entries<'_> {
617 2496 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::ELF_DynamicEntry>) -> Self {
618 2496 : unsafe {
619 2496 : let cmd_ref = ffi_entry.as_ref().unwrap();
620 2496 :
621 2496 : if ffi::ELF_DynamicEntryLibrary::classof(cmd_ref) {
622 260 : let raw = {
623 260 : type From = cxx::UniquePtr<ffi::ELF_DynamicEntry>;
624 260 : type To = cxx::UniquePtr<ffi::ELF_DynamicEntryLibrary>;
625 260 : std::mem::transmute::<From, To>(ffi_entry)
626 260 : };
627 260 : Entries::Library(Library::from_ffi(raw))
628 2236 : } else if ffi::ELF_DynamicEntryArray::classof(cmd_ref) {
629 143 : let raw = {
630 143 : type From = cxx::UniquePtr<ffi::ELF_DynamicEntry>;
631 143 : type To = cxx::UniquePtr<ffi::ELF_DynamicEntryArray>;
632 143 : std::mem::transmute::<From, To>(ffi_entry)
633 143 : };
634 143 : Entries::Array(Array::from_ffi(raw))
635 2093 : } else if ffi::ELF_DynamicEntryRpath::classof(cmd_ref) {
636 13 : let raw = {
637 13 : type From = cxx::UniquePtr<ffi::ELF_DynamicEntry>;
638 13 : type To = cxx::UniquePtr<ffi::ELF_DynamicEntryRpath>;
639 13 : std::mem::transmute::<From, To>(ffi_entry)
640 13 : };
641 13 : Entries::Rpath(Rpath::from_ffi(raw))
642 2080 : } else if ffi::ELF_DynamicEntryRunPath::classof(cmd_ref) {
643 13 : let raw = {
644 13 : type From = cxx::UniquePtr<ffi::ELF_DynamicEntry>;
645 13 : type To = cxx::UniquePtr<ffi::ELF_DynamicEntryRunPath>;
646 13 : std::mem::transmute::<From, To>(ffi_entry)
647 13 : };
648 13 : Entries::RunPath(RunPath::from_ffi(raw))
649 2067 : } else if ffi::ELF_DynamicSharedObject::classof(cmd_ref) {
650 13 : let raw = {
651 13 : type From = cxx::UniquePtr<ffi::ELF_DynamicEntry>;
652 13 : type To = cxx::UniquePtr<ffi::ELF_DynamicSharedObject>;
653 13 : std::mem::transmute::<From, To>(ffi_entry)
654 13 : };
655 13 : Entries::SharedObject(SharedObject::from_ffi(raw))
656 2054 : } else if ffi::ELF_DynamicEntryAuxiliary::classof(cmd_ref) {
657 26 : let raw = {
658 26 : type From = cxx::UniquePtr<ffi::ELF_DynamicEntry>;
659 26 : type To = cxx::UniquePtr<ffi::ELF_DynamicEntryAuxiliary>;
660 26 : std::mem::transmute::<From, To>(ffi_entry)
661 26 : };
662 26 : Entries::Auxiliary(Auxiliary::from_ffi(raw))
663 2028 : } else if ffi::ELF_DynamicEntryFilter::classof(cmd_ref) {
664 13 : let raw = {
665 13 : type From = cxx::UniquePtr<ffi::ELF_DynamicEntry>;
666 13 : type To = cxx::UniquePtr<ffi::ELF_DynamicEntryFilter>;
667 13 : std::mem::transmute::<From, To>(ffi_entry)
668 13 : };
669 13 : Entries::Filter(Filter::from_ffi(raw))
670 2015 : } else if ffi::ELF_DynamicEntryFlags::classof(cmd_ref) {
671 26 : let raw = {
672 26 : type From = cxx::UniquePtr<ffi::ELF_DynamicEntry>;
673 26 : type To = cxx::UniquePtr<ffi::ELF_DynamicEntryFlags>;
674 26 : std::mem::transmute::<From, To>(ffi_entry)
675 26 : };
676 26 : Entries::Flags(Flags::from_ffi(raw))
677 : } else {
678 1989 : Entries::Generic(Generic::from_ffi(ffi_entry))
679 : }
680 : }
681 2496 : }
682 : }
683 :
684 : /// Generic structure for the dynamic entries whose [`DynamicEntry::value`] can be interpreted
685 : /// as is.
686 : pub struct Generic<'a> {
687 : ptr: cxx::UniquePtr<ffi::ELF_DynamicEntry>,
688 : _owner: PhantomData<&'a ffi::ELF_Binary>,
689 : }
690 :
691 : impl FromFFI<ffi::ELF_DynamicEntry> for Generic<'_> {
692 1989 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_DynamicEntry>) -> Self {
693 1989 : Self {
694 1989 : ptr,
695 1989 : _owner: PhantomData,
696 1989 : }
697 1989 : }
698 : }
699 :
700 : impl DynamicEntry for Generic<'_> {
701 3978 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
702 3978 : self.ptr.as_ref().unwrap()
703 3978 : }
704 :
705 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
706 0 : unsafe {
707 0 : Pin::new_unchecked({
708 0 : (self.ptr.as_ref().unwrap() as *const ffi::ELF_DynamicEntry
709 0 : as *mut ffi::ELF_DynamicEntry)
710 0 : .as_mut()
711 0 : .unwrap()
712 0 : })
713 0 : }
714 0 : }
715 : }
716 :
717 : impl std::fmt::Debug for Generic<'_> {
718 1989 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
719 1989 : f.debug_struct("Generic").finish()
720 1989 : }
721 : }
722 :
723 : /// Structure that represents a dynamic entry associated with a library name (e.g. `DT_NEEDED`)
724 : pub struct Library<'a> {
725 : ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryLibrary>,
726 : _owner: PhantomData<&'a ffi::ELF_Binary>,
727 : }
728 :
729 : impl Library<'_> {
730 : /// Name of the library (e.g. `libc.so.6`)
731 260 : pub fn name(&self) -> String {
732 260 : self.ptr.name().to_string()
733 260 : }
734 :
735 : /// Set a new library name
736 0 : pub fn set_name(&mut self, new_name: &str) {
737 0 : self.ptr.pin_mut().set_name(new_name.to_string());
738 0 : }
739 : }
740 :
741 : impl FromFFI<ffi::ELF_DynamicEntryLibrary> for Library<'_> {
742 286 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryLibrary>) -> Self {
743 286 : Self {
744 286 : ptr,
745 286 : _owner: PhantomData,
746 286 : }
747 286 : }
748 : }
749 :
750 : impl DynamicEntry for Library<'_> {
751 520 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
752 520 : self.ptr.as_ref().unwrap().as_ref()
753 520 : }
754 :
755 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
756 0 : unsafe {
757 0 : Pin::new_unchecked({
758 0 : (self.ptr.as_ref().unwrap().as_ref() as *const ffi::ELF_DynamicEntry
759 0 : as *mut ffi::ELF_DynamicEntry)
760 0 : .as_mut()
761 0 : .unwrap()
762 0 : })
763 0 : }
764 0 : }
765 : }
766 :
767 : impl std::fmt::Debug for Library<'_> {
768 260 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
769 260 : f.debug_struct("Library").finish()
770 260 : }
771 : }
772 :
773 : /// Structure that represents a dynamic entry associated with an array (e.g. `DT_INIT_ARRAY`)
774 : pub struct Array<'a> {
775 : ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryArray>,
776 : _owner: PhantomData<&'a ffi::ELF_Binary>,
777 : }
778 :
779 : impl Array<'_> {
780 143 : pub fn array(&self) -> Vec<u64> {
781 143 : Vec::from(self.ptr.array().as_slice())
782 143 : }
783 : }
784 :
785 : impl FromFFI<ffi::ELF_DynamicEntryArray> for Array<'_> {
786 143 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryArray>) -> Self {
787 143 : Self {
788 143 : ptr,
789 143 : _owner: PhantomData,
790 143 : }
791 143 : }
792 : }
793 :
794 : impl DynamicEntry for Array<'_> {
795 286 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
796 286 : self.ptr.as_ref().unwrap().as_ref()
797 286 : }
798 :
799 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
800 0 : unsafe {
801 0 : Pin::new_unchecked({
802 0 : (self.ptr.as_ref().unwrap().as_ref() as *const ffi::ELF_DynamicEntry
803 0 : as *mut ffi::ELF_DynamicEntry)
804 0 : .as_mut()
805 0 : .unwrap()
806 0 : })
807 0 : }
808 0 : }
809 : }
810 :
811 : impl std::fmt::Debug for Array<'_> {
812 143 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
813 143 : f.debug_struct("Array").finish()
814 143 : }
815 : }
816 :
817 : /// Structure that represents a dynamic entry associated with the rpath info
818 : pub struct Rpath<'a> {
819 : ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryRpath>,
820 : _owner: PhantomData<&'a ffi::ELF_Binary>,
821 : }
822 :
823 : impl Rpath<'_> {
824 : /// Create a new Rpath entry with the given path(s)
825 : ///
826 : /// For instance:
827 : ///
828 : /// ```
829 : /// Rpath::new("$ORIGIN/../:/lib64")
830 : /// ```
831 0 : pub fn new(value: &str) -> Rpath<'static> {
832 0 : Rpath::from_ffi(lief_ffi::ELF_DynamicEntryRpath::create(value.to_string()))
833 0 : }
834 :
835 : /// Create a new Rpath entry from a slice of paths
836 : ///
837 : /// For instance:
838 : ///
839 : /// ```
840 : /// Rpath::with_paths(&vec!["$ORIGIN/../", "/lib64"])
841 : /// ```
842 0 : pub fn with_paths(values: &[&str]) -> Rpath<'static> {
843 0 : Rpath::new(&values.join(":"))
844 0 : }
845 :
846 : /// The actual rpath as a string
847 13 : pub fn rpath(&self) -> String {
848 13 : self.ptr.rpath().to_string()
849 13 : }
850 :
851 : /// Change the rpath value
852 0 : pub fn set_rpath(&mut self, value: &str) {
853 0 : self.ptr.pin_mut().set_rpath(value.to_string());
854 0 : }
855 :
856 : /// Change the rpath value with the given slice
857 0 : pub fn set_rpath_with_value(&mut self, values: &[&str]) {
858 0 : self.ptr.pin_mut().set_rpath(values.join(":"));
859 0 : }
860 :
861 : /// The specified paths as a list of string
862 0 : pub fn paths(&self) -> Vec<String> {
863 0 : let mut result = Vec::new();
864 0 : for entry in self.ptr.paths().into_iter() {
865 0 : result.push(entry.to_string());
866 0 : }
867 0 : result
868 0 : }
869 :
870 : /// Insert a `path` at the given `position`
871 0 : pub fn insert(&mut self, pos: u32, path: &str) {
872 0 : self.ptr.pin_mut().insert(pos, path.to_string());
873 0 : }
874 :
875 : /// Append the given path
876 0 : pub fn append(&mut self, path: &str) {
877 0 : self.ptr.pin_mut().append(path.to_string());
878 0 : }
879 :
880 : /// The given path
881 0 : pub fn remove(&mut self, path: &str) {
882 0 : self.ptr.pin_mut().remove(path.to_string());
883 0 : }
884 : }
885 :
886 : impl FromFFI<ffi::ELF_DynamicEntryRpath> for Rpath<'_> {
887 13 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryRpath>) -> Self {
888 13 : Self {
889 13 : ptr,
890 13 : _owner: PhantomData,
891 13 : }
892 13 : }
893 : }
894 :
895 : impl DynamicEntry for Rpath<'_> {
896 13 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
897 13 : self.ptr.as_ref().unwrap().as_ref()
898 13 : }
899 :
900 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
901 0 : unsafe {
902 0 : Pin::new_unchecked({
903 0 : (self.ptr.as_ref().unwrap().as_ref() as *const ffi::ELF_DynamicEntry
904 0 : as *mut ffi::ELF_DynamicEntry)
905 0 : .as_mut()
906 0 : .unwrap()
907 0 : })
908 0 : }
909 0 : }
910 : }
911 :
912 : impl std::fmt::Debug for Rpath<'_> {
913 13 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
914 13 : f.debug_struct("Rpath").finish()
915 13 : }
916 : }
917 :
918 : /// Structure that represents a dynamic entry associated with the runpath info
919 : pub struct RunPath<'a> {
920 : ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryRunPath>,
921 : _owner: PhantomData<&'a ffi::ELF_Binary>,
922 : }
923 :
924 : impl RunPath<'_> {
925 : /// Create a new RunPath entry with the given path(s)
926 : ///
927 : /// For instance:
928 : ///
929 : /// ```
930 : /// RunPath::new("$ORIGIN/../:/lib64")
931 : /// ```
932 0 : pub fn new(value: &str) -> RunPath<'static> {
933 0 : RunPath::from_ffi(lief_ffi::ELF_DynamicEntryRunPath::create(value.to_string()))
934 0 : }
935 :
936 : /// Create a new RunPath entry from a slice of paths
937 : ///
938 : /// For instance:
939 : ///
940 : /// ```
941 : /// RunPath::with_paths(&vec!["$ORIGIN/../", "/lib64"])
942 : /// ```
943 0 : pub fn with_paths(values: &[&str]) -> RunPath<'static> {
944 0 : RunPath::new(&values.join(":"))
945 0 : }
946 :
947 13 : pub fn runpath(&self) -> String {
948 13 : self.ptr.runpath().to_string()
949 13 : }
950 :
951 : /// The specified paths as a list of string
952 0 : pub fn paths(&self) -> Vec<String> {
953 0 : let mut result = Vec::new();
954 0 : for entry in self.ptr.paths().into_iter() {
955 0 : result.push(entry.to_string());
956 0 : }
957 0 : result
958 0 : }
959 :
960 : /// Change the runpath value
961 0 : pub fn set_runpath(&mut self, value: &str) {
962 0 : self.ptr.pin_mut().set_runpath(value.to_string());
963 0 : }
964 :
965 : /// Change the runpath value with the given slice
966 0 : pub fn set_runpath_with_value(&mut self, values: &[&str]) {
967 0 : self.ptr.pin_mut().set_runpath(values.join(":"));
968 0 : }
969 :
970 : /// Insert a `path` at the given `position`
971 0 : pub fn insert(&mut self, pos: u32, path: &str) {
972 0 : self.ptr.pin_mut().insert(pos, path.to_string());
973 0 : }
974 :
975 : /// Append the given path
976 0 : pub fn append(&mut self, path: &str) {
977 0 : self.ptr.pin_mut().append(path.to_string());
978 0 : }
979 :
980 : /// The given path
981 0 : pub fn remove(&mut self, path: &str) {
982 0 : self.ptr.pin_mut().remove(path.to_string());
983 0 : }
984 : }
985 :
986 : impl FromFFI<ffi::ELF_DynamicEntryRunPath> for RunPath<'_> {
987 13 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryRunPath>) -> Self {
988 13 : Self {
989 13 : ptr,
990 13 : _owner: PhantomData,
991 13 : }
992 13 : }
993 : }
994 :
995 : impl DynamicEntry for RunPath<'_> {
996 13 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
997 13 : self.ptr.as_ref().unwrap().as_ref()
998 13 : }
999 :
1000 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
1001 0 : unsafe {
1002 0 : Pin::new_unchecked({
1003 0 : (self.ptr.as_ref().unwrap().as_ref() as *const ffi::ELF_DynamicEntry
1004 0 : as *mut ffi::ELF_DynamicEntry)
1005 0 : .as_mut()
1006 0 : .unwrap()
1007 0 : })
1008 0 : }
1009 0 : }
1010 : }
1011 :
1012 : impl std::fmt::Debug for RunPath<'_> {
1013 13 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1014 13 : f.debug_struct("RunPath").finish()
1015 13 : }
1016 : }
1017 :
1018 : /// Structure that represents a dynamic entry associated with the name of a library (`DT_SONAME`)
1019 : pub struct SharedObject<'a> {
1020 : ptr: cxx::UniquePtr<ffi::ELF_DynamicSharedObject>,
1021 : _owner: PhantomData<&'a ffi::ELF_Binary>,
1022 : }
1023 :
1024 : impl SharedObject<'_> {
1025 0 : pub fn new(name: &str) -> SharedObject<'static> {
1026 0 : SharedObject::from_ffi(lief_ffi::ELF_DynamicSharedObject::create(name.to_string()))
1027 0 : }
1028 :
1029 13 : pub fn name(&self) -> String {
1030 13 : self.ptr.name().to_string()
1031 13 : }
1032 :
1033 0 : pub fn set_name(&mut self, name: &str) {
1034 0 : self.ptr.pin_mut().set_name(name.to_string());
1035 0 : }
1036 : }
1037 :
1038 : impl FromFFI<ffi::ELF_DynamicSharedObject> for SharedObject<'_> {
1039 13 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_DynamicSharedObject>) -> Self {
1040 13 : Self {
1041 13 : ptr,
1042 13 : _owner: PhantomData,
1043 13 : }
1044 13 : }
1045 : }
1046 :
1047 : impl DynamicEntry for SharedObject<'_> {
1048 13 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
1049 13 : self.ptr.as_ref().unwrap().as_ref()
1050 13 : }
1051 :
1052 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
1053 0 : unsafe {
1054 0 : Pin::new_unchecked({
1055 0 : (self.ptr.as_ref().unwrap().as_ref() as *const ffi::ELF_DynamicEntry
1056 0 : as *mut ffi::ELF_DynamicEntry)
1057 0 : .as_mut()
1058 0 : .unwrap()
1059 0 : })
1060 0 : }
1061 0 : }
1062 : }
1063 :
1064 : impl std::fmt::Debug for SharedObject<'_> {
1065 13 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1066 13 : f.debug_struct("SharedObject").finish()
1067 13 : }
1068 : }
1069 :
1070 : /// Structure that represents a dynamic entry associated with the name of a library (`DT_AUXILIARY`)
1071 : pub struct Auxiliary<'a> {
1072 : ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryAuxiliary>,
1073 : _owner: PhantomData<&'a ffi::ELF_Binary>,
1074 : }
1075 :
1076 : impl Auxiliary<'_> {
1077 0 : pub fn new(name: &str) -> Auxiliary<'static> {
1078 0 : Auxiliary::from_ffi(lief_ffi::ELF_DynamicEntryAuxiliary::create(
1079 0 : name.to_string(),
1080 0 : ))
1081 0 : }
1082 :
1083 26 : pub fn name(&self) -> String {
1084 26 : self.ptr.name().to_string()
1085 26 : }
1086 :
1087 0 : pub fn set_name(&mut self, name: &str) {
1088 0 : self.ptr.pin_mut().set_name(name.to_string());
1089 0 : }
1090 : }
1091 :
1092 : impl FromFFI<ffi::ELF_DynamicEntryAuxiliary> for Auxiliary<'_> {
1093 26 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryAuxiliary>) -> Self {
1094 26 : Self {
1095 26 : ptr,
1096 26 : _owner: PhantomData,
1097 26 : }
1098 26 : }
1099 : }
1100 :
1101 : impl DynamicEntry for Auxiliary<'_> {
1102 26 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
1103 26 : self.ptr.as_ref().unwrap().as_ref()
1104 26 : }
1105 :
1106 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
1107 0 : unsafe {
1108 0 : Pin::new_unchecked({
1109 0 : (self.ptr.as_ref().unwrap().as_ref() as *const ffi::ELF_DynamicEntry
1110 0 : as *mut ffi::ELF_DynamicEntry)
1111 0 : .as_mut()
1112 0 : .unwrap()
1113 0 : })
1114 0 : }
1115 0 : }
1116 : }
1117 :
1118 : impl std::fmt::Debug for Auxiliary<'_> {
1119 26 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1120 26 : f.debug_struct("Auxiliary").finish()
1121 26 : }
1122 : }
1123 :
1124 : /// Structure that represents a dynamic entry associated with the name of a library (`DT_FILTER`)
1125 : pub struct Filter<'a> {
1126 : ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryFilter>,
1127 : _owner: PhantomData<&'a ffi::ELF_Binary>,
1128 : }
1129 :
1130 : impl Filter<'_> {
1131 0 : pub fn new(name: &str) -> Filter<'static> {
1132 0 : Filter::from_ffi(lief_ffi::ELF_DynamicEntryFilter::create(name.to_string()))
1133 0 : }
1134 :
1135 13 : pub fn name(&self) -> String {
1136 13 : self.ptr.name().to_string()
1137 13 : }
1138 :
1139 0 : pub fn set_name(&mut self, name: &str) {
1140 0 : self.ptr.pin_mut().set_name(name.to_string());
1141 0 : }
1142 : }
1143 :
1144 : impl FromFFI<ffi::ELF_DynamicEntryFilter> for Filter<'_> {
1145 13 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryFilter>) -> Self {
1146 13 : Self {
1147 13 : ptr,
1148 13 : _owner: PhantomData,
1149 13 : }
1150 13 : }
1151 : }
1152 :
1153 : impl DynamicEntry for Filter<'_> {
1154 13 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
1155 13 : self.ptr.as_ref().unwrap().as_ref()
1156 13 : }
1157 :
1158 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
1159 0 : unsafe {
1160 0 : Pin::new_unchecked({
1161 0 : (self.ptr.as_ref().unwrap().as_ref() as *const ffi::ELF_DynamicEntry
1162 0 : as *mut ffi::ELF_DynamicEntry)
1163 0 : .as_mut()
1164 0 : .unwrap()
1165 0 : })
1166 0 : }
1167 0 : }
1168 : }
1169 :
1170 : impl std::fmt::Debug for Filter<'_> {
1171 13 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1172 13 : f.debug_struct("Filter").finish()
1173 13 : }
1174 : }
1175 :
1176 : /// Structure that represents a dynamic flag entry: `DT_FLAGS` or `DT_FLAGS_1`
1177 : pub struct Flags<'a> {
1178 : ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryFlags>,
1179 : _owner: PhantomData<&'a ffi::ELF_Binary>,
1180 : }
1181 :
1182 : impl Flags<'_> {
1183 26 : pub fn flags(&self) -> DtFlags {
1184 26 : DtFlags::from(self.ptr.flags())
1185 26 : }
1186 :
1187 0 : pub fn add_flag(&mut self, flag: DtFlags) {
1188 0 : self.ptr.pin_mut().add_flag(flag.into())
1189 0 : }
1190 :
1191 0 : pub fn remove_flag(&mut self, flag: DtFlags) {
1192 0 : self.ptr.pin_mut().remove_flag(flag.into())
1193 0 : }
1194 :
1195 0 : pub fn create_dt_flag(value: u64) -> Self {
1196 0 : Self::from_ffi(ffi::ELF_DynamicEntryFlags::create_dt_flag(value))
1197 0 : }
1198 :
1199 0 : pub fn create_dt_flag_1(value: u64) -> Self {
1200 0 : Self::from_ffi(ffi::ELF_DynamicEntryFlags::create_dt_flag_1(value))
1201 0 : }
1202 : }
1203 :
1204 : impl FromFFI<ffi::ELF_DynamicEntryFlags> for Flags<'_> {
1205 26 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_DynamicEntryFlags>) -> Self {
1206 26 : Self {
1207 26 : ptr,
1208 26 : _owner: PhantomData,
1209 26 : }
1210 26 : }
1211 : }
1212 :
1213 : impl DynamicEntry for Flags<'_> {
1214 26 : fn as_base(&self) -> &ffi::ELF_DynamicEntry {
1215 26 : self.ptr.as_ref().unwrap().as_ref()
1216 26 : }
1217 :
1218 0 : fn as_mut_base(&mut self) -> Pin<&mut ffi::ELF_DynamicEntry> {
1219 0 : unsafe {
1220 0 : Pin::new_unchecked({
1221 0 : (self.ptr.as_ref().unwrap().as_ref() as *const ffi::ELF_DynamicEntry
1222 0 : as *mut ffi::ELF_DynamicEntry)
1223 0 : .as_mut()
1224 0 : .unwrap()
1225 0 : })
1226 0 : }
1227 0 : }
1228 : }
1229 :
1230 : impl std::fmt::Debug for Flags<'_> {
1231 26 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1232 26 : f.debug_struct("Flags").finish()
1233 26 : }
1234 : }
1235 :
1236 0 : bitflags! {
1237 26 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1238 0 : pub struct DtFlags: u64 {
1239 0 : const ORIGIN = 0x1;
1240 0 : const SYMBOLIC = 0x2;
1241 0 : const TEXTREL = 0x4;
1242 0 : const BIND_NOW = 0x8;
1243 0 : const STATIC_TLS = 0x10;
1244 0 : const NOW = 0x100000001;
1245 0 : const GLOBAL = 0x100000002;
1246 0 : const GROUP = 0x100000004;
1247 0 : const NODELETE = 0x100000008;
1248 0 : const LOADFLTR = 0x100000010;
1249 0 : const INITFIRST = 0x100000020;
1250 0 : const NOOPEN = 0x100000040;
1251 0 : const HANDLE_ORIGIN = 0x100000080;
1252 0 : const DIRECT = 0x100000100;
1253 0 : const TRANS = 0x100000200;
1254 0 : const INTERPOSE = 0x100000400;
1255 0 : const NODEFLIB = 0x100000800;
1256 0 : const NODUMP = 0x100001000;
1257 0 : const CONFALT = 0x100002000;
1258 0 : const ENDFILTEE = 0x100004000;
1259 0 : const DISPRELDNE = 0x100008000;
1260 0 : const DISPRELPND = 0x100010000;
1261 0 : const NODIRECT = 0x100020000;
1262 0 : const IGNMULDEF = 0x100040000;
1263 0 : const NOKSYMS = 0x100080000;
1264 0 : const NOHDR = 0x100100000;
1265 0 : const EDITED = 0x100200000;
1266 0 : const NORELOC = 0x100400000;
1267 0 : const SYMINTPOSE = 0x100800000;
1268 0 : const GLOBAUDIT = 0x101000000;
1269 0 : const SINGLETON = 0x102000000;
1270 0 : const PIE = 0x108000000;
1271 0 : const KMOD = 0x110000000;
1272 0 : const WEAKFILTER = 0x120000000;
1273 0 : const NOCOMMON = 0x140000000;
1274 0 : }
1275 0 : }
1276 :
1277 : impl From<u64> for DtFlags {
1278 26 : fn from(value: u64) -> Self {
1279 26 : DtFlags::from_bits_truncate(value)
1280 26 : }
1281 : }
1282 : impl From<DtFlags> for u64 {
1283 0 : fn from(value: DtFlags) -> Self {
1284 0 : value.bits()
1285 0 : }
1286 : }
1287 : impl std::fmt::Display for DtFlags {
1288 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1289 0 : bitflags::parser::to_writer(self, f)
1290 0 : }
1291 : }
1292 :
1293 2496 : declare_iterator!(
1294 2496 : DynamicEntries,
1295 2496 : Entries<'a>,
1296 2496 : ffi::ELF_DynamicEntry,
1297 2496 : ffi::ELF_Binary,
1298 2496 : ffi::ELF_Binary_it_dynamic_entries
1299 2496 : );
|