On 64 bit, only create new thread stack if started from 32 bit process on affected platforms
* dcrt0.cc (dll_crt0_0): On 64 bit, set wow64_needs_stack_adjustment if not started from a 64 bit process. (_dll_crt0): Enable wow64_needs_stack_adjustment branch on 64 bit as well. Remove 64 bit only code. Introduce CREATE_STACK and FIX_STACK macros to conditionalize the code. Rearrange and partially rewrite comments. * wincap.h (wincaps::has_3264_stack_broken): New element. * wincap.cc: Implement above element throughout. (wincapc::init): Set has_3264_stack_broken to false on 32 bit. * wow64.cc: Enable functionality on 64 bit architecture, except for wow64_revert_to_original_stack. Enhance comments to explain. (wow64_eval_expected_main_stack): Make 64 bit clean. (wow64_test_for_64bit_parent): Ditto. * wow64.h: Export wow64_revert_to_original_stack on 32 bit only, everything else on all architectures. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
8f4da28eb6
commit
12743c2d5d
|
@ -1,3 +1,21 @@
|
||||||
|
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* dcrt0.cc (dll_crt0_0): On 64 bit, set wow64_needs_stack_adjustment
|
||||||
|
if not started from a 64 bit process.
|
||||||
|
(_dll_crt0): Enable wow64_needs_stack_adjustment branch on 64 bit
|
||||||
|
as well. Remove 64 bit only code. Introduce CREATE_STACK and
|
||||||
|
FIX_STACK macros to conditionalize the code. Rearrange and
|
||||||
|
partially rewrite comments.
|
||||||
|
* wincap.h (wincaps::has_3264_stack_broken): New element.
|
||||||
|
* wincap.cc: Implement above element throughout.
|
||||||
|
(wincapc::init): Set has_3264_stack_broken to false on 32 bit.
|
||||||
|
* wow64.cc: Enable functionality on 64 bit architecture, except for
|
||||||
|
wow64_revert_to_original_stack. Enhance comments to explain.
|
||||||
|
(wow64_eval_expected_main_stack): Make 64 bit clean.
|
||||||
|
(wow64_test_for_64bit_parent): Ditto.
|
||||||
|
* wow64.h: Export wow64_revert_to_original_stack on 32 bit only,
|
||||||
|
everything else on all architectures.
|
||||||
|
|
||||||
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
|
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_process.cc (thread_info::thread_info): Accommodate the fact
|
* fhandler_process.cc (thread_info::thread_info): Accommodate the fact
|
||||||
|
|
|
@ -782,6 +782,11 @@ dll_crt0_0 ()
|
||||||
description in wow64_test_for_64bit_parent. */
|
description in wow64_test_for_64bit_parent. */
|
||||||
if (wincap.wow64_has_secondary_stack ())
|
if (wincap.wow64_has_secondary_stack ())
|
||||||
wow64_needs_stack_adjustment = wow64_test_for_64bit_parent ();
|
wow64_needs_stack_adjustment = wow64_test_for_64bit_parent ();
|
||||||
|
#else
|
||||||
|
/* Windows 10 1511 has a stack move when a 64 bit process is started from
|
||||||
|
a 32 bit process, just as it was vice versa in XP/2003. */
|
||||||
|
if (wincap.has_3264_stack_broken ())
|
||||||
|
wow64_needs_stack_adjustment = !wow64_test_for_64bit_parent ();
|
||||||
#endif /* !__x86_64__ */
|
#endif /* !__x86_64__ */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1062,67 +1067,50 @@ __cygwin_exit_return: \n\
|
||||||
extern "C" void __stdcall
|
extern "C" void __stdcall
|
||||||
_dll_crt0 ()
|
_dll_crt0 ()
|
||||||
{
|
{
|
||||||
#ifndef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
/* Handle 64 bit process on Windows 10 rel 1511 which has been started from
|
||||||
|
32 bit WOW64 process. See comment in wow64_test_for_64bit_parent for a
|
||||||
|
problem description. Unfortunately the areas the stacks would have to
|
||||||
|
be moved to are both taken by "something else"(tm) in both, forker and
|
||||||
|
forkee, so we can't use the wow64_revert_to_original_stack method as in
|
||||||
|
the 32 bit case. Rather, we move the main thread stack to the stack area
|
||||||
|
reserved for pthread stacks for this process. */
|
||||||
|
#define CREATE_STACK(a) create_new_main_thread_stack(a)
|
||||||
|
#define FIX_STACK(s) __asm__ ("\n" \
|
||||||
|
"movq %[ADDR], %%rsp \n" \
|
||||||
|
"movq %%rsp, %%rbp \n" \
|
||||||
|
: : [ADDR] "r" (s))
|
||||||
|
#else
|
||||||
/* Handle WOW64 process on XP/2K3 which has been started from native 64 bit
|
/* Handle WOW64 process on XP/2K3 which has been started from native 64 bit
|
||||||
process. See comment in wow64_test_for_64bit_parent for a full problem
|
process. See comment in wow64_test_for_64bit_parent for a full problem
|
||||||
description. */
|
description. */
|
||||||
|
#define CREATE_STACK(a) wow64_revert_to_original_stack(a)
|
||||||
|
#define FIX_STACK(s) __asm__ ("\n" \
|
||||||
|
"movl %[ADDR], %%esp \n" \
|
||||||
|
"xorl %%ebp, %%ebp \n" \
|
||||||
|
: : [ADDR] "r" (s))
|
||||||
|
#endif
|
||||||
if (wow64_needs_stack_adjustment && !dynamically_loaded)
|
if (wow64_needs_stack_adjustment && !dynamically_loaded)
|
||||||
{
|
{
|
||||||
/* Must be static since it's referenced after the stack and frame
|
/* Must be static since it's referenced after the stack and frame
|
||||||
pointer registers have been changed. */
|
pointer registers have been changed. */
|
||||||
static PVOID allocationbase = 0;
|
static PVOID allocationbase;
|
||||||
|
|
||||||
/* Check if we just move the stack. If so, wow64_revert_to_original_stack
|
PVOID stackaddr = CREATE_STACK (allocationbase);
|
||||||
returns a non-NULL, 16 byte aligned address. See comments in
|
|
||||||
wow64_revert_to_original_stack for the gory details. */
|
|
||||||
PVOID stackaddr = wow64_revert_to_original_stack (allocationbase);
|
|
||||||
if (stackaddr)
|
if (stackaddr)
|
||||||
{
|
{
|
||||||
/* 2nd half of the stack move. Set stack pointer to new address.
|
/* 2nd half of the stack move. Set stack pointer to new address.
|
||||||
Set frame pointer to 0. */
|
Set frame pointer to 0. */
|
||||||
__asm__ ("\n\
|
FIX_STACK (stackaddr);
|
||||||
movl %[ADDR], %%esp \n\
|
|
||||||
xorl %%ebp, %%ebp \n"
|
|
||||||
: : [ADDR] "r" (stackaddr));
|
|
||||||
/* Now we're back on the original stack. Free up space taken by the
|
/* Now we're back on the original stack. Free up space taken by the
|
||||||
former main thread stack and set DeallocationStack correctly. */
|
former main thread stack and set DeallocationStack correctly. */
|
||||||
VirtualFree (NtCurrentTeb ()->DeallocationStack, 0, MEM_RELEASE);
|
VirtualFree (NtCurrentTeb ()->DeallocationStack, 0, MEM_RELEASE);
|
||||||
NtCurrentTeb ()->DeallocationStack = allocationbase;
|
NtCurrentTeb ()->DeallocationStack = allocationbase;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Fall back to respawn if wow64_revert_to_original_stack fails. */
|
/* Fall back to respawning if creating a new stack fails. */
|
||||||
wow64_respawn_process ();
|
wow64_respawn_process ();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
/* Starting with Windows 10 rel 1511, the main stack of an application is
|
|
||||||
not reproducible if a 64 bit process has been started from a 32 bit
|
|
||||||
process. Given that we have enough virtual address space on 64 bit
|
|
||||||
anyway, we now move the main thread stack to the stack area reserved for
|
|
||||||
pthread stacks. This allows a reproducible stack space under our own
|
|
||||||
control and avoids collision with the OS. */
|
|
||||||
if (!in_forkee && !dynamically_loaded)
|
|
||||||
{
|
|
||||||
/* Must be static since it's referenced after the stack and frame
|
|
||||||
pointer registers have been changed. */
|
|
||||||
static PVOID allocationbase;
|
|
||||||
|
|
||||||
PVOID stackaddr = create_new_main_thread_stack (allocationbase);
|
|
||||||
if (stackaddr)
|
|
||||||
{
|
|
||||||
/* 2nd half of the stack move. Set stack pointer to new address.
|
|
||||||
Don't set frame pointer to 0 since x86_64 uses the stack while
|
|
||||||
evaluating NtCurrentTeb (). */
|
|
||||||
__asm__ ("\n\
|
|
||||||
movq %[ADDR], %%rsp \n\
|
|
||||||
movq %%rsp, %%rbp \n"
|
|
||||||
: : [ADDR] "r" (stackaddr));
|
|
||||||
/* Now we're back on the new stack. Free up space taken by the
|
|
||||||
former main thread stack and set DeallocationStack correctly. */
|
|
||||||
VirtualFree (NtCurrentTeb ()->DeallocationStack, 0, MEM_RELEASE);
|
|
||||||
NtCurrentTeb ()->DeallocationStack = allocationbase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* !__x86_64__ */
|
|
||||||
_feinitialise ();
|
_feinitialise ();
|
||||||
#ifndef __x86_64__
|
#ifndef __x86_64__
|
||||||
main_environ = user_data->envptr;
|
main_environ = user_data->envptr;
|
||||||
|
|
|
@ -52,6 +52,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_3264_stack_broken:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -86,6 +87,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_3264_stack_broken:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -120,6 +122,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_3264_stack_broken:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -154,6 +157,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_3264_stack_broken:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -188,6 +192,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_3264_stack_broken:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -222,6 +227,7 @@ wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
has_broken_prefetchvm:true,
|
has_broken_prefetchvm:true,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_3264_stack_broken:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -256,6 +262,7 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) =
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:true,
|
has_new_pebteb_region:true,
|
||||||
|
has_3264_stack_broken:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
|
@ -320,6 +327,10 @@ wincapc::init ()
|
||||||
target process on 64 bit XP/2003 in native 64 bit mode only. Reset the
|
target process on 64 bit XP/2003 in native 64 bit mode only. Reset the
|
||||||
flag here for 32 bit. */
|
flag here for 32 bit. */
|
||||||
((wincaps *)caps)->has_broken_rtl_query_process_debug_information = false;
|
((wincaps *)caps)->has_broken_rtl_query_process_debug_information = false;
|
||||||
|
/* Windows 10 1511 has a stack move when a 64 bit process is started from
|
||||||
|
a 32 bit process, just as it was vice versa in XP/2003. Reset the flag
|
||||||
|
here for 32 bit. */
|
||||||
|
((wincaps *)caps)->has_3264_stack_broken = false;
|
||||||
if (NT_SUCCESS (NtQueryInformationProcess (NtCurrentProcess (),
|
if (NT_SUCCESS (NtQueryInformationProcess (NtCurrentProcess (),
|
||||||
ProcessWow64Information,
|
ProcessWow64Information,
|
||||||
&wow64, sizeof wow64, NULL))
|
&wow64, sizeof wow64, NULL))
|
||||||
|
|
|
@ -45,6 +45,7 @@ struct wincaps
|
||||||
unsigned has_processor_groups : 1;
|
unsigned has_processor_groups : 1;
|
||||||
unsigned has_broken_prefetchvm : 1;
|
unsigned has_broken_prefetchvm : 1;
|
||||||
unsigned has_new_pebteb_region : 1;
|
unsigned has_new_pebteb_region : 1;
|
||||||
|
unsigned has_3264_stack_broken : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
|
@ -104,6 +105,7 @@ public:
|
||||||
bool IMPLEMENT (has_processor_groups)
|
bool IMPLEMENT (has_processor_groups)
|
||||||
bool IMPLEMENT (has_broken_prefetchvm)
|
bool IMPLEMENT (has_broken_prefetchvm)
|
||||||
bool IMPLEMENT (has_new_pebteb_region)
|
bool IMPLEMENT (has_new_pebteb_region)
|
||||||
|
bool IMPLEMENT (has_3264_stack_broken)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#undef IMPLEMENT
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,10 +8,6 @@ This software is a copyrighted work licensed under the terms of the
|
||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#ifndef __x86_64__
|
|
||||||
/* WOW64 only plays a role in the 32 bit version. Don't use any of this
|
|
||||||
in the 64 bit version. */
|
|
||||||
|
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
|
@ -25,11 +21,11 @@ static void
|
||||||
wow64_eval_expected_main_stack (PVOID &allocbase, PVOID &stackbase)
|
wow64_eval_expected_main_stack (PVOID &allocbase, PVOID &stackbase)
|
||||||
{
|
{
|
||||||
PIMAGE_DOS_HEADER dosheader;
|
PIMAGE_DOS_HEADER dosheader;
|
||||||
PIMAGE_NT_HEADERS32 ntheader;
|
PIMAGE_NT_HEADERS ntheader;
|
||||||
DWORD size;
|
SIZE_T size;
|
||||||
|
|
||||||
dosheader = (PIMAGE_DOS_HEADER) GetModuleHandle (NULL);
|
dosheader = (PIMAGE_DOS_HEADER) GetModuleHandle (NULL);
|
||||||
ntheader = (PIMAGE_NT_HEADERS32) ((PBYTE) dosheader + dosheader->e_lfanew);
|
ntheader = (PIMAGE_NT_HEADERS) ((PBYTE) dosheader + dosheader->e_lfanew);
|
||||||
/* The main thread stack is expected to be located at 0x30000, which is the
|
/* The main thread stack is expected to be located at 0x30000, which is the
|
||||||
case for all observed NT systems up to Server 2003 R2, unless the
|
case for all observed NT systems up to Server 2003 R2, unless the
|
||||||
stacksize requested by the StackReserve field in the PE/COFF header is
|
stacksize requested by the StackReserve field in the PE/COFF header is
|
||||||
|
@ -41,8 +37,15 @@ wow64_eval_expected_main_stack (PVOID &allocbase, PVOID &stackbase)
|
||||||
stack address on Vista/2008 64 bit is 0x80000 and on W7/2K8R2 64 bit
|
stack address on Vista/2008 64 bit is 0x80000 and on W7/2K8R2 64 bit
|
||||||
it is 0x90000. However, this is no problem because the system sticks
|
it is 0x90000. However, this is no problem because the system sticks
|
||||||
to that address for all WOW64 processes, not only for the first one
|
to that address for all WOW64 processes, not only for the first one
|
||||||
started from a 64 bit parent. */
|
started from a 64 bit parent.
|
||||||
|
|
||||||
|
On 64 bit W10 1511 the stack starts at 0x400000 by default. See comment
|
||||||
|
in wow64_test_for_64bit_parent. */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
allocbase = (PVOID) 0x400000;
|
||||||
|
#else
|
||||||
allocbase = (PVOID) 0x30000;
|
allocbase = (PVOID) 0x30000;
|
||||||
|
#endif
|
||||||
/* Stack size. The OS always rounds the size up to allocation granularity
|
/* Stack size. The OS always rounds the size up to allocation granularity
|
||||||
and it never allocates less than 256K. */
|
and it never allocates less than 256K. */
|
||||||
size = roundup2 (ntheader->OptionalHeader.SizeOfStackReserve,
|
size = roundup2 (ntheader->OptionalHeader.SizeOfStackReserve,
|
||||||
|
@ -71,11 +74,19 @@ wow64_test_for_64bit_parent ()
|
||||||
we have to "alloc_stack_hard_way". However, this fails in almost all
|
we have to "alloc_stack_hard_way". However, this fails in almost all
|
||||||
cases because the stack slot of the parent process is taken by something
|
cases because the stack slot of the parent process is taken by something
|
||||||
else in the child process.
|
else in the child process.
|
||||||
What we do here is to check if the current stack is the excpected main
|
What we do here is to check if the current stack is the expected main
|
||||||
thread stack and if not, if we really have been started from a 64 bit
|
thread stack and if not, if we really have been started from a 64 bit
|
||||||
process here. If so, we note this fact in wow64_needs_stack_adjustment
|
process here. If so, we note this fact in wow64_needs_stack_adjustment
|
||||||
so we can workaround the stack problem in _dll_crt0. See there for how
|
so we can workaround the stack problem in _dll_crt0. See there for how
|
||||||
we go along. */
|
we go along. */
|
||||||
|
|
||||||
|
/* Amazing but true: Starting with Windows 10 1511 this problem has been
|
||||||
|
reintroduced, just in the opposite direction: If a 64 bit process is
|
||||||
|
created from a 32 bit WOW64 process, the main thread stack in the 64
|
||||||
|
bit child gets moved to another location than the default. In the
|
||||||
|
forked child, the stack is back where it usually is when started from
|
||||||
|
another 64 bit process. Therefore we have to be able to recognize
|
||||||
|
this scenarion now on 64 bit as well. We I don't believe it... */
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
PROCESS_BASIC_INFORMATION pbi;
|
PROCESS_BASIC_INFORMATION pbi;
|
||||||
HANDLE parent;
|
HANDLE parent;
|
||||||
|
@ -86,7 +97,7 @@ wow64_test_for_64bit_parent ()
|
||||||
/* First check if the current stack is where it belongs. If so, we don't
|
/* First check if the current stack is where it belongs. If so, we don't
|
||||||
have to do anything special. This is the case on Vista and later. */
|
have to do anything special. This is the case on Vista and later. */
|
||||||
wow64_eval_expected_main_stack (allocbase, stackbase);
|
wow64_eval_expected_main_stack (allocbase, stackbase);
|
||||||
if (&wow64 >= (PULONG) allocbase && &wow64 < (PULONG) stackbase)
|
if (&wow64 >= (PULONG_PTR) allocbase && &wow64 < (PULONG_PTR) stackbase)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Check if the parent is a native 64 bit process. Unfortunately there's
|
/* Check if the parent is a native 64 bit process. Unfortunately there's
|
||||||
|
@ -107,6 +118,8 @@ wow64_test_for_64bit_parent ()
|
||||||
return !wow64;
|
return !wow64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
wow64_revert_to_original_stack (PVOID &allocationbase)
|
wow64_revert_to_original_stack (PVOID &allocationbase)
|
||||||
{
|
{
|
||||||
|
@ -177,6 +190,8 @@ wow64_revert_to_original_stack (PVOID &allocationbase)
|
||||||
return PTR_ADD (NtCurrentTeb()->Tib.StackBase, -16);
|
return PTR_ADD (NtCurrentTeb()->Tib.StackBase, -16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* !__x86_64__ */
|
||||||
|
|
||||||
/* Respawn WOW64 process. This is only called if we can't reuse the original
|
/* Respawn WOW64 process. This is only called if we can't reuse the original
|
||||||
stack. See comment in wow64_revert_to_original_stack for details. See
|
stack. See comment in wow64_revert_to_original_stack for details. See
|
||||||
_dll_crt0 for the call of this function.
|
_dll_crt0 for the call of this function.
|
||||||
|
@ -211,5 +226,3 @@ wow64_respawn_process ()
|
||||||
TerminateProcess (GetCurrentProcess (), ret);
|
TerminateProcess (GetCurrentProcess (), ret);
|
||||||
ExitProcess (ret);
|
ExitProcess (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__x86_64__ */
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* wow64.h
|
/* wow64.h
|
||||||
|
|
||||||
Copyright 2011, 2012 Red Hat, Inc.
|
Copyright 2011, 2012, 2015 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -8,14 +8,12 @@ This software is a copyrighted work licensed under the terms of the
|
||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#ifndef __x86_64__
|
|
||||||
/* WOW64 only plays a role in the 32 bit version. Don't use any of this
|
|
||||||
in the 64 bit version. */
|
|
||||||
|
|
||||||
extern bool NO_COPY wow64_needs_stack_adjustment;
|
extern bool NO_COPY wow64_needs_stack_adjustment;
|
||||||
|
|
||||||
extern bool wow64_test_for_64bit_parent ();
|
extern bool wow64_test_for_64bit_parent ();
|
||||||
extern PVOID wow64_revert_to_original_stack (PVOID &allocationbase);
|
|
||||||
extern void wow64_respawn_process () __attribute__ ((noreturn));
|
extern void wow64_respawn_process () __attribute__ ((noreturn));
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
|
|
||||||
|
extern PVOID wow64_revert_to_original_stack (PVOID &allocationbase);
|
||||||
|
|
||||||
#endif /* !__x86_64__ */
|
#endif /* !__x86_64__ */
|
||||||
|
|
Loading…
Reference in New Issue