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