Steffen Prohaska wrote:
> 2) The msys-dll from CVS does not work on Vista, independently
> of my changes to the argument mangling function.
>
The Vista patch for msys-dll is not yet in CVS (my fault), but is
present in the source tarball. You can also find it as patch4.txt at the
end of the following page (I will attach it to this message as well for
your convenience).
http://sourceforge.net/tracker/index.php?func=detail&aid=1674783&group_id=2435&atid=102435
So, you could either rebase your mangling patch onto the source tarball
for msys-1.0.11-20071204 or apply the Vista patch over your work.
Regards,
Cesar Strauss
2007-07-28 Cesar Strauss <[EMAIL PROTECTED]>
Work around a bug in Vista 64 which failed to copy the child_info
structure properly. Thanks to: Oscar Bonilla, jdrasch and madwizard.
* autoload.cc (IsWow64Process): Add auto-load function.
* child_info.h (child_info::msv_count): Rename from "zero".
(child_info_spawn::filler): Add filler bytes.
(child_info_fork::filler): Ditto.
(init_child_info): Add new parameter.
* dcrt0.cc (_dll_crt0): Remove "zero" check.
(set_os_type): Detect Vista WOW64.
* sigproc.cc (init_child_info): Add new parameter.
Initialize msv_count.
* fork.cc (fork_parent): Adjust cbReserved2 not to take the filler
bytes into account. Pass the structure size to init_child_info.
* spawn.cc (spawn_guts): Ditto
* winsup.h (isVistaWOW64): Add new flag.
Index: src/winsup/cygwin/autoload.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/autoload.cc,v
retrieving revision 1.4
diff -u -3 -p -r1.4 autoload.cc
--- src/winsup/cygwin/autoload.cc 18 Apr 2003 12:16:47 -0000 1.4
+++ src/winsup/cygwin/autoload.cc 28 Jul 2007 18:54:56 -0000
@@ -505,6 +505,7 @@ LoadDLLfuncEx (GetConsoleWindow, 0, kern
LoadDLLfuncEx (GetSystemTimes, 12, kernel32, 1)
LoadDLLfuncEx2 (IsDebuggerPresent, 0, kernel32, 1, 1)
LoadDLLfunc (IsProcessorFeaturePresent, 4, kernel32);
+LoadDLLfuncEx (IsWow64Process, 8, kernel32, 1);
LoadDLLfuncEx (Process32First, 8, kernel32, 1)
LoadDLLfuncEx (Process32Next, 8, kernel32, 1)
LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1)
Index: src/winsup/cygwin/child_info.h
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/child_info.h,v
retrieving revision 1.2
diff -u -3 -p -r1.2 child_info.h
--- src/winsup/cygwin/child_info.h 15 Oct 2001 22:22:32 -0000 1.2
+++ src/winsup/cygwin/child_info.h 28 Jul 2007 18:54:56 -0000
@@ -29,7 +29,7 @@ enum
class child_info
{
public:
- DWORD zero[1]; // must be zeroed
+ DWORD msv_count; // zeroed on < W2K3, set to pseudo-count on Vista 64
DWORD cb; // size of this record
DWORD type; // type of record
int cygpid; // cygwin pid of child process
@@ -53,6 +53,7 @@ public:
jmp_buf jmp; // where child will jump to
void *stacktop; // location of top of parent stack
void *stackbottom; // location of bottom of parent stack
+ char filler[4]; // struct is copied in chunks of 5 bytes on Vista 64
};
class fhandler_base;
@@ -74,6 +75,7 @@ class child_info_spawn: public child_inf
public:
cygheap_exec_info *moreinfo;
HANDLE hexec_proc;
+ char filler[4]; // struct is copied in chunks of 5 bytes on Vista 64
child_info_spawn (): moreinfo (NULL) {}
~child_info_spawn ()
@@ -96,6 +98,6 @@ public:
}
};
-void __stdcall init_child_info (DWORD, child_info *, int, HANDLE);
+void __stdcall init_child_info (DWORD, child_info *, unsigned, int, HANDLE);
extern child_info_fork *child_proc_info;
Index: src/winsup/cygwin/dcrt0.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/dcrt0.cc,v
retrieving revision 1.9
diff -u -3 -p -r1.9 dcrt0.cc
--- src/winsup/cygwin/dcrt0.cc 15 Mar 2004 11:51:36 -0000 1.9
+++ src/winsup/cygwin/dcrt0.cc 28 Jul 2007 18:54:56 -0000
@@ -162,6 +162,13 @@ do_global_ctors (void (**in_pfunc)(), in
os_type NO_COPY os_being_run;
char NO_COPY osname[40];
bool iswinnt;
+bool isVistaWOW64;
+
+/* Declare the function prototype for this WIN32 API call,
+ in case the w32api version used to build MSYS is too old. */
+#ifndef IsWow64Process
+ extern "C" BOOL WINAPI IsWow64Process(HANDLE,PBOOL);
+#endif
/* set_os_type: Set global variable os_being_run with type of Win32
operating system being run. This information is used internally
@@ -179,12 +186,19 @@ set_os_type ()
GetVersionEx (&os_version_info);
iswinnt = 0;
+ isVistaWOW64 = 0;
switch (os_version_info.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
os_being_run = winNT;
os = "NT";
iswinnt = 1;
+ if(os_version_info.dwMajorVersion == 6)
+ {
+ BOOL is_wow64_proc = FALSE;
+ if (IsWow64Process (GetCurrentProcess (), &is_wow64_proc))
+ isVistaWOW64 = is_wow64_proc;
+ }
break;
case VER_PLATFORM_WIN32_WINDOWS:
if (os_version_info.dwMinorVersion == 0)
@@ -903,7 +917,6 @@ _dll_crt0 ()
if (GetEnvironmentVariable ("CYGWIN_TESTING", envbuf, sizeof (envbuf) - 1))
_cygwin_testing = 1;
- char zeros[sizeof (fork_info->zero)] = {0};
#ifdef DEBUGGING
strace.microseconds ();
#endif
@@ -924,8 +937,7 @@ _dll_crt0 ()
&hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
GetStartupInfo (&si);
- if (si.cbReserved2 >= EXEC_MAGIC_SIZE &&
- memcmp (fork_info->zero, zeros, sizeof (zeros)) == 0)
+ if (si.cbReserved2 >= EXEC_MAGIC_SIZE )
{
switch (fork_info->type)
{
Index: src/winsup/cygwin/fork.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/fork.cc,v
retrieving revision 1.4
diff -u -3 -p -r1.4 fork.cc
--- src/winsup/cygwin/fork.cc 3 Oct 2005 19:14:58 -0000 1.4
+++ src/winsup/cygwin/fork.cc 28 Jul 2007 18:54:56 -0000
@@ -428,7 +428,7 @@ fork_parent (HANDLE& hParent, dll *&firs
ProtectHandle (subproc_ready);
ProtectHandle (forker_finished);
- init_child_info (PROC_FORK1, &ch, 1, subproc_ready);
+ init_child_info (PROC_FORK1, &ch, sizeof(ch), 1, subproc_ready);
ch.forker_finished = forker_finished;
@@ -436,7 +436,7 @@ fork_parent (HANDLE& hParent, dll *&firs
si.cb = sizeof (STARTUPINFO);
si.lpReserved2 = (LPBYTE)&ch;
- si.cbReserved2 = sizeof(ch);
+ si.cbReserved2 = sizeof(ch) - 4; // Do not count the filler bytes
/* Remove impersonation */
if (cygheap->user.impersonated && cygheap->user.token !=
INVALID_HANDLE_VALUE)
Index: src/winsup/cygwin/sigproc.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/sigproc.cc,v
retrieving revision 1.4
diff -u -3 -p -r1.4 sigproc.cc
--- src/winsup/cygwin/sigproc.cc 12 Feb 2003 15:50:27 -0000 1.4
+++ src/winsup/cygwin/sigproc.cc 28 Jul 2007 18:54:57 -0000
@@ -844,12 +844,34 @@ subproc_init (void)
/* Initialize some of the memory block passed to child processes
by fork/spawn/exec. */
+
void __stdcall
-init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
+init_child_info (DWORD chtype, child_info *ch, unsigned ch_size, pid_t pid,
HANDLE subproc_ready)
{
TRACE_IN;
memset (ch, 0, sizeof *ch);
ch->cb = sizeof *ch;
+ /*
+ * Work around what appears to be a bug in Vista 64-bit. The problem
+ * is related to how fork passes information to the child. Basically
+ * the child_info struct * is put in the lpReserved2 field of the
+ * STARTUPINFO struct that gets passed to CreateProcess(). In all
+ * versions of Windows, the size of the data to be passed is in the
+ * cbReserved2 field of the same structure, except on Vista 64-bit.
+ *
+ * It seems that WOW64 (the 32-bit emulation layer of 64-bit Vista)
+ * expects the size of the data passed in lpReserved2 to be the first
+ * word in that same pointer, only it expects the size in "elements"
+ * of a BYTE[] and HANDLE[] arrays (the MS C runtime has this
+ * convention).
+ *
+ * We work around it by filling in the size as (sizeof struct)/5 and
+ * zero padding the end of the child_info_* structs.
+ */
+ if (isVistaWOW64)
+ ch->msv_count = ch_size / 5;
+ else
+ ch->msv_count = 0;
ch->type = chtype;
ch->cygpid = pid;
ch->subproc_ready = subproc_ready;
Index: src/winsup/cygwin/spawn.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/spawn.cc,v
retrieving revision 1.27
diff -u -3 -p -r1.27 spawn.cc
--- src/winsup/cygwin/spawn.cc 26 Jul 2006 15:01:37 -0000 1.27
+++ src/winsup/cygwin/spawn.cc 28 Jul 2007 18:54:57 -0000
@@ -345,7 +345,7 @@ spawn_guts (HANDLE hToken, const char *
child_info_spawn ciresrv;
si.lpReserved2 = (LPBYTE) &ciresrv;
- si.cbReserved2 = sizeof (ciresrv);
+ si.cbReserved2 = sizeof (ciresrv) - 4; // Do not count the filler bytes
DWORD chtype;
if (mode != _P_OVERLAY && mode != _P_VFORK)
@@ -362,7 +362,7 @@ spawn_guts (HANDLE hToken, const char *
ProtectHandle (spr);
}
- init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1,
spr);
+ init_child_info (chtype, &ciresrv, sizeof(ciresrv), (mode == _P_OVERLAY) ?
myself->pid : 1, spr);
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &ciresrv.parent, 0, 1,
DUPLICATE_SAME_ACCESS))
{
Index: src/winsup/cygwin/winsup.h
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/winsup.h,v
retrieving revision 1.18
diff -u -3 -p -r1.18 winsup.h
--- src/winsup/cygwin/winsup.h 26 Jul 2006 15:01:37 -0000 1.18
+++ src/winsup/cygwin/winsup.h 28 Jul 2007 18:54:57 -0000
@@ -95,6 +95,7 @@ extern "C" DWORD WINAPI GetLastError (vo
enum os_type {winNT = 1, win95, win98, winME, win32s, unknown};
extern os_type os_being_run;
extern bool iswinnt;
+extern bool isVistaWOW64;
enum codepage_type {ansi_cp, oem_cp};
extern codepage_type current_codepage;