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