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 mod stack_map; 7 8 pub use self::stack_map::StackMap; 9 use core::fmt; 10 #[cfg(feature = "enable-serde")] 11 use 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. 17 pub type CodeOffset = u32; 18 19 /// Addend to add to the symbol value. 20 pub 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))] 25 pub 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 127 impl 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)] 168 pub struct CodeInfo { 169 /// Number of bytes in total. 170 pub total_size: CodeOffset, 171 } 172