Skip to content

Commit

Permalink
msys2-runtime: uname: add host machine tag to sysname
Browse files Browse the repository at this point in the history
This backports the `uname` patches from Cygwin where Windows/ARM64 is
indicated by an `-ARM64` suffix.

It corresponds to msys2/msys2-runtime#245 and
msys2/msys2-runtime#244.

Signed-off-by: Johannes Schindelin <[email protected]>
  • Loading branch information
dscho authored and stahta01 committed Dec 21, 2024
1 parent 15d414c commit 1b9e1d9
Show file tree
Hide file tree
Showing 6 changed files with 355 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
From c427dfe3218f9b918571ce1f8daf226b67bac8b6 Mon Sep 17 00:00:00 2001
From: Jeremy Drake <[email protected]>
Date: Tue, 19 Nov 2024 17:18:16 -0800
Subject: [PATCH 60/N] 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 <[email protected]>
---
winsup/cygwin/path.cc | 6 ++----
winsup/cygwin/wincap.cc | 28 ++++++++++++++++++++++++++++
winsup/cygwin/wincap.h | 4 ++++
3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 8a373c4..abb6f27 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -5023,14 +5023,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)
f_cwd_ptr = NULL;
else
{
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index f37ed6b..256d3fd 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -438,9 +438,16 @@ wincaps wincap_10_1903 __attribute__((section (".cygwin_dll_common"), shared)) =

wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));

+/* __asm__ to work around i386 leading underscore */
+extern IMAGE_DOS_HEADER
+__image_base__ __asm__ ("__image_base__");
+
void
wincapc::init ()
{
+ PIMAGE_NT_HEADERS ntheader;
+ USHORT emul_mach;
+
if (caps)
return; // already initialized

@@ -512,4 +519,25 @@ 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 two
+ realistic options for host_mach are AMD64 or I386 */
+#if defined (__x86_64__)
+ host_mach = IMAGE_FILE_MACHINE_AMD64;
+#elif defined (__i386__)
+ host_mach = wow64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
+#else
+ /* this should not happen */
+ assert (0 && "IsWow64Process2 failed on non-i386/x86_64");
+ host_mach = IMAGE_FILE_MACHINE_UNKNOWN;
+#endif
+ }
+
+ ntheader = (PIMAGE_NT_HEADERS)((LPBYTE) &__image_base__
+ + __image_base__.e_lfanew);
+ cygwin_mach = ntheader->FileHeader.Machine;
}
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index c5e7c9a..951fa6a 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -57,6 +57,8 @@ class wincapc
char osnam[40];
ULONG_PTR wow64;
void *caps;
+ USHORT host_mach;
+ USHORT cygwin_mach;

public:
void init ();
@@ -76,6 +78,8 @@ public:
const char *osname () const { return osnam; }
const DWORD build_number () const { return version.dwBuildNumber; }
const bool is_wow64 () const { return !!wow64; }
+ 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; }

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
From 51909270bb8322cd659ea88edd4f37ed424c567e Mon Sep 17 00:00:00 2001
From: Jeremy Drake <[email protected]>
Date: Tue, 19 Nov 2024 22:41:42 -0800
Subject: [PATCH 61/N] Cygwin: uname: add host machine tag to sysname.

If the Cygwin dll's architecture is different from the host system's
architecture, append an additional tag that indicates the host system
architecture (the Cygwin dll's architecture is already indicated in
machine).

Signed-off-by: Jeremy Drake <[email protected]>
---
winsup/cygwin/uname.cc | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc
index f6a5f88..efd233c 100644
--- a/winsup/cygwin/uname.cc
+++ b/winsup/cygwin/uname.cc
@@ -51,14 +51,34 @@ uname_x (struct utsname *name)
{
char buf[NI_MAXHOST + 1] ATTRIBUTE_NONSTRING;
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
+ int n;

memset (name, 0, sizeof (*name));
/* sysname */
const char* sysname = get_sysname();
- __small_sprintf (name->sysname, "%s_%s-%u%s",
- sysname,
- wincap.osname (), wincap.build_number (),
- wincap.is_wow64 () ? "-WOW64" : "");
+ n = __small_sprintf (name->sysname, "%s_%s-%u",
+ sysname,
+ wincap.osname (), wincap.build_number ());
+ if (wincap.host_machine () != wincap.cygwin_machine ())
+ {
+ switch (wincap.host_machine ())
+ {
+ case IMAGE_FILE_MACHINE_AMD64:
+ /* special case for backwards compatibility */
+ if (wincap.cygwin_machine () == IMAGE_FILE_MACHINE_I386)
+ n = stpcpy (name->sysname + n, "-WOW64") - name->sysname;
+ else
+ n = stpcpy (name->sysname + n, "-x64") - name->sysname;
+ break;
+ case IMAGE_FILE_MACHINE_ARM64:
+ n = stpcpy (name->sysname + n, "-ARM64") - name->sysname;
+ break;
+ default:
+ n += __small_sprintf (name->sysname + n, "-%04y",
+ (int) wincap.host_machine ());
+ break;
+ }
+ }
/* nodename */
memset (buf, 0, sizeof buf);
cygwin_gethostname (buf, sizeof buf - 1);
14 changes: 10 additions & 4 deletions msys2-runtime-3.3/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
pkgbase=msys2-runtime-3.3
pkgname=('msys2-runtime-3.3' 'msys2-runtime-3.3-devel')
pkgver=3.3.6
pkgrel=12
pkgrel=13
pkgdesc="Cygwin POSIX emulation engine"
arch=('i686' 'x86_64')
url="https://www.cygwin.com/"
Expand Down Expand Up @@ -87,7 +87,9 @@ source=('msys2-runtime'::git://sourceware.org/git/newlib-cygwin.git#tag=cygwin-$
0056-cygthread-suspend-thread-before-terminating.patch
0057-fixup-cygthread-suspend-thread-before-terminating.patch
0058-fixup-cygthread-suspend-thread-before-terminating.patch
0059-Cygwin-revert-use-of-CancelSyncronousIo-on-wait_thre.patch)
0059-Cygwin-revert-use-of-CancelSyncronousIo-on-wait_thre.patch
0060-Cygwin-cache-IsWow64Process2-host-arch-in-wincap.patch
0061-Cygwin-uname-add-host-machine-tag-to-sysname.patch)
sha256sums=('1495f90ffd49a3ef4835a879881fa5dbb28dc6aa3ee55be3c4327bbab471e9b8'
'c375315e58181ee5589b7966101aa095de3f864a579c3c3f0f0683595d4e428d'
'01ea2b131cf5a3b27fdbc458019eac14e45a36782ce3ce33e62328eefcd2d02e'
Expand Down Expand Up @@ -147,7 +149,9 @@ sha256sums=('1495f90ffd49a3ef4835a879881fa5dbb28dc6aa3ee55be3c4327bbab471e9b8'
'67a060066f26446f21e08c8fed4fc855529b6e786f0789c9b5385881026d3fd0'
'f4e2a1595e7fe9bdceb17f7e909d6eb51b7a8d3f1a2d0b2ad938e2127308d9b4'
'df1d1cdcc2349c88fef991ab0f520c0873da51c347ec64ded17b4f688512fddc'
'8eaf698b404506e45a3651ea0cecba78680e52da291613a8c6683b6b1f1043da')
'8eaf698b404506e45a3651ea0cecba78680e52da291613a8c6683b6b1f1043da'
'63edc5575d19ce7566d9b726442dafd34f58be423f667325e5b7cc808647bbc9'
'1735df76f61bac7d075407a0f3ecf8d4fffce7b6f7a42136ccaf34a534a7ab0c')

# Helper macros to help make tasks easier #
apply_patch_with_msg() {
Expand Down Expand Up @@ -243,7 +247,9 @@ prepare() {
0056-cygthread-suspend-thread-before-terminating.patch \
0057-fixup-cygthread-suspend-thread-before-terminating.patch \
0058-fixup-cygthread-suspend-thread-before-terminating.patch \
0059-Cygwin-revert-use-of-CancelSyncronousIo-on-wait_thre.patch
0059-Cygwin-revert-use-of-CancelSyncronousIo-on-wait_thre.patch \
0060-Cygwin-cache-IsWow64Process2-host-arch-in-wincap.patch \
0061-Cygwin-uname-add-host-machine-tag-to-sysname.patch
}

build() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
From fe383b0dadf5ea0d3181395475e0462955fb2852 Mon Sep 17 00:00:00 2001
From: Jeremy Drake <[email protected]>
Date: Wed, 27 Nov 2024 11:22:49 -0800
Subject: [PATCH 46/N] 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 <[email protected]>
(cherry picked from commit 46f7bcc1e575826f6d3e4a5770ae61423d9be5a9)
---
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 c148727..250866f 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 f8afd4c..5d2f0a5 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -4826,14 +4826,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 30d9c14..deecf8b 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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
From 8d847f4e94acea433d18c2397221e726ab2d06ec Mon Sep 17 00:00:00 2001
From: Jeremy Drake <[email protected]>
Date: Wed, 27 Nov 2024 11:26:50 -0800
Subject: [PATCH 47/N] Cygwin: uname: add host machine tag to sysname.

If the Cygwin dll's architecture is different from the host system's
architecture, append an additional tag that indicates the host system
architecture (the Cygwin dll's architecture is already indicated in
machine).

Signed-off-by: Jeremy Drake <[email protected]>
(cherry picked from commit 7923059bff6c120c6fb74b63c7553ea345c0a8f3)
---
winsup/cygwin/uname.cc | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc
index a978363..ba73edd 100644
--- a/winsup/cygwin/uname.cc
+++ b/winsup/cygwin/uname.cc
@@ -51,13 +51,27 @@ uname_x (struct utsname *name)
__try
{
char buf[NI_MAXHOST + 1] ATTRIBUTE_NONSTRING;
+ int n;

memset (name, 0, sizeof (*name));
/* sysname */
const char* sysname = get_sysname();
- __small_sprintf (name->sysname, "%s_%s-%u",
- sysname,
- wincap.osname (), wincap.build_number ());
+ n = __small_sprintf (name->sysname, "%s_%s-%u",
+ sysname,
+ wincap.osname (), wincap.build_number ());
+ if (wincap.host_machine () != wincap.cygwin_machine ())
+ {
+ switch (wincap.host_machine ())
+ {
+ case IMAGE_FILE_MACHINE_ARM64:
+ n = stpcpy (name->sysname + n, "-ARM64") - name->sysname;
+ break;
+ default:
+ n += __small_sprintf (name->sysname + n, "-%04y",
+ (int) wincap.host_machine ());
+ break;
+ }
+ }
/* nodename */
memset (buf, 0, sizeof buf);
cygwin_gethostname (buf, sizeof buf - 1);
Loading

0 comments on commit 1b9e1d9

Please sign in to comment.