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