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