summaryrefslogtreecommitdiff
path: root/win32_threads.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2019-09-05 11:44:27 +0300
committerIvan Maidanski <ivmai@mail.ru>2019-09-05 11:44:27 +0300
commit5ff5ddaa6fc077c15e83c7076835a530b716e4a3 (patch)
treecee129fb63d38db2c017e57997e7646f381d61f0 /win32_threads.c
parent0cd8caff0ac9542a16aea5f8a020358bc9630def (diff)
downloadbdwgc-5ff5ddaa6fc077c15e83c7076835a530b716e4a3.tar.gz
Refactoring of WoW64 workaround (Win32)
(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).
Diffstat (limited to 'win32_threads.c')
-rw-r--r--win32_threads.c140
1 files changed, 69 insertions, 71 deletions
diff --git a/win32_threads.c b/win32_threads.c
index f45e8c04..7fa14b93 100644
--- a/win32_threads.c
+++ b/win32_threads.c
@@ -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"));