Exception.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* This Hello World simply print out "Hello World" */
  2. #include <stdatomic.h>
  3. #include <inttypes.h>
  4. #include "pal.h"
  5. #include "pal_debug.h"
  6. void handler1 (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
  7. {
  8. pal_printf("Arithmetic Exception Handler 1: 0x%08lx, rip = 0x%08lx\n",
  9. arg, context->rip);
  10. while (*(unsigned char *) context->rip != 0x90)
  11. context->rip++;
  12. DkExceptionReturn(event);
  13. }
  14. void handler2 (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
  15. {
  16. pal_printf("Arithmetic Exception Handler 2: 0x%08lx, rip = 0x%08lx\n",
  17. arg, context->rip);
  18. while (*(unsigned char *) context->rip != 0x90)
  19. context->rip++;
  20. DkExceptionReturn(event);
  21. }
  22. void handler3 (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
  23. {
  24. pal_printf("Memory Fault Exception Handler: 0x%08lx, rip = 0x%08lx\n",
  25. arg, context->rip);
  26. while (*(unsigned char *) context->rip != 0x90)
  27. context->rip++;
  28. DkExceptionReturn(event);
  29. }
  30. atomic_bool handler4_called = false;
  31. void handler4(PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
  32. {
  33. pal_printf("Arithmetic Exception Handler 4: 0x%" PRIx64 ", rip = 0x%" PRIx64 "\n", arg, context->rip);
  34. while (*(unsigned char *) context->rip != 0x90)
  35. context->rip++;
  36. handler4_called = true;
  37. DkExceptionReturn(event);
  38. }
  39. static void red_zone_test() {
  40. uint64_t res = 0;
  41. // First call some function to ensure that gcc doesn't use the red zone
  42. // itself.
  43. pal_printf("Testing red zone...\n");
  44. __asm__ volatile (
  45. // Fill the red zone with a pattern (0xaa 0xa9 0xa8 ...)
  46. "movq $-128, %%rax\n"
  47. "movq $0xaa, %%rbx\n"
  48. "1:\n"
  49. "movb %%bl, (%%rsp, %%rax, 1)\n"
  50. "decq %%rbx\n"
  51. "incq %%rax\n"
  52. "jnz 1b\n"
  53. // Trigger exception
  54. "movq $1, %%rax\n"
  55. "cqo\n"
  56. "movq $0, %%rbx\n"
  57. "divq %%rbx\n"
  58. "nop\n"
  59. // Calculate sum of pattern
  60. "movq $-128, %%rax\n"
  61. "movq $0, %%rbx\n"
  62. "movq $0, %%rcx\n"
  63. "1:\n"
  64. "movb (%%rsp, %%rax, 1), %%bl\n"
  65. "addq %%rbx, %%rcx\n"
  66. "incq %%rax\n"
  67. "jnz 1b\n"
  68. "movq %%rcx, %q0\n"
  69. : "=rm"(res)
  70. :
  71. : "rax", "rbx", "rcx", "rdx", "cc", "memory");
  72. if (!handler4_called) {
  73. pal_printf("Exception handler was not called!\n");
  74. return;
  75. }
  76. if (res != 13632) {
  77. pal_printf("Sum over red zone (%lu) doesn't match!\n", res);
  78. return;
  79. }
  80. pal_printf("Red zone test ok.\n");
  81. }
  82. int main (void)
  83. {
  84. volatile long i;
  85. DkSetExceptionHandler(handler1, PAL_EVENT_ARITHMETIC_ERROR);
  86. i = 0;
  87. i = 1 / i;
  88. __asm__ volatile("nop");
  89. DkSetExceptionHandler(handler2, PAL_EVENT_ARITHMETIC_ERROR);
  90. i = 0;
  91. i = 1 / i;
  92. __asm__ volatile("nop");
  93. DkSetExceptionHandler(handler3, PAL_EVENT_MEMFAULT);
  94. *(volatile long *) 0x1000 = 0;
  95. __asm__ volatile("nop");
  96. DkSetExceptionHandler(handler4, PAL_EVENT_ARITHMETIC_ERROR);
  97. red_zone_test();
  98. return 0;
  99. }