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