1#![allow(missing_docs)]
2
3use crate::define_enum_v2;
4use crate::define_infallible_enum;
5use crate::Error;
6
7define_infallible_enum! {
8 "ELF file type.",
9 FileKind, u16,
10 (None, 0, "Unknown file type."),
11 (Relocatable, 1, "Relocatable file."),
12 (Executable, 2, "Executable file."),
13 (Shared, 3, "Shared object."),
14 (Core, 4, "Core dump."),
15}
16
17impl FileKind {
18 pub const fn as_u16(self) -> u16 {
20 self.as_number()
21 }
22}
23
24define_infallible_enum! {
25 "Operating system ABI.",
26 OsAbi, u8,
27 (Sysv, 0, "UNIX System V."),
28 (Hpux, 1, "HP-UX."),
29 (Netbsd, 2, "NetBSD."),
30 (Gnu, 3, "Linux/GNU."),
31 (Solaris, 6, "Solaris."),
32 (Aix, 7, "IBM AIX."),
33 (Irix, 8, "SGI IRIX."),
34 (Freebsd, 9, "FreeBSD."),
35 (Tru64, 10, "Compaq TRU64 UNIX."),
36 (Modesto, 11, "Novell Modesto."),
37 (Openbsd, 12, "OpenBSD."),
38 (ArmAeabi, 64, "Arm EABI."),
39 (Arm, 97, "Arm."),
40 (Standalone, 255, "Standalone (embedded)."),
41}
42
43impl OsAbi {
44 pub const fn as_u8(self) -> u8 {
46 self.as_number()
47 }
48}
49
50define_infallible_enum! {
51 "Architecture.",
52 Machine, u16,
53 (None, 0, "Unknown architecture."),
54 (M32, 1),
55 (Sparc, 2),
56 (I386, 3, "Intel 386."),
57 (M68k, 4),
58 (M88k, 5),
59 (Iamcu, 6),
60 (I860, 7),
61 (Mips, 8, "MIPS."),
62 (S370, 9),
63 (MipsRs3Le, 10),
64 (Parisc, 15),
65 (Vpp500, 17),
66 (Sparc32plus, 18),
67 (I960, 19),
68 (Ppc, 20),
69 (Ppc64, 21),
70 (S390, 22),
71 (Spu, 23),
72 (V800, 36),
73 (Fr20, 37),
74 (Rh32, 38),
75 (Rce, 39),
76 (Arm, 40, "Arm 32-bit."),
77 (FakeAlpha, 41),
78 (Sh, 42),
79 (Sparcv9, 43),
80 (Tricore, 44),
81 (Arc, 45),
82 (H8300, 46),
83 (H8300h, 47),
84 (H8s, 48),
85 (H8500, 49),
86 (Ia64, 50),
87 (MipsX, 51),
88 (Coldfire, 52),
89 (M68hc12, 53),
90 (Mma, 54),
91 (Pcp, 55),
92 (Ncpu, 56),
93 (Ndr1, 57),
94 (Starcore, 58),
95 (Me16, 59),
96 (St100, 60),
97 (Tinyj, 61),
98 (X86_64, 62, "AMD x86-64."),
99 (Pdsp, 63),
100 (Pdp10, 64),
101 (Pdp11, 65),
102 (Fx66, 66),
103 (St9plus, 67),
104 (St7, 68),
105 (M68hc16, 69),
106 (M68hc11, 70),
107 (M68hc08, 71),
108 (M68hc05, 72),
109 (Svx, 73),
110 (St19, 74),
111 (Vax, 75),
112 (Cris, 76),
113 (Javelin, 77),
114 (Firepath, 78),
115 (Zsp, 79),
116 (Mmix, 80),
117 (Huany, 81),
118 (Prism, 82),
119 (Avr, 83),
120 (Fr30, 84),
121 (D10v, 85),
122 (D30v, 86),
123 (V850, 87),
124 (M32r, 88),
125 (Mn10300, 89),
126 (Mn10200, 90),
127 (Pj, 91),
128 (Openrisc, 92),
129 (ArcCompact, 93),
130 (Xtensa, 94),
131 (Videocore, 95),
132 (TmmGpp, 96),
133 (Ns32k, 97),
134 (Tpc, 98),
135 (Snp1k, 99),
136 (St200, 100),
137 (Ip2k, 101),
138 (Max, 102),
139 (Cr, 103),
140 (F2mc16, 104),
141 (Msp430, 105),
142 (Blackfin, 106),
143 (SeC33, 107),
144 (Sep, 108),
145 (Arca, 109),
146 (Unicore, 110),
147 (Excess, 111),
148 (Dxp, 112),
149 (AlteraNios2, 113),
150 (Crx, 114),
151 (Xgate, 115),
152 (C166, 116),
153 (M16c, 117),
154 (Dspic30f, 118),
155 (Ce, 119),
156 (M32c, 120),
157 (Tsk3000, 131),
158 (Rs08, 132),
159 (Sharc, 133),
160 (Ecog2, 134),
161 (Score7, 135),
162 (Dsp24, 136),
163 (Videocore3, 137),
164 (Latticemico32, 138),
165 (SeC17, 139),
166 (TiC6000, 140),
167 (TiC2000, 141),
168 (TiC5500, 142),
169 (TiArp32, 143),
170 (TiPru, 144),
171 (MmdspPlus, 160),
172 (CypressM8c, 161),
173 (R32c, 162),
174 (Trimedia, 163),
175 (Qdsp6, 164),
176 (I8051, 165),
177 (Stxp7x, 166),
178 (Nds32, 167),
179 (Ecog1x, 168),
180 (Maxq30, 169),
181 (Ximo16, 170),
182 (Manik, 171),
183 (Craynv2, 172),
184 (Rx, 173),
185 (Metag, 174),
186 (McstElbrus, 175),
187 (Ecog16, 176),
188 (Cr16, 177),
189 (Etpu, 178),
190 (Sle9x, 179),
191 (L10m, 180),
192 (K10m, 181),
193 (Aarch64, 183, "Arm 64-bit."),
194 (Avr32, 185),
195 (Stm8, 186),
196 (Tile64, 187),
197 (Tilepro, 188),
198 (Microblaze, 189),
199 (Cuda, 190, "NVIDIA CUDA."),
200 (Tilegx, 191),
201 (Cloudshield, 192),
202 (Corea1st, 193),
203 (Corea2nd, 194),
204 (Arcv2, 195),
205 (Open8, 196),
206 (Rl78, 197),
207 (Videocore5, 198),
208 (R78kor, 199),
209 (F56800ex, 200),
210 (Ba1, 201),
211 (Ba2, 202),
212 (Xcore, 203),
213 (MchpPic, 204),
214 (Intelgt, 205),
215 (Km32, 210),
216 (Kmx32, 211),
217 (Emx16, 212),
218 (Emx8, 213),
219 (Kvarc, 214),
220 (Cdp, 215),
221 (Coge, 216),
222 (Cool, 217),
223 (Norc, 218),
224 (CsrKalimba, 219),
225 (Z80, 220),
226 (Visium, 221),
227 (Ft32, 222),
228 (Moxie, 223),
229 (Amdgpu, 224, "AMD GPU."),
230 (Riscv, 243, "RISC-V."),
231 (Bpf, 247, "Linux BPF."),
232 (Csky, 252),
233 (Loongarch, 258),
234}
235
236impl Machine {
237 pub const fn as_u16(self) -> u16 {
239 self.as_number()
240 }
241}
242
243define_infallible_enum! {
244 "Segment type.",
245 SegmentKind, u32,
246 (Null, 0, "Inactive/removed segment."),
247 (Loadable, 1, "A segment that is mapped from the file into memory segment on program execution."),
248 (Dynamic, 2, "A segment that contains dynamic linking information."),
249 (Interpreter, 3, "A segment that contains NUL-terminated interpreter path."),
250 (Note, 4, "A segment that contains notes."),
251 (Shlib, 5, "Reserved."),
252 (ProgramHeader, 6, "A segment that contains program header itself."),
253 (Tls, 7, "A segment that contains thread-local storage."),
254}
255
256impl SegmentKind {
257 pub const fn as_u32(self) -> u32 {
259 self.as_number()
260 }
261}
262
263define_infallible_enum! {
264 "Dynamic table tag.",
265 DynamicTag, u32,
266 (Null, 0, "End of the table."),
267 (Needed, 1, "String table offset to the name of the needed library."),
268 (PltRelSize, 2),
269 (PltGot, 3),
270 (Hash, 4, "The address of the symbol hash table."),
271 (StringTableAddress, 5, "The address of the string table."),
272 (SymbolTableAddress, 6, "The address of the symbol table."),
273 (RelaTableAddress, 7, "The address of the relocation with addends table."),
274 (RelaTableSize, 8, "The size in bytes of the relocation with addends table."),
275 (RelaEntrySize, 9, "Relocation with addends entry size."),
276 (StringTableSize, 10, "The size in bytes of the string table."),
277 (SymbolEntrySize, 11, "Symbol table entry size."),
278 (InitAddress, 12),
279 (FiniAddress, 13),
280 (SharedObjectName, 14, "String table offset to the name of the shared object."),
281 (Rpath, 15, "String table offset to the library search path."),
282 (Symbolic, 16),
283 (RelTableAddress, 17, "The address of relocation table."),
284 (RelTableSize, 18, "The size in bytes of the relocation table."),
285 (RelEntrySize, 19, "Relocation entry size."),
286 (PltRel, 20),
287 (Debug, 21),
288 (TextRel, 22),
289 (JmpRel, 23),
290 (BindNow, 24),
291 (InitArray, 25),
292 (FiniArray, 26),
293 (InitArraySize, 27),
294 (FiniArraySize, 28),
295 (Runpath, 29, "String table offset to the library search path."),
296 (Flags, 30),
297 (PreInitArray, 32),
298 (PreInitArraySize, 33),
299 (SymbolTableIndex, 34),
300 (RelrTableSize, 35, "The size in bytes of the relative relocation table."),
301 (RelrTableAddress, 36, "The address of relative relocation table."),
302 (RelrEntrySize, 37, "Relative relocation entry size."),
303}
304
305impl DynamicTag {
306 pub const fn as_u32(self) -> u32 {
308 self.as_number()
309 }
310}
311
312impl TryFrom<u64> for DynamicTag {
313 type Error = Error;
314 fn try_from(other: u64) -> Result<Self, Self::Error> {
315 let number: u32 = other.try_into().map_err(|_| Error::TooBig("dynamic-tag"))?;
316 Ok(number.into())
317 }
318}
319
320define_infallible_enum! {
321 "Section type.",
322 SectionKind, u32,
323 (Null, 0, "Inactive/removed section."),
324 (ProgramBits, 1, "Program-related data."),
325 (SymbolTable, 2, "Symbol table."),
326 (StringTable, 3, "String table."),
327 (RelaTable, 4, "Relocation entries with addends."),
328 (Hash, 5, "Symbol hash table."),
329 (Dynamic, 6, "Dynamic linking information."),
330 (Note, 7, "Notes."),
331 (NoBits, 8, "Same as `ProgramBits` but occupies no space in the file."),
332 (RelTable, 9, "Relocation entries without addends."),
333 (Shlib, 10, "Reserved."),
334 (DynamicSymbolTable, 11, "Dynamic linker symbol table."),
335 (InitArray, 14, "Constructors."),
336 (FiniArray, 15, "Destructors."),
337 (PreInitArray, 16, "Pre-constructors."),
338 (Group, 17, "Section group."),
339 (SymbolTableIndex, 18, "Extended section indices."),
340 (RelrTable, 19, "Relative relocation entries."),
341}
342
343impl SectionKind {
344 pub const fn as_u32(self) -> u32 {
346 self.as_number()
347 }
348}
349
350#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
352#[cfg_attr(test, derive(arbitrary::Arbitrary))]
353#[repr(u8)]
354pub enum SymbolVisibility {
355 Default = 0,
357 Internal = 1,
359 Hidden = 2,
361 Protected = 3,
364}
365
366impl SymbolVisibility {
367 pub const fn from_other(other: u8) -> Self {
369 match other & 3 {
370 0 => Self::Default,
371 1 => Self::Internal,
372 2 => Self::Hidden,
373 3 => Self::Protected,
374 _ => unreachable!(),
375 }
376 }
377}
378
379define_enum_v2! {
380 "Symbol binding.",
381 SymbolBinding, u8,
382 (Local, 0, "Local symbol."),
383 (Global, 1, "Global symbol."),
384 (Weak, 2, "Weak symbol."),
385}
386
387impl SymbolBinding {
388 pub const fn as_u8(self) -> u8 {
390 self.as_number()
391 }
392
393 pub fn from_info(info: u8) -> Self {
395 Self::from(info >> 4)
396 }
397
398 pub const fn to_info_bits(self) -> u8 {
400 self.as_u8() << 4
401 }
402}
403
404define_enum_v2! {
405 "Symbol type.",
406 SymbolKind, u8,
407 (None, 0, "Unspecified."),
408 (Object, 1, "Data object."),
409 (Function, 2, "Code object."),
410 (Section, 3, "Associated with a section."),
411 (File, 4, "File name."),
412 (Common, 5, "Common data object."),
413 (Tls, 6, "Thread-local data object."),
414}
415
416impl SymbolKind {
417 pub const fn as_u8(self) -> u8 {
419 self.as_number()
420 }
421
422 pub fn from_info(info: u8) -> Self {
424 Self::from(info & 0xf)
425 }
426
427 pub const fn to_info_bits(self) -> u8 {
429 self.as_u8() & 0xf
430 }
431}