/src/wasmtime/cranelift/codegen/src/binemit/mod.rs
Line | Count | Source |
1 | | //! Binary machine code emission. |
2 | | //! |
3 | | //! The `binemit` module contains code for translating Cranelift's intermediate representation into |
4 | | //! binary machine code. |
5 | | |
6 | | use core::fmt; |
7 | | #[cfg(feature = "enable-serde")] |
8 | | use serde_derive::{Deserialize, Serialize}; |
9 | | |
10 | | /// Offset in bytes from the beginning of the function. |
11 | | /// |
12 | | /// Cranelift can be used as a cross compiler, so we don't want to use a type like `usize` which |
13 | | /// depends on the *host* platform, not the *target* platform. |
14 | | pub type CodeOffset = u32; |
15 | | |
16 | | /// Addend to add to the symbol value. |
17 | | pub type Addend = i64; |
18 | | |
19 | | /// Relocation kinds for every ISA |
20 | | #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
21 | | #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] |
22 | | pub enum Reloc { |
23 | | /// absolute 4-byte |
24 | | Abs4, |
25 | | /// absolute 8-byte |
26 | | Abs8, |
27 | | /// x86 PC-relative 4-byte |
28 | | X86PCRel4, |
29 | | /// x86 call to PC-relative 4-byte. |
30 | | /// |
31 | | /// This relocation is only ever applied to the displacement of a `call` |
32 | | /// or `jmp` instruction, never to address materialization (e.g. `lea`, |
33 | | /// which uses [`Reloc::X86PCRel4`] instead). Consumers may therefore |
34 | | /// redirect the control transfer through a veneer when the target is out |
35 | | /// of range of the 32-bit displacement. |
36 | | X86CallPCRel4, |
37 | | /// x86 call to PLT-relative 4-byte |
38 | | X86CallPLTRel4, |
39 | | /// x86 GOT PC-relative 4-byte |
40 | | X86GOTPCRel4, |
41 | | /// The 32-bit offset of the target from the beginning of its section. |
42 | | /// Equivalent to `IMAGE_REL_AMD64_SECREL`. |
43 | | /// See: [PE Format](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format) |
44 | | X86SecRel, |
45 | | /// Arm32 call target |
46 | | Arm32Call, |
47 | | /// Arm64 call target. Encoded as bottom 26 bits of instruction. This |
48 | | /// value is sign-extended, multiplied by 4, and added to the PC of |
49 | | /// the call instruction to form the destination address. |
50 | | Arm64Call, |
51 | | /// s390x PC-relative 4-byte offset |
52 | | S390xPCRel32Dbl, |
53 | | /// s390x PC-relative 4-byte offset to PLT |
54 | | S390xPLTRel32Dbl, |
55 | | |
56 | | /// Elf x86_64 32 bit signed PC relative offset to two GOT entries for GD symbol. |
57 | | ElfX86_64TlsGd, |
58 | | |
59 | | /// Mach-O x86_64 32 bit signed PC relative offset to a `__thread_vars` entry. |
60 | | MachOX86_64Tlv, |
61 | | |
62 | | /// Mach-O Aarch64 TLS |
63 | | /// PC-relative distance to the page of the TLVP slot. |
64 | | MachOAarch64TlsAdrPage21, |
65 | | |
66 | | /// Mach-O Aarch64 TLS |
67 | | /// Offset within page of TLVP slot. |
68 | | MachOAarch64TlsAdrPageOff12, |
69 | | |
70 | | /// Aarch64 TLSDESC Adr Page21 |
71 | | /// This is equivalent to `R_AARCH64_TLSDESC_ADR_PAGE21` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#57105thread-local-storage-descriptors) |
72 | | Aarch64TlsDescAdrPage21, |
73 | | |
74 | | /// Aarch64 TLSDESC Ld64 Lo12 |
75 | | /// This is equivalent to `R_AARCH64_TLSDESC_LD64_LO12` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#57105thread-local-storage-descriptors) |
76 | | Aarch64TlsDescLd64Lo12, |
77 | | |
78 | | /// Aarch64 TLSDESC Add Lo12 |
79 | | /// This is equivalent to `R_AARCH64_TLSGD_ADD_LO12` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#57105thread-local-storage-descriptors) |
80 | | Aarch64TlsDescAddLo12, |
81 | | |
82 | | /// Aarch64 TLSDESC Call |
83 | | /// This is equivalent to `R_AARCH64_TLSDESC_CALL` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#57105thread-local-storage-descriptors) |
84 | | Aarch64TlsDescCall, |
85 | | |
86 | | /// AArch64 GOT Page |
87 | | /// Set the immediate value of an ADRP to bits 32:12 of X; check that –2^32 <= X < 2^32 |
88 | | /// This is equivalent to `R_AARCH64_ADR_GOT_PAGE` (311) in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#static-aarch64-relocations) |
89 | | Aarch64AdrGotPage21, |
90 | | |
91 | | /// Equivalent of `R_AARCH64_ADR_PREL_PG_HI21`. |
92 | | Aarch64AdrPrelPgHi21, |
93 | | /// Equivalent of `R_AARCH64_ADD_ABS_LO12_NC`. |
94 | | Aarch64AddAbsLo12Nc, |
95 | | |
96 | | /// AArch64 GOT Low bits |
97 | | |
98 | | /// Set the LD/ST immediate field to bits 11:3 of X. No overflow check; check that X&7 = 0 |
99 | | /// This is equivalent to `R_AARCH64_LD64_GOT_LO12_NC` (312) in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#static-aarch64-relocations) |
100 | | Aarch64Ld64GotLo12Nc, |
101 | | |
102 | | /// RISC-V Call PLT: 32-bit PC-relative function call, macros call, tail (PIC) |
103 | | /// |
104 | | /// Despite having PLT in the name, this relocation is also used for normal calls. |
105 | | /// The non-PLT version of this relocation has been deprecated. |
106 | | /// |
107 | | /// This is the `R_RISCV_CALL_PLT` relocation from the RISC-V ELF psABI document. |
108 | | /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#procedure-calls> |
109 | | RiscvCallPlt, |
110 | | |
111 | | /// RISC-V TLS GD: High 20 bits of 32-bit PC-relative TLS GD GOT reference, |
112 | | /// |
113 | | /// This is the `R_RISCV_TLS_GD_HI20` relocation from the RISC-V ELF psABI document. |
114 | | /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#global-dynamic> |
115 | | RiscvTlsGdHi20, |
116 | | |
117 | | /// Low 12 bits of a 32-bit PC-relative relocation (I-Type instruction) |
118 | | /// |
119 | | /// This is the `R_RISCV_PCREL_LO12_I` relocation from the RISC-V ELF psABI document. |
120 | | /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses> |
121 | | RiscvPCRelLo12I, |
122 | | |
123 | | /// High 20 bits of a 32-bit PC-relative GOT offset relocation |
124 | | /// |
125 | | /// This is the `R_RISCV_GOT_HI20` relocation from the RISC-V ELF psABI document. |
126 | | /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses> |
127 | | RiscvGotHi20, |
128 | | |
129 | | /// High 20 bits of a 32-bit PC-relative offset relocation |
130 | | /// |
131 | | /// This is the `R_RISCV_PCREL_HI20` relocation from the RISC-V ELF psABI document. |
132 | | /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses> |
133 | | RiscvPCRelHi20, |
134 | | |
135 | | /// s390x TLS GD64 - 64-bit offset of tls_index for GD symbol in GOT |
136 | | S390xTlsGd64, |
137 | | /// s390x TLS GDCall - marker to enable optimization of TLS calls |
138 | | S390xTlsGdCall, |
139 | | |
140 | | /// Pulley - a relocation which is a pc-relative offset. |
141 | | PulleyPcRel, |
142 | | |
143 | | /// Pulley - call a host function indirectly where the embedder resolving |
144 | | /// this relocation needs to fill the 8-bit immediate that's part of the |
145 | | /// `call_indirect_host` opcode (an opaque identifier used by the host). |
146 | | PulleyCallIndirectHost, |
147 | | } |
148 | | |
149 | | impl fmt::Display for Reloc { |
150 | | /// Display trait implementation drops the arch, since its used in contexts where the arch is |
151 | | /// already unambiguous, e.g. clif syntax with isa specified. In other contexts, use Debug. |
152 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
153 | 0 | match *self { |
154 | 0 | Self::Abs4 => write!(f, "Abs4"), |
155 | 0 | Self::Abs8 => write!(f, "Abs8"), |
156 | 0 | Self::S390xPCRel32Dbl => write!(f, "PCRel32Dbl"), |
157 | 0 | Self::S390xPLTRel32Dbl => write!(f, "PLTRel32Dbl"), |
158 | 0 | Self::X86PCRel4 => write!(f, "PCRel4"), |
159 | 0 | Self::X86CallPCRel4 => write!(f, "CallPCRel4"), |
160 | 0 | Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"), |
161 | 0 | Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"), |
162 | 0 | Self::X86SecRel => write!(f, "SecRel"), |
163 | 0 | Self::Arm32Call | Self::Arm64Call => write!(f, "Call"), |
164 | 0 | Self::RiscvCallPlt => write!(f, "RiscvCallPlt"), |
165 | 0 | Self::RiscvTlsGdHi20 => write!(f, "RiscvTlsGdHi20"), |
166 | 0 | Self::RiscvGotHi20 => write!(f, "RiscvGotHi20"), |
167 | 0 | Self::RiscvPCRelHi20 => write!(f, "RiscvPCRelHi20"), |
168 | 0 | Self::RiscvPCRelLo12I => write!(f, "RiscvPCRelLo12I"), |
169 | 0 | Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"), |
170 | 0 | Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"), |
171 | 0 | Self::MachOAarch64TlsAdrPage21 => write!(f, "MachOAarch64TlsAdrPage21"), |
172 | 0 | Self::MachOAarch64TlsAdrPageOff12 => write!(f, "MachOAarch64TlsAdrPageOff12"), |
173 | 0 | Self::Aarch64TlsDescAdrPage21 => write!(f, "Aarch64TlsDescAdrPage21"), |
174 | 0 | Self::Aarch64TlsDescLd64Lo12 => write!(f, "Aarch64TlsDescLd64Lo12"), |
175 | 0 | Self::Aarch64TlsDescAddLo12 => write!(f, "Aarch64TlsDescAddLo12"), |
176 | 0 | Self::Aarch64TlsDescCall => write!(f, "Aarch64TlsDescCall"), |
177 | 0 | Self::Aarch64AdrGotPage21 => write!(f, "Aarch64AdrGotPage21"), |
178 | 0 | Self::Aarch64Ld64GotLo12Nc => write!(f, "Aarch64AdrGotLo12Nc"), |
179 | 0 | Self::Aarch64AdrPrelPgHi21 => write!(f, "Aarch64AdrPrelPgHi21"), |
180 | 0 | Self::Aarch64AddAbsLo12Nc => write!(f, "Aarch64AddAbsLo12Nc"), |
181 | 0 | Self::S390xTlsGd64 => write!(f, "TlsGd64"), |
182 | 0 | Self::S390xTlsGdCall => write!(f, "TlsGdCall"), |
183 | 0 | Self::PulleyPcRel => write!(f, "PulleyPcRel"), |
184 | 0 | Self::PulleyCallIndirectHost => write!(f, "PulleyCallIndirectHost"), |
185 | | } |
186 | 0 | } |
187 | | } |
188 | | |
189 | | /// Container for information about a vector of compiled code and its supporting read-only data. |
190 | | /// |
191 | | /// The code starts at offset 0 and is followed optionally by relocatable jump tables and copyable |
192 | | /// (raw binary) read-only data. Any padding between sections is always part of the section that |
193 | | /// precedes the boundary between the sections. |
194 | | #[derive(Debug, PartialEq)] |
195 | | pub struct CodeInfo { |
196 | | /// Number of bytes in total. |
197 | | pub total_size: CodeOffset, |
198 | | } |