Skip to content

Commit

Permalink
Cygwin: cache IsWow64Process2 host arch in wincap.
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
Jeremy Drake authored and github-cygwin committed Nov 28, 2024
1 parent 6adfb1f commit 46f7bcc
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
4 changes: 4 additions & 0 deletions winsup/cygwin/local_includes/wincap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -61,6 +63,8 @@ class wincapc
{ 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; }

Expand Down
6 changes: 2 additions & 4 deletions winsup/cygwin/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions winsup/cygwin/wincap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
}

0 comments on commit 46f7bcc

Please sign in to comment.