1
0
Fork 0

Pass the new stack pointer by value into the swap trampoline

This commit is contained in:
Amanieu d'Antras 2016-09-03 12:03:30 +01:00 committed by edef
parent 86e29b2baa
commit b1f5b7458f
4 changed files with 19 additions and 25 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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)
} }
} }