#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:
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
#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:
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
#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);
*/
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
// 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();
}