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