Files
MSYS2-packages/msys2-runtime/0045-use-IsWow64Process2-to-detect-arm-cases.patch

198 lines
6.4 KiB
Diff

From 0fa367cc1d8c135c35a6a68fafeb8eb85efb2e41 Mon Sep 17 00:00:00 2001
From: Jeremy Drake <github@jdrake.com>
Date: Fri, 18 Jun 2021 15:39:24 -0700
Subject: [PATCH 45/N] use IsWow64Process2 to detect arm cases.
kill doesn't appear to have the cygwin autoload stuff, so use
GetProcAddress manually
Unfortunately, IsWow64Process2 doesn't consider x86_64 processes on
ARM64 to be Wow64, and returns exactly the same information as it does
for native ARM64 processes. Use
GetProcessInformation/ProcessMachineTypeInfo to further refine the
answer in that case, when available (see #8991)
add exe names for arm, but they are not built as the tooling for
targeting arm is complicated.
---
winsup/cygwin/include/cygwin/exit_process.h | 131 +++++++++++++++-----
1 file changed, 103 insertions(+), 28 deletions(-)
diff --git a/winsup/cygwin/include/cygwin/exit_process.h b/winsup/cygwin/include/cygwin/exit_process.h
index 5e04c0f..0486a0c 100644
--- a/winsup/cygwin/include/cygwin/exit_process.h
+++ b/winsup/cygwin/include/cygwin/exit_process.h
@@ -46,7 +46,7 @@
#define small_printf(...) fprintf (stderr, __VA_ARGS__)
#endif
-static BOOL get_wow (HANDLE process, BOOL &is_wow, int &bitness);
+static BOOL get_wow (HANDLE process, BOOL &is_wow, USHORT &process_arch);
static int exit_process_tree (HANDLE main_process, int exit_code);
static BOOL
@@ -54,24 +54,36 @@ kill_via_console_helper (HANDLE process, wchar_t *function_name, int exit_code,
DWORD pid)
{
BOOL is_wow;
- int bitness;
- if (!get_wow (process, is_wow, bitness))
+ USHORT process_arch;
+ if (!get_wow (process, is_wow, process_arch))
{
return FALSE;
}
const char *name;
- if (bitness == 32)
- name = "/usr/libexec/getprocaddr32.exe";
- else if (bitness == 64)
- name = "/usr/libexec/getprocaddr64.exe";
- else
- return NULL; /* what?!? */
+ switch (process_arch)
+ {
+ case IMAGE_FILE_MACHINE_I386:
+ name = "/usr/libexec/getprocaddr32.exe";
+ break;
+ case IMAGE_FILE_MACHINE_AMD64:
+ name = "/usr/libexec/getprocaddr64.exe";
+ break;
+ /* TODO: provide exes for these */
+ case IMAGE_FILE_MACHINE_ARMNT:
+ name = "/usr/libexec/getprocaddrarm32.exe";
+ break;
+ case IMAGE_FILE_MACHINE_ARM64:
+ name = "/usr/libexec/getprocaddrarm64.exe";
+ break;
+ default:
+ return FALSE; /* what?!? */
+ }
wchar_t wbuf[PATH_MAX];
if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, name, wbuf, PATH_MAX)
|| GetFileAttributesW (wbuf) == INVALID_FILE_ATTRIBUTES)
- return NULL;
+ return FALSE;
STARTUPINFOW si = {};
PROCESS_INFORMATION pi;
@@ -116,33 +128,96 @@ kill_via_console_helper (HANDLE process, wchar_t *function_name, int exit_code,
static int current_is_wow = -1;
static int is_32_bit_os = -1;
+typedef BOOL (WINAPI * IsWow64Process2_t) (HANDLE, USHORT *, USHORT *);
+static bool wow64process2initialized = false;
+static IsWow64Process2_t pIsWow64Process2 /* = NULL */;
+
+typedef BOOL (WINAPI * GetProcessInformation_t) (HANDLE,
+ PROCESS_INFORMATION_CLASS,
+ LPVOID, DWORD);
+static bool getprocessinfoinitialized = false;
+static GetProcessInformation_t pGetProcessInformation /* = NULL */;
+
static BOOL
-get_wow (HANDLE process, BOOL &is_wow, int &bitness)
+get_wow (HANDLE process, BOOL &is_wow, USHORT &process_arch)
{
- if (is_32_bit_os == -1)
+ USHORT native_arch = IMAGE_FILE_MACHINE_UNKNOWN;
+ if (!wow64process2initialized)
{
- SYSTEM_INFO info;
-
- GetNativeSystemInfo (&info);
- if (info.wProcessorArchitecture == 0)
- is_32_bit_os = 1;
- else if (info.wProcessorArchitecture == 9)
- is_32_bit_os = 0;
- else
- is_32_bit_os = -2;
+ pIsWow64Process2 = (IsWow64Process2_t)
+ GetProcAddress (GetModuleHandle ("KERNEL32"),
+ "IsWow64Process2");
+ MemoryBarrier ();
+ wow64process2initialized = true;
}
+ if (!pIsWow64Process2)
+ {
+ if (is_32_bit_os == -1)
+ {
+ SYSTEM_INFO info;
+
+ GetNativeSystemInfo (&info);
+ if (info.wProcessorArchitecture == 0)
+ is_32_bit_os = 1;
+ else if (info.wProcessorArchitecture == 9)
+ is_32_bit_os = 0;
+ else
+ is_32_bit_os = -2;
+ }
- if (current_is_wow == -1
- && !IsWow64Process (GetCurrentProcess (), &current_is_wow))
- current_is_wow = -2;
+ if (current_is_wow == -1
+ && !IsWow64Process (GetCurrentProcess (), &current_is_wow))
+ current_is_wow = -2;
- if (is_32_bit_os == -2 || current_is_wow == -2)
- return FALSE;
+ if (is_32_bit_os == -2 || current_is_wow == -2)
+ return FALSE;
+
+ if (!IsWow64Process (process, &is_wow))
+ return FALSE;
+
+ process_arch = is_32_bit_os || is_wow ? IMAGE_FILE_MACHINE_I386 :
+ IMAGE_FILE_MACHINE_AMD64;
+ return TRUE;
+ }
- if (!IsWow64Process (process, &is_wow))
+ if (!pIsWow64Process2 (process, &process_arch, &native_arch))
return FALSE;
- bitness = is_32_bit_os || is_wow ? 32 : 64;
+ /* The value will be IMAGE_FILE_MACHINE_UNKNOWN if the target process
+ * is not a WOW64 process
+ */
+ if (process_arch == IMAGE_FILE_MACHINE_UNKNOWN)
+ {
+ struct /* _PROCESS_MACHINE_INFORMATION */
+ {
+ /* 0x0000 */ USHORT ProcessMachine;
+ /* 0x0002 */ USHORT Res0;
+ /* 0x0004 */ DWORD MachineAttributes;
+ } /* size: 0x0008 */ process_machine_info;
+
+ is_wow = FALSE;
+ /* However, x86_64 on ARM64 claims not to be WOW64, so we have to
+ * dig harder... */
+ if (!getprocessinfoinitialized)
+ {
+ pGetProcessInformation = (GetProcessInformation_t)
+ GetProcAddress (GetModuleHandle ("KERNEL32"),
+ "GetProcessInformation");
+ MemoryBarrier ();
+ getprocessinfoinitialized = true;
+ }
+ /*#define ProcessMachineTypeInfo 9*/
+ if (pGetProcessInformation &&
+ pGetProcessInformation (process, (PROCESS_INFORMATION_CLASS)9,
+ &process_machine_info, sizeof (process_machine_info)))
+ process_arch = process_machine_info.ProcessMachine;
+ else
+ process_arch = native_arch;
+ }
+ else
+ {
+ is_wow = TRUE;
+ }
return TRUE;
}
--
2.32.0.windows.1