Browse Source

[Pal/regression] Add test for red zone

Simon Gaiser 6 years ago
parent
commit
2b8c4fc30b
2 changed files with 75 additions and 0 deletions
  1. 3 0
      Pal/regression/01_Exception.py
  2. 72 0
      Pal/regression/Exception.c

+ 3 - 0
Pal/regression/01_Exception.py

@@ -18,5 +18,8 @@ regression.add_check(name="Exception Handler Swap",
 regression.add_check(name="Exception Handling (Set Context)",
     check=lambda res: any([line.startswith("Arithmetic Exception Handler 1") for line in res[0].log]))
 
+regression.add_check(name="Exception Handling (Red zone)",
+    check=lambda res: "Red zone test ok." in res[0].log)
+
 rv = regression.run_checks()
 if rv: sys.exit(rv)

+ 72 - 0
Pal/regression/Exception.c

@@ -3,6 +3,9 @@
 
 /* This Hello World simply print out "Hello World" */
 
+#include <stdatomic.h>
+#include <inttypes.h>
+
 #include "pal.h"
 #include "pal_debug.h"
 
@@ -39,6 +42,72 @@ void handler3 (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
     DkExceptionReturn(event);
 }
 
+atomic_bool handler4_called = false;
+
+void handler4(PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
+{
+    pal_printf("Arithmetic Exception Handler 4: 0x%" PRIx64 ", rip = 0x%" PRIx64 "\n", arg, context->rip);
+
+    while (*(unsigned char *) context->rip != 0x90)
+        context->rip++;
+
+    handler4_called = true;
+
+    DkExceptionReturn(event);
+}
+
+
+static void red_zone_test() {
+    uint64_t res = 0;
+
+    // First call some function to ensure that gcc doesn't use the red zone
+    // itself.
+    pal_printf("Testing red zone...\n");
+
+    __asm__ volatile (
+            // Fill the red zone with a pattern (0xaa 0xa9 0xa8 ...)
+            "movq $-128, %%rax\n"
+            "movq $0xaa, %%rbx\n"
+            "1:\n"
+            "movb %%bl, (%%rsp, %%rax, 1)\n"
+            "decq %%rbx\n"
+            "incq %%rax\n"
+            "jnz 1b\n"
+
+            // Trigger exception
+            "movq $1, %%rax\n"
+            "cqo\n"
+            "movq $0, %%rbx\n"
+            "divq %%rbx\n"
+            "nop\n"
+
+            // Calculate sum of pattern
+            "movq $-128, %%rax\n"
+            "movq $0, %%rbx\n"
+            "movq $0, %%rcx\n"
+            "1:\n"
+            "movb (%%rsp, %%rax, 1), %%bl\n"
+            "addq %%rbx, %%rcx\n"
+            "incq %%rax\n"
+            "jnz 1b\n"
+            "movq %%rcx, %q0\n"
+            : "=rm"(res)
+            :
+            : "rax", "rbx", "rcx", "rdx", "cc", "memory");
+
+    if (!handler4_called) {
+        pal_printf("Exception handler was not called!\n");
+        return;
+    }
+
+    if (res != 13632) {
+        pal_printf("Sum over red zone (%lu) doesn't match!\n", res);
+        return;
+    }
+
+    pal_printf("Red zone test ok.\n");
+}
+
 int main (void)
 {
     volatile long i;
@@ -57,5 +126,8 @@ int main (void)
     *(volatile long *) 0x1000 = 0;
     __asm__ volatile("nop");
 
+    DkSetExceptionHandler(handler4, PAL_EVENT_ARITHMETIC_ERROR);
+    red_zone_test();
+
     return 0;
 }