198 lines
6.4 KiB
Diff
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 (), ¤t_is_wow))
|
|
- current_is_wow = -2;
|
|
+ if (current_is_wow == -1
|
|
+ && !IsWow64Process (GetCurrentProcess (), ¤t_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
|
|
|