about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-07-06 15:06:30 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-07-06 15:07:04 -0700
commit91eb63eaee238061d278ecb8609775ac8f7aced8 (patch)
tree8a42a6cb705bcde49f17c9d3a114a36bf1d8bbf5
parent2f7bc90514c650fca4947835998458c56439cf33 (diff)
downloadrust-91eb63eaee238061d278ecb8609775ac8f7aced8.tar.gz
rust-91eb63eaee238061d278ecb8609775ac8f7aced8.zip
rt: Add a stack check to upcall_get_type_desc
-rw-r--r--src/rt/rust_kernel.cpp11
-rw-r--r--src/rt/rust_kernel.h1
-rw-r--r--src/rt/rust_upcall.cpp17
3 files changed, 29 insertions, 0 deletions
diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp
index 8a75e1adcbc..85a6178ded7 100644
--- a/src/rt/rust_kernel.cpp
+++ b/src/rt/rust_kernel.cpp
@@ -122,6 +122,17 @@ rust_kernel::log(uint32_t level, char const *fmt, ...) {
 }
 
 void
+rust_kernel::fatal(char const *fmt, ...) {
+    char buf[BUF_BYTES];
+    va_list args;
+    va_start(args, fmt);
+    vsnprintf(buf, sizeof(buf), fmt, args);
+    _log.trace_ln(NULL, (uint32_t)0, buf);
+    exit(1);
+    va_end(args);
+}
+
+void
 rust_kernel::pump_message_queues() {
     for (size_t i = 0; i < message_queues.length(); i++) {
         rust_message_queue *queue = message_queues[i];
diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h
index bea5afd5de3..f61935c8c48 100644
--- a/src/rt/rust_kernel.h
+++ b/src/rt/rust_kernel.h
@@ -106,6 +106,7 @@ public:
 
     void log_all_scheduler_state();
     void log(uint32_t level, char const *fmt, ...);
+    void fatal(char const *fmt, ...);
     virtual ~rust_kernel();
 
     void *malloc(size_t size);
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 05220f02606..d8ff9236aa6 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -21,6 +21,22 @@
 extern "C" CDECL char const *
 str_buf(rust_task *task, rust_str *s);
 
+#ifdef __i386__
+void
+check_stack(rust_task *task) {
+    void *esp;
+    asm volatile("movl %%esp,%0" : "=r" (esp));
+    if (esp < task->stk->data)
+        task->kernel->fatal("Out of stack space, sorry");
+}
+#else
+#warning "Stack checks are not supported on this architecture"
+void
+check_stack(rust_task *task) {
+    // TODO
+}
+#endif
+
 extern "C" void
 upcall_grow_task(rust_task *task, size_t n_frame_bytes) {
     I(task->sched, false);
@@ -463,6 +479,7 @@ upcall_get_type_desc(rust_task *task,
                      size_t align,
                      size_t n_descs,
                      type_desc const **descs) {
+    check_stack(task);
     LOG_UPCALL_ENTRY(task);
     scoped_lock with(task->kernel->scheduler_lock);
     LOG(task, cache, "upcall get_type_desc with size=%" PRIdPTR