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