1/// A CPU architecture.
2#[allow(missing_docs)]
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4#[non_exhaustive]
5pub enum Architecture {
6 Unknown,
7 Aarch64,
8 #[allow(non_camel_case_types)]
9 Aarch64_Ilp32,
10 Arm,
11 Avr,
12 Bpf,
13 Csky,
14 I386,
15 X86_64,
16 #[allow(non_camel_case_types)]
17 X86_64_X32,
18 Hexagon,
19 LoongArch64,
20 Mips,
21 Mips64,
22 Msp430,
23 PowerPc,
24 PowerPc64,
25 Riscv32,
26 Riscv64,
27 S390x,
28 Sbf,
29 Sharc,
30 Sparc64,
31 Wasm32,
32 Wasm64,
33 Xtensa,
34}
35
36/// A CPU sub-architecture.
37#[allow(missing_docs)]
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
39#[non_exhaustive]
40pub enum SubArchitecture {
41 Arm64E,
42 Arm64EC,
43}
44
45impl Architecture {
46 /// The size of an address value for this architecture.
47 ///
48 /// Returns `None` for unknown architectures.
49 pub fn address_size(self) -> Option<AddressSize> {
50 match self {
51 Architecture::Unknown => None,
52 Architecture::Aarch64 => Some(AddressSize::U64),
53 Architecture::Aarch64_Ilp32 => Some(AddressSize::U32),
54 Architecture::Arm => Some(AddressSize::U32),
55 Architecture::Avr => Some(AddressSize::U8),
56 Architecture::Bpf => Some(AddressSize::U64),
57 Architecture::Csky => Some(AddressSize::U32),
58 Architecture::I386 => Some(AddressSize::U32),
59 Architecture::X86_64 => Some(AddressSize::U64),
60 Architecture::X86_64_X32 => Some(AddressSize::U32),
61 Architecture::Hexagon => Some(AddressSize::U32),
62 Architecture::LoongArch64 => Some(AddressSize::U64),
63 Architecture::Mips => Some(AddressSize::U32),
64 Architecture::Mips64 => Some(AddressSize::U64),
65 Architecture::Msp430 => Some(AddressSize::U16),
66 Architecture::PowerPc => Some(AddressSize::U32),
67 Architecture::PowerPc64 => Some(AddressSize::U64),
68 Architecture::Riscv32 => Some(AddressSize::U32),
69 Architecture::Riscv64 => Some(AddressSize::U64),
70 Architecture::S390x => Some(AddressSize::U64),
71 Architecture::Sbf => Some(AddressSize::U64),
72 Architecture::Sharc => Some(AddressSize::U32),
73 Architecture::Sparc64 => Some(AddressSize::U64),
74 Architecture::Wasm32 => Some(AddressSize::U32),
75 Architecture::Wasm64 => Some(AddressSize::U64),
76 Architecture::Xtensa => Some(AddressSize::U32),
77 }
78 }
79}
80
81/// The size of an address value for an architecture.
82///
83/// This may differ from the address size supported by the file format (such as for COFF).
84#[allow(missing_docs)]
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
86#[non_exhaustive]
87#[repr(u8)]
88pub enum AddressSize {
89 U8 = 1,
90 U16 = 2,
91 U32 = 4,
92 U64 = 8,
93}
94
95impl AddressSize {
96 /// The size in bytes of an address value.
97 #[inline]
98 pub fn bytes(self) -> u8 {
99 self as u8
100 }
101}
102
103/// A binary file format.
104#[allow(missing_docs)]
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
106#[non_exhaustive]
107pub enum BinaryFormat {
108 Coff,
109 Elf,
110 MachO,
111 Pe,
112 Wasm,
113 Xcoff,
114}
115
116/// The kind of a section.
117#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
118#[non_exhaustive]
119pub enum SectionKind {
120 /// The section kind is unknown.
121 Unknown,
122 /// An executable code section.
123 ///
124 /// Example ELF sections: `.text`
125 ///
126 /// Example Mach-O sections: `__TEXT/__text`
127 Text,
128 /// A data section.
129 ///
130 /// Example ELF sections: `.data`
131 ///
132 /// Example Mach-O sections: `__DATA/__data`
133 Data,
134 /// A read only data section.
135 ///
136 /// Example ELF sections: `.rodata`
137 ///
138 /// Example Mach-O sections: `__TEXT/__const`, `__DATA/__const`, `__TEXT/__literal4`
139 ReadOnlyData,
140 /// A read only data section with relocations.
141 ///
142 /// This is the same as either `Data` or `ReadOnlyData`, depending on the file format.
143 /// This value is only used in the API for writing files. It is never returned when reading files.
144 ReadOnlyDataWithRel,
145 /// A loadable string section.
146 ///
147 /// Example ELF sections: `.rodata.str`
148 ///
149 /// Example Mach-O sections: `__TEXT/__cstring`
150 ReadOnlyString,
151 /// An uninitialized data section.
152 ///
153 /// Example ELF sections: `.bss`
154 ///
155 /// Example Mach-O sections: `__DATA/__bss`
156 UninitializedData,
157 /// An uninitialized common data section.
158 ///
159 /// Example Mach-O sections: `__DATA/__common`
160 Common,
161 /// A TLS data section.
162 ///
163 /// Example ELF sections: `.tdata`
164 ///
165 /// Example Mach-O sections: `__DATA/__thread_data`
166 Tls,
167 /// An uninitialized TLS data section.
168 ///
169 /// Example ELF sections: `.tbss`
170 ///
171 /// Example Mach-O sections: `__DATA/__thread_bss`
172 UninitializedTls,
173 /// A TLS variables section.
174 ///
175 /// This contains TLS variable structures, rather than the variable initializers.
176 ///
177 /// Example Mach-O sections: `__DATA/__thread_vars`
178 TlsVariables,
179 /// A non-loadable string section.
180 ///
181 /// Example ELF sections: `.comment`, `.debug_str`
182 OtherString,
183 /// Some other non-loadable section.
184 ///
185 /// Example ELF sections: `.debug_info`
186 Other,
187 /// Debug information.
188 ///
189 /// Example Mach-O sections: `__DWARF/__debug_info`
190 Debug,
191 /// Information for the linker.
192 ///
193 /// Example COFF sections: `.drectve`
194 Linker,
195 /// ELF note section.
196 Note,
197 /// Metadata such as symbols or relocations.
198 ///
199 /// Example ELF sections: `.symtab`, `.strtab`, `.group`
200 Metadata,
201 /// Some other ELF section type.
202 ///
203 /// This is the `sh_type` field in the section header.
204 /// The meaning may be dependent on the architecture.
205 Elf(u32),
206}
207
208impl SectionKind {
209 /// Return true if this section contains zerofill data.
210 pub fn is_bss(self) -> bool {
211 self == SectionKind::UninitializedData
212 || self == SectionKind::UninitializedTls
213 || self == SectionKind::Common
214 }
215}
216
217/// The selection kind for a COMDAT section group.
218///
219/// This determines the way in which the linker resolves multiple definitions of the COMDAT
220/// sections.
221#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
222#[non_exhaustive]
223pub enum ComdatKind {
224 /// The selection kind is unknown.
225 Unknown,
226 /// Multiple definitions are allowed.
227 ///
228 /// An arbitrary definition is selected, and the rest are removed.
229 ///
230 /// This is the only supported selection kind for ELF.
231 Any,
232 /// Multiple definitions are not allowed.
233 ///
234 /// This is used to group sections without allowing duplicates.
235 NoDuplicates,
236 /// Multiple definitions must have the same size.
237 ///
238 /// An arbitrary definition is selected, and the rest are removed.
239 SameSize,
240 /// Multiple definitions must match exactly.
241 ///
242 /// An arbitrary definition is selected, and the rest are removed.
243 ExactMatch,
244 /// Multiple definitions are allowed, and the largest is selected.
245 ///
246 /// An arbitrary definition with the largest size is selected, and the rest are removed.
247 Largest,
248 /// Multiple definitions are allowed, and the newest is selected.
249 Newest,
250}
251
252/// The kind of a symbol.
253#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
254#[non_exhaustive]
255pub enum SymbolKind {
256 /// The symbol kind is unknown.
257 Unknown,
258 /// The symbol is a null placeholder.
259 Null,
260 /// The symbol is for executable code.
261 Text,
262 /// The symbol is for a data object.
263 Data,
264 /// The symbol is for a section.
265 Section,
266 /// The symbol is the name of a file. It precedes symbols within that file.
267 File,
268 /// The symbol is for a code label.
269 Label,
270 /// The symbol is for a thread local storage entity.
271 Tls,
272}
273
274/// A symbol scope.
275#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
276pub enum SymbolScope {
277 /// Unknown scope.
278 Unknown,
279 /// Symbol is visible to the compilation unit.
280 Compilation,
281 /// Symbol is visible to the static linkage unit.
282 Linkage,
283 /// Symbol is visible to dynamically linked objects.
284 Dynamic,
285}
286
287/// The operation used to calculate the result of the relocation.
288///
289/// The relocation descriptions use the following definitions. Note that
290/// these definitions probably don't match any ELF ABI.
291///
292/// * A - The value of the addend.
293/// * G - The address of the symbol's entry within the global offset table.
294/// * L - The address of the symbol's entry within the procedure linkage table.
295/// * P - The address of the place of the relocation.
296/// * S - The address of the symbol.
297/// * GotBase - The address of the global offset table.
298/// * Image - The base address of the image.
299/// * Section - The address of the section containing the symbol.
300///
301/// 'XxxRelative' means 'Xxx + A - P'. 'XxxOffset' means 'S + A - Xxx'.
302#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
303#[non_exhaustive]
304pub enum RelocationKind {
305 /// S + A
306 Absolute,
307 /// S + A - P
308 Relative,
309 /// G + A - GotBase
310 Got,
311 /// G + A - P
312 GotRelative,
313 /// GotBase + A - P
314 GotBaseRelative,
315 /// S + A - GotBase
316 GotBaseOffset,
317 /// L + A - P
318 PltRelative,
319 /// S + A - Image
320 ImageOffset,
321 /// S + A - Section
322 SectionOffset,
323 /// The index of the section containing the symbol.
324 SectionIndex,
325 /// Some other ELF relocation. The value is dependent on the architecture.
326 Elf(u32),
327 /// Some other Mach-O relocation. The value is dependent on the architecture.
328 MachO {
329 /// The relocation type.
330 value: u8,
331 /// Whether the relocation is relative to the place.
332 relative: bool,
333 },
334 /// Some other COFF relocation. The value is dependent on the architecture.
335 Coff(u16),
336 /// Some other XCOFF relocation.
337 Xcoff(u8),
338}
339
340/// Information about how the result of the relocation operation is encoded in the place.
341///
342/// This is usually architecture specific, such as specifying an addressing mode or
343/// a specific instruction.
344#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
345#[non_exhaustive]
346pub enum RelocationEncoding {
347 /// Generic encoding.
348 Generic,
349
350 /// x86 sign extension at runtime.
351 ///
352 /// Used with `RelocationKind::Absolute`.
353 X86Signed,
354 /// x86 rip-relative addressing.
355 ///
356 /// The `RelocationKind` must be PC relative.
357 X86RipRelative,
358 /// x86 rip-relative addressing in movq instruction.
359 ///
360 /// The `RelocationKind` must be PC relative.
361 X86RipRelativeMovq,
362 /// x86 branch instruction.
363 ///
364 /// The `RelocationKind` must be PC relative.
365 X86Branch,
366
367 /// s390x PC-relative offset shifted right by one bit.
368 ///
369 /// The `RelocationKind` must be PC relative.
370 S390xDbl,
371
372 /// AArch64 call target.
373 ///
374 /// The `RelocationKind` must be PC relative.
375 AArch64Call,
376
377 /// LoongArch branch offset with two trailing zeros.
378 ///
379 /// The `RelocationKind` must be PC relative.
380 LoongArchBranch,
381
382 /// SHARC+ 48-bit Type A instruction
383 ///
384 /// Represents these possible variants, each with a corresponding
385 /// `R_SHARC_*` constant:
386 ///
387 /// * 24-bit absolute address
388 /// * 32-bit absolute address
389 /// * 6-bit relative address
390 /// * 24-bit relative address
391 /// * 6-bit absolute address in the immediate value field
392 /// * 16-bit absolute address in the immediate value field
393 SharcTypeA,
394
395 /// SHARC+ 32-bit Type B instruction
396 ///
397 /// Represents these possible variants, each with a corresponding
398 /// `R_SHARC_*` constant:
399 ///
400 /// * 6-bit absolute address in the immediate value field
401 /// * 7-bit absolute address in the immediate value field
402 /// * 16-bit absolute address
403 /// * 6-bit relative address
404 SharcTypeB,
405}
406
407/// File flags that are specific to each file format.
408#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
409#[non_exhaustive]
410pub enum FileFlags {
411 /// No file flags.
412 None,
413 /// ELF file flags.
414 Elf {
415 /// `os_abi` field in the ELF file header.
416 os_abi: u8,
417 /// `abi_version` field in the ELF file header.
418 abi_version: u8,
419 /// `e_flags` field in the ELF file header.
420 e_flags: u32,
421 },
422 /// Mach-O file flags.
423 MachO {
424 /// `flags` field in the Mach-O file header.
425 flags: u32,
426 },
427 /// COFF file flags.
428 Coff {
429 /// `Characteristics` field in the COFF file header.
430 characteristics: u16,
431 },
432 /// XCOFF file flags.
433 Xcoff {
434 /// `f_flags` field in the XCOFF file header.
435 f_flags: u16,
436 },
437}
438
439/// Segment flags that are specific to each file format.
440#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
441#[non_exhaustive]
442pub enum SegmentFlags {
443 /// No segment flags.
444 None,
445 /// ELF segment flags.
446 Elf {
447 /// `p_flags` field in the segment header.
448 p_flags: u32,
449 },
450 /// Mach-O segment flags.
451 MachO {
452 /// `flags` field in the segment header.
453 flags: u32,
454 /// `maxprot` field in the segment header.
455 maxprot: u32,
456 /// `initprot` field in the segment header.
457 initprot: u32,
458 },
459 /// COFF segment flags.
460 Coff {
461 /// `Characteristics` field in the segment header.
462 characteristics: u32,
463 },
464}
465
466/// Section flags that are specific to each file format.
467#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
468#[non_exhaustive]
469pub enum SectionFlags {
470 /// No section flags.
471 None,
472 /// ELF section flags.
473 Elf {
474 /// `sh_flags` field in the section header.
475 sh_flags: u64,
476 },
477 /// Mach-O section flags.
478 MachO {
479 /// `flags` field in the section header.
480 flags: u32,
481 },
482 /// COFF section flags.
483 Coff {
484 /// `Characteristics` field in the section header.
485 characteristics: u32,
486 },
487 /// XCOFF section flags.
488 Xcoff {
489 /// `s_flags` field in the section header.
490 s_flags: u32,
491 },
492}
493
494/// Symbol flags that are specific to each file format.
495#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
496#[non_exhaustive]
497pub enum SymbolFlags<Section, Symbol> {
498 /// No symbol flags.
499 None,
500 /// ELF symbol flags.
501 Elf {
502 /// `st_info` field in the ELF symbol.
503 st_info: u8,
504 /// `st_other` field in the ELF symbol.
505 st_other: u8,
506 },
507 /// Mach-O symbol flags.
508 MachO {
509 /// `n_desc` field in the Mach-O symbol.
510 n_desc: u16,
511 },
512 /// COFF flags for a section symbol.
513 CoffSection {
514 /// `Selection` field in the auxiliary symbol for the section.
515 selection: u8,
516 /// `Number` field in the auxiliary symbol for the section.
517 associative_section: Option<Section>,
518 },
519 /// XCOFF symbol flags.
520 Xcoff {
521 /// `n_sclass` field in the XCOFF symbol.
522 n_sclass: u8,
523 /// `x_smtyp` field in the CSECT auxiliary symbol.
524 ///
525 /// Only valid if `n_sclass` is `C_EXT`, `C_WEAKEXT`, or `C_HIDEXT`.
526 x_smtyp: u8,
527 /// `x_smclas` field in the CSECT auxiliary symbol.
528 ///
529 /// Only valid if `n_sclass` is `C_EXT`, `C_WEAKEXT`, or `C_HIDEXT`.
530 x_smclas: u8,
531 /// The containing csect for the symbol.
532 ///
533 /// Only valid if `x_smtyp` is `XTY_LD`.
534 containing_csect: Option<Symbol>,
535 },
536}
537