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::{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 /// Arm32 call target 39 Arm32Call, 40 /// Arm64 call target. Encoded as bottom 26 bits of instruction. This 41 /// value is sign-extended, multiplied by 4, and added to the PC of 42 /// the call instruction to form the destination address. 43 Arm64Call, 44 /// s390x PC-relative 4-byte offset 45 S390xPCRel32Dbl, 46 47 /// Elf x86_64 32 bit signed PC relative offset to two GOT entries for GD symbol. 48 ElfX86_64TlsGd, 49 50 /// Mach-O x86_64 32 bit signed PC relative offset to a `__thread_vars` entry. 51 MachOX86_64Tlv, 52 53 /// AArch64 TLS GD 54 /// Set an ADRP immediate field to the top 21 bits of the final address. Checks for overflow. 55 /// 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) 56 Aarch64TlsGdAdrPage21, 57 58 /// AArch64 TLS GD 59 /// Set the add immediate field to the low 12 bits of the final address. Does not check for overflow. 60 /// 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) 61 Aarch64TlsGdAddLo12Nc, 62 } 63 64 impl fmt::Display for Reloc { 65 /// Display trait implementation drops the arch, since its used in contexts where the arch is 66 /// already unambiguous, e.g. clif syntax with isa specified. In other contexts, use Debug. 67 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 68 match *self { 69 Self::Abs4 => write!(f, "Abs4"), 70 Self::Abs8 => write!(f, "Abs8"), 71 Self::S390xPCRel32Dbl => write!(f, "PCRel32Dbl"), 72 Self::X86PCRel4 => write!(f, "PCRel4"), 73 Self::X86CallPCRel4 => write!(f, "CallPCRel4"), 74 Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"), 75 Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"), 76 Self::Arm32Call | Self::Arm64Call => write!(f, "Call"), 77 78 Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"), 79 Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"), 80 Self::Aarch64TlsGdAdrPage21 => write!(f, "Aarch64TlsGdAdrPage21"), 81 Self::Aarch64TlsGdAddLo12Nc => write!(f, "Aarch64TlsGdAddLo12Nc"), 82 } 83 } 84 } 85 86 /// Container for information about a vector of compiled code and its supporting read-only data. 87 /// 88 /// The code starts at offset 0 and is followed optionally by relocatable jump tables and copyable 89 /// (raw binary) read-only data. Any padding between sections is always part of the section that 90 /// precedes the boundary between the sections. 91 #[derive(PartialEq)] 92 pub struct CodeInfo { 93 /// Number of bytes in total. 94 pub total_size: CodeOffset, 95 } 96