rt: Rewrite 32-bit __morestack to use the shim upcall
This commit is contained in:
parent
fdebd1e2ef
commit
037ca7f7cb
@ -6,42 +6,22 @@
|
||||
// prolog when we run out.
|
||||
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
#define RUST_NEW_STACK _rust_new_stack
|
||||
#define RUST_NEW_STACK2 _rust_new_stack2
|
||||
#define RUST_DEL_STACK _rust_del_stack
|
||||
#define RUST_GET_PREV_STACK _rust_get_prev_stack
|
||||
#define RUST_GET_TASK _rust_get_task
|
||||
#define UPCALL_ALLOC_C_STACK _upcall_alloc_c_stack
|
||||
#define UPCALL_CALL_C_STACK _upcall_call_c_stack
|
||||
#define UPCALL_CALL_C _upcall_call_shim_on_c_stack
|
||||
#define MORESTACK ___morestack
|
||||
#else
|
||||
#define RUST_NEW_STACK rust_new_stack
|
||||
#define RUST_NEW_STACK2 rust_new_stack2
|
||||
#define RUST_DEL_STACK rust_del_stack
|
||||
#define RUST_GET_PREV_STACK rust_get_prev_stack
|
||||
#define RUST_GET_TASK rust_get_task
|
||||
#define UPCALL_ALLOC_C_STACK upcall_alloc_c_stack
|
||||
#define UPCALL_CALL_C_STACK upcall_call_c_stack
|
||||
#define UPCALL_CALL_C upcall_call_shim_on_c_stack
|
||||
#define MORESTACK __morestack
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define ALIGNMENT 4
|
||||
#else
|
||||
#define ALIGNMENT 8
|
||||
#endif
|
||||
|
||||
#if defined (__APPLE__)
|
||||
#define NEW_STACK_ADDR rust_new_stack_sym-.L$pic_ref_pt_0(%eax)
|
||||
#define DEL_STACK_ADDR rust_del_stack_sym-.L$pic_ref_pt_1(%edx)
|
||||
#else
|
||||
#if defined (_WIN32)
|
||||
#define NEW_STACK_ADDR $_rust_new_stack
|
||||
#define DEL_STACK_ADDR $_rust_del_stack
|
||||
#else
|
||||
#define NEW_STACK_ADDR $rust_new_stack
|
||||
#define DEL_STACK_ADDR $rust_del_stack
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ALIGNMENT 8
|
||||
#define RETURN_OFFSET 7
|
||||
|
||||
.globl RUST_NEW_STACK
|
||||
@ -68,68 +48,66 @@
|
||||
#if defined(__linux__)
|
||||
MORESTACK:
|
||||
|
||||
// Sanity check to make sure that there is a currently-running task.
|
||||
subl $12,%esp
|
||||
calll RUST_GET_TASK
|
||||
testl %eax,%eax
|
||||
jz .L$bail
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
|
||||
// FIXME (1226): main is compiled with the split-stack prologue,
|
||||
// causing it to call __morestack, so we have to jump back out
|
||||
subl $24,%esp
|
||||
calll RUST_GET_TASK
|
||||
testl %eax,%eax
|
||||
jz .L$bail
|
||||
|
||||
movl $16, (%esp)
|
||||
calll UPCALL_ALLOC_C_STACK
|
||||
movl %eax,%edx
|
||||
// The arguments to rust_new_stack2
|
||||
movl %esp, 20(%esp) // Save the stack pointer
|
||||
movl 36(%esp),%eax // Size of stack arguments
|
||||
movl %eax,16(%esp)
|
||||
leal 44+ALIGNMENT(%esp),%eax // Address of stack arguments
|
||||
movl %eax,12(%esp)
|
||||
movl 32(%esp),%eax // The amount of stack needed
|
||||
movl %eax,8(%esp)
|
||||
|
||||
movl %esp, 12(%edx)
|
||||
// C stack | esp+12
|
||||
// ---------------------+-------------------------
|
||||
movl 20(%esp),%eax // | ra stksz argsz x ra args
|
||||
movl %eax,8(%edx) // argsz > | ra stksz argsz x ra args
|
||||
leal 28+ALIGNMENT(%esp),%eax // argsz | ra stksz argsz x ra args
|
||||
movl %eax,4(%edx) // argp > argsz | ra stksz argsz x ra args
|
||||
movl 16(%esp),%eax // argp argsz | ra stksz argsz x ra args
|
||||
movl %eax,(%edx) // stksz > argp argsz | ra stksz argsz x ra args
|
||||
movl $RUST_NEW_STACK2,4(%esp)
|
||||
leal 8(%esp), %eax
|
||||
movl %eax,(%esp)
|
||||
call UPCALL_CALL_C
|
||||
|
||||
calll .L$pic_ref_pt_0
|
||||
.L$pic_ref_pt_0:
|
||||
popl %eax
|
||||
movl 28(%esp),%edx // Grab the return pointer.
|
||||
addl $RETURN_OFFSET,%edx // Skip past the `add esp,4` and the `ret`.
|
||||
|
||||
movl NEW_STACK_ADDR,%eax
|
||||
movl %eax,(%esp)
|
||||
movl %edx,4(%esp)
|
||||
// FIXME: Don't understand why just _here_ I have to say @PLT
|
||||
calll UPCALL_CALL_C_STACK@PLT
|
||||
movl %eax,%esp // Switch stacks.
|
||||
call *%edx // Re-enter the function that called us.
|
||||
|
||||
movl 12(%esp),%edx // Grab the return pointer.
|
||||
addl $RETURN_OFFSET,%edx // Skip past the `add esp,4` and the `ret`.
|
||||
// Now the function that called us has returned, so we need to delete the
|
||||
// old stack space.
|
||||
|
||||
movl %eax,%esp // Switch stacks.
|
||||
calll *%edx // Re-enter the function that called us.
|
||||
// NB: This is assuming we already have at least 2 words
|
||||
// pushed onto the C stack. This is always true because
|
||||
// Rust functions have implicit arguments.
|
||||
movl $RUST_GET_PREV_STACK,4(%esp)
|
||||
movl $0, (%esp)
|
||||
call UPCALL_CALL_C
|
||||
|
||||
// Now the function that called us has returned, so we need to delete the
|
||||
// old stack space.
|
||||
// Switch back to the rust stack
|
||||
movl %eax, %esp
|
||||
|
||||
calll RUST_GET_PREV_STACK
|
||||
movl %eax,%esp // Switch back to the old stack.
|
||||
movl $RUST_DEL_STACK,4(%esp)
|
||||
movl $0, (%esp)
|
||||
call UPCALL_CALL_C
|
||||
|
||||
movl $0,(%esp)
|
||||
calll UPCALL_ALLOC_C_STACK
|
||||
|
||||
calll .L$pic_ref_pt_1
|
||||
.L$pic_ref_pt_1:
|
||||
popl %edx
|
||||
|
||||
movl DEL_STACK_ADDR,%edx
|
||||
movl %edx,(%esp)
|
||||
movl %eax,4(%esp)
|
||||
calll UPCALL_CALL_C_STACK
|
||||
|
||||
addl $12,%esp
|
||||
retl $8 // ra stksz argsz x ra args
|
||||
addl $24,%esp
|
||||
popl %ebp
|
||||
retl $8
|
||||
|
||||
.L$bail:
|
||||
movl 12(%esp),%edx
|
||||
addl $RETURN_OFFSET,%edx
|
||||
addl $12+4+8+ALIGNMENT,%esp
|
||||
jmpl *%edx
|
||||
movl 28(%esp),%edx
|
||||
addl $RETURN_OFFSET,%edx
|
||||
|
||||
addl $24, %esp
|
||||
popl %ebp
|
||||
addl $4+8+ALIGNMENT,%esp
|
||||
|
||||
jmpl *%edx
|
||||
|
||||
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user