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