2015-04-16 12:16:23 +08:00
|
|
|
// Copyright (c) 2015, edef <edef@edef.eu>
|
|
|
|
// See LICENSE file that comes with this distribution.
|
|
|
|
|
2015-04-16 12:22:50 +08:00
|
|
|
//! initialise a new context
|
|
|
|
//! arguments:
|
|
|
|
//! * rdi: stack pointer
|
|
|
|
//! * rsi: function pointer
|
|
|
|
//! * rdx: data pointer
|
|
|
|
//! * rcx: stack limit
|
|
|
|
//!
|
|
|
|
//! return values:
|
|
|
|
//! * rdi: new stack pointer
|
2015-03-27 15:31:02 +08:00
|
|
|
|
|
|
|
// switch to the fresh stack
|
2015-01-14 15:31:17 +08:00
|
|
|
xchg %rsp, %rdi
|
|
|
|
|
2015-03-27 15:31:02 +08:00
|
|
|
// save the function pointer, data pointer, and stack limit, respectively
|
2015-01-14 15:31:17 +08:00
|
|
|
pushq %rsi
|
|
|
|
pushq %rdx
|
|
|
|
pushq %rcx
|
2015-03-27 15:31:02 +08:00
|
|
|
|
|
|
|
// save the return address, control flow continues at label 1
|
2015-01-14 15:31:17 +08:00
|
|
|
call 1f
|
2015-03-27 15:31:02 +08:00
|
|
|
// we arrive here once this context is reactivated (see swap.s)
|
2015-01-14 15:31:17 +08:00
|
|
|
|
2015-03-27 15:31:02 +08:00
|
|
|
// restore the stack limit, data pointer, and function pointer, respectively
|
2015-01-14 15:31:17 +08:00
|
|
|
popq %fs:0x70
|
|
|
|
popq %rdi
|
|
|
|
popq %rax
|
|
|
|
|
2015-03-27 15:31:02 +08:00
|
|
|
// initialise the frame pointer
|
2015-01-14 15:31:17 +08:00
|
|
|
movq $$0, %rbp
|
2015-03-27 15:31:02 +08:00
|
|
|
|
|
|
|
// call the function pointer with the data pointer (rdi is the first argument)
|
2015-01-14 15:31:17 +08:00
|
|
|
call *%rax
|
2015-03-27 15:31:02 +08:00
|
|
|
|
|
|
|
// crash if it ever returns
|
2015-01-14 15:31:17 +08:00
|
|
|
ud2
|
|
|
|
|
|
|
|
1:
|
2015-03-27 15:31:02 +08:00
|
|
|
// save our neatly-setup new stack
|
2015-01-14 15:31:17 +08:00
|
|
|
xchg %rsp, %rdi
|
2015-03-27 15:31:02 +08:00
|
|
|
// back into Rust-land we go
|