]> granicus.if.org Git - gc/commitdiff
Refactoring of WoW64 workaround (Win32)
authorIvan Maidanski <ivmai@mail.ru>
Thu, 5 Sep 2019 08:44:27 +0000 (11:44 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 5 Sep 2019 08:44:27 +0000 (11:44 +0300)
(code refactoring of commit 9483d5bba)

Issue #262 (bdwgc).

* include/private/gcconfig.h [I386 && (CYGWIN32 || MSWIN32)]
(WOW64_THREAD_CONTEXT_WORKAROUND): Define macro.
* win32_threads.c [!CONTEXT_EXCEPTION_ACTIVE] (CONTEXT_EXCEPTION_ACTIVE,
CONTEXT_EXCEPTION_REQUEST, CONTEXT_EXCEPTION_REPORTING): Move macro
definition upper to be before GC_suspend(); define only if
WOW64_THREAD_CONTEXT_WORKAROUND is defined (instead of I386).
* win32_threads.c (isWow64): Move static variable upper to be before
GC_suspend(); define only if WOW64_THREAD_CONTEXT_WORKAROUND.
* win32_threads.c (GET_THREAD_CONTEXT_FLAGS): New macro.
* win32_threads.c (GC_push_stack_for): Always set context.ContextFlags
to GET_THREAD_CONTEXT_FLAGS.
* win32_threads.c [I386] (GC_push_stack_for): Always store context.Esp
to sp (as the initial value).
* win32_threads.c (GC_push_stack_for): Use WoW64 workaround only
if WOW64_THREAD_CONTEXT_WORKAROUND (instead of I386).
* win32_threads.c (GC_thr_init): Set isWow64 only if
WOW64_THREAD_CONTEXT_WORKAROUND (instead of I386).

include/private/gcconfig.h
win32_threads.c

index d9935d89f125e99942f11b12bf3d6abe661bbd4e..21093b68c20d4d7f0c863c3554db56552905268c 100644 (file)
@@ -1543,6 +1543,7 @@ EXTERN_C_BEGIN
 #   endif
 #   ifdef CYGWIN32
 #       define OS_TYPE "CYGWIN32"
+#       define WOW64_THREAD_CONTEXT_WORKAROUND
 #       define DATASTART ((ptr_t)GC_DATASTART)  /* From gc.h */
 #       define DATAEND   ((ptr_t)GC_DATAEND)
 #       ifdef USE_WINALLOC
@@ -1576,6 +1577,7 @@ EXTERN_C_BEGIN
 #   endif
 #   ifdef MSWIN32
 #       define OS_TYPE "MSWIN32"
+#       define WOW64_THREAD_CONTEXT_WORKAROUND
                 /* STACKBOTTOM and DATASTART are handled specially in   */
                 /* os_dep.c.                                            */
 #       define MPROTECT_VDB
index f45e8c04458af6dec6ff04b5de70d20c57be2326..7fa14b930be38edc1cca59db425b379256b34194 100644 (file)
@@ -1222,6 +1222,21 @@ void GC_push_thread_structures(void)
 # endif
 }
 
+#ifdef WOW64_THREAD_CONTEXT_WORKAROUND
+# ifndef CONTEXT_EXCEPTION_ACTIVE
+#   define CONTEXT_EXCEPTION_ACTIVE    0x08000000
+#   define CONTEXT_EXCEPTION_REQUEST   0x40000000
+#   define CONTEXT_EXCEPTION_REPORTING 0x80000000
+# endif
+  static BOOL isWow64;  /* Is running 32-bit code on Win64?     */
+# define GET_THREAD_CONTEXT_FLAGS (isWow64 \
+                        ? CONTEXT_INTEGER | CONTEXT_CONTROL \
+                          | CONTEXT_EXCEPTION_REQUEST | CONTEXT_SEGMENTS \
+                        : CONTEXT_INTEGER | CONTEXT_CONTROL)
+#else
+# define GET_THREAD_CONTEXT_FLAGS (CONTEXT_INTEGER | CONTEXT_CONTROL)
+#endif /* !WOW64_THREAD_CONTEXT_WORKAROUND */
+
 /* Suspend the given thread, if it's still active.      */
 STATIC void GC_suspend(GC_thread t)
 {
@@ -1442,10 +1457,6 @@ static GC_bool may_be_in_stack(ptr_t s)
           && !(last_info.Protect & PAGE_GUARD);
 }
 
-#if defined(I386)
-  static BOOL isWow64;  /* Is running 32-bit code on Win64?     */
-#endif
-
 STATIC word GC_push_stack_for(GC_thread thread, DWORD me)
 {
   ptr_t sp, stack_min;
@@ -1459,22 +1470,8 @@ STATIC word GC_push_stack_for(GC_thread thread, DWORD me)
               /* Use saved sp value for blocked threads. */
     /* For unblocked threads call GetThreadContext().   */
     CONTEXT context;
-#   if defined(I386)
-#     ifndef CONTEXT_EXCEPTION_ACTIVE
-#       define CONTEXT_EXCEPTION_ACTIVE    0x08000000
-#       define CONTEXT_EXCEPTION_REQUEST   0x40000000
-#       define CONTEXT_EXCEPTION_REPORTING 0x80000000
-#     endif
 
-      if (isWow64) {
-        context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL
-                                | CONTEXT_EXCEPTION_REQUEST
-                                | CONTEXT_SEGMENTS;
-      } else
-#   endif
-    /* else */ {
-      context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
-    }
+    context.ContextFlags = GET_THREAD_CONTEXT_FLAGS;
     if (!GetThreadContext(THREAD_HANDLE(thread), &context))
       ABORT("GetThreadContext failed");
 
@@ -1486,6 +1483,47 @@ STATIC word GC_push_stack_for(GC_thread thread, DWORD me)
 #   define PUSH4(r1,r2,r3,r4) (PUSH2(r1,r2), PUSH2(r3,r4))
 #   if defined(I386)
       PUSH4(Edi,Esi,Ebx,Edx), PUSH2(Ecx,Eax), PUSH1(Ebp);
+      sp = (ptr_t)context.Esp;
+#   elif defined(X86_64)
+      PUSH4(Rax,Rcx,Rdx,Rbx); PUSH2(Rbp, Rsi); PUSH1(Rdi);
+      PUSH4(R8, R9, R10, R11); PUSH4(R12, R13, R14, R15);
+      sp = (ptr_t)context.Rsp;
+#   elif defined(ARM32)
+      PUSH4(R0,R1,R2,R3),PUSH4(R4,R5,R6,R7),PUSH4(R8,R9,R10,R11);
+      PUSH1(R12);
+      sp = (ptr_t)context.Sp;
+#   elif defined(AARCH64)
+      PUSH4(X0,X1,X2,X3),PUSH4(X4,X5,X6,X7),PUSH4(X8,X9,X10,X11);
+      PUSH4(X12,X13,X14,X15),PUSH4(X16,X17,X18,X19),PUSH4(X20,X21,X22,X23);
+      PUSH4(X24,X25,X26,X27),PUSH1(X28);
+      PUSH1(Lr);
+      sp = (ptr_t)context.Sp;
+#   elif defined(SHx)
+      PUSH4(R0,R1,R2,R3), PUSH4(R4,R5,R6,R7), PUSH4(R8,R9,R10,R11);
+      PUSH2(R12,R13), PUSH1(R14);
+      sp = (ptr_t)context.R15;
+#   elif defined(MIPS)
+      PUSH4(IntAt,IntV0,IntV1,IntA0), PUSH4(IntA1,IntA2,IntA3,IntT0);
+      PUSH4(IntT1,IntT2,IntT3,IntT4), PUSH4(IntT5,IntT6,IntT7,IntS0);
+      PUSH4(IntS1,IntS2,IntS3,IntS4), PUSH4(IntS5,IntS6,IntS7,IntT8);
+      PUSH4(IntT9,IntK0,IntK1,IntS8);
+      sp = (ptr_t)context.IntSp;
+#   elif defined(PPC)
+      PUSH4(Gpr0, Gpr3, Gpr4, Gpr5),  PUSH4(Gpr6, Gpr7, Gpr8, Gpr9);
+      PUSH4(Gpr10,Gpr11,Gpr12,Gpr14), PUSH4(Gpr15,Gpr16,Gpr17,Gpr18);
+      PUSH4(Gpr19,Gpr20,Gpr21,Gpr22), PUSH4(Gpr23,Gpr24,Gpr25,Gpr26);
+      PUSH4(Gpr27,Gpr28,Gpr29,Gpr30), PUSH1(Gpr31);
+      sp = (ptr_t)context.Gpr1;
+#   elif defined(ALPHA)
+      PUSH4(IntV0,IntT0,IntT1,IntT2), PUSH4(IntT3,IntT4,IntT5,IntT6);
+      PUSH4(IntT7,IntS0,IntS1,IntS2), PUSH4(IntS3,IntS4,IntS5,IntFp);
+      PUSH4(IntA0,IntA1,IntA2,IntA3), PUSH4(IntA4,IntA5,IntT8,IntT9);
+      PUSH4(IntT10,IntT11,IntT12,IntAt);
+      sp = (ptr_t)context.IntSp;
+#   elif !defined(CPPCHECK)
+#     error Architecture is not supported
+#   endif
+#   ifdef WOW64_THREAD_CONTEXT_WORKAROUND
       /* WoW64 workaround. */
       if (isWow64
           && (context.ContextFlags & CONTEXT_EXCEPTION_REPORTING) != 0
@@ -1526,58 +1564,18 @@ STATIC word GC_push_stack_for(GC_thread thread, DWORD me)
             /* while we are inside a coroutine.                         */
           }
         }
-      } else {
-#       ifdef DEBUG_THREADS
-          {
-            static GC_bool logged;
-            if (isWow64 && !logged
-                && (context.ContextFlags & CONTEXT_EXCEPTION_REPORTING) == 0) {
-              GC_log_printf("CONTEXT_EXCEPTION_REQUEST not supported\n");
-              logged = TRUE;
-            }
+      } /* else */
+#     ifdef DEBUG_THREADS
+        else {
+          static GC_bool logged;
+          if (isWow64 && !logged
+              && (context.ContextFlags & CONTEXT_EXCEPTION_REPORTING) == 0) {
+            GC_log_printf("CONTEXT_EXCEPTION_REQUEST not supported\n");
+            logged = TRUE;
           }
-#       endif
-        sp = (ptr_t)context.Esp;
-      }
-#   elif defined(X86_64)
-      PUSH4(Rax,Rcx,Rdx,Rbx); PUSH2(Rbp, Rsi); PUSH1(Rdi);
-      PUSH4(R8, R9, R10, R11); PUSH4(R12, R13, R14, R15);
-      sp = (ptr_t)context.Rsp;
-#   elif defined(ARM32)
-      PUSH4(R0,R1,R2,R3),PUSH4(R4,R5,R6,R7),PUSH4(R8,R9,R10,R11);
-      PUSH1(R12);
-      sp = (ptr_t)context.Sp;
-#   elif defined(AARCH64)
-      PUSH4(X0,X1,X2,X3),PUSH4(X4,X5,X6,X7),PUSH4(X8,X9,X10,X11);
-      PUSH4(X12,X13,X14,X15),PUSH4(X16,X17,X18,X19),PUSH4(X20,X21,X22,X23);
-      PUSH4(X24,X25,X26,X27),PUSH1(X28);
-      PUSH1(Lr);
-      sp = (ptr_t)context.Sp;
-#   elif defined(SHx)
-      PUSH4(R0,R1,R2,R3), PUSH4(R4,R5,R6,R7), PUSH4(R8,R9,R10,R11);
-      PUSH2(R12,R13), PUSH1(R14);
-      sp = (ptr_t)context.R15;
-#   elif defined(MIPS)
-      PUSH4(IntAt,IntV0,IntV1,IntA0), PUSH4(IntA1,IntA2,IntA3,IntT0);
-      PUSH4(IntT1,IntT2,IntT3,IntT4), PUSH4(IntT5,IntT6,IntT7,IntS0);
-      PUSH4(IntS1,IntS2,IntS3,IntS4), PUSH4(IntS5,IntS6,IntS7,IntT8);
-      PUSH4(IntT9,IntK0,IntK1,IntS8);
-      sp = (ptr_t)context.IntSp;
-#   elif defined(PPC)
-      PUSH4(Gpr0, Gpr3, Gpr4, Gpr5),  PUSH4(Gpr6, Gpr7, Gpr8, Gpr9);
-      PUSH4(Gpr10,Gpr11,Gpr12,Gpr14), PUSH4(Gpr15,Gpr16,Gpr17,Gpr18);
-      PUSH4(Gpr19,Gpr20,Gpr21,Gpr22), PUSH4(Gpr23,Gpr24,Gpr25,Gpr26);
-      PUSH4(Gpr27,Gpr28,Gpr29,Gpr30), PUSH1(Gpr31);
-      sp = (ptr_t)context.Gpr1;
-#   elif defined(ALPHA)
-      PUSH4(IntV0,IntT0,IntT1,IntT2), PUSH4(IntT3,IntT4,IntT5,IntT6);
-      PUSH4(IntT7,IntS0,IntS1,IntS2), PUSH4(IntS3,IntS4,IntS5,IntFp);
-      PUSH4(IntA0,IntA1,IntA2,IntA3), PUSH4(IntA4,IntA5,IntT8,IntT9);
-      PUSH4(IntT10,IntT11,IntT12,IntAt);
-      sp = (ptr_t)context.IntSp;
-#   elif !defined(CPPCHECK)
-#     error Architecture is not supported
-#   endif
+        }
+#     endif
+#   endif /* WOW64_THREAD_CONTEXT_WORKAROUND */
   } /* ! current thread */
 
   /* Set stack_min to the lowest address in the thread stack,   */
@@ -2576,7 +2574,7 @@ GC_INNER void GC_thr_init(void)
     }
 # endif
 
-# if defined(I386)
+# ifdef WOW64_THREAD_CONTEXT_WORKAROUND
     /* Set isWow64 flag. */
     {
       HMODULE hK32 = GetModuleHandle(TEXT("kernel32.dll"));