forked from M-Labs/libfringe
Pass the new stack pointer by value into the swap trampoline
This commit is contained in:
parent
86e29b2baa
commit
b1f5b7458f
|
@ -42,7 +42,7 @@ use stack::Stack;
|
||||||
|
|
||||||
pub const STACK_ALIGNMENT: usize = 4;
|
pub const STACK_ALIGNMENT: usize = 4;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct StackPointer(*mut usize);
|
pub struct StackPointer(*mut usize);
|
||||||
|
|
||||||
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
||||||
|
@ -107,7 +107,7 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: *const StackPointer,
|
pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: StackPointer,
|
||||||
new_stack: &Stack) -> usize {
|
new_stack: &Stack) -> usize {
|
||||||
// Address of the topmost CFA stack slot.
|
// Address of the topmost CFA stack slot.
|
||||||
let new_cfa = (new_stack.base() as *mut usize).offset(-1);
|
let new_cfa = (new_stack.base() as *mut usize).offset(-1);
|
||||||
|
@ -124,12 +124,10 @@ pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: *const StackPo
|
||||||
# the call instruction that invoked the trampoline.
|
# the call instruction that invoked the trampoline.
|
||||||
l.sw -8(r1), r2
|
l.sw -8(r1), r2
|
||||||
|
|
||||||
# Remember stack pointer of the old context, in case r5==r4.
|
|
||||||
l.or r13, r0, r1
|
|
||||||
# Load stack pointer of the new context.
|
|
||||||
l.lwz r1, 0(r5)
|
|
||||||
# Save stack pointer of the old context.
|
# Save stack pointer of the old context.
|
||||||
l.sw 0(r4), r13
|
l.sw 0(r4), r1
|
||||||
|
# Load stack pointer of the new context.
|
||||||
|
l.or r1, r0, r5
|
||||||
|
|
||||||
# Restore frame pointer of the new context.
|
# Restore frame pointer of the new context.
|
||||||
l.lwz r2, -8(r1)
|
l.lwz r2, -8(r1)
|
||||||
|
@ -156,7 +154,7 @@ pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: *const StackPo
|
||||||
: "s" (trampoline as usize)
|
: "s" (trampoline as usize)
|
||||||
"{r3}" (arg)
|
"{r3}" (arg)
|
||||||
"{r4}" (old_sp)
|
"{r4}" (old_sp)
|
||||||
"{r5}" (new_sp)
|
"{r5}" (new_sp.0)
|
||||||
"{r6}" (new_cfa)
|
"{r6}" (new_cfa)
|
||||||
:/*"r0", "r1", "r2", "r3",*/"r4", "r5", "r6", "r7",
|
:/*"r0", "r1", "r2", "r3",*/"r4", "r5", "r6", "r7",
|
||||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||||
|
|
|
@ -43,7 +43,7 @@ use stack::Stack;
|
||||||
|
|
||||||
pub const STACK_ALIGNMENT: usize = 16;
|
pub const STACK_ALIGNMENT: usize = 16;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct StackPointer(*mut usize);
|
pub struct StackPointer(*mut usize);
|
||||||
|
|
||||||
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
||||||
|
@ -106,7 +106,7 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: *const StackPointer,
|
pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: StackPointer,
|
||||||
new_stack: &Stack) -> usize {
|
new_stack: &Stack) -> usize {
|
||||||
// Address of the topmost CFA stack slot.
|
// Address of the topmost CFA stack slot.
|
||||||
let new_cfa = (new_stack.base() as *mut usize).offset(-1);
|
let new_cfa = (new_stack.base() as *mut usize).offset(-1);
|
||||||
|
@ -120,12 +120,10 @@ pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: *const StackPo
|
||||||
# the call instruction that invoked the trampoline.
|
# the call instruction that invoked the trampoline.
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
|
|
||||||
# Remember stack pointer of the old context, in case %edx==%esi.
|
|
||||||
movl %esp, %ebx
|
|
||||||
# Load stack pointer of the new context.
|
|
||||||
movl (%edx), %esp
|
|
||||||
# Save stack pointer of the old context.
|
# Save stack pointer of the old context.
|
||||||
movl %ebx, (%esi)
|
movl %esp, (%esi)
|
||||||
|
# Load stack pointer of the new context.
|
||||||
|
movl %edx, %esp
|
||||||
|
|
||||||
# Restore frame pointer of the new context.
|
# Restore frame pointer of the new context.
|
||||||
popl %ebp
|
popl %ebp
|
||||||
|
@ -151,7 +149,7 @@ pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: *const StackPo
|
||||||
: "s" (trampoline as usize)
|
: "s" (trampoline as usize)
|
||||||
"{eax}" (arg)
|
"{eax}" (arg)
|
||||||
"{esi}" (old_sp)
|
"{esi}" (old_sp)
|
||||||
"{edx}" (new_sp)
|
"{edx}" (new_sp.0)
|
||||||
"{edi}" (new_cfa)
|
"{edi}" (new_cfa)
|
||||||
:/*"eax",*/"ebx", "ecx", "edx", "esi", "edi",/*"ebp", "esp",*/
|
:/*"eax",*/"ebx", "ecx", "edx", "esi", "edi",/*"ebp", "esp",*/
|
||||||
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
|
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
|
||||||
|
|
|
@ -47,7 +47,7 @@ use stack::Stack;
|
||||||
|
|
||||||
pub const STACK_ALIGNMENT: usize = 16;
|
pub const STACK_ALIGNMENT: usize = 16;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct StackPointer(*mut usize);
|
pub struct StackPointer(*mut usize);
|
||||||
|
|
||||||
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
||||||
|
@ -133,7 +133,7 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: *const StackPointer,
|
pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: StackPointer,
|
||||||
new_stack: &Stack) -> usize {
|
new_stack: &Stack) -> usize {
|
||||||
// Address of the topmost CFA stack slot.
|
// Address of the topmost CFA stack slot.
|
||||||
let new_cfa = (new_stack.base() as *mut usize).offset(-1);
|
let new_cfa = (new_stack.base() as *mut usize).offset(-1);
|
||||||
|
@ -147,12 +147,10 @@ pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: *const StackPo
|
||||||
# the call instruction that invoked the trampoline.
|
# the call instruction that invoked the trampoline.
|
||||||
pushq %rbp
|
pushq %rbp
|
||||||
|
|
||||||
# Remember stack pointer of the old context, in case %rdx==%rsi.
|
|
||||||
movq %rsp, %rbx
|
|
||||||
# Load stack pointer of the new context.
|
|
||||||
movq (%rdx), %rsp
|
|
||||||
# Save stack pointer of the old context.
|
# Save stack pointer of the old context.
|
||||||
movq %rbx, (%rsi)
|
movq %rsp, (%rsi)
|
||||||
|
# Load stack pointer of the new context.
|
||||||
|
movq %rdx, %rsp
|
||||||
|
|
||||||
# Restore frame pointer of the new context.
|
# Restore frame pointer of the new context.
|
||||||
popq %rbp
|
popq %rbp
|
||||||
|
@ -178,7 +176,7 @@ pub unsafe fn swap(arg: usize, old_sp: *mut StackPointer, new_sp: *const StackPo
|
||||||
: "s" (trampoline as usize)
|
: "s" (trampoline as usize)
|
||||||
"{rdi}" (arg)
|
"{rdi}" (arg)
|
||||||
"{rsi}" (old_sp)
|
"{rsi}" (old_sp)
|
||||||
"{rdx}" (new_sp)
|
"{rdx}" (new_sp.0)
|
||||||
"{rcx}" (new_cfa)
|
"{rcx}" (new_cfa)
|
||||||
: "rax", "rbx", "rcx", "rdx", "rsi", /*"rdi", "rbp", "rsp",*/
|
: "rax", "rbx", "rcx", "rdx", "rsi", /*"rdi", "rbp", "rsp",*/
|
||||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl<OldStack> Context<OldStack> where OldStack: stack::Stack {
|
||||||
new_ctx: *const Context<NewStack>,
|
new_ctx: *const Context<NewStack>,
|
||||||
arg: usize) -> usize
|
arg: usize) -> usize
|
||||||
where NewStack: stack::Stack {
|
where NewStack: stack::Stack {
|
||||||
arch::swap(arg, &mut (*old_ctx).stack_ptr, &(*new_ctx).stack_ptr, &(*new_ctx).stack)
|
arch::swap(arg, &mut (*old_ctx).stack_ptr, (*new_ctx).stack_ptr, &(*new_ctx).stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue