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}