cranelift_codegen/isa/x64/inst/stack_switch.rs
1use crate::{isa::x64::inst::regs, machinst::Reg};
2
3/// The `stack_switch` instruction loads information about the stack to switch
4/// to and stores information about the current stack by receiving pointers to
5/// memory laid out as in the struct `ControlContext` below.
6///
7/// The instruction is only supported on x64 Linux at the moment.
8///
9/// ```
10/// #[repr(C)]
11/// pub struct ControlContext {
12/// pub stack_pointer: *mut u8,
13/// pub frame_pointer: *mut u8,
14/// pub instruction_pointer: *mut u8,
15/// }
16/// ```
17///
18/// Note that this layout is deliberately chosen to make frame pointer walking
19/// possible, if desired: The layout enables stack layouts where a
20/// `ControlContext` is part of a frame pointer chain, putting the frame pointer
21/// next to the corresponding IP.
22///
23/// We never actually interact with values of that type in Cranelift, but are
24/// only interested in its layout for the purposes of generating code.
25pub struct ControlContextLayout {
26 pub stack_pointer_offset: usize,
27 pub frame_pointer_offset: usize,
28 pub ip_offset: usize,
29}
30
31pub fn control_context_layout() -> ControlContextLayout {
32 ControlContextLayout {
33 stack_pointer_offset: 0,
34 frame_pointer_offset: 8,
35 ip_offset: 16,
36 }
37}
38
39/// The register used for handing over the payload when switching stacks.
40///
41/// We must use a fixed register for sending and receiving the payload: When
42/// switching from one stack to another using two matching``stack_switch``
43/// instructions, they must agree on the register where the payload is, similar
44/// to a calling convention. The same holds when `stack_switch`-ing to a newly
45/// initialized stack, where the entry trampoline must know which register the
46/// payload is in.
47pub fn payload_register() -> Reg {
48 regs::rdi()
49}