1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Target description: the format, architecture and ABI being linked for.
use std::fmt;
/// Container format of the output.
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum BinaryFormat {
/// ELF (Linux, BSD, bare metal, …).
Elf,
/// PE/COFF (Windows).
Pe,
/// Mach-O (macOS, iOS, …).
MachO,
/// A flat image with no container, produced by `--oformat binary`.
Binary,
/// AmigaOS Hunk (`--oformat amigahunk`), the load file and object
/// format of AmigaDOS.
Hunk,
}
/// Processor architecture.
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Architecture {
/// x86-64 (AMD64).
X86_64,
/// x86-64 with 32-bit pointers (x32).
X86_64X32,
/// 32-bit x86.
X86,
/// 64-bit Arm.
Aarch64,
/// 32-bit Arm.
Arm,
/// 64-bit RISC-V.
Riscv64,
/// 32-bit RISC-V.
Riscv32,
/// 64-bit PowerPC.
PowerPc64,
/// 64-bit LoongArch.
LoongArch64,
/// IBM z/Architecture.
S390x,
/// Motorola 68000 series.
M68k,
}
/// Byte order.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Endianness {
/// Least significant byte first.
Little,
/// Most significant byte first.
Big,
}
/// Native pointer size.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum PointerWidth {
/// 32-bit pointers.
Bits32,
/// 64-bit pointers.
Bits64,
}
/// Operating system and ABI the output runs on.
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum OperatingSystem {
/// Linux, any libc.
Linux,
/// Apple platforms.
Darwin,
/// Windows (MinGW or MSVC environment).
Windows,
/// No operating system: firmware, kernels, bare metal.
None,
}
/// A complete target description.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Target {
/// Output container format.
pub format: BinaryFormat,
/// Processor architecture.
pub arch: Architecture,
/// Byte order.
pub endian: Endianness,
/// Pointer size.
pub pointer_width: PointerWidth,
/// Operating system.
pub os: OperatingSystem,
}
impl Target {
/// x86-64 Linux ELF.
pub const X86_64_LINUX: Self = Self {
format: BinaryFormat::Elf,
arch: Architecture::X86_64,
endian: Endianness::Little,
pointer_width: PointerWidth::Bits64,
os: OperatingSystem::Linux,
};
/// AArch64 Linux ELF.
pub const AARCH64_LINUX: Self = Self {
format: BinaryFormat::Elf,
arch: Architecture::Aarch64,
endian: Endianness::Little,
pointer_width: PointerWidth::Bits64,
os: OperatingSystem::Linux,
};
/// Whether addresses are 64 bits wide.
#[must_use]
pub fn is_64bit(self) -> bool {
matches!(self.pointer_width, PointerWidth::Bits64)
}
}
impl fmt::Display for Target {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}-{:?}-{:?}", self.arch, self.os, self.format)
}
}