* dcrt0.cc (dll_crt0_0): Remove call to wincap.init.

* init.cc (dll_entry): Rename is_wow64_proc to wow64_test_stack_marker.
	Call wincap.init here before doing anything else.  Use wincap.is_wow64
	to determine if we're running in a WOW64 emulator.
	* mmap.cc (MapViewNT): Don't use AT_ROUND_TO_PAGE in WOW64, it's
	apparently not supported.
	(mmap64): Don't create mappings beyond EOF, which would need to use
	AT_ROUND_TO_PAGE, on WOW64.
	* wincap.cc (wincap): Throw into the .cygwin_dll_common section.
	(wincapc::init): Determine if running in WOW64 and set wow_64 flag.
	* wincap.h (class wincapc): Add wow64 member.
	(wincapc::is_wow64): New method.
This commit is contained in:
Corinna Vinschen 2006-01-10 18:11:32 +00:00
parent dea958bc06
commit b773a592d3
6 changed files with 38 additions and 12 deletions

View File

@ -1,3 +1,18 @@
2006-01-10 Corinna Vinschen <corinna@vinschen.de>
* dcrt0.cc (dll_crt0_0): Remove call to wincap.init.
* init.cc (dll_entry): Rename is_wow64_proc to wow64_test_stack_marker.
Call wincap.init here before doing anything else. Use wincap.is_wow64
to determine if we're running in a WOW64 emulator.
* mmap.cc (MapViewNT): Don't use AT_ROUND_TO_PAGE in WOW64, it's
apparently not supported.
(mmap64): Don't create mappings beyond EOF, which would need to use
AT_ROUND_TO_PAGE, on WOW64.
* wincap.cc (wincap): Throw into the .cygwin_dll_common section.
(wincapc::init): Determine if running in WOW64 and set wow_64 flag.
* wincap.h (class wincapc): Add wow64 member.
(wincapc::is_wow64): New method.
2006-01-10 Christopher Faylor <cgf@timesys.com> 2006-01-10 Christopher Faylor <cgf@timesys.com>
* fhandler_proc.cc (format_proc_cpuinfo): Avoid leading whitespace in * fhandler_proc.cc (format_proc_cpuinfo): Avoid leading whitespace in

View File

@ -680,7 +680,6 @@ dll_crt0_0 ()
_impure_ptr->_current_locale = "C"; _impure_ptr->_current_locale = "C";
user_data->impure_ptr = _impure_ptr; user_data->impure_ptr = _impure_ptr;
user_data->impure_ptr_ptr = &_impure_ptr; user_data->impure_ptr_ptr = &_impure_ptr;
wincap.init ();
initial_env (); initial_env ();
mmap_init (); mmap_init ();

View File

@ -143,7 +143,7 @@ HMODULE NO_COPY cygwin_hmodule;
extern "C" BOOL WINAPI extern "C" BOOL WINAPI
dll_entry (HANDLE h, DWORD reason, void *static_load) dll_entry (HANDLE h, DWORD reason, void *static_load)
{ {
BOOL is_wow64_proc = FALSE; BOOL wow64_test_stack_marker;
// _STRACE_ON; // _STRACE_ON;
switch (reason) switch (reason)
@ -152,15 +152,16 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
cygwin_hmodule = (HMODULE) h; cygwin_hmodule = (HMODULE) h;
dynamically_loaded = (static_load == NULL); dynamically_loaded = (static_load == NULL);
wincap.init ();
/* Is the stack at an unusual address? This is, an address which /* Is the stack at an unusual address? This is, an address which
is in the usual space occupied by the process image, but below is in the usual space occupied by the process image, but below
the auto load address of DLLs? the auto load address of DLLs?
Check if we're running in WOW64 on a 64 bit machine *and* are Check if we're running in WOW64 on a 64 bit machine *and* are
spawned by a genuine 64 bit process. If so, respawn. */ spawned by a genuine 64 bit process. If so, respawn. */
if (&is_wow64_proc >= (PBOOL) 0x400000 if (wincap.is_wow64 ()
&& &is_wow64_proc <= (PBOOL) 0x10000000 && &wow64_test_stack_marker >= (PBOOL) 0x400000
&& IsWow64Process (GetCurrentProcess (), &is_wow64_proc) && &wow64_test_stack_marker <= (PBOOL) 0x10000000)
&& is_wow64_proc)
respawn_wow64_process (); respawn_wow64_process ();
dll_crt0_0 (); dll_crt0_0 ();

View File

@ -350,7 +350,7 @@ MapViewNT (HANDLE h, void *addr, size_t len, DWORD openflags,
void *base = addr; void *base = addr;
ULONG commitsize = attached (prot) ? 0 : len; ULONG commitsize = attached (prot) ? 0 : len;
ULONG viewsize = len; ULONG viewsize = len;
ULONG alloc_type = base ? AT_ROUND_TO_PAGE : 0; ULONG alloc_type = base && !wincap.is_wow64 () ? AT_ROUND_TO_PAGE : 0;
/* Try mapping using the given address first, even if it's NULL. /* Try mapping using the given address first, even if it's NULL.
If it failed, and addr was not NULL and flags is not MAP_FIXED, If it failed, and addr was not NULL and flags is not MAP_FIXED,
@ -1109,8 +1109,13 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
anonymous pages. That's not possible on 9x for two reasons. anonymous pages. That's not possible on 9x for two reasons.
It neither allows to create reserved pages in the shared memory It neither allows to create reserved pages in the shared memory
area, nor does it allow to create page aligend mappings (in area, nor does it allow to create page aligend mappings (in
contrast to granularity aligned mappings). */ contrast to granularity aligned mappings).
Note that this isn't done in WOW64 environments since apparently
WOW64 does not support the AT_ROUND_TO_PAGE flag which is required
to get this right. Too bad. */
if (wincap.virtual_protect_works_on_shared_pages () if (wincap.virtual_protect_works_on_shared_pages ()
&& !wincap.is_wow64 ()
&& ((len > fsiz && !autogrow (flags)) && ((len > fsiz && !autogrow (flags))
|| len < pagesize)) || len < pagesize))
orig_len = len; orig_len = len;
@ -1177,9 +1182,9 @@ go_ahead:
protection as the file's pages, then as much pages as necessary protection as the file's pages, then as much pages as necessary
to accomodate the requested length, but as reserved pages which to accomodate the requested length, but as reserved pages which
raise a SIGBUS when trying to access them. AT_ROUND_TO_PAGE raise a SIGBUS when trying to access them. AT_ROUND_TO_PAGE
and page protection on shared pages is only supported by NT, so and page protection on shared pages is only supported by 32 bit NT,
don't even try on 9x. This is accomplished by not setting so don't even try on 9x and in WOW64. This is accomplished by not
orig_len on 9x above. */ setting orig_len on 9x and in WOW64 above. */
orig_len = roundup2 (orig_len, pagesize); orig_len = roundup2 (orig_len, pagesize);
len = roundup2 (len, getsystempagesize ()); len = roundup2 (len, getsystempagesize ());
if (orig_len - len) if (orig_len - len)

View File

@ -713,7 +713,7 @@ static NO_COPY wincaps wincap_vista = {
has_working_virtual_lock:true has_working_virtual_lock:true
}; };
wincapc wincap; wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
void void
wincapc::init () wincapc::init ()
@ -820,6 +820,10 @@ wincapc::init ()
((wincaps *)this->caps)->is_server = true; ((wincaps *)this->caps)->is_server = true;
} }
BOOL is_wow64_proc = FALSE;
if (IsWow64Process (GetCurrentProcess (), &is_wow64_proc))
wow64 = is_wow64_proc;
__small_sprintf (osnam, "%s-%d.%d", os, version.dwMajorVersion, __small_sprintf (osnam, "%s-%d.%d", os, version.dwMajorVersion,
version.dwMinorVersion); version.dwMinorVersion);
} }

View File

@ -70,6 +70,7 @@ class wincapc
{ {
OSVERSIONINFOEX version; OSVERSIONINFOEX version;
char osnam[40]; char osnam[40];
bool wow64;
void *caps; void *caps;
public: public:
@ -78,6 +79,7 @@ public:
void set_chunksize (DWORD nchunksize); void set_chunksize (DWORD nchunksize);
const char *osname () const { return osnam; } const char *osname () const { return osnam; }
const bool is_wow64 () const { return wow64; }
#define IMPLEMENT(cap) cap() const { return ((wincaps *) this->caps)->cap; } #define IMPLEMENT(cap) cap() const { return ((wincaps *) this->caps)->cap; }