about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-04-18 10:27:40 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-04-18 11:56:10 -0700
commitd94821d301b5ea89221e8164382a03e72ac26851 (patch)
tree9b89f165c8f9eaf0b3d5ecd3c4efe140ca5b4cb5
parentd0804ac04bece4ea885530bfc21efe70b0425189 (diff)
downloadmu-d94821d301b5ea89221e8164382a03e72ac26851.tar.gz
some primitives for monitoring code integrity
-rw-r--r--315stack-debug.subx51
-rw-r--r--400.mu4
-rw-r--r--shell/evaluate.mu3
3 files changed, 58 insertions, 0 deletions
diff --git a/315stack-debug.subx b/315stack-debug.subx
new file mode 100644
index 00000000..9734fd7a
--- /dev/null
+++ b/315stack-debug.subx
@@ -0,0 +1,51 @@
+# The stack shouldn't grow into the code area.
+
+== code
+
+check-stack:
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    50/push-eax
+    #
+    89/<- %eax 4/r32/esp
+    81 7/subop/compare %eax 0x48600/imm32
+    {
+      7f/jump-if-> break/disp8
+      (abort "stack overflow")
+    }
+$check-stack:end:
+    # . restore registers
+    58/pop-to-eax
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
+show-stack-state:
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    50/push-eax
+    51/push-ecx
+    52/push-edx
+    #
+    89/<- %edx 4/r32/esp
+    # save old cursor position
+    (cursor-position 0)  # => eax, ecx
+    # print at top-right
+    (set-cursor-position 0 0x70 0)
+    (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 0xf 0xc)
+    # restore cursor position
+    (set-cursor-position %eax %ecx)
+$check-stack:end:
+    # . restore registers
+    5a/pop-to-edx
+    59/pop-to-ecx
+    58/pop-to-eax
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
diff --git a/400.mu b/400.mu
index a31edbb6..a5064018 100644
--- a/400.mu
+++ b/400.mu
@@ -23,6 +23,10 @@ sig string-equal? s: (addr array byte), benchmark: (addr array byte) -> _/eax: b
 sig string-starts-with? s: (addr array byte), benchmark: (addr array byte) -> _/eax: boolean
 sig check-strings-equal s: (addr array byte), expected: (addr array byte), msg: (addr array byte)
 
+# debugging
+sig check-stack
+sig show-stack-state
+
 # streams
 sig clear-stream f: (addr stream _)
 sig rewind-stream f: (addr stream _)
diff --git a/shell/evaluate.mu b/shell/evaluate.mu
index fa8610c7..8dd794db 100644
--- a/shell/evaluate.mu
+++ b/shell/evaluate.mu
@@ -2,6 +2,9 @@
 # we never modify `in` or `env`
 # ignore 'screen-cell' on a first reading; it's a hack for sandboxes
 fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) {
+  # stack overflow?
+  check-stack
+  show-stack-state
   # errors? skip
   {
     compare trace, 0