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