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::{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 TLS GD
68    /// Set an ADRP immediate field to the top 21 bits of the final address. Checks for overflow.
69    /// This is equivalent to `R_AARCH64_TLSGD_ADR_PAGE21` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#relocations-for-thread-local-storage)
70    Aarch64TlsGdAdrPage21,
71
72    /// Aarch64 TLS GD
73    /// Set the add immediate field to the low 12 bits of the final address. Does not check for overflow.
74    /// This is equivalent to `R_AARCH64_TLSGD_ADD_LO12_NC` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#relocations-for-thread-local-storage)
75    Aarch64TlsGdAddLo12Nc,
76
77    /// AArch64 GOT Page
78    /// Set the immediate value of an ADRP to bits 32:12 of X; check that –232 <= X < 232
79    /// 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)
80    Aarch64AdrGotPage21,
81
82    /// AArch64 GOT Low bits
83
84    /// Set the LD/ST immediate field to bits 11:3 of X. No overflow check; check that X&7 = 0
85    /// 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)
86    Aarch64Ld64GotLo12Nc,
87
88    /// procedure call.
89    /// call symbol
90    /// expands to the following assembly and relocation:
91    /// auipc ra, 0
92    /// jalr ra, ra, 0
93    RiscvCall,
94
95    /// s390x TLS GD64 - 64-bit offset of tls_index for GD symbol in GOT
96    S390xTlsGd64,
97    /// s390x TLS GDCall - marker to enable optimization of TLS calls
98    S390xTlsGdCall,
99}
100
101impl fmt::Display for Reloc {
102    /// Display trait implementation drops the arch, since its used in contexts where the arch is
103    /// already unambiguous, e.g. clif syntax with isa specified. In other contexts, use Debug.
104    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105        match *self {
106            Self::Abs4 => write!(f, "Abs4"),
107            Self::Abs8 => write!(f, "Abs8"),
108            Self::S390xPCRel32Dbl => write!(f, "PCRel32Dbl"),
109            Self::S390xPLTRel32Dbl => write!(f, "PLTRel32Dbl"),
110            Self::X86PCRel4 => write!(f, "PCRel4"),
111            Self::X86CallPCRel4 => write!(f, "CallPCRel4"),
112            Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"),
113            Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"),
114            Self::X86SecRel => write!(f, "SecRel"),
115            Self::Arm32Call | Self::Arm64Call => write!(f, "Call"),
116            Self::RiscvCall => write!(f, "RiscvCall"),
117
118            Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"),
119            Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"),
120            Self::MachOAarch64TlsAdrPage21 => write!(f, "MachOAarch64TlsAdrPage21"),
121            Self::MachOAarch64TlsAdrPageOff12 => write!(f, "MachOAarch64TlsAdrPageOff12"),
122            Self::Aarch64TlsGdAdrPage21 => write!(f, "Aarch64TlsGdAdrPage21"),
123            Self::Aarch64TlsGdAddLo12Nc => write!(f, "Aarch64TlsGdAddLo12Nc"),
124            Self::Aarch64AdrGotPage21 => write!(f, "Aarch64AdrGotPage21"),
125            Self::Aarch64Ld64GotLo12Nc => write!(f, "Aarch64AdrGotLo12Nc"),
126            Self::S390xTlsGd64 => write!(f, "TlsGd64"),
127            Self::S390xTlsGdCall => write!(f, "TlsGdCall"),
128        }
129    }
130}
131
132/// Container for information about a vector of compiled code and its supporting read-only data.
133///
134/// The code starts at offset 0 and is followed optionally by relocatable jump tables and copyable
135/// (raw binary) read-only data.  Any padding between sections is always part of the section that
136/// precedes the boundary between the sections.
137#[derive(Debug, PartialEq)]
138pub struct CodeInfo {
139    /// Number of bytes in total.
140    pub total_size: CodeOffset,
141}