1use super::{Error, Result, RW};
2
3macro_rules! int_enum {
4 ($name: ident as $type: ty: $($variant: ident = $value: expr,)+) => {
5 impl $name {
6 pub(super) fn int_value(self) -> $type {
7 match self {
8 $(Self::$variant => $value,)+
9 Self::Custom(value) => value,
10 }
11 }
12
13 pub(super) fn from_int(value: $type) -> Self {
14 match value {
15 $($value => Self::$variant,)+
16 value => Self::Custom(value),
17 }
18 }
19 }
20 };
21
22 (!$name: ident as $type: ty: $($variant: ident = $value: expr,)+) => {
24 impl $name {
25 pub(super) fn int_value(self) -> $type {
26 match self {
27 $(Self::$variant => $value,)+
28 }
29 }
30
31 pub(super) fn from_int(value: $type) -> Result<Self> {
32 match value {
33 $($value => Ok(Self::$variant),)+
34 value => Err(Error::Error(format!("Invalid value for {}: {value}", stringify!($name)))),
35 }
36 }
37 }
38 };
39}
40
41#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
44pub enum Class {
45 ELF32,
47 #[default]
49 ELF64,
50 Custom(u8),
52}
53
54int_enum! {
55 Class as u8:
56 ELF32 = 1,
57 ELF64 = 2,
58}
59
60#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
62pub enum ByteOrder {
63 #[default]
65 LSB,
66 MSB,
68}
69
70int_enum! {
71 !ByteOrder as u8:
72 LSB = 1,
73 MSB = 2,
74}
75
76#[cfg(feature = "target-lexicon")]
77impl From<target_lexicon::Endianness> for ByteOrder {
78 fn from(value: target_lexicon::Endianness) -> Self {
79 match value {
80 target_lexicon::Endianness::Little => Self::LSB,
81 target_lexicon::Endianness::Big => Self::MSB,
82 }
83 }
84}
85
86#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
88pub enum ABI {
89 #[default]
90 None,
92 HPUX,
94 NetBSD,
96 Linux,
98 Hurd,
100 Solaris,
102 AIX,
104 IRIX,
106 FreeBSD,
108 Tru64,
110 Modesto,
112 OpenBSD,
114 OpenVMS,
116 NSK,
118 AROS,
120 FenixOS,
122 CloudABI,
124 OpenVOS,
126 Custom(u8),
128}
129
130int_enum! {
131 ABI as u8:
132 None = 0x00,
133 HPUX = 0x01,
134 NetBSD = 0x02,
135 Linux = 0x03,
136 Hurd = 0x04,
137 Solaris = 0x06,
138 AIX = 0x07,
139 IRIX = 0x08,
140 FreeBSD = 0x09,
141 Tru64 = 0x0A,
142 Modesto = 0x0B,
143 OpenBSD = 0x0C,
144 OpenVMS = 0x0D,
145 NSK = 0x0E,
146 AROS = 0x0F,
147 FenixOS = 0x10,
148 CloudABI = 0x11,
149 OpenVOS = 0x12,
150}
151
152#[cfg(feature = "target-lexicon")]
153impl From<target_lexicon::OperatingSystem> for ABI {
154 fn from(value: target_lexicon::OperatingSystem) -> Self {
155 match value {
156 target_lexicon::OperatingSystem::Unknown => Self::None,
157 target_lexicon::OperatingSystem::Aix => Self::AIX,
158 target_lexicon::OperatingSystem::Cloudabi => Self::CloudABI,
159 target_lexicon::OperatingSystem::Freebsd => Self::FreeBSD,
160 target_lexicon::OperatingSystem::Linux => Self::Linux,
161 target_lexicon::OperatingSystem::Netbsd => Self::NetBSD,
162 target_lexicon::OperatingSystem::None_ => Self::None,
163 target_lexicon::OperatingSystem::Openbsd => Self::OpenBSD,
164 target_lexicon::OperatingSystem::Solaris => Self::Solaris,
165 _ => Self::None,
166 }
167 }
168}
169
170#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
172pub enum Type {
173 Rel,
175 Exec,
177 Dyn,
179 Core,
181 Custom(u16),
183}
184
185int_enum! {
186 Type as u16:
187 Rel = 1,
188 Exec = 2,
189 Dyn = 3,
190 Core = 4,
191}
192
193#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
195pub enum Machine {
196 None,
198 M32,
200 SPARC,
202 X86,
204 M68k,
206 M88k,
208 IntelMCU,
210 Intel80860,
212 MIPS,
214 S370,
216 MipsRS3LE,
218 PARISC,
220 Intel80960,
222 PowerPC,
224 PowerPC64,
226 S390,
228 SPU,
230 V800,
232 FR20,
234 RH32,
236 RCE,
238 ARM,
240 DigitalAlpha,
242 SuperH,
244 SPARC9,
246 TriCore,
248 ARC,
250 H8_300,
252 H8_300H,
254 H8S,
256 H8_500,
258 IA64,
260 MipsX,
262 ColdFire,
264 M68HC12,
266 MMA,
268 PCP,
270 NCPU,
272 NDR1,
274 StarCore,
276 ME16,
278 ST100,
280 TinyJ,
282 X86_64,
284 SonyDSP,
286 PDP10,
288 PDP11,
290 FX66,
292 ST9,
294 ST7,
296 MC68HC16,
298 MC68HC11,
300 MC68HC08,
302 MC68HC05,
304 SVx,
306 ST19,
308 DigitalVAX,
310 AxisCommunications,
312 InfineonTechnologies,
314 Element14,
316 LSILogic,
318 TMS320C6000,
320 MCSTElbrusE2k,
322 ARM64,
324 Z80,
326 RISCV,
328 BerkeleyPacketFilter,
330 WDC65C816,
332 Custom(u16),
334}
335
336int_enum! {
337 Machine as u16:
338 None = 0x00,
339 M32 = 0x01,
340 SPARC = 0x02,
341 X86 = 0x03,
342 M68k = 0x04,
343 M88k = 0x05,
344 IntelMCU = 0x06,
345 Intel80860 = 0x07,
346 MIPS = 0x08,
347 S370 = 0x09,
348 MipsRS3LE = 0x0A,
349 PARISC = 0x0F,
350 Intel80960 = 0x13,
351 PowerPC = 0x14,
352 PowerPC64 = 0x15,
353 S390 = 0x16,
354 SPU = 0x17,
355 V800 = 0x24,
356 FR20 = 0x25,
357 RH32 = 0x26,
358 RCE = 0x27,
359 ARM = 0x28,
360 DigitalAlpha = 0x29,
361 SuperH = 0x2A,
362 SPARC9 = 0x2B,
363 TriCore = 0x2C,
364 ARC = 0x2D,
365 H8_300 = 0x2E,
366 H8_300H = 0x2F,
367 H8S = 0x30,
368 H8_500 = 0x31,
369 IA64 = 0x32,
370 MipsX = 0x33,
371 ColdFire = 0x34,
372 M68HC12 = 0x35,
373 MMA = 0x36,
374 PCP = 0x37,
375 NCPU = 0x38,
376 NDR1 = 0x39,
377 StarCore = 0x3A,
378 ME16 = 0x3B,
379 ST100 = 0x3C,
380 TinyJ = 0x3D,
381 X86_64 = 0x3E,
382 SonyDSP = 0x3F,
383 PDP10 = 0x40,
384 PDP11 = 0x41,
385 FX66 = 0x42,
386 ST9 = 0x43,
387 ST7 = 0x44,
388 MC68HC16 = 0x45,
389 MC68HC11 = 0x46,
390 MC68HC08 = 0x47,
391 MC68HC05 = 0x48,
392 SVx = 0x49,
393 ST19 = 0x4A,
394 DigitalVAX = 0x4B,
395 AxisCommunications = 0x4C,
396 InfineonTechnologies = 0x4D,
397 Element14 = 0x4E,
398 LSILogic = 0x4F,
399 TMS320C6000 = 0x8C,
400 MCSTElbrusE2k = 0xAF,
401 ARM64 = 0xB7,
402 Z80 = 0xDC,
403 RISCV = 0xF3,
404 BerkeleyPacketFilter = 0xF7,
405 WDC65C816 = 0x101,
406}
407
408#[cfg(feature = "target-lexicon")]
409impl From<target_lexicon::Architecture> for Machine {
410 fn from(value: target_lexicon::Architecture) -> Self {
411 match value {
412 target_lexicon::Architecture::Unknown => Self::None,
413 target_lexicon::Architecture::Arm(_) => Self::ARM,
414 target_lexicon::Architecture::Aarch64(_) => Self::ARM64,
415 target_lexicon::Architecture::X86_32(_) => Self::X86,
416 target_lexicon::Architecture::M68k => Self::M68k,
417 target_lexicon::Architecture::Mips32(_) => Self::MIPS,
418 target_lexicon::Architecture::Mips64(_) => Self::MIPS,
419 target_lexicon::Architecture::Powerpc => Self::PowerPC,
420 target_lexicon::Architecture::Powerpc64 => Self::PowerPC64,
421 target_lexicon::Architecture::Powerpc64le => Self::PowerPC64,
422 target_lexicon::Architecture::Riscv32(_) => Self::RISCV,
423 target_lexicon::Architecture::Riscv64(_) => Self::RISCV,
424 target_lexicon::Architecture::S390x => Self::S390,
425 target_lexicon::Architecture::Sparc => Self::SPARC,
426 target_lexicon::Architecture::Sparc64 => Self::SPARC9,
427 target_lexicon::Architecture::Sparcv9 => Self::SPARC9,
428 target_lexicon::Architecture::X86_64 => Self::X86_64,
429 target_lexicon::Architecture::X86_64h => Self::X86_64,
430 _ => todo!(),
431 }
432 }
433}
434
435pub trait SizeT: Sized + RW {
437 fn new(value: u64) -> Self;
438 fn value(&self) -> u64;
439 const CLASS: Class;
440 const ELF_HEADER_SIZE: u16;
441 const SEGMENT_HEADER_SIZE: u16;
442 const SECTION_HEADER_SIZE: u16;
443 const MOVE_PFLAGS: bool;
444}
445
446#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
450pub enum SegmentType {
451 None,
453 Load,
455 Dynamic,
457 Interpreter,
459 Note,
461 ShLib,
463 Phdr,
465 Tls,
467 Custom(u32),
469}
470
471int_enum! {
472 SegmentType as u32:
473 None = 0x00,
474 Load = 0x01,
475 Dynamic = 0x02,
476 Interpreter = 0x03,
477 Note = 0x04,
478 ShLib = 0x05,
479 Phdr = 0x06,
480 Tls = 0x07,
481}
482
483#[repr(u32)]
485#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
486pub enum SegmentFlags {
487 Executable = 0x01,
489 Writeable = 0x02,
491 Readable = 0x04,
493}