[newlib-cygwin/main] Cygwin: cache IsWow64Process2 host arch in wincap.

Corinna Vinschen corinna@sourceware.org
Fri Nov 29 09:57:39 GMT 2024


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=46f7bcc1e575826f6d3e4a5770ae61423d9be5a9

commit 46f7bcc1e575826f6d3e4a5770ae61423d9be5a9
Author:     Jeremy Drake <cygwin@jdrake.com>
AuthorDate: Wed Nov 27 11:22:49 2024 -0800
Commit:     Corinna Vinschen <corinna@vinschen.de>
CommitDate: Thu Nov 28 23:52:40 2024 +0100

    Cygwin: cache IsWow64Process2 host arch in wincap.
    
    This was already used in the FAST_CWD check, and could be used in a
    couple other places.
    
    I found the "emulated"/process value returned from the function largely
    useless, so I did not cache it.  It is useless because, as the docs say,
    it is set to IMAGE_FILE_MACHINE_UNKNOWN (0) if the process is not
    running under WOW64, but Microsoft also doesn't consider x64-on-ARM64 to
    be WOW64, so it is set to 0 regardless if the process is ARM64 or x64.
    You can tell the difference via
    GetProcessInformation(ProcessMachineTypeInfo), but for the current
    process even that's overkill: what we really want to know is the
    IMAGE_FILE_MACHINE_* constant for the Cygwin dll itself, which is
    conveniently located in memory already, so cache that in wincap also for
    easy comparisons.
    
    Signed-off-by: Jeremy Drake <cygwin@jdrake.com>

Diff:
---
 winsup/cygwin/local_includes/wincap.h |  4 ++++
 winsup/cygwin/path.cc                 |  6 ++----
 winsup/cygwin/wincap.cc               | 19 +++++++++++++++++++
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/local_includes/wincap.h b/winsup/cygwin/local_includes/wincap.h
index c14872787ca2..250866f0614c 100644
--- a/winsup/cygwin/local_includes/wincap.h
+++ b/winsup/cygwin/local_includes/wincap.h
@@ -42,6 +42,8 @@ class wincapc
   RTL_OSVERSIONINFOEXW	version;
   char			osnam[40];
   const void		*caps;
+  USHORT		host_mach;
+  USHORT		cygwin_mach;
   bool			_is_server;
 
 public:
@@ -61,6 +63,8 @@ public:
 		     { return (size_t) system_info.dwAllocationGranularity; }
   const char *osname () const { return osnam; }
   const DWORD build_number () const { return version.dwBuildNumber; }
+  const USHORT host_machine () const { return host_mach; }
+  const USHORT cygwin_machine () const { return cygwin_mach; }
 
 #define IMPLEMENT(cap) cap() const { return ((wincaps *) this->caps)->cap; }
 
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 5cfcbc0f2f6e..869383c836cb 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -4617,14 +4617,12 @@ find_fast_cwd_pointer ()
 static fcwd_access_t **
 find_fast_cwd ()
 {
-  USHORT emulated, hosted;
   fcwd_access_t **f_cwd_ptr;
 
-  /* First check if we're running in WOW64 on ARM64 emulating AMD64.  Skip
+  /* First check if we're running on an ARM64 system.  Skip
      fetching FAST_CWD pointer as long as there's no solution for finding
      it on that system. */
-  if (IsWow64Process2 (GetCurrentProcess (), &emulated, &hosted)
-      && hosted == IMAGE_FILE_MACHINE_ARM64)
+  if (wincap.host_machine () == IMAGE_FILE_MACHINE_ARM64)
     return NULL;
 
   /* Fetch the pointer but don't set the global fast_cwd_ptr yet.  First
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 30d9c14e8d3b..deecf8ba519d 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -235,9 +235,15 @@ static const wincaps wincap_11 = {
 
 wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
 
+extern IMAGE_DOS_HEADER
+__image_base__;
+
 void
 wincapc::init ()
 {
+  PIMAGE_NT_HEADERS ntheader;
+  USHORT emul_mach;
+
   if (caps)
     return;		// already initialized
 
@@ -282,4 +288,17 @@ wincapc::init ()
 
   __small_sprintf (osnam, "NT-%d.%d", version.dwMajorVersion,
 		   version.dwMinorVersion);
+
+  if (!IsWow64Process2 (GetCurrentProcess (), &emul_mach, &host_mach))
+    {
+      /* If IsWow64Process2 succeeded, it filled in host_mach.  Assume the only
+	 way it fails for the current process is that we're running on an OS
+	 version where it's not implemented yet.  As such, the only realistic
+	 option for host_mach is AMD64 */
+      host_mach = IMAGE_FILE_MACHINE_AMD64;
+    }
+
+  ntheader = (PIMAGE_NT_HEADERS)((LPBYTE) &__image_base__
+				 + __image_base__.e_lfanew);
+  cygwin_mach = ntheader->FileHeader.Machine;
 }


More information about the Cygwin-cvs mailing list