1747ad3c4Slazypassion //! Binary machine code emission. 2747ad3c4Slazypassion //! 3747ad3c4Slazypassion //! The `binemit` module contains code for translating Cranelift's intermediate representation into 4747ad3c4Slazypassion //! binary machine code. 5747ad3c4Slazypassion 6747ad3c4Slazypassion use core::fmt; 79e884b44SArtur Jamro #[cfg(feature = "enable-serde")] 89ec02f9dSChristopher Serr use serde_derive::{Deserialize, Serialize}; 9747ad3c4Slazypassion 10747ad3c4Slazypassion /// Offset in bytes from the beginning of the function. 11747ad3c4Slazypassion /// 12747ad3c4Slazypassion /// Cranelift can be used as a cross compiler, so we don't want to use a type like `usize` which 13747ad3c4Slazypassion /// depends on the *host* platform, not the *target* platform. 14747ad3c4Slazypassion pub type CodeOffset = u32; 15747ad3c4Slazypassion 16747ad3c4Slazypassion /// Addend to add to the symbol value. 17747ad3c4Slazypassion pub type Addend = i64; 18747ad3c4Slazypassion 19747ad3c4Slazypassion /// Relocation kinds for every ISA 20d3815a03SArtur Jamro #[derive(Copy, Clone, Debug, PartialEq, Eq)] 219e884b44SArtur Jamro #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] 22747ad3c4Slazypassion pub enum Reloc { 23747ad3c4Slazypassion /// absolute 4-byte 24747ad3c4Slazypassion Abs4, 25747ad3c4Slazypassion /// absolute 8-byte 26747ad3c4Slazypassion Abs8, 27747ad3c4Slazypassion /// x86 PC-relative 4-byte 28747ad3c4Slazypassion X86PCRel4, 29747ad3c4Slazypassion /// x86 call to PC-relative 4-byte 30747ad3c4Slazypassion X86CallPCRel4, 31747ad3c4Slazypassion /// x86 call to PLT-relative 4-byte 32747ad3c4Slazypassion X86CallPLTRel4, 33747ad3c4Slazypassion /// x86 GOT PC-relative 4-byte 34747ad3c4Slazypassion X86GOTPCRel4, 35c5bc368cSAfonso Bordado /// The 32-bit offset of the target from the beginning of its section. 36c5bc368cSAfonso Bordado /// Equivalent to `IMAGE_REL_AMD64_SECREL`. 37c5bc368cSAfonso Bordado /// See: [PE Format](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format) 38c5bc368cSAfonso Bordado X86SecRel, 39747ad3c4Slazypassion /// Arm32 call target 40747ad3c4Slazypassion Arm32Call, 41875d2758SChris Fallin /// Arm64 call target. Encoded as bottom 26 bits of instruction. This 42875d2758SChris Fallin /// value is sign-extended, multiplied by 4, and added to the PC of 43875d2758SChris Fallin /// the call instruction to form the destination address. 44747ad3c4Slazypassion Arm64Call, 45e1cc1a67SUlrich Weigand /// s390x PC-relative 4-byte offset 46e1cc1a67SUlrich Weigand S390xPCRel32Dbl, 47be36dd6bSUlrich Weigand /// s390x PC-relative 4-byte offset to PLT 48be36dd6bSUlrich Weigand S390xPLTRel32Dbl, 490a1bb3baSbjorn3 500a1bb3baSbjorn3 /// Elf x86_64 32 bit signed PC relative offset to two GOT entries for GD symbol. 510a1bb3baSbjorn3 ElfX86_64TlsGd, 520a1bb3baSbjorn3 530a1bb3baSbjorn3 /// Mach-O x86_64 32 bit signed PC relative offset to a `__thread_vars` entry. 540a1bb3baSbjorn3 MachOX86_64Tlv, 55b8ad99e4SAfonso Bordado 56c3decdf9SNathan Whitaker /// Mach-O Aarch64 TLS 57c3decdf9SNathan Whitaker /// PC-relative distance to the page of the TLVP slot. 58c3decdf9SNathan Whitaker MachOAarch64TlsAdrPage21, 59c3decdf9SNathan Whitaker 60c3decdf9SNathan Whitaker /// Mach-O Aarch64 TLS 61c3decdf9SNathan Whitaker /// Offset within page of TLVP slot. 62c3decdf9SNathan Whitaker MachOAarch64TlsAdrPageOff12, 63c3decdf9SNathan Whitaker 64ccaf2bfaSAfonso Bordado /// Aarch64 TLSDESC Adr Page21 65ccaf2bfaSAfonso Bordado /// 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) 66ccaf2bfaSAfonso Bordado Aarch64TlsDescAdrPage21, 67b8ad99e4SAfonso Bordado 68ccaf2bfaSAfonso Bordado /// Aarch64 TLSDESC Ld64 Lo12 69ccaf2bfaSAfonso Bordado /// 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) 70ccaf2bfaSAfonso Bordado Aarch64TlsDescLd64Lo12, 71ccaf2bfaSAfonso Bordado 72ccaf2bfaSAfonso Bordado /// Aarch64 TLSDESC Add Lo12 73ccaf2bfaSAfonso Bordado /// 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) 74ccaf2bfaSAfonso Bordado Aarch64TlsDescAddLo12, 75ccaf2bfaSAfonso Bordado 76ccaf2bfaSAfonso Bordado /// Aarch64 TLSDESC Call 77ccaf2bfaSAfonso Bordado /// 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) 78ccaf2bfaSAfonso Bordado Aarch64TlsDescCall, 7950fcab29SUlrich Weigand 80eabd43a1SAfonso Bordado /// AArch64 GOT Page 81cd97c9f1SMrmaxmeier /// Set the immediate value of an ADRP to bits 32:12 of X; check that –2^32 <= X < 2^32 82eabd43a1SAfonso Bordado /// 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) 83eabd43a1SAfonso Bordado Aarch64AdrGotPage21, 84eabd43a1SAfonso Bordado 8510d2cbc5SAlex Crichton /// Equivalent of `R_AARCH64_ADR_PREL_PG_HI21`. 8610d2cbc5SAlex Crichton Aarch64AdrPrelPgHi21, 8710d2cbc5SAlex Crichton /// Equivalent of `R_AARCH64_ADD_ABS_LO12_NC`. 8810d2cbc5SAlex Crichton Aarch64AddAbsLo12Nc, 8910d2cbc5SAlex Crichton 90eabd43a1SAfonso Bordado /// AArch64 GOT Low bits 91eabd43a1SAfonso Bordado 92eabd43a1SAfonso Bordado /// Set the LD/ST immediate field to bits 11:3 of X. No overflow check; check that X&7 = 0 93eabd43a1SAfonso Bordado /// 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) 94eabd43a1SAfonso Bordado Aarch64Ld64GotLo12Nc, 95eabd43a1SAfonso Bordado 96ecc1b794SAfonso Bordado /// RISC-V Call PLT: 32-bit PC-relative function call, macros call, tail (PIC) 97ecc1b794SAfonso Bordado /// 98ecc1b794SAfonso Bordado /// Despite having PLT in the name, this relocation is also used for normal calls. 99ecc1b794SAfonso Bordado /// The non-PLT version of this relocation has been deprecated. 100ecc1b794SAfonso Bordado /// 101ecc1b794SAfonso Bordado /// This is the `R_RISCV_CALL_PLT` relocation from the RISC-V ELF psABI document. 102d38d387aSAlex Crichton /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#procedure-calls> 103ecc1b794SAfonso Bordado RiscvCallPlt, 104cdecc858Syuyang-ok 105b23f534cSAfonso Bordado /// RISC-V TLS GD: High 20 bits of 32-bit PC-relative TLS GD GOT reference, 106b23f534cSAfonso Bordado /// 107b23f534cSAfonso Bordado /// This is the `R_RISCV_TLS_GD_HI20` relocation from the RISC-V ELF psABI document. 108d38d387aSAlex Crichton /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#global-dynamic> 109b23f534cSAfonso Bordado RiscvTlsGdHi20, 110b23f534cSAfonso Bordado 111b23f534cSAfonso Bordado /// Low 12 bits of a 32-bit PC-relative relocation (I-Type instruction) 112b23f534cSAfonso Bordado /// 113b23f534cSAfonso Bordado /// This is the `R_RISCV_PCREL_LO12_I` relocation from the RISC-V ELF psABI document. 114d38d387aSAlex Crichton /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses> 115b23f534cSAfonso Bordado RiscvPCRelLo12I, 116b23f534cSAfonso Bordado 117ecc1b794SAfonso Bordado /// High 20 bits of a 32-bit PC-relative GOT offset relocation 118ecc1b794SAfonso Bordado /// 119ecc1b794SAfonso Bordado /// This is the `R_RISCV_GOT_HI20` relocation from the RISC-V ELF psABI document. 120d38d387aSAlex Crichton /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses> 121ecc1b794SAfonso Bordado RiscvGotHi20, 122ecc1b794SAfonso Bordado 123*13b300deSAlex Crichton /// High 20 bits of a 32-bit PC-relative offset relocation 124*13b300deSAlex Crichton /// 125*13b300deSAlex Crichton /// This is the `R_RISCV_PCREL_HI20` relocation from the RISC-V ELF psABI document. 126*13b300deSAlex Crichton /// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses> 127*13b300deSAlex Crichton RiscvPCRelHi20, 128*13b300deSAlex Crichton 12950fcab29SUlrich Weigand /// s390x TLS GD64 - 64-bit offset of tls_index for GD symbol in GOT 13050fcab29SUlrich Weigand S390xTlsGd64, 13150fcab29SUlrich Weigand /// s390x TLS GDCall - marker to enable optimization of TLS calls 13250fcab29SUlrich Weigand S390xTlsGdCall, 133438fc938SAlex Crichton 13462276749SAlex Crichton /// Pulley - a relocation which is a pc-relative offset. 13562276749SAlex Crichton PulleyPcRel, 13662276749SAlex Crichton 137438fc938SAlex Crichton /// Pulley - call a host function indirectly where the embedder resolving 1382f7b0f58SAlex Crichton /// this relocation needs to fill the 8-bit immediate that's part of the 1392f7b0f58SAlex Crichton /// `call_indirect_host` opcode (an opaque identifier used by the host). 140438fc938SAlex Crichton PulleyCallIndirectHost, 141747ad3c4Slazypassion } 142747ad3c4Slazypassion 143747ad3c4Slazypassion impl fmt::Display for Reloc { 144747ad3c4Slazypassion /// Display trait implementation drops the arch, since its used in contexts where the arch is 145747ad3c4Slazypassion /// already unambiguous, e.g. clif syntax with isa specified. In other contexts, use Debug. fmt(&self, f: &mut fmt::Formatter) -> fmt::Result146747ad3c4Slazypassion fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 147747ad3c4Slazypassion match *self { 1489f506692SPeter Huene Self::Abs4 => write!(f, "Abs4"), 1499f506692SPeter Huene Self::Abs8 => write!(f, "Abs8"), 150e1cc1a67SUlrich Weigand Self::S390xPCRel32Dbl => write!(f, "PCRel32Dbl"), 151be36dd6bSUlrich Weigand Self::S390xPLTRel32Dbl => write!(f, "PLTRel32Dbl"), 1529f506692SPeter Huene Self::X86PCRel4 => write!(f, "PCRel4"), 1539f506692SPeter Huene Self::X86CallPCRel4 => write!(f, "CallPCRel4"), 1549f506692SPeter Huene Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"), 1559f506692SPeter Huene Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"), 156c5bc368cSAfonso Bordado Self::X86SecRel => write!(f, "SecRel"), 15759e18b7dSbjorn3 Self::Arm32Call | Self::Arm64Call => write!(f, "Call"), 158ecc1b794SAfonso Bordado Self::RiscvCallPlt => write!(f, "RiscvCallPlt"), 159b23f534cSAfonso Bordado Self::RiscvTlsGdHi20 => write!(f, "RiscvTlsGdHi20"), 160ecc1b794SAfonso Bordado Self::RiscvGotHi20 => write!(f, "RiscvGotHi20"), 161*13b300deSAlex Crichton Self::RiscvPCRelHi20 => write!(f, "RiscvPCRelHi20"), 162b23f534cSAfonso Bordado Self::RiscvPCRelLo12I => write!(f, "RiscvPCRelLo12I"), 1630a1bb3baSbjorn3 Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"), 1640a1bb3baSbjorn3 Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"), 165c3decdf9SNathan Whitaker Self::MachOAarch64TlsAdrPage21 => write!(f, "MachOAarch64TlsAdrPage21"), 166c3decdf9SNathan Whitaker Self::MachOAarch64TlsAdrPageOff12 => write!(f, "MachOAarch64TlsAdrPageOff12"), 167ccaf2bfaSAfonso Bordado Self::Aarch64TlsDescAdrPage21 => write!(f, "Aarch64TlsDescAdrPage21"), 168ccaf2bfaSAfonso Bordado Self::Aarch64TlsDescLd64Lo12 => write!(f, "Aarch64TlsDescLd64Lo12"), 169ccaf2bfaSAfonso Bordado Self::Aarch64TlsDescAddLo12 => write!(f, "Aarch64TlsDescAddLo12"), 170ccaf2bfaSAfonso Bordado Self::Aarch64TlsDescCall => write!(f, "Aarch64TlsDescCall"), 171eabd43a1SAfonso Bordado Self::Aarch64AdrGotPage21 => write!(f, "Aarch64AdrGotPage21"), 172eabd43a1SAfonso Bordado Self::Aarch64Ld64GotLo12Nc => write!(f, "Aarch64AdrGotLo12Nc"), 17310d2cbc5SAlex Crichton Self::Aarch64AdrPrelPgHi21 => write!(f, "Aarch64AdrPrelPgHi21"), 17410d2cbc5SAlex Crichton Self::Aarch64AddAbsLo12Nc => write!(f, "Aarch64AddAbsLo12Nc"), 17550fcab29SUlrich Weigand Self::S390xTlsGd64 => write!(f, "TlsGd64"), 17650fcab29SUlrich Weigand Self::S390xTlsGdCall => write!(f, "TlsGdCall"), 17762276749SAlex Crichton Self::PulleyPcRel => write!(f, "PulleyPcRel"), 178438fc938SAlex Crichton Self::PulleyCallIndirectHost => write!(f, "PulleyCallIndirectHost"), 179747ad3c4Slazypassion } 180747ad3c4Slazypassion } 181747ad3c4Slazypassion } 182747ad3c4Slazypassion 183420850adSLars T Hansen /// Container for information about a vector of compiled code and its supporting read-only data. 184420850adSLars T Hansen /// 185420850adSLars T Hansen /// The code starts at offset 0 and is followed optionally by relocatable jump tables and copyable 186420850adSLars T Hansen /// (raw binary) read-only data. Any padding between sections is always part of the section that 187420850adSLars T Hansen /// precedes the boundary between the sections. 1888a9b1a90SBenjamin Bouvier #[derive(Debug, PartialEq)] 189420850adSLars T Hansen pub struct CodeInfo { 190420850adSLars T Hansen /// Number of bytes in total. 191420850adSLars T Hansen pub total_size: CodeOffset, 192420850adSLars T Hansen } 193