summarylogtreecommitdiffstats
path: root/0001-libsigsegv-2.11-fix-assembly.patch
blob: abd0ff5fb6e4f2b3836a16b7e8664c88a51f5460 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
--- libsigsegv-2.11/src/handler-win32-orig.c	2017-11-30 17:36:43.362197800 -0500
+++ libsigsegv-2.11/src/handler-win32.c	2017-11-30 17:42:56.526459500 -0500
@@ -167,6 +167,91 @@
       )
 #endif
      )
+#ifdef _WIN64
+    {
+#if 0 /* for debugging only */
+      printf ("Exception!\n");
+      printf ("Code = 0x%x\n",
+              ExceptionInfo->ExceptionRecord->ExceptionCode);
+      printf ("Flags = 0x%x\n",
+              ExceptionInfo->ExceptionRecord->ExceptionFlags);
+      printf ("Address = 0x%x\n",
+              ExceptionInfo->ExceptionRecord->ExceptionAddress);
+      printf ("Params:");
+      {
+        DWORD i;
+        for (i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++)
+          printf (" 0x%x,",
+                  ExceptionInfo->ExceptionRecord->ExceptionInformation[i]);
+      }
+      printf ("\n");
+      printf ("Registers:\n");
+      printf ("rip = 0x%x\n", ExceptionInfo->ContextRecord->Rip);
+      printf ("rax = 0x%x, ", ExceptionInfo->ContextRecord->Rax);
+      printf ("rbx = 0x%x, ", ExceptionInfo->ContextRecord->Rbx);
+      printf ("rcx = 0x%x, ", ExceptionInfo->ContextRecord->Rcx);
+      printf ("rdx = 0x%x\n", ExceptionInfo->ContextRecord->Rdx);
+      printf ("rsi = 0x%x, ", ExceptionInfo->ContextRecord->Rsi);
+      printf ("rdi = 0x%x, ", ExceptionInfo->ContextRecord->Rdi);
+      printf ("rbp = 0x%x, ", ExceptionInfo->ContextRecord->Rbp);
+      printf ("rsp = 0x%x\n", ExceptionInfo->ContextRecord->Rsp);
+#endif
+      if (ExceptionInfo->ExceptionRecord->NumberParameters == 2)
+        {
+          if (stk_user_handler
+              && ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW)
+            {
+              char *address = (char *) ExceptionInfo->ExceptionRecord->ExceptionInformation[1];
+              /* Restart the program, giving it a sane value for %esp.
+                 At the same time, copy the contents of
+                 ExceptionInfo->ContextRecord (which, on Windows XP, happens
+                 to be allocated in the guard page, where it will be
+                 inaccessible as soon as we restore the PAGE_GUARD bit!) to
+                 this new stack.  */
+              uintptr_t faulting_page_address = (uintptr_t)address & -0x1000;
+              uintptr_t new_safe_rsp = ((stk_extra_stack + stk_extra_stack_size) & -16);
+              CONTEXT *orig_context = ExceptionInfo->ContextRecord;
+              CONTEXT *safe_context = (CONTEXT *) (new_safe_rsp -= sizeof (CONTEXT)); /* make room */
+              memcpy (safe_context, orig_context, sizeof (CONTEXT));
+              new_safe_rsp -= 8; /* make room for arguments */
+              new_safe_rsp &= -16; /* align */
+              new_safe_rsp -= 4; /* make room for (unused) return address slot */
+              ExceptionInfo->ContextRecord->Rsp = new_safe_rsp;
+              /* Call stack_overflow_handler(faulting_page_address,safe_context).  */
+              ExceptionInfo->ContextRecord->Rip = (uintptr_t)&stack_overflow_handler;
+              *(uintptr_t *)(new_safe_rsp + 4) = faulting_page_address;
+              *(uintptr_t *)(new_safe_rsp + 8) = (uintptr_t) safe_context;
+              return EXCEPTION_CONTINUE_EXECUTION;
+            }
+#if !MIXING_UNIX_SIGSEGV_AND_WIN32_STACKOVERFLOW_HANDLING || OLD_CYGWIN_WORKAROUND
+          if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
+            {
+#if MIXING_UNIX_SIGSEGV_AND_WIN32_STACKOVERFLOW_HANDLING
+              /* Store the fault address.  Then pass control to Cygwin's
+                 exception filter, which will decide whether to recognize
+                 a fault inside a "system call" (and return errno = EFAULT)
+                 or to pass it on to the program (by invoking the Unix signal
+                 handler).  */
+              last_seen_fault_address = (void *) ExceptionInfo->ExceptionRecord->ExceptionInformation[1];
+#else
+              if (user_handler != (sigsegv_handler_t) NULL)
+                {
+                  /* ExceptionInfo->ExceptionRecord->ExceptionInformation[0] is
+                     1 if it's a write access, 0 if it's a read access. But we
+                     don't need this info because we don't have it on Unix
+                     either.  */
+                  void *address = (void *) ExceptionInfo->ExceptionRecord->ExceptionInformation[1];
+                  if ((*user_handler) (address, 1))
+                    return EXCEPTION_CONTINUE_EXECUTION;
+                }
+#endif
+            }
+#endif
+        }
+    }
+  return EXCEPTION_CONTINUE_SEARCH;
+}
+#else
     {
 #if 0 /* for debugging only */
       printf ("Exception!\n");
@@ -250,7 +335,7 @@
     }
   return EXCEPTION_CONTINUE_SEARCH;
 }
-
+#endif
 #if defined __CYGWIN__ && defined __i386__
 
 /* In Cygwin programs, SetUnhandledExceptionFilter has no effect because Cygwin