diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2019-09-05 11:44:27 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2019-09-05 11:44:27 +0300 |
commit | 5ff5ddaa6fc077c15e83c7076835a530b716e4a3 (patch) | |
tree | cee129fb63d38db2c017e57997e7646f381d61f0 /win32_threads.c | |
parent | 0cd8caff0ac9542a16aea5f8a020358bc9630def (diff) | |
download | bdwgc-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.c | 140 |
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")); |