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>
This commit is contained in:
Jeremy Drake 2024-11-27 11:22:49 -08:00 committed by Corinna Vinschen
parent 6adfb1fc28
commit 46f7bcc1e5
3 changed files with 25 additions and 4 deletions

View File

@ -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; }

View File

@ -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

View File

@ -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;
}