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}