diff options
| author | Brian Anderson <banderson@mozilla.com> | 2011-12-15 00:24:35 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2011-12-16 18:18:43 -0800 |
| commit | 121c4201844c1bec4a8f2a4450e4b9330ee9bf28 (patch) | |
| tree | 54b9576ba501dc5de392ad5a1a49d4ff11cd9c63 | |
| parent | 4f826b34cbb101f2bfe2660f5c4f8db6d044f83a (diff) | |
| download | rust-121c4201844c1bec4a8f2a4450e4b9330ee9bf28.tar.gz rust-121c4201844c1bec4a8f2a4450e4b9330ee9bf28.zip | |
rt: Insert stack alignment checks into upcalls
| -rw-r--r-- | src/rt/arch/i386/record_sp.S | 12 | ||||
| -rw-r--r-- | src/rt/arch/x86_64/record_sp.S | 10 | ||||
| -rw-r--r-- | src/rt/rust_upcall.cpp | 10 |
3 files changed, 31 insertions, 1 deletions
diff --git a/src/rt/arch/i386/record_sp.S b/src/rt/arch/i386/record_sp.S index 0c9f0782846..b9c42a650d8 100644 --- a/src/rt/arch/i386/record_sp.S +++ b/src/rt/arch/i386/record_sp.S @@ -3,13 +3,16 @@ #if defined(__APPLE__) || defined(_WIN32) #define RECORD_SP _record_sp #define GET_SP _get_sp +#define CHECK_STACK _check_stack_alignment #else #define RECORD_SP record_sp #define GET_SP get_sp +#define CHECK_STACK check_stack_alignment #endif .globl RECORD_SP .globl GET_SP +.globl CHECK_STACK #if defined(__linux__) RECORD_SP: @@ -35,4 +38,11 @@ RECORD_SP: GET_SP: movl %esp, %eax - ret \ No newline at end of file + ret + +// This will segfault if not called on a 16-byte boundary +CHECK_STACK: + subl $28, %esp + movaps %xmm0, (%esp) + addl $28, %esp + ret diff --git a/src/rt/arch/x86_64/record_sp.S b/src/rt/arch/x86_64/record_sp.S index 415f6685655..af217d0f37f 100644 --- a/src/rt/arch/x86_64/record_sp.S +++ b/src/rt/arch/x86_64/record_sp.S @@ -3,13 +3,16 @@ #if defined(__APPLE__) || defined(_WIN32) #define RECORD_SP _record_sp #define GET_SP _get_sp +#define CHECK_STACK _check_stack_alignment #else #define RECORD_SP record_sp #define GET_SP get_sp +#define CHECK_STACK check_stack_alignment #endif .globl RECORD_SP .globl GET_SP +.globl CHECK_STACK #if defined(__linux__) RECORD_SP: @@ -30,3 +33,10 @@ RECORD_SP: GET_SP: movq %rsp, %rax ret + +// This will segfault if not called on a 16-byte boundary +CHECK_STACK: + subq $24, %rsp + movaps %xmm0, (%rsp) + addq $24, %rsp + ret diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 97e1321c02d..dd7e275cd04 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -14,6 +14,14 @@ #include "rust_upcall.h" #include <stdint.h> + +// This is called to ensure we've set up our rust stacks +// correctly. Strategically placed at entry to upcalls because they begin on +// the rust stack and happen frequently enough to catch most stack changes, +// including at the beginning of all landing pads. +extern "C" void +check_stack_alignment() __attribute__ ((aligned (16))); + #define SWITCH_STACK(A, F) upcall_call_shim_on_c_stack((void*)A, (void*)F) extern "C" void record_sp(void *limit); @@ -26,6 +34,7 @@ extern "C" void record_sp(void *limit); */ extern "C" CDECL void upcall_call_shim_on_c_stack(void *args, void *fn_ptr) { + check_stack_alignment(); rust_task *task = rust_scheduler::get_task(); // FIXME (1226) - The shim functions generated by rustc contain the @@ -594,6 +603,7 @@ upcall_del_stack() { // needs to acquire the value of the stack pointer extern "C" CDECL void upcall_reset_stack_limit() { + check_stack_alignment(); rust_task *task = rust_scheduler::get_task(); task->reset_stack_limit(); } |
