Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Kreijstal/1cd0bd27e12111a5b5ccb16189e31724 to your computer and use it in GitHub Desktop.

Select an option

Save Kreijstal/1cd0bd27e12111a5b5ccb16189e31724 to your computer and use it in GitHub Desktop.
Windows 11 ARM64 QEMU/HVF setup and experimental native MSYS2 runtime/Bash port
From 9890fe6ae79b81bde8ec7a990c6ca5e89fc627c3 Mon Sep 17 00:00:00 2001
From: Kreijstal <kreijstal@users.noreply.github.com>
Date: Sat, 18 Jul 2026 05:07:06 +0200
Subject: [PATCH 1/7] build: recognize the AArch64 MSYS target
Teach the top-level, newlib, and winsup build logic to configure aarch64-pc-msys. Select the ARM64 runtime sources and direct linker path while retaining the existing x86_64 link rule.
Assisted-by: OpenAI Codex: GPT-5
---
configure.ac | 2 +-
newlib/configure.host | 8 ++++----
winsup/configure.ac | 11 ++++++-----
winsup/cygwin/Makefile.am | 29 +++++++++++++++++++++++++++++
4 files changed, 40 insertions(+), 10 deletions(-)
diff --git a/configure.ac b/configure.ac
index 05ddf69870..99ae73adf9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1178,7 +1178,7 @@ case "${target}" in
i[[3456789]]86-*-mingw*)
target_configdirs="$target_configdirs target-winsup"
;;
- *-*-cygwin*)
+ *-*-cygwin* | *-*-msys*)
target_configdirs="$target_configdirs target-libtermcap target-winsup"
noconfigdirs="$noconfigdirs target-libgloss"
# always build newlib if winsup directory is present.
diff --git a/newlib/configure.host b/newlib/configure.host
index c43cfcf9a4..cf72bb97b7 100644
--- a/newlib/configure.host
+++ b/newlib/configure.host
@@ -199,7 +199,7 @@ case "${host_cpu}" in
shared_machine_dir=shared_x86
# Don't use for these since they provide their own setjmp.
case ${host} in
- *-*-sco* | *-*-cygwin*)
+ *-*-sco* | *-*-cygwin* | *-*-msys*)
;;
*)
mach_add_setjmp=true
@@ -411,7 +411,7 @@ fi
if [ "x${newlib_mb}" = "x" ]; then
case "${host}" in
- *-*-cygwin*)
+ *-*-cygwin* | *-*-msys*)
newlib_mb=yes
;;
esac
@@ -430,7 +430,7 @@ fi
# THIS TABLE IS ALPHA SORTED. KEEP IT THAT WAY.
case "${host}" in
- *-*-cygwin*)
+ *-*-cygwin* | *-*-msys*)
posix_dir=posix
xdr_dir=xdr
;;
@@ -599,7 +599,7 @@ esac
# THIS TABLE IS ALPHA SORTED. KEEP IT THAT WAY.
case "${host}" in
- *-*-cygwin*)
+ *-*-cygwin* | *-*-msys*)
test -z "$cygwin_srcdir" && cygwin_srcdir="${abs_newlib_basedir}/../winsup/cygwin"
export cygwin_srcdir
default_newlib_io_c99_formats="yes"
diff --git a/winsup/configure.ac b/winsup/configure.ac
index 4dd5ccb9f9..93936fb378 100644
--- a/winsup/configure.ac
+++ b/winsup/configure.ac
@@ -71,7 +71,7 @@ no)
yes|auto)
if MSYS2_RUNTIME_COMMIT="$(git --git-dir="$srcdir/../.git" rev-parse HEAD)"
then
- MSYS2_RUNTIME_COMMIT_SHORT="$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')"
+ MSYS2_RUNTIME_COMMIT_SHORT="$(printf '%s' "$MSYS2_RUNTIME_COMMIT" | cut -c1-8)"
MSYS2_RUNTIME_COMMIT_HEX="0x${MSYS2_RUNTIME_COMMIT_SHORT}ul"
else
AC_MSG_WARN([Could not determine msys2-runtime commit])
@@ -83,7 +83,7 @@ yes|auto)
*)
expr "$MSYS2_RUNTIME_COMMIT" : '@<:@0-9a-f@:>@\{6,64\}$' ||
AC_MSG_ERROR([Invalid commit name: "$MSYS2_RUNTIME_COMMIT"])
- MSYS2_RUNTIME_COMMIT_SHORT="$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')"
+ MSYS2_RUNTIME_COMMIT_SHORT="$(printf '%s' "$MSYS2_RUNTIME_COMMIT" | cut -c1-8)"
MSYS2_RUNTIME_COMMIT_HEX="0x${MSYS2_RUNTIME_COMMIT_SHORT}ul"
;;
esac
@@ -102,13 +102,14 @@ esac
DLL_ENTRY="dll_entry"
case "$target_cpu" in
- x86_64) ;;
+ x86_64|aarch64) ;;
*) AC_MSG_ERROR([Invalid target processor "$target_cpu"]) ;;
esac
AC_SUBST(DLL_ENTRY)
AM_CONDITIONAL(TARGET_X86_64, [test $target_cpu = "x86_64"])
+AM_CONDITIONAL(TARGET_AARCH64, [test $target_cpu = "aarch64"])
AC_ARG_ENABLE(doc,
[AS_HELP_STRING([--disable-doc], [do not build documentation])],,
@@ -135,9 +136,9 @@ if test -z "$XMLTO"; then
fi
if test "x$with_cross_bootstrap" != "xyes"; then
- AC_CHECK_PROGS(MINGW_CXX, ${target_cpu}-w64-mingw32-g++)
+ AC_CHECK_PROGS(MINGW_CXX, ${target_cpu}-w64-mingw32-clang++ ${target_cpu}-w64-mingw32-g++)
test -n "$MINGW_CXX" || AC_MSG_ERROR([no acceptable MinGW g++ found in \$PATH])
- AC_CHECK_PROGS(MINGW_CC, ${target_cpu}-w64-mingw32-gcc)
+ AC_CHECK_PROGS(MINGW_CC, ${target_cpu}-w64-mingw32-clang ${target_cpu}-w64-mingw32-gcc)
test -n "$MINGW_CC" || AC_MSG_ERROR([no acceptable MinGW gcc found in \$PATH])
AC_CHECK_PROGS(MINGW32_CC, i686-w64-mingw32-gcc)
diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am
index 41190bdb7a..81b69eca3b 100644
--- a/winsup/cygwin/Makefile.am
+++ b/winsup/cygwin/Makefile.am
@@ -67,6 +67,13 @@ TARGET_FILES= \
x86_64/wmemmove.S \
x86_64/wmempcpy.S
endif
+if TARGET_AARCH64
+TARGET_FILES= \
+ aarch64/signal_stubs.S \
+ aarch64/compat.c \
+ math/isinf.c \
+ math/isnan.c
+endif
LIB_FILES= \
lib/_cygwin_crt0_common.cc \
@@ -151,6 +158,11 @@ LIBC_FILES= \
libc/tss.c \
libc/xsique.cc
+if TARGET_AARCH64
+# These overrides are x87 implementations. ARM64 resolves the same public
+# math entry points from newlib/libm until native optimized variants exist.
+MATH_FILES=
+else
MATH_FILES= \
math/acoshl.c \
math/acosl.c \
@@ -246,6 +258,7 @@ MATH_FILES= \
math/tanl.S \
math/tgammal.c \
math/truncl.c
+endif
MM_FILES = \
mm/cygheap.cc \
@@ -606,8 +619,23 @@ $(LDSCRIPT): $(LDSCRIPT).in
# msys-2.0 dll
# Set PE and export table header timestamps to zero for reproducible builds.
+ARM64_WINDOWS_LIBDIR ?= $(tooldir)/lib/w32api
+ARM64_RUNTIME_LIBS ?= -lgcc
$(NEW_DLL_NAME): $(LDSCRIPT) libdll.a $(VERSION_OFILES) $(LIBSERVER)\
$(newlib_build)/libm.a $(newlib_build)/libc.a
+if TARGET_AARCH64
+ $(AM_V_CXXLD)$(LD) --gc-sections -T$(LDSCRIPT) \
+ $${SOURCE_DATE_EPOCH:+--no-insert-timestamp} --heap=0 \
+ --out-implib msysdll.a --shared -o $@ \
+ -e @DLL_ENTRY@ $(DEF_FILE) \
+ --whole-archive libdll.a --no-whole-archive \
+ $(VERSION_OFILES) $(LIBSERVER) \
+ $(newlib_build)/libm.a $(newlib_build)/libc.a \
+ --whole-archive $(word 1,$(ARM64_RUNTIME_LIBS)) --no-whole-archive \
+ $(wordlist 2,999,$(ARM64_RUNTIME_LIBS)) \
+ -L$(ARM64_WINDOWS_LIBDIR) \
+ -lkernel32 -lntdll -lntdllcrt -Map msys.map
+else
$(AM_V_CXXLD)$(CXX) $(CXXFLAGS) \
-mno-use-libstdc-wrappers \
-Wl,--gc-sections -nostdlib -Wl,-T$(LDSCRIPT) -static \
@@ -620,6 +648,7 @@ $(NEW_DLL_NAME): $(LDSCRIPT) libdll.a $(VERSION_OFILES) $(LIBSERVER)\
$(newlib_build)/libm.a \
$(newlib_build)/libc.a \
-lgcc -lkernel32 -lntdll -Wl,-Map,msys.map
+endif
@$(MKDIR_P) ${target_builddir}/winsup/testsuite/testinst/bin/
$(AM_V_at)$(INSTALL_PROGRAM) $(NEW_DLL_NAME) ${target_builddir}/winsup/testsuite/testinst/bin/$(DLL_NAME)
From 632c01f16559be4dbe24bb43127782dba48f31fb Mon Sep 17 00:00:00 2001
From: Kreijstal <kreijstal@users.noreply.github.com>
Date: Sat, 18 Jul 2026 05:07:06 +0200
Subject: [PATCH 2/7] winsup: make shared sources compile cleanly with Clang
Resolve const-correctness, initializer, exception-specification, unused-code, and recursive-overload diagnostics exposed by the ARM64 Clang bootstrap. These changes are architecture-independent and intentionally isolated from the ARM64 implementation.
Assisted-by: OpenAI Codex: GPT-5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---
newlib/libc/include/machine/_default_types.h | 4 +++-
winsup/cygwin/cxx.cc | 8 ++++----
winsup/cygwin/dtable.cc | 4 ++--
winsup/cygwin/environ.cc | 4 ++--
winsup/cygwin/fhandler/dev_disk.cc | 3 ---
winsup/cygwin/fhandler/pipe.cc | 7 -------
winsup/cygwin/fhandler/proc.cc | 2 +-
winsup/cygwin/fhandler/process.cc | 2 +-
winsup/cygwin/fhandler/pty.cc | 5 ++---
winsup/cygwin/libc/bsdlib.cc | 2 +-
winsup/cygwin/libc/fts.c | 6 ++----
winsup/cygwin/libc/rexec.cc | 2 +-
winsup/cygwin/libc/strptime.cc | 6 +++---
winsup/cygwin/local_includes/fhandler.h | 1 -
winsup/cygwin/local_includes/timerfd.h | 3 ++-
winsup/cygwin/mktemp.cc | 2 +-
winsup/cygwin/nlsfuncs.cc | 8 +++++---
winsup/cygwin/path.cc | 4 ++--
winsup/cygwin/scripts/cygmagic | 3 ++-
winsup/cygwin/scripts/gentls_offsets | 12 +++++++-----
winsup/cygwin/spawn.cc | 2 --
winsup/cygwin/syscalls.cc | 2 +-
winsup/cygwin/uinfo.cc | 13 ++++++++-----
winsup/cygwin/winf.cc | 2 +-
24 files changed, 51 insertions(+), 56 deletions(-)
diff --git a/newlib/libc/include/machine/_default_types.h b/newlib/libc/include/machine/_default_types.h
index 11ff90beb2..d541a1ae1e 100644
--- a/newlib/libc/include/machine/_default_types.h
+++ b/newlib/libc/include/machine/_default_types.h
@@ -327,7 +327,9 @@ typedef __PTRDIFF_TYPE__ __ptrdiff_t;
typedef long int __ptrdiff_t;
#endif
-#ifdef __WCHAR_TYPE__
+#if defined(__MSYS_CLANG_MS_EXTENSIONS__) && defined(__clang__) && defined(__cplusplus)
+/* With -fms-extensions Clang provides __wchar_t as a builtin type. */
+#elif defined(__WCHAR_TYPE__)
typedef __WCHAR_TYPE__ __wchar_t;
#elif defined (__WCHAR_MAX__) && __WCHAR_MAX__ == 0xffff
typedef short unsigned int __wchar_t;
diff --git a/winsup/cygwin/cxx.cc b/winsup/cygwin/cxx.cc
index b69524acad..374602628e 100644
--- a/winsup/cygwin/cxx.cc
+++ b/winsup/cygwin/cxx.cc
@@ -52,26 +52,26 @@ operator delete[] (void *p)
/* Nothrow versions, provided only for completeness in the fallback array. */
void *
-operator new (std::size_t s, const std::nothrow_t &)
+operator new (std::size_t s, const std::nothrow_t &) noexcept
{
void *p = calloc (1, s);
return p;
}
void
-operator delete (void *p, const std::nothrow_t &)
+operator delete (void *p, const std::nothrow_t &) noexcept
{
free (p);
}
void *
-operator new[] (std::size_t s, const std::nothrow_t &nt)
+operator new[] (std::size_t s, const std::nothrow_t &nt) noexcept
{
return ::operator new (s, nt);
}
void
-operator delete[] (void *p, const std::nothrow_t &nt)
+operator delete[] (void *p, const std::nothrow_t &nt) noexcept
{
::operator delete (p, nt);
}
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index 6ccc19a715..3d2d404c80 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -834,7 +834,7 @@ dtable::select_write (int fd, select_stuff *ss)
if (not_open (fd))
{
set_errno (EBADF);
- return NULL;
+ return false;
}
fhandler_base *fh = fds[fd];
select_record *s = fh->select_write (ss);
@@ -851,7 +851,7 @@ dtable::select_except (int fd, select_stuff *ss)
if (not_open (fd))
{
set_errno (EBADF);
- return NULL;
+ return false;
}
fhandler_base *fh = fds[fd];
select_record *s = fh->select_except (ss);
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 4e049211e9..7a946ebb44 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -1085,8 +1085,8 @@ env_compare (const void *key, const void *memb)
const char *k = *(const char **) key;
const char *m = *(const char **) memb;
- char *ke = strchr (k, '=');
- char *me = strchr (m, '=');
+ const char *ke = strchr (k, '=');
+ const char *me = strchr (m, '=');
if (ke == NULL || me == NULL)
return strcasecmp (k, m);
int ret = strncasecmp (k, m, MIN (ke - k, me - m));
diff --git a/winsup/cygwin/fhandler/dev_disk.cc b/winsup/cygwin/fhandler/dev_disk.cc
index 29af9de95a..b86bef9c60 100644
--- a/winsup/cygwin/fhandler/dev_disk.cc
+++ b/winsup/cygwin/fhandler/dev_disk.cc
@@ -645,9 +645,6 @@ get_by_id_table (by_id_entry * &table, fhandler_dev_disk::dev_disk_location loc)
const char dev_disk[] = "/dev/disk";
const size_t dev_disk_len = sizeof (dev_disk) - 1;
-static const char by_drive[] = "/by-drive";
-const size_t by_drive_len = sizeof(by_drive) - 1;
-
/* Keep this in sync with enum fhandler_dev_disk::dev_disk_location starting
at disk_by_drive. */
static const char * const by_dir_names[] {
diff --git a/winsup/cygwin/fhandler/pipe.cc b/winsup/cygwin/fhandler/pipe.cc
index 11ef78c73b..4f3f2497b0 100644
--- a/winsup/cygwin/fhandler/pipe.cc
+++ b/winsup/cygwin/fhandler/pipe.cc
@@ -952,13 +952,6 @@ fhandler_pipe::create (LPSECURITY_ATTRIBUTES sa_ptr, PHANDLE r, PHANDLE w,
return 0;
}
-inline static bool
-is_running_as_service (void)
-{
- return check_token_membership (well_known_service_sid)
- || cygheap->user.saved_sid () == well_known_system_sid;
-}
-
/* The next version of fhandler_pipe::create used to call the previous
version. But the read handle created by the latter doesn't have
FILE_WRITE_ATTRIBUTES access unless the pipe is created with
diff --git a/winsup/cygwin/fhandler/proc.cc b/winsup/cygwin/fhandler/proc.cc
index f1cd468fc2..4e21871c84 100644
--- a/winsup/cygwin/fhandler/proc.cc
+++ b/winsup/cygwin/fhandler/proc.cc
@@ -2049,7 +2049,7 @@ format_proc_swaps (void *, char *&destbuf)
size_t tabo = strlen (filename) / 8; /* offset tabs to space name */
bufptr += sprintf (bufptr, "%s%s%s\t\t%llu%s\t%llu%s\t%d\n",
filename,
- tabo < 5 ? "\t\t\t\t\t" + tabo : " ",
+ tabo < 5 ? &"\t\t\t\t\t"[tabo] : " ",
"file",
total >> 10,
total < 10000000000 ? "\t" : "",
diff --git a/winsup/cygwin/fhandler/process.cc b/winsup/cygwin/fhandler/process.cc
index e00cae58d7..50a5f2160e 100644
--- a/winsup/cygwin/fhandler/process.cc
+++ b/winsup/cygwin/fhandler/process.cc
@@ -370,7 +370,7 @@ format_process_fd (void *data, char *&destbuf)
/* path looks like "$PID/fd", "$PID/fd/", "$PID/fd/[0-9]*". In the latter
case a trailing slash and more followup chars are allowed, provided the
descriptor symlink points to a directory. */
- char *fdp = strchr (path, '/') + 3;
+ char *fdp = const_cast<char *> (strchr (path, '/')) + 3;
/* The "fd" directory itself? */
if (fdp[0] =='\0' || (fdp[0] == '/' && fdp[1] == '\0'))
{
diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index 6f6164a859..1f497f9ce3 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -2206,7 +2206,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
If the reply for "CSI6n" is divided into multiple writes,
pseudo console sometimes does not recognize it. Therefore,
put them together into wpbuf and write all at once. */
- static const int wpbuf_len = strlen ("\033[32768;32868R");
+ static constexpr int wpbuf_len = sizeof ("\033[32768;32868R") - 1;
static char wpbuf[wpbuf_len];
static int ixput = 0;
static int state = 0;
@@ -3475,6 +3475,7 @@ fhandler_pty_slave::setup_pseudoconsole ()
get_ttyp ()->switch_to_nat_pipe = true;
HANDLE hpConIn, hpConOut;
+ HPCON hpcon = NULL;
if (get_ttyp ()->pcon_activated)
{ /* The pseudo console is already activated. */
if (GetStdHandle (STD_INPUT_HANDLE) == get_handle ())
@@ -3515,8 +3516,6 @@ fhandler_pty_slave::setup_pseudoconsole ()
PROCESS_INFORMATION pi;
HANDLE hello, goodbye;
HANDLE hr, hw;
- HPCON hpcon;
-
do
{ /* Create new pseudo console */
COORD size = {
diff --git a/winsup/cygwin/libc/bsdlib.cc b/winsup/cygwin/libc/bsdlib.cc
index 14df033353..87d26a46da 100644
--- a/winsup/cygwin/libc/bsdlib.cc
+++ b/winsup/cygwin/libc/bsdlib.cc
@@ -247,7 +247,7 @@ setprogname (const char *newprogname)
/* Per BSD man page, setprogname keeps a pointer to the last
path component of the argument. It does *not* copy the
argument before. */
- __progname = strrchr (newprogname, '/');
+ __progname = const_cast<char *> (strrchr (newprogname, '/'));
if (__progname)
++__progname;
else
diff --git a/winsup/cygwin/libc/fts.c b/winsup/cygwin/libc/fts.c
index 6f060e54e3..2d309994c8 100644
--- a/winsup/cygwin/libc/fts.c
+++ b/winsup/cygwin/libc/fts.c
@@ -123,10 +123,8 @@ static const char *ufslike_filesystems[] = {
#endif
FTS *
-fts_open(argv, options, compar)
- char * const *argv;
- int options;
- int (*compar)(const FTSENT * const *, const FTSENT * const *);
+fts_open(char * const *argv, int options,
+ int (*compar)(const FTSENT * const *, const FTSENT * const *))
{
struct _fts_private *priv;
FTS *sp;
diff --git a/winsup/cygwin/libc/rexec.cc b/winsup/cygwin/libc/rexec.cc
index 7e337f1e21..f34a8f0de8 100644
--- a/winsup/cygwin/libc/rexec.cc
+++ b/winsup/cygwin/libc/rexec.cc
@@ -192,7 +192,7 @@ next:
*/
if (strcasecmp(host, tokval) == 0)
goto match;
- if ((tmp = strchr(host, '.')) != NULL &&
+ if ((tmp = const_cast<char *> (strchr(host, '.'))) != NULL &&
strcasecmp(tmp, mydomain) == 0 &&
strncasecmp(host, tokval, tmp - host) == 0 &&
tokval[tmp - host] == '\0')
diff --git a/winsup/cygwin/libc/strptime.cc b/winsup/cygwin/libc/strptime.cc
index dc6771fe5e..cf1c3a7334 100644
--- a/winsup/cygwin/libc/strptime.cc
+++ b/winsup/cygwin/libc/strptime.cc
@@ -166,7 +166,7 @@ get_era_info (const char *era, locale_t locale)
era = c + 1;
}
/* era_C */
- c = strchr (era, ':');
+ c = const_cast<char *> (strchr (era, ':'));
len = c - era;
ei[cur].era_C = (CHAR *) malloc ((len + 1) * sizeof (CHAR));
if (!ei[cur].era_C)
@@ -180,9 +180,9 @@ get_era_info (const char *era, locale_t locale)
ei[cur].era_C[len] = '\0';
/* era_Y */
++era;
- c = strchr (era, ';');
+ c = const_cast<char *> (strchr (era, ';'));
if (!c)
- c = strchr (era, '\0');
+ c = const_cast<char *> (strchr (era, '\0'));
len = c - era;
ei[cur].era_Y = (CHAR *) malloc ((len + 1) * sizeof (CHAR));
if (!ei[cur].era_Y)
diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h
index 09e04c14f4..56bfc2c746 100644
--- a/winsup/cygwin/local_includes/fhandler.h
+++ b/winsup/cygwin/local_includes/fhandler.h
@@ -3196,7 +3196,6 @@ class fhandler_process_fd : public fhandler_process
class fhandler_procnet: public fhandler_proc
{
- pid_t pid;
public:
fhandler_procnet ();
fhandler_procnet (void *) {}
diff --git a/winsup/cygwin/local_includes/timerfd.h b/winsup/cygwin/local_includes/timerfd.h
index 80688e79ec..f6c09b5ae6 100644
--- a/winsup/cygwin/local_includes/timerfd.h
+++ b/winsup/cygwin/local_includes/timerfd.h
@@ -107,7 +107,8 @@ class timerfd_tracker /* cygheap! */
SetEvent (_disarm_evt);
return 0;
}
- void timer_expired () const { timer_expired (); }
+ void timer_expired () const
+ { const_cast<timerfd_tracker *> (this)->timer_expired (); }
LONG64 expiration_count () const { return tfd_shared->_expiration_count; }
void increment_expiration_count (LONG64 add) const
diff --git a/winsup/cygwin/mktemp.cc b/winsup/cygwin/mktemp.cc
index 710e432b40..99a5b7296b 100644
--- a/winsup/cygwin/mktemp.cc
+++ b/winsup/cygwin/mktemp.cc
@@ -59,7 +59,7 @@ static int
_gettemp(char *path, int *doopen, int domkdir, size_t suffixlen, int flags)
{
char *start, *trv, *suffp;
- char *pad;
+ const char *pad;
if (doopen && domkdir)
{
diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc
index f57465a4f2..94ea154854 100644
--- a/winsup/cygwin/nlsfuncs.cc
+++ b/winsup/cygwin/nlsfuncs.cc
@@ -1279,8 +1279,10 @@ extern "C" int
__wscollate_range_cmp (wint_t *c1, wint_t *c2,
size_t c1len, size_t c2len)
{
- wchar_t s1[c1len * 2 + 1] = { 0 }; /* # of chars if all are surrogates */
- wchar_t s2[c2len * 2 + 1] = { 0 };
+ wchar_t s1[c1len * 2 + 1]; /* # of chars if all are surrogates */
+ wchar_t s2[c2len * 2 + 1];
+ memset (s1, 0, sizeof s1);
+ memset (s2, 0, sizeof s2);
/* wcscoll() ignores case in many locales. but we don't want that
for filenames... */
@@ -1529,7 +1531,7 @@ __set_charset_from_locale (const char *loc, char *charset)
/* Cut out explicit codeset */
stpcpy (locale, loc);
- modifier = strchr (loc, '@');
+ modifier = const_cast<char *> (strchr (loc, '@'));
if ((c = strchr (locale, '.')))
stpcpy (c, modifier ?: "");
/* Ignore @cjk* modifiers, they are newlib specials. */
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index bcde89c5ac..87b1daa6d1 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3166,9 +3166,9 @@ suffix_scan::has (const char *in_path, const suffix_info *in_suffixes)
const char *fname = strrchr (in_path, '\\');
fname = fname ? fname + 1 : in_path;
- char *ext_here = strrchr (fname, '.');
+ char *ext_here = const_cast<char *> (strrchr (fname, '.'));
path = in_path;
- eopath = strchr (path, '\0');
+ eopath = const_cast<char *> (strchr (path, '\0'));
if (!ext_here)
goto noext;
diff --git a/winsup/cygwin/scripts/cygmagic b/winsup/cygwin/scripts/cygmagic
index eee4a3b734..ebfd261f9f 100755
--- a/winsup/cygwin/scripts/cygmagic
+++ b/winsup/cygwin/scripts/cygmagic
@@ -9,7 +9,8 @@
set -e
shopt -s -o pipefail
-shopt -s inherit_errexit
+# Bash 3.2 (still shipped by macOS) predates inherit_errexit.
+shopt -s inherit_errexit 2>/dev/null || true
file_magic=$1; shift
gcc=$1; shift
diff --git a/winsup/cygwin/scripts/gentls_offsets b/winsup/cygwin/scripts/gentls_offsets
index 040b5de6b5..422bd89dba 100755
--- a/winsup/cygwin/scripts/gentls_offsets
+++ b/winsup/cygwin/scripts/gentls_offsets
@@ -4,12 +4,14 @@ input_file=$1
output_file=$2
tmp_file=/tmp/${output_file}.$$
-trap "rm -f ${tmp_file}" 0 1 2 15
+if test -z "$KEEP_GENTLS_TEMP"; then
+ trap "rm -f ${tmp_file}" 0 1 2 15
+fi
# Preprocess cygtls.h and filter out only the member lines from
# class _cygtls to generate an input file for the cross compiler
# to generate the member offsets for tlsoffsets-$(target_cpu).h.
-${CXXCOMPILE} -E -P "${input_file}" 2> /dev/null | \
+${CXXCOMPILE} -x c++ -E -P "${input_file}" | tee ${tmp_file}.i | \
gawk '
BEGIN {
# marker is used to split out the member lines from class _cygtls
@@ -44,7 +46,7 @@ gawk '
print "extern \"C\" const uint32_t __CYGTLS__" $NF " = offsetof (class _cygtls, " $NF ");";
}
}
-' | \
+' | tee ${tmp_file}.cc | \
# Now run the compiler to generate an assembler file.
${CXXCOMPILE} -x c++ -g0 -S - -o ${tmp_file} && \
# The assembler file consists of lines like these:
@@ -62,7 +64,7 @@ start_offset=$(gawk '\
/^__CYGTLS__/ {
varname = gensub (/__CYGTLS__(\w+):/, "\\1", "g");
}
- /\s*\.long\s+/ {
+ /\s*\.(long|word)\s+/ {
if (length (varname) > 0) {
if (varname == "start_offset") {
print $2;
@@ -85,7 +87,7 @@ gawk -v start_offset="$start_offset" '\
varname = "";
}
}
- /\s*\.long\s+/ {
+ /\s*\.(long|word)\s+/ {
if (length (varname) > 0) {
if (varname == "start_offset") {
printf (".equ _cygtls.%s, -%u\n", varname, start_offset);
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 9408903659..ae3249621c 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -338,7 +338,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
int c_flags;
STARTUPINFOW si = {};
- int looped = 0;
fhandler_termios::spawn_worker term_spawn_worker;
@@ -890,7 +889,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
{
if (!proc_retry (pi.hProcess))
{
- looped++;
goto loop;
}
close_all_files (true);
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 6a935aac63..10a1615e63 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -5169,7 +5169,7 @@ pipe2 (int filedes[2], int mode)
extern "C" FILE *
tmpfile (void)
{
- char *dir = getenv ("TMPDIR");
+ const char *dir = getenv ("TMPDIR");
if (!dir)
dir = P_tmpdir;
int fd = open (dir, O_RDWR | O_BINARY | O_TMPFILE, S_IRUSR | S_IWUSR);
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index 3d3b804c83..78759e89b6 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -53,7 +53,8 @@ cygheap_user::init ()
if (GetEnvironmentVariableW (L"USERNAME", user_name, user_name_len)
|| GetEnvironmentVariableW (L"USER", user_name, user_name_len))
{
- char mb_user_name[user_name_len = sys_wcstombs (NULL, 0, user_name) + 1];
+ user_name_len = sys_wcstombs (NULL, 0, user_name) + 1;
+ char mb_user_name[user_name_len];
sys_wcstombs (mb_user_name, user_name_len, user_name);
set_name (mb_user_name);
}
@@ -614,7 +615,7 @@ void
cygheap_pwdgrp::nss_init_line (const char *line)
{
const char *c = line + strspn (line, " \t");
- char *comment = strchr (c, '#');
+ char *comment = const_cast<char *> (strchr (c, '#'));
if (comment)
*comment = '\0';
switch (*c)
@@ -842,7 +843,8 @@ fetch_from_description (PCWSTR desc, PCWSTR search, size_t len)
PWCHAR s, e;
char *ret = NULL;
- if ((s = wcsstr (desc, L"<cygwin ")) && (e = wcsstr (s + 8, L"/>")))
+ if ((s = const_cast<PWCHAR> (wcsstr (desc, L"<cygwin ")))
+ && (e = const_cast<PWCHAR> (wcsstr (s + 8, L"/>"))))
{
s += 8;
while (s && s < e)
@@ -1727,7 +1729,7 @@ pwdgrp::fetch_account_from_line (fetch_user_arg_t &arg, const char *line)
{
case SID_arg:
/* Ignore fields, just scan for SID string. */
- if (!(p = strstr (line, arg.name)) || p[arg.len] != ':')
+ if (!(p = const_cast<char *> (strstr (line, arg.name))) || p[arg.len] != ':')
return NULL;
break;
case NAME_arg:
@@ -1737,7 +1739,8 @@ pwdgrp::fetch_account_from_line (fetch_user_arg_t &arg, const char *line)
break;
case ID_arg:
/* Skip to third field. */
- if (!(p = strchr (line, ':')) || !(p = strchr (p + 1, ':')))
+ if (!(p = const_cast<char *> (strchr (line, ':')))
+ || !(p = strchr (p + 1, ':')))
return NULL;
if (strtoul (p + 1, &e, 10) != arg.id || !e || *e != ':')
return NULL;
diff --git a/winsup/cygwin/winf.cc b/winsup/cygwin/winf.cc
index d0c5c440fb..9b3af03716 100644
--- a/winsup/cygwin/winf.cc
+++ b/winsup/cygwin/winf.cc
@@ -68,7 +68,7 @@ linebuf::fromargv (av& newargv, const char *real_path, bool cmdlenoverflow_ok)
bool success = true;
for (int i = 0; i < newargv.argc; i++)
{
- char *p = NULL;
+ const char *p = NULL;
const char *a;
a = i ? newargv[i] : (char *) real_path;
From 2dcfcda9f307ec324934071cceaa3686f25206cc Mon Sep 17 00:00:00 2001
From: Kreijstal <kreijstal@users.noreply.github.com>
Date: Sat, 18 Jul 2026 05:07:06 +0200
Subject: [PATCH 3/7] newlib: support the AArch64 MSYS PE ABI
Adapt AArch64 assembly and setjmp for PE/COFF, provide ARM64-only weak aliases without STABS, and select the long-double library sources appropriate for the LP64 MSYS ABI.
Assisted-by: OpenAI Codex: GPT-5
---
newlib/configure.ac | 1 +
newlib/libc/include/sys/cdefs.h | 9 ++++++++-
newlib/libc/machine/aarch64/asmdefs.h | 24 +++++++++++++++++++++---
newlib/libc/machine/aarch64/rawmemchr.S | 7 +++++--
newlib/libc/machine/aarch64/setjmp.S | 8 ++++++++
newlib/libm/Makefile.inc | 4 ++++
6 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/newlib/configure.ac b/newlib/configure.ac
index a4807830ed..7eb8b9e077 100644
--- a/newlib/configure.ac
+++ b/newlib/configure.ac
@@ -723,6 +723,7 @@ rm -f conftest*])
if test $newlib_cv_ldbl_eq_dbl = yes; then
AC_DEFINE(_LDBL_EQ_DBL, 1, [Define if the platform long double type is equal to double.])
fi
+AM_CONDITIONAL(LDBL_EQ_DBL, test x"$newlib_cv_ldbl_eq_dbl" = x"yes")
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
diff --git a/newlib/libc/include/sys/cdefs.h b/newlib/libc/include/sys/cdefs.h
index d13a92a79e..806819aaf6 100644
--- a/newlib/libc/include/sys/cdefs.h
+++ b/newlib/libc/include/sys/cdefs.h
@@ -543,7 +543,14 @@
#if defined(__GNUC__)
#define __strong_reference(sym,aliassym) \
extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)))
-#ifdef __ELF__
+#if (defined(__CYGWIN__) || defined(__MSYS__)) && defined(__aarch64__)
+/* ARM64 PE/COFF has no STABS support. Keep weak aliases in ordinary
+ assembler syntax and omit link-time advisory strings. */
+#define __weak_reference(sym,alias) \
+ __asm__(".weak " #alias); \
+ __asm__(".equ " #alias ", " #sym)
+#define __warn_references(sym,msg)
+#elif defined(__ELF__)
#ifdef __STDC__
#define __weak_reference(sym,alias) \
__asm__(".weak " #alias); \
diff --git a/newlib/libc/machine/aarch64/asmdefs.h b/newlib/libc/machine/aarch64/asmdefs.h
index 131b95e1fe..cbb7292f05 100644
--- a/newlib/libc/machine/aarch64/asmdefs.h
+++ b/newlib/libc/machine/aarch64/asmdefs.h
@@ -50,7 +50,9 @@
/* If set then the GNU Property Note section will be added to
mark objects to support BTI and PAC-RET. */
-#ifndef WANT_GNU_PROPERTY
+#if defined(__CYGWIN__) || defined(__MSYS__)
+#define WANT_GNU_PROPERTY 0
+#elif !defined(WANT_GNU_PROPERTY)
#define WANT_GNU_PROPERTY 1
#endif
@@ -59,15 +61,28 @@
GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI|FEATURE_1_PAC)
#endif
+#if defined(__CYGWIN__) || defined(__MSYS__)
#define ENTRY_ALIGN(name, alignment) \
.global name; \
- .type name,%function; \
.align alignment; \
name: \
.cfi_startproc; \
BTI_C;
-#define ENTRY(name) ENTRY_ALIGN(name, 6)
+#define ENTRY_ALIAS(name) \
+ .global name; \
+ name:
+
+#define END(name) \
+ .cfi_endproc;
+#else
+#define ENTRY_ALIGN(name, alignment) \
+ .global name; \
+ .type name,%function; \
+ .align alignment; \
+ name: \
+ .cfi_startproc; \
+ BTI_C;
#define ENTRY_ALIAS(name) \
.global name; \
@@ -77,6 +92,9 @@ GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI|FEATURE_1_PAC)
#define END(name) \
.cfi_endproc; \
.size name, .-name;
+#endif
+
+#define ENTRY(name) ENTRY_ALIGN(name, 6)
#define L(l) .L ## l
diff --git a/newlib/libc/machine/aarch64/rawmemchr.S b/newlib/libc/machine/aarch64/rawmemchr.S
index 26da810054..1b4d58438e 100644
--- a/newlib/libc/machine/aarch64/rawmemchr.S
+++ b/newlib/libc/machine/aarch64/rawmemchr.S
@@ -40,7 +40,9 @@
.text
.p2align \p2align
.global \f
+#if !defined(__CYGWIN__) && !defined(__MSYS__)
.type \f, %function
+#endif
\f:
.endm
@@ -63,6 +65,7 @@ L(do_strlen):
ret x15
.cfi_endproc
- .size rawmemchr, . - rawmemchr
+#if !defined(__CYGWIN__) && !defined(__MSYS__)
+ .size rawmemchr, . - rawmemchr
+#endif
#endif
-
diff --git a/newlib/libc/machine/aarch64/setjmp.S b/newlib/libc/machine/aarch64/setjmp.S
index 0856145bf4..2c1cadf97f 100644
--- a/newlib/libc/machine/aarch64/setjmp.S
+++ b/newlib/libc/machine/aarch64/setjmp.S
@@ -43,7 +43,9 @@
// int setjmp (jmp_buf)
.global setjmp
+#if !defined(__CYGWIN__) && !defined(__MSYS__)
.type setjmp, %function
+#endif
setjmp:
mov x16, sp
#define REG_PAIR(REG1, REG2, OFFS) stp REG1, REG2, [x0, OFFS]
@@ -54,11 +56,15 @@ setjmp:
#undef REG_ONE
mov w0, #0
ret
+#if !defined(__CYGWIN__) && !defined(__MSYS__)
.size setjmp, .-setjmp
+#endif
// void longjmp (jmp_buf, int) __attribute__ ((noreturn))
.global longjmp
+#if !defined(__CYGWIN__) && !defined(__MSYS__)
.type longjmp, %function
+#endif
longjmp:
#define REG_PAIR(REG1, REG2, OFFS) ldp REG1, REG2, [x0, OFFS]
#define REG_ONE(REG1, OFFS) ldr REG1, [x0, OFFS]
@@ -71,4 +77,6 @@ longjmp:
cinc w0, w1, eq
// use br not ret, as ret is guaranteed to mispredict
br x30
+#if !defined(__CYGWIN__) && !defined(__MSYS__)
.size longjmp, .-longjmp
+#endif
diff --git a/newlib/libm/Makefile.inc b/newlib/libm/Makefile.inc
index bf31b1be78..caf95b40f1 100644
--- a/newlib/libm/Makefile.inc
+++ b/newlib/libm/Makefile.inc
@@ -46,7 +46,9 @@ endif
include %D%/common/Makefile.inc
if HAVE_FPMATH_H
+if !LDBL_EQ_DBL
include %D%/ld/Makefile.inc
+endif
endif # HAVE_FPMATH_H
include %D%/complex/Makefile.inc
@@ -55,8 +57,10 @@ include %D%/test/Makefile.inc
if HAVE_LIBM_MACHINE_AARCH64
include %D%/machine/aarch64/Makefile.inc
+if !LDBL_EQ_DBL
include %D%/ld128/Makefile.inc
endif
+endif
if HAVE_LIBM_MACHINE_AMDGCN
include %D%/machine/amdgcn/Makefile.inc
endif
From c12688950cccb16a7da8f3e18b979a76a832779c Mon Sep 17 00:00:00 2001
From: Kreijstal <kreijstal@users.noreply.github.com>
Date: Sat, 18 Jul 2026 05:07:06 +0200
Subject: [PATCH 4/7] winsup: add the Windows ARM64 runtime implementation
Implement ARM64 startup, autoload thunks, TLS, signal contexts, exception handling, allocator bootstrap, import decoding, fork reconstruction, child-start retry, linker layout, and compatibility exports. Architecture-specific behavior is guarded from the x86_64 path.
Assisted-by: OpenAI Codex: GPT-5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---
winsup/cygwin/aarch64/compat.c | 42 +++++++
winsup/cygwin/aarch64/signal_stubs.S | 46 +++++++
winsup/cygwin/autoload.cc | 152 +++++++++++++++++++++++
winsup/cygwin/create_posix_thread.cc | 25 +++-
winsup/cygwin/cygwin.sc.in | 17 +++
winsup/cygwin/dcrt0.cc | 24 ++++
winsup/cygwin/exceptions.cc | 67 +++++++++-
winsup/cygwin/fhandler/socket_inet.cc | 6 +-
winsup/cygwin/fork.cc | 15 +++
winsup/cygwin/include/cygwin/config.h | 6 +
winsup/cygwin/include/cygwin/signal.h | 33 ++++-
winsup/cygwin/include/machine/_endian.h | 8 ++
winsup/cygwin/lib/_cygwin_crt0_common.cc | 24 ++++
winsup/cygwin/libstdcxx_wrapper.cc | 27 +++-
winsup/cygwin/local_includes/cpuid.h | 14 ++-
winsup/cygwin/local_includes/cygmalloc.h | 7 ++
winsup/cygwin/local_includes/cygtls.h | 16 +++
winsup/cygwin/local_includes/exception.h | 10 ++
winsup/cygwin/mm/heap.cc | 14 +++
winsup/cygwin/mm/malloc.cc | 45 +++++++
winsup/cygwin/mm/malloc_wrapper.cc | 26 ++++
winsup/cygwin/profil.c | 3 +-
winsup/cygwin/resource.cc | 4 +
winsup/cygwin/scripts/gendef | 23 ++++
winsup/cygwin/scripts/mkimport | 11 ++
winsup/cygwin/sigproc.cc | 22 +++-
winsup/cygwin/thread.cc | 13 ++
winsup/cygwin/wincap.cc | 4 +
28 files changed, 693 insertions(+), 11 deletions(-)
create mode 100644 winsup/cygwin/aarch64/compat.c
create mode 100644 winsup/cygwin/aarch64/signal_stubs.S
diff --git a/winsup/cygwin/aarch64/compat.c b/winsup/cygwin/aarch64/compat.c
new file mode 100644
index 0000000000..c40246cbd3
--- /dev/null
+++ b/winsup/cygwin/aarch64/compat.c
@@ -0,0 +1,42 @@
+/* ARM64 compatibility exports that have no implementation in newlib's
+ generic AArch64 configuration. */
+
+#include <stdint.h>
+
+#define FE_ALL_EXCEPT 0x1f
+#define FPCR_ENABLE_SHIFT 8
+
+/* Kept for ABI compatibility with pre-locale Cygwin clients. */
+const char _ctype_[384] = { 0 };
+
+/* ARM64 has a single floating-point format and no x87-style precision mode. */
+static const uint64_t arm64_fe_nomask_env = FE_ALL_EXCEPT << FPCR_ENABLE_SHIFT;
+const uint64_t *_fe_nomask_env = &arm64_fe_nomask_env;
+
+int
+fedisableexcept (int mask)
+{
+ uint64_t old_fpcr;
+ uint64_t new_fpcr;
+
+ __asm__ volatile ("mrs %0, fpcr" : "=r" (old_fpcr));
+ new_fpcr = old_fpcr & ~((uint64_t) (mask & FE_ALL_EXCEPT)
+ << FPCR_ENABLE_SHIFT);
+ __asm__ volatile ("msr fpcr, %0" : : "r" (new_fpcr));
+ return (old_fpcr >> FPCR_ENABLE_SHIFT) & FE_ALL_EXCEPT;
+}
+
+int
+fegetexcept (void)
+{
+ uint64_t fpcr;
+
+ __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr));
+ return (fpcr >> FPCR_ENABLE_SHIFT) & FE_ALL_EXCEPT;
+}
+
+double
+scalbl (double x, long exponent)
+{
+ return __builtin_scalbln (x, exponent);
+}
diff --git a/winsup/cygwin/aarch64/signal_stubs.S b/winsup/cygwin/aarch64/signal_stubs.S
new file mode 100644
index 0000000000..4d7dc3cbde
--- /dev/null
+++ b/winsup/cygwin/aarch64/signal_stubs.S
@@ -0,0 +1,46 @@
+/* Temporary ARM64 link veneers. These establish the symbols required by the
+ runtime while the full TLS signal-stack transition is being ported. */
+ .text
+ .p2align 2
+ .global sigdelayed
+ .global _sigbe
+ .global _sigdelayed_end
+sigdelayed:
+_sigbe:
+ ret
+_sigdelayed_end:
+
+ /* sigsetjmp/siglongjmp, mirroring the x86_64 versions in gendef.
+ The AArch64 newlib jmp_buf (_JBLEN 22, see machine/setjmp.h) holds
+ x19-x30, sp and d8-d15 in its first 176 bytes; sigjmp_buf appends
+ the savemask flag at byte 176 (_SAVEMASK) and the saved sigset_t
+ at byte 184 (_SIGMASK).
+
+ Keep the ABI exports out of the early loader text. */
+ .section .text.zsigsetjmp,"xr"
+ .p2align 2
+ .global sigsetjmp
+sigsetjmp:
+ str w1, [x0, #176] /* buf[_SAVEMASK] = savemask */
+ cbz w1, 1f /* mask not requested, plain setjmp */
+ stp x0, x30, [sp, #-16]!
+ add x2, x0, #184 /* oset = &buf[_SIGMASK] */
+ mov x1, xzr /* set = NULL */
+ mov w0, #0 /* how = SIG_SETMASK */
+ bl pthread_sigmask
+ ldp x0, x30, [sp], #16
+1: b setjmp
+
+ .global siglongjmp
+siglongjmp:
+ ldr w2, [x0, #176] /* buf[_SAVEMASK] set? */
+ cbz w2, 1f /* no, plain longjmp */
+ stp x0, x1, [sp, #-32]!
+ str x30, [sp, #16]
+ add x1, x0, #184 /* set = &buf[_SIGMASK] */
+ mov x2, xzr /* oset = NULL */
+ mov w0, #0 /* how = SIG_SETMASK */
+ bl pthread_sigmask
+ ldr x30, [sp, #16]
+ ldp x0, x1, [sp], #32
+1: b longjmp
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index d5d344d21d..526b4dd7da 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -83,6 +83,22 @@ bool NO_COPY wsock_started;
.set " #dllname "_primed, 1 \n\
.endif \n\
");
+#elif defined (__aarch64__)
+#define LoadDLLprime(dllname, init_also, no_resolve_on_fork) __asm__ ("\n\
+.ifndef " #dllname "_primed \n\
+ .section .data_cygwin_nocopy,\"w\" \n\
+ .p2align 3 \n\
+." #dllname "_info: \n\
+ .quad 0 \n\
+ .quad " #no_resolve_on_fork " \n\
+ .long -1 \n\
+ .long 0 \n\
+ .quad " #init_also " \n\
+ .asciz \"" #dllname ".dll\" \n\
+ .text \n\
+ .set " #dllname "_primed, 1 \n\
+.endif \n\
+");
#else
#error unimplemented for this target
#endif
@@ -123,6 +139,63 @@ _win32_" #name ": \n\
.asciz \"" #name "\" \n\
.text \n\
");
+#elif defined (__aarch64__)
+/* Windows ARM64 has no direct branch capable of spanning the full address
+ space. Keep a naturally aligned pointer beside each stub and use a generic
+ first-call path which preserves every register that may carry an argument. */
+#define LoadDLLfuncEx3(name, dllname, notimp, err, no_resolve_on_fork) \
+ LoadDLLprime (dllname, dll_func_load, no_resolve_on_fork) \
+ __asm__ (" \n\
+ .section ." #dllname "_autoload_text,\"xr\" \n\
+ .global " #name " \n\
+ .global _win32_" #name " \n\
+ .p2align 4 \n\
+" #name ": \n\
+_win32_" #name ": \n\
+ adrp x16, 3f \n\
+ add x16, x16, :lo12:3f \n\
+ ldr x17, [x16] \n\
+ cbz x17, 1f \n\
+ br x17 \n\
+1:sub sp, sp, #208 \n\
+ stp x0, x1, [sp, #0] \n\
+ stp x2, x3, [sp, #16] \n\
+ stp x4, x5, [sp, #32] \n\
+ stp x6, x7, [sp, #48] \n\
+ stp q0, q1, [sp, #64] \n\
+ stp q2, q3, [sp, #96] \n\
+ stp q4, q5, [sp, #128] \n\
+ stp q6, q7, [sp, #160] \n\
+ str x30, [sp, #192] \n\
+ adrp x0, 2f \n\
+ add x0, x0, :lo12:2f \n\
+ bl autoload_resolve_arm64 \n\
+ mov x17, x0 \n\
+ ldp x0, x1, [sp, #0] \n\
+ ldp x2, x3, [sp, #16] \n\
+ ldp x4, x5, [sp, #32] \n\
+ ldp x6, x7, [sp, #48] \n\
+ ldp q0, q1, [sp, #64] \n\
+ ldp q2, q3, [sp, #96] \n\
+ ldp q4, q5, [sp, #128] \n\
+ ldp q6, q7, [sp, #160] \n\
+ ldr x30, [sp, #192] \n\
+ add sp, sp, #208 \n\
+ cbnz x17, 4f \n\
+ adrp x16, 2f \n\
+ add x16, x16, :lo12:2f \n\
+ ldrsh w0, [x16, #10] \n\
+ ret \n\
+4:br x17 \n\
+ .p2align 3 \n\
+2:.quad ." #dllname "_info \n\
+ .hword " #notimp " \n\
+ .hword ((" #err ") & 0xffff) \n\
+ .long 0 \n\
+3:.quad 0 \n\
+ .asciz \"" #name "\" \n\
+ .text \n\
+");
#else
#error unimplemented for this target
#endif
@@ -203,6 +276,11 @@ dll_chain: \n\
push %rax # Restore 'return address' \n\
jmp *%rdx # Jump to next init function \n\
");
+#elif defined (__aarch64__)
+/* ARM64 resolves through autoload_resolve_arm64 below; these symbols remain
+ as data markers used by the common DLL metadata. */
+void dll_func_load () {}
+void dll_chain () {}
#else
#error unimplemented for this target
#endif
@@ -216,7 +294,11 @@ struct dll_info
HANDLE handle;
LONG here;
void (*init) ();
+#ifdef __aarch64__
+ char name[];
+#else
WCHAR name[];
+#endif
};
struct func_info
@@ -239,6 +321,7 @@ union retchain
http://www.microsoft.com/technet/security/advisory/2269637.mspx
https://msdn.microsoft.com/library/ff919712 */
+#ifndef __aarch64__
static __inline bool
dll_load (HANDLE& handle, PWCHAR name)
{
@@ -256,6 +339,27 @@ dll_load (HANDLE& handle, PWCHAR name)
handle = h;
return true;
}
+#endif
+
+#ifdef __aarch64__
+static __inline bool
+dll_load (HANDLE& handle, const char *name)
+{
+ char dll_path[MAX_PATH];
+ size_t prefix = wcstombs (dll_path, windows_system_directory,
+ sizeof dll_path - 1);
+ if (prefix == (size_t) -1 || prefix >= sizeof dll_path)
+ return false;
+ strlcpy (dll_path + prefix, name, sizeof dll_path - prefix);
+ HANDLE h = LoadLibraryA (dll_path);
+ if (!h)
+ h = LoadLibraryA (name);
+ if (!h)
+ return false;
+ handle = h;
+ return true;
+}
+#endif
#define RETRY_COUNT 10
@@ -300,6 +404,9 @@ _" #func ": \n\
INIT_WRAPPER (std_dll_init)
+#elif defined (__aarch64__)
+/* ARM64 does not rewrite a caller return address. Its first-call stub passes
+ func_info directly to the resolver, so no ABI wrapper is required. */
#else
#error unimplemented for this target
#endif
@@ -345,7 +452,11 @@ std_dll_init (struct func_info *func)
if ((func->decoration & 1))
dll->handle = INVALID_HANDLE_VALUE;
else
+#ifdef __aarch64__
+ api_fatal ("unable to load %s, %E", dll->name);
+#else
api_fatal ("unable to load %W, %E", dll->name);
+#endif
}
fesetenv (&fpuenv);
}
@@ -363,6 +474,8 @@ std_dll_init (struct func_info *func)
#ifdef __x86_64__
/* See above comment preceeding std_dll_init. */
INIT_WRAPPER (wsock_init)
+#elif defined (__aarch64__)
+/* The ARM64 resolver calls the implementation directly. */
#else
#error unimplemented for this target
#endif
@@ -413,6 +526,45 @@ wsock_init (struct func_info *func)
return ret.ll;
}
+#ifdef __aarch64__
+extern "C" two_addr_t
+_wsock_init (struct func_info *func)
+{
+ return wsock_init (func);
+}
+
+/* Resolve one generated stub. The assembly caller has saved x0-x7 and
+ q0-q7, so this function may freely use the normal Windows ARM64 ABI. */
+extern "C" uintptr_t
+autoload_resolve_arm64 (struct func_info *func)
+{
+ struct dll_info *dll = func->dll;
+
+ if ((uintptr_t) dll->handle <= 1)
+ std_dll_init (func);
+
+ /* winsock has one extra, process-wide initialization step. */
+ if (dll->init == (void (*) ()) _wsock_init)
+ wsock_init (func);
+
+ FARPROC addr = GetProcAddress ((HMODULE) dll->handle, func->name);
+ if (!addr)
+ {
+ if (func->decoration & 1)
+ {
+ SetLastError (ERROR_PROC_NOT_FOUND);
+ return 0;
+ }
+ api_fatal ("couldn't dynamically determine load address for '%s' "
+ "(handle %p), %E", func->name, dll->handle);
+ }
+
+ InterlockedExchangePointer ((PVOID volatile *) &func->func_addr,
+ (PVOID) addr);
+ return (uintptr_t) addr;
+}
+#endif
+
LoadDLLprime (ws2_32, _wsock_init, 0)
LoadDLLfunc (CheckTokenMembership, advapi32)
diff --git a/winsup/cygwin/create_posix_thread.cc b/winsup/cygwin/create_posix_thread.cc
index 3fcd617072..4c4b2d4d8f 100644
--- a/winsup/cygwin/create_posix_thread.cc
+++ b/winsup/cygwin/create_posix_thread.cc
@@ -99,6 +99,27 @@ pthread_wrapper (PVOID arg)
call *%%r12 # Call thread func \n"
: : [WRAPPER_ARG] "o" (wrapper_arg),
[CYGTLS] "i" (__CYGTLS_PADSIZE__));
+#elif defined (__aarch64__)
+ __asm__ volatile ("\n\
+ mov x9, %[WRAPPER_ARG] \n\
+ ldr x19, [x9, #0] // thread function \n\
+ ldr x20, [x9, #8] // thread argument \n\
+ ldr x0, [x9, #16] // old OS stack allocation \n\
+ ldr x21, [x9, #24] // new stack base \n\
+ mov sp, x21 \n\
+ mov x10, %[CYGTLS] \n\
+ sub sp, sp, x10 \n\
+ mov x1, xzr // dwSize: 0 \n\
+ mov x2, #0x8000 // dwFreeType: MEM_RELEASE \n\
+ bl VirtualFree \n\
+ mov x0, x20 \n\
+ blr x19 \n\
+"
+ :
+ : [WRAPPER_ARG] "r" (&wrapper_arg),
+ [CYGTLS] "i" (__CYGTLS_PADSIZE__)
+ : "x0", "x1", "x2", "x9", "x10", "x19", "x20", "x21",
+ "x30", "memory");
#else
#error unimplemented for this target
#endif
@@ -124,7 +145,7 @@ class thread_allocator
THREAD_STACK_SLOT
};
/* g++ 11.2 workaround: don't use initializer */
- MEM_EXTENDED_PARAMETER thread_ext = { 0 };
+ MEM_EXTENDED_PARAMETER thread_ext = {{ 0 }};
thread_ext.Type = MemExtendedParameterAddressRequirements;
thread_ext.Pointer = (PVOID) &thread_req;
@@ -145,7 +166,7 @@ class thread_allocator
THREAD_STACK_SLOT
};
/* g++ 11.2 workaround: don't use initializer */
- MEM_EXTENDED_PARAMETER mmap_ext = { 0 };
+ MEM_EXTENDED_PARAMETER mmap_ext = {{ 0 }};
mmap_ext.Type = MemExtendedParameterAddressRequirements;
mmap_ext.Pointer = (PVOID) &mmap_req;
diff --git a/winsup/cygwin/cygwin.sc.in b/winsup/cygwin/cygwin.sc.in
index 4dc5daed8d..a959c879fe 100644
--- a/winsup/cygwin/cygwin.sc.in
+++ b/winsup/cygwin/cygwin.sc.in
@@ -5,6 +5,13 @@ SEARCH_DIR("/usr/x86_64-pc-msys/lib/w32api"); SEARCH_DIR("=/usr/lib/w32api");
# else
SEARCH_DIR("/usr/x86_64-pc-cygwin/lib/w32api"); SEARCH_DIR("=/usr/lib/w32api");
# endif
+#elif defined(__aarch64__)
+OUTPUT_FORMAT(pei-aarch64-little)
+# ifdef __MSYS__
+SEARCH_DIR("/usr/aarch64-pc-msys/lib/w32api"); SEARCH_DIR("=/usr/lib/w32api");
+# else
+SEARCH_DIR("/usr/aarch64-pc-cygwin/lib/w32api"); SEARCH_DIR("=/usr/lib/w32api");
+# endif
#else
#error unimplemented for this target
#endif
@@ -27,6 +34,14 @@ SECTIONS
LONG (-1); LONG (-1); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0); LONG (0);
___DTOR_LIST__ = .; __DTOR_LIST__ = .;
LONG (-1); LONG (-1); *(SORT(.dtors.*)); *(.dtors); *(.dtor); LONG (0); LONG (0);
+#elif defined(__aarch64__)
+ /* The runtime iterates constructor and destructor lists as function
+ pointers. Use complete 64-bit sentinels on the 64-bit ARM target. */
+ . = ALIGN(8);
+ ___CTOR_LIST__ = .; __CTOR_LIST__ = .;
+ LONG (0); LONG (0); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0); LONG (0);
+ ___DTOR_LIST__ = .; __DTOR_LIST__ = .;
+ LONG (0); LONG (0); *(SORT(.dtors.*)); *(.dtors); *(.dtor); LONG (0); LONG (0);
#else
___CTOR_LIST__ = .; __CTOR_LIST__ = .;
LONG (-1); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0);
@@ -141,6 +156,8 @@ SECTIONS
.debug_pubtypes ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_pubtypes) }
/* DWARF 2 */
.debug_info ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_info) }
+ .debug_addr ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_addr) }
+ .debug_str_offsets ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_str_offsets) }
.debug_abbrev ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
.debug_line ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_line) }
.debug_frame ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_frame) }
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 33cad1e3fe..65a147b919 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -584,9 +584,19 @@ get_cygwin_startup_info ()
void
child_info_fork::handle_fork ()
{
+#ifdef __aarch64__
+ parent = OpenProcess (PROCESS_VM_READ, FALSE, parent_winpid);
+ if (!parent)
+ api_fatal ("unable to reopen fork parent %u, %E", parent_winpid);
+#endif
cygheap_fixup_in_child (false);
memory_init ();
myself.thisproc (NULL);
+#ifdef __aarch64__
+ /* thisproc creates the replacement ARM64 process mapping. Keep the
+ process-global pinfo wrapper from releasing it during teardown. */
+ myself.preserve ();
+#endif
myself->uid = cygheap->user.real_uid;
myself->gid = cygheap->user.real_gid;
@@ -641,11 +651,18 @@ child_info_spawn::handle_spawn ()
{
extern void fixup_lockf_after_exec (bool);
HANDLE h = INVALID_HANDLE_VALUE;
+#ifdef __aarch64__
+ if (!get_parent_handle ())
+ api_fatal ("unable to reopen spawn parent %u, %E", parent_winpid);
+ cygheap_fixup_in_child (true);
+ memory_init ();
+#else
if (!dynamically_loaded || get_parent_handle ())
{
cygheap_fixup_in_child (true);
memory_init ();
}
+#endif
cygheap->pid = cygpid;
@@ -1051,6 +1068,13 @@ _dll_crt0 ()
movq %%rsp, %%rbp \n\
subq $32,%%rsp \n"
: : [ADDR] "r" (stackaddr));
+#elif defined (__aarch64__)
+ /* Windows ARM64 keeps SP 16-byte aligned. Establish a fresh
+ frame record on the relocated stack before making calls. */
+ __asm__ volatile ("mov sp, %[ADDR]\n\t"
+ "mov x29, sp\n\t"
+ "sub sp, sp, #32"
+ : : [ADDR] "r" (stackaddr) : "memory");
#else
#error unimplemented for this target
#endif
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index ca86b36438..90107f5905 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -44,6 +44,14 @@ details. */
#define _MC_instPtr rip
#define _MC_stackPtr rsp
#define _MC_uclinkReg rbx /* MUST be callee-saved reg */
+#elif defined (__aarch64__)
+#define _CX_instPtr Pc
+#define _CX_stackPtr Sp
+#define _CX_framePtr Fp
+#define _MC_retReg x[0]
+#define _MC_instPtr pc
+#define _MC_stackPtr sp
+#define _MC_uclinkReg x[19] /* x19 is callee-saved */
#else
#error unimplemented for this target
#endif
@@ -251,6 +259,23 @@ cygwin_exception::dump_exception ()
small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
ctx->SegCs, ctx->SegDs, ctx->SegEs, ctx->SegFs,
ctx->SegGs, ctx->SegSs);
+#elif defined (__aarch64__)
+ if (exception_name)
+ small_printf ("Exception: %s at pc=%016X\r\n", exception_name, ctx->Pc);
+ else
+ small_printf ("Signal %d at pc=%016X\r\n", e->ExceptionCode, ctx->Pc);
+ small_printf ("x0 =%016X x1 =%016X x2 =%016X\r\n",
+ ctx->X0, ctx->X1, ctx->X2);
+ small_printf ("x3 =%016X x4 =%016X x5 =%016X\r\n",
+ ctx->X3, ctx->X4, ctx->X5);
+ small_printf ("x6 =%016X x7 =%016X x8 =%016X\r\n",
+ ctx->X6, ctx->X7, ctx->X8);
+ small_printf ("x19=%016X x20=%016X x21=%016X\r\n",
+ ctx->X19, ctx->X20, ctx->X21);
+ small_printf ("fp =%016X lr =%016X sp =%016X\r\n",
+ ctx->Fp, ctx->Lr, ctx->Sp);
+ small_printf ("program=%W, pid %u, thread %s\r\n",
+ myself->progname, myself->pid, mythreadname ());
#else
#error unimplemented for this target
#endif
@@ -324,8 +349,13 @@ __unwind_single_frame (PCONTEXT ctx)
&establisher, NULL);
else
{
+#ifdef __aarch64__
+ ctx->_CX_instPtr = ctx->Lr;
+ ctx->Lr = 0;
+#else
ctx->_CX_instPtr = *(ULONG_PTR *) ctx->_CX_stackPtr;
ctx->_CX_stackPtr += 8;
+#endif
}
}
@@ -1111,7 +1141,7 @@ out:
return interrupted;
}
-static inline bool
+static inline bool __attribute__ ((unused))
has_visible_window_station ()
{
HWINSTA station_hdl;
@@ -1816,6 +1846,8 @@ _cygtls::call_signal_handler ()
{
#ifdef __x86_64__
context1.uc_mcontext.rip = retaddr ();
+#elif defined (__aarch64__)
+ context1.uc_mcontext.pc = (uintptr_t) retaddr ();
#else
#error unimplemented for this target
#endif
@@ -1935,6 +1967,11 @@ _cygtls::call_signal_handler ()
[FUNC] "o" (thisfunc),
[WRAPPER] "o" (altstack_wrapper)
: "memory");
+#elif defined (__aarch64__)
+ /* TODO: switch SP in a dedicated out-of-line ARM64 SEH thunk. Calling
+ through the wrapper keeps signal delivery functional while bringing
+ up the rest of the runtime, but SA_ONSTACK is not yet honoured. */
+ altstack_wrapper (thissig, &thissi, thiscontext, thisfunc);
#else
#error unimplemented for this target
#endif
@@ -2076,6 +2113,23 @@ __cont_link_context: \n\
.seh_endproc \n\
");
+#elif defined (__aarch64__)
+/* x19 contains the address of the saved uc_link slot. */
+__asm__ ("\t\t\t\t\n\
+\t.global\t__cont_link_context\t\n\
+\t.seh_proc __cont_link_context\t\n\
+__cont_link_context:\t\t\t\n\
+\t.seh_endprologue\t\t\n\
+\tmov\tsp, x19\t\t\n\
+\tldr\tx0, [x19]\t\t\n\
+\tcbz\tx0, 1f\t\t\n\
+\tbl\tsetcontext\t\t\n\
+\tmov\tx0, #255\t\t\n\
+1:\t\t\t\t\n\
+\tbl\tcygwin_exit\t\t\n\
+\tbrk\t#0\t\t\t\n\
+\t.seh_endproc\t\t\t\n\
+\t");
#else
#error unimplemented for this target
#endif
@@ -2141,6 +2195,14 @@ makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
sp[i + 1] = va_arg (ap, uintptr_t);
break;
}
+#elif defined (__aarch64__)
+ {
+ uintptr_t arg = va_arg (ap, uintptr_t);
+ if (i < 8)
+ ucp->uc_mcontext.x[i] = arg;
+ else
+ sp[i + 1] = arg;
+ }
#else
#error unimplemented for this target
#endif
@@ -2156,4 +2218,7 @@ makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
ucp->uc_mcontext._MC_instPtr = (uint64_t) func;
ucp->uc_mcontext._MC_stackPtr = (uint64_t) sp;
ucp->uc_mcontext._MC_uclinkReg = (uint64_t) (sp + argc + 1);
+#ifdef __aarch64__
+ ucp->uc_mcontext.x[30] = (uint64_t) __cont_link_context;
+#endif
}
diff --git a/winsup/cygwin/fhandler/socket_inet.cc b/winsup/cygwin/fhandler/socket_inet.cc
index 5ed0cb0ec7..85275e59d7 100644
--- a/winsup/cygwin/fhandler/socket_inet.cc
+++ b/winsup/cygwin/fhandler/socket_inet.cc
@@ -70,9 +70,13 @@
ReleaseMutex (wsock_mtx); \
}
+#ifdef __aarch64__
+static wsa_event wsa_events[NUM_SOCKS] __attribute__((section (".cygwin_dll_common")));
+static LONG socket_serial_number __attribute__((section (".cygwin_dll_common")));
+#else
static wsa_event wsa_events[NUM_SOCKS] __attribute__((section (".cygwin_dll_common"), shared));
-
static LONG socket_serial_number __attribute__((section (".cygwin_dll_common"), shared));
+#endif
static HANDLE wsa_slot_mtx;
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 2aa52737ca..2c63ac57b1 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -95,7 +95,14 @@ bool
frok::error (const char *fmt, ...)
{
DWORD exit_code = ch.exit_code;
+#ifdef __aarch64__
+ /* ARM64 QEMU child-start faults arrive as a child exit code; consult
+ proc_retry even then so it can recognize the transient cases before
+ the child has synchronized. */
+ if (hchild)
+#else
if (!exit_code && hchild)
+#endif
{
exit_code = ch.proc_retry (hchild);
if (!exit_code)
@@ -338,6 +345,12 @@ frok::parent (volatile char * volatile stack_here)
ch.refresh_cygheap ();
ch.prefork (); /* set up process tracking pipes. */
+#ifdef __aarch64__
+ /* ARM64 forkees reopen the parent instead of relying on an inherited
+ process handle, which is not stable across CreateProcess. */
+ ch.parent_winpid = GetCurrentProcessId ();
+#endif
+
*with_forkables = dlls.setup_forkables (*with_forkables);
ch.silentfail (!*with_forkables); /* fail silently without forkables */
@@ -667,6 +680,8 @@ dofork (void **proc, bool *with_forkables)
volatile char * volatile stackp;
#ifdef __x86_64__
__asm__ volatile ("movq %%rsp,%0": "=r" (stackp));
+#elif defined (__aarch64__)
+ __asm__ volatile ("mov %0, sp" : "=r" (stackp));
#else
#error unimplemented for this target
#endif
diff --git a/winsup/cygwin/include/cygwin/config.h b/winsup/cygwin/include/cygwin/config.h
index 2a70832789..a690117dc3 100644
--- a/winsup/cygwin/include/cygwin/config.h
+++ b/winsup/cygwin/include/cygwin/config.h
@@ -38,6 +38,12 @@ extern inline struct _reent *__getreent (void)
register char *ret;
#ifdef __x86_64__
__asm __volatile__ ("movq %%gs:8,%0" : "=r" (ret));
+#elif defined (__aarch64__)
+ /* Windows ARM64 reserves x18 as the TEB pointer. Cygwin/MSYS stores the
+ top of its per-thread cygtls area in the pointer slot at TEB + 8. */
+ register char *teb;
+ __asm __volatile__ ("mov %0, x18" : "=r" (teb));
+ ret = *(char **) (teb + 8);
#else
#error unimplemented for this target
#endif
diff --git a/winsup/cygwin/include/cygwin/signal.h b/winsup/cygwin/include/cygwin/signal.h
index de728bedec..1e935d6cb1 100644
--- a/winsup/cygwin/include/cygwin/signal.h
+++ b/winsup/cygwin/include/cygwin/signal.h
@@ -98,13 +98,44 @@ struct __attribute__ ((__aligned__ (16))) __mcontext
__uint64_t cr2;
};
+#elif defined (__aarch64__)
+
+struct _uc_neon128
+{
+ __uint64_t low;
+ __int64_t high;
+};
+
+/* Match Windows ARM64_NT_CONTEXT, followed by the two Cygwin fields. */
+struct __attribute__ ((__aligned__ (16))) __mcontext
+{
+ __uint32_t ctxflags;
+ __uint32_t cpsr;
+ __uint64_t x[31];
+ __uint64_t sp;
+ __uint64_t pc;
+ struct _uc_neon128 v[32];
+ __uint32_t fpcr;
+ __uint32_t fpsr;
+ __uint32_t bcr[8];
+ __uint64_t bvr[8];
+ __uint32_t wcr[2];
+ __uint64_t wvr[2];
+ __uint64_t oldmask;
+ __uint64_t cr2;
+};
+
#else
#error unimplemented for this target
#endif
/* Needed for GDB. It only compiles in the context copy code if this macro is
defined. This is not sizeof(CONTEXT) due to historical accidents. */
-#define __COPY_CONTEXT_SIZE 816
+#ifdef __aarch64__
+# define __COPY_CONTEXT_SIZE 912
+#else
+# define __COPY_CONTEXT_SIZE 816
+#endif
typedef union sigval
{
diff --git a/winsup/cygwin/include/machine/_endian.h b/winsup/cygwin/include/machine/_endian.h
index dbd4429b80..4cc59babf9 100644
--- a/winsup/cygwin/include/machine/_endian.h
+++ b/winsup/cygwin/include/machine/_endian.h
@@ -26,17 +26,25 @@ _ELIDABLE_INLINE __uint16_t __ntohs(__uint16_t);
_ELIDABLE_INLINE __uint32_t
__ntohl(__uint32_t _x)
{
+#ifdef __aarch64__
+ return __builtin_bswap32 (_x);
+#else
__asm__("bswap %0" : "=r" (_x) : "0" (_x));
return _x;
+#endif
}
_ELIDABLE_INLINE __uint16_t
__ntohs(__uint16_t _x)
{
+#ifdef __aarch64__
+ return __builtin_bswap16 (_x);
+#else
__asm__("xchgb %b0,%h0" /* swap bytes */
: "=Q" (_x)
: "0" (_x));
return _x;
+#endif
}
#define __htonl(_x) __ntohl(_x)
diff --git a/winsup/cygwin/lib/_cygwin_crt0_common.cc b/winsup/cygwin/lib/_cygwin_crt0_common.cc
index 801b6f91ca..72cb939008 100644
--- a/winsup/cygwin/lib/_cygwin_crt0_common.cc
+++ b/winsup/cygwin/lib/_cygwin_crt0_common.cc
@@ -27,6 +27,7 @@ details. */
references to these operators toward the redirectors in the Cygwin DLL; this
way we can record what definitions were visible at final link time but still
send all calls to the redirectors. */
+#ifndef __aarch64__
extern WEAK void *operator new(std::size_t sz) noexcept (false)
__asm__ (REAL_ZNWX);
extern WEAK void *operator new[](std::size_t sz) noexcept (false)
@@ -43,9 +44,25 @@ extern WEAK void operator delete(void *p, const std::nothrow_t &nt) noexcept (tr
__asm__ (REAL_ZDLPV_NOTHROW_T);
extern WEAK void operator delete[](void *p, const std::nothrow_t &nt) noexcept (true)
__asm__ (REAL_ZDAPV_NOTHROW_T);
+#else
+extern "C" WEAK void *__real__Znwm (std::size_t);
+extern "C" WEAK void *__real__Znam (std::size_t);
+extern "C" WEAK void __real__ZdlPv (void *);
+extern "C" WEAK void __real__ZdaPv (void *);
+extern "C" WEAK void *__real__ZnwmRKSt9nothrow_t (std::size_t,
+ const std::nothrow_t &);
+extern "C" WEAK void *__real__ZnamRKSt9nothrow_t (std::size_t,
+ const std::nothrow_t &);
+extern "C" WEAK void __real__ZdlPvRKSt9nothrow_t (void *,
+ const std::nothrow_t &);
+extern "C" WEAK void __real__ZdaPvRKSt9nothrow_t (void *,
+ const std::nothrow_t &);
+#endif
/* Avoid an info message from linker when linking applications. */
+#ifndef __aarch64__
extern __declspec(dllimport) struct _reent *_impure_ptr;
+#endif
/* Initialised in _cygwin_dll_entry. */
extern int __dynamically_loaded;
@@ -63,10 +80,17 @@ extern char __image_base__;
struct per_process_cxx_malloc __cygwin_cxx_malloc =
{
+#ifndef __aarch64__
&(operator new), &(operator new[]),
&(operator delete), &(operator delete[]),
&(operator new), &(operator new[]),
&(operator delete), &(operator delete[])
+#else
+ __real__Znwm, __real__Znam,
+ __real__ZdlPv, __real__ZdaPv,
+ __real__ZnwmRKSt9nothrow_t, __real__ZnamRKSt9nothrow_t,
+ __real__ZdlPvRKSt9nothrow_t, __real__ZdaPvRKSt9nothrow_t
+#endif
};
/* Set up pointers to various pieces so the dll can then use them,
diff --git a/winsup/cygwin/libstdcxx_wrapper.cc b/winsup/cygwin/libstdcxx_wrapper.cc
index 34911d0e11..1da68e41c6 100644
--- a/winsup/cygwin/libstdcxx_wrapper.cc
+++ b/winsup/cygwin/libstdcxx_wrapper.cc
@@ -25,6 +25,7 @@ details. */
#define MANGLED_ZNWX_NOTHROW_T "__wrap__ZnwmRKSt9nothrow_t"
#define MANGLED_ZNAX_NOTHROW_T "__wrap__ZnamRKSt9nothrow_t"
+#ifndef __aarch64__
extern void *operator new(std::size_t sz) noexcept (false)
__asm__ (MANGLED_ZNWX);
extern void *operator new[](std::size_t sz) noexcept (false)
@@ -89,4 +90,28 @@ operator delete[](void *p, const std::nothrow_t &nt) noexcept (true)
{
(*user_data->cxx_malloc->oper_delete___nt) (p, nt);
}
-
+#else
+/* Clang has already seen libc++'s operator declarations, so it correctly
+ rejects changing their assembler names. Define the GNU ld --wrap entry
+ points directly instead. */
+extern "C" void *__wrap__Znwm (std::size_t sz)
+{ return (*user_data->cxx_malloc->oper_new) (sz); }
+extern "C" void *__wrap__Znam (std::size_t sz)
+{ return (*user_data->cxx_malloc->oper_new__) (sz); }
+extern "C" void __wrap__ZdlPv (void *p)
+{ (*user_data->cxx_malloc->oper_delete) (p); }
+extern "C" void __wrap__ZdaPv (void *p)
+{ (*user_data->cxx_malloc->oper_delete__) (p); }
+extern "C" void *__wrap__ZnwmRKSt9nothrow_t (std::size_t sz,
+ const std::nothrow_t &nt)
+{ return (*user_data->cxx_malloc->oper_new_nt) (sz, nt); }
+extern "C" void *__wrap__ZnamRKSt9nothrow_t (std::size_t sz,
+ const std::nothrow_t &nt)
+{ return (*user_data->cxx_malloc->oper_new___nt) (sz, nt); }
+extern "C" void __wrap__ZdlPvRKSt9nothrow_t (void *p,
+ const std::nothrow_t &nt)
+{ (*user_data->cxx_malloc->oper_delete_nt) (p, nt); }
+extern "C" void __wrap__ZdaPvRKSt9nothrow_t (void *p,
+ const std::nothrow_t &nt)
+{ (*user_data->cxx_malloc->oper_delete___nt) (p, nt); }
+#endif
diff --git a/winsup/cygwin/local_includes/cpuid.h b/winsup/cygwin/local_includes/cpuid.h
index 6dbb1bddf8..4a606a116f 100644
--- a/winsup/cygwin/local_includes/cpuid.h
+++ b/winsup/cygwin/local_includes/cpuid.h
@@ -13,14 +13,20 @@ static inline void __attribute ((always_inline))
cpuid (uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t ain,
uint32_t cin = 0)
{
+#ifdef __aarch64__
+ (void) ain;
+ (void) cin;
+ *a = *b = *c = *d = 0;
+#else
asm volatile ("cpuid"
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
: "a" (ain), "c" (cin));
+#endif
}
#ifdef __x86_64__
static inline bool __attribute ((always_inline))
-can_set_flag (uint32_t long flag)
+can_set_flag (uint32_t flag)
{
uint32_t long r1, r2;
@@ -39,6 +45,12 @@ can_set_flag (uint32_t long flag)
);
return ((r1 ^ r2) & flag) != 0;
}
+#elif defined (__aarch64__)
+static inline bool __attribute ((always_inline))
+can_set_flag (uint32_t)
+{
+ return false;
+}
#else
#error unimplemented for this target
#endif
diff --git a/winsup/cygwin/local_includes/cygmalloc.h b/winsup/cygwin/local_includes/cygmalloc.h
index 5e1fe81541..ca9070a819 100644
--- a/winsup/cygwin/local_includes/cygmalloc.h
+++ b/winsup/cygwin/local_includes/cygmalloc.h
@@ -6,6 +6,8 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
+#include <errno.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -21,13 +23,18 @@ int dlmalloc_trim (size_t);
int dlmallopt (int p, int v);
void dlmalloc_stats ();
+#ifndef MALLOC_ALIGNMENT
#define MALLOC_ALIGNMENT ((size_t)16U)
+#endif
#if defined (DLMALLOC_VERSION) /* Building malloc.cc */
extern "C" void __set_ENOMEM ();
+# undef MALLOC_FAILURE_ACTION
# define MALLOC_FAILURE_ACTION __set_ENOMEM ()
# define USE_DL_PREFIX 1
+# define USE_SPIN_LOCKS 1
+# define USE_LOCKS 1
#elif defined (__INSIDE_CYGWIN__)
diff --git a/winsup/cygwin/local_includes/cygtls.h b/winsup/cygwin/local_includes/cygtls.h
index 306497a337..324fe79086 100644
--- a/winsup/cygwin/local_includes/cygtls.h
+++ b/winsup/cygwin/local_includes/cygtls.h
@@ -246,6 +246,8 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
{
#ifdef __x86_64__
__asm__ ("pause");
+#elif defined (__aarch64__)
+ __asm__ ("yield");
#else
#error unimplemented for this target
#endif
@@ -323,7 +325,11 @@ public:
address of the _except block to restore the context correctly.
See comment preceeding myfault_altstack_handler in exception.cc. */
ret = (DWORD64) _ret;
+#ifdef __aarch64__
+ __asm__ volatile ("mov %0, sp" : "=r" (frame));
+#else
__asm__ volatile ("movq %%rsp,%0": "=o" (frame));
+#endif
}
~san () __attribute__ ((always_inline))
{
@@ -336,6 +342,15 @@ public:
};
/* Exception handling macros. This is a handmade SEH try/except. */
+#ifdef __aarch64__
+/* Clang can generate Windows ARM64 scope records directly. Keep the public
+ macro shape, including the errno side effect expected by callers. */
+#define __try __try
+#define __leave __leave
+#define __except(__errno) \
+ __except (EXCEPTION_EXECUTE_HANDLER) { if (__errno) set_errno (__errno);
+#define __endtry }
+#else
#define __mem_barrier __asm__ __volatile__ ("" ::: "memory")
#define __try \
{ \
@@ -371,6 +386,7 @@ public:
__l_endtry: \
__mem_barrier; \
}
+#endif
class wait_signal_arrived
{
diff --git a/winsup/cygwin/local_includes/exception.h b/winsup/cygwin/local_includes/exception.h
index 13159d17b0..84ab709732 100644
--- a/winsup/cygwin/local_includes/exception.h
+++ b/winsup/cygwin/local_includes/exception.h
@@ -7,7 +7,9 @@ details. */
#pragma once
#define exception_list void
+#ifndef __aarch64__
typedef struct _DISPATCHER_CONTEXT *PDISPATCHER_CONTEXT;
+#endif
class exception
{
@@ -15,6 +17,7 @@ class exception
CONTEXT *, PDISPATCHER_CONTEXT);
static EXCEPTION_DISPOSITION handle (EXCEPTION_RECORD *, exception_list *,
CONTEXT *, PDISPATCHER_CONTEXT);
+#ifndef __aarch64__
public:
exception () __attribute__ ((always_inline))
{
@@ -36,6 +39,13 @@ public:
2: \n\
nop \n");
}
+#else
+public:
+ /* Clang emits native ARM64 SEH for the __try macros below. The handful of
+ legacy RAII guard sites need no inline scope-table fragment on ARM64. */
+ exception () = default;
+ ~exception () = default;
+#endif
};
LONG CALLBACK myfault_altstack_handler (EXCEPTION_POINTERS *);
diff --git a/winsup/cygwin/mm/heap.cc b/winsup/cygwin/mm/heap.cc
index 267f4ffa7d..87574f4556 100644
--- a/winsup/cygwin/mm/heap.cc
+++ b/winsup/cygwin/mm/heap.cc
@@ -22,6 +22,13 @@ details. */
static ptrdiff_t page_const;
+/* dlmalloc is entered by the DLL constructors before setup_cygheap(). On
+ ARM64, avoid treating cygheap_dummy as a fully initialized user heap; the
+ allocator's ARM64 MORECORE hook provides the small bootstrap allocation. */
+#if defined (__aarch64__)
+static bool user_heap_initialized;
+#endif
+
/* Minimum size of the base heap. */
#define MINHEAP_SIZE (4 * 1024 * 1024)
/* Chunksize of subsequent heap reservations. */
@@ -176,6 +183,9 @@ user_heap_info::init ()
debug_printf ("heap base %p, heap top %p, heap size %ly (%lu)",
base, top, chunk, chunk);
page_const--;
+#if defined (__aarch64__)
+ user_heap_initialized = true;
+#endif
}
#define pround(n) (((size_t)(n) + page_const) & ~page_const)
@@ -185,6 +195,10 @@ user_heap_info::init ()
extern "C" void *
sbrk (ptrdiff_t n)
{
+#if defined (__aarch64__)
+ if (!user_heap_initialized)
+ return (void *) -1;
+#endif
return cygheap->user_heap.sbrk (n);
}
diff --git a/winsup/cygwin/mm/malloc.cc b/winsup/cygwin/mm/malloc.cc
index 8a1fc257ea..42aa37f501 100644
--- a/winsup/cygwin/mm/malloc.cc
+++ b/winsup/cygwin/mm/malloc.cc
@@ -539,6 +539,17 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
#define WIN32 1
#endif /* _WIN32_WCE */
#endif /* WIN32 */
+
+/* The Cygwin/MSYS fork implementation copies the user heap explicitly.
+ Native ARM64 address randomization makes the standalone Win32 mmap arena
+ impossible to reconstruct reliably in a freshly created forkee. */
+#if defined (__CYGWIN__) && defined (__aarch64__) \
+ && !defined (__MSYS_ARM64_WIN32_MALLOC)
+#undef WIN32
+#define HAVE_MMAP 0
+#define HAVE_MORECORE 1
+#endif
+
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -1637,6 +1648,39 @@ unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
#define MFAIL ((void*)(MAX_SIZE_T))
#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */
+#if defined (__CYGWIN__) && defined (__aarch64__) \
+ && !defined (__MSYS_ARM64_WIN32_MALLOC)
+/* DLL constructors allocate before cygheap installs the normal user heap.
+ Keep this arena inside the image so it is present at the same address in a
+ CreateProcess-based forkee without requiring the loader to service an
+ imported VirtualAlloc call. */
+static unsigned char arm64_msys_bootstrap_heap[4 * 1024 * 1024]
+ __attribute__ ((aligned (16)));
+static size_t arm64_msys_bootstrap_used;
+
+static void *
+arm64_msys_morecore (ptrdiff_t size)
+{
+ void *result = sbrk (size);
+ if (result && result != (void *) -1)
+ return result;
+
+ if (size == 0)
+ return arm64_msys_bootstrap_heap + arm64_msys_bootstrap_used;
+ if (size < 0)
+ return MFAIL;
+
+ size_t allocation = ((size_t) size + 15) & ~((size_t) 15);
+ if (allocation > sizeof arm64_msys_bootstrap_heap
+ - arm64_msys_bootstrap_used)
+ return MFAIL;
+ result = arm64_msys_bootstrap_heap + arm64_msys_bootstrap_used;
+ arm64_msys_bootstrap_used += allocation;
+ return result;
+}
+#define MORECORE arm64_msys_morecore
+#endif
+
#if HAVE_MMAP
#ifndef WIN32
@@ -4017,6 +4061,7 @@ static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
break;
}
assert(nfences >= 2);
+ (void) nfences;
/* Insert the rest of old top into a bin as an ordinary free chunk */
if (csp != old_top) {
diff --git a/winsup/cygwin/mm/malloc_wrapper.cc b/winsup/cygwin/mm/malloc_wrapper.cc
index de3cf7ddc1..17d4e9a9c2 100644
--- a/winsup/cygwin/mm/malloc_wrapper.cc
+++ b/winsup/cygwin/mm/malloc_wrapper.cc
@@ -50,6 +50,25 @@ import_address (void *imp)
{
__try
{
+#ifdef __aarch64__
+ const uint32_t *code = (const uint32_t *) imp;
+
+ /* GNU dlltool emits an ADRP/ADD/LDR/BR import thunk using x16. */
+ if ((code[0] & 0x9f00001f) == 0x90000010
+ && (code[1] & 0xffc003ff) == 0x91000210
+ && code[2] == 0xf9400210
+ && code[3] == 0xd61f0200)
+ {
+ int64_t page_delta = (((int64_t) ((code[0] >> 5) & 0x7ffff)) << 2)
+ | ((code[0] >> 29) & 3);
+ if (page_delta & (INT64_C (1) << 20))
+ page_delta -= INT64_C (1) << 21;
+ uintptr_t page = (uintptr_t) imp & ~(uintptr_t) 0xfff;
+ uintptr_t slot = page + (page_delta << 12)
+ + ((code[1] >> 10) & 0xfff);
+ return *(void **) slot;
+ }
+#else
if (*((uint16_t *) imp) == 0x25ff)
{
const char *ptr = (const char *) imp;
@@ -57,6 +76,7 @@ import_address (void *imp)
(ptr + 6 + *(int32_t *)(ptr + 2));
return (void *) *jmpto;
}
+#endif
}
__except (NO_ERROR) {}
__endtry
@@ -309,6 +329,12 @@ SRWLOCK NO_COPY mallock = SRWLOCK_INIT;
void
malloc_init ()
{
+#if defined (__aarch64__)
+ /* ARM64 reaches this during the DLL loader transition, before the import
+ thunks and process bookkeeping are stable enough to probe safely. The
+ internal allocator is the default and remains selected. */
+ return;
+#endif
/* Check if malloc is provided by application. If so, redirect all
calls to malloc/free/realloc to application provided. This may
happen if some other dll calls cygwin's malloc, but main code provides
diff --git a/winsup/cygwin/profil.c b/winsup/cygwin/profil.c
index 30b37244af..04c120884e 100644
--- a/winsup/cygwin/profil.c
+++ b/winsup/cygwin/profil.c
@@ -44,6 +44,8 @@ get_thrpc (HANDLE thr)
if (GetThreadContext (thr, &ctx)) {
#ifdef __x86_64__
pc = ctx.Rip;
+#elif defined (__aarch64__)
+ pc = ctx.Pc;
#else
#error unimplemented for this target
#endif
@@ -252,4 +254,3 @@ profil (char *samples, size_t size, size_t offset, uint32_t scale)
{
return profile_ctl (&prof, samples, size, offset, scale);
}
-
diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc
index 5ec436c2cf..20fa3336c8 100644
--- a/winsup/cygwin/resource.cc
+++ b/winsup/cygwin/resource.cc
@@ -165,7 +165,11 @@ get_rlimit_stack (void)
return (size_t) rl.rlim_cur;
}
+#ifdef __aarch64__
+static LONG job_serial_number __attribute__((section (".cygwin_dll_common")));
+#else
static LONG job_serial_number __attribute__((section (".cygwin_dll_common"), shared));
+#endif
static PWCHAR
job_shared_name (PWCHAR buf, LONG num)
diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef
index 6328fe2fbd..a849ebc1fe 100755
--- a/winsup/cygwin/scripts/gendef
+++ b/winsup/cygwin/scripts/gendef
@@ -22,6 +22,7 @@ if (!defined($cpu) || !defined($output_def)) {
}
my $is_x86_64 = $cpu eq 'x86_64';
+my $is_aarch64 = $cpu eq 'aarch64';
# FIXME? Do other (non-32 bit) arches on Windows still use symbol prefixes?
my $sym_prefix = '';
@@ -30,6 +31,15 @@ while (<>) {
push(@top, cleanup $_);
last if /^\s*exports$/oi;
}
+
+# The x86_64 runtime keeps its historical 0x180040000 base. The ARM64
+# port's startup and fork address calculations use the Windows ARM64 DLL base
+# at 0x180000000 instead.
+if ($is_aarch64) {
+ $top[0] =~ s/\s+BASE=0x[[:xdigit:]]+//i;
+ $top[0] =~ s/\n?$/ BASE=0x180000000\n/;
+}
+
my @in = cleanup <>;
my %sigfe = ();
@@ -38,6 +48,10 @@ my @nosigfuncs = ();
my @text = ();
for (@in) {
chomp;
+ # ARM64 has no caller-visible alloca helper or x87 precision-control
+ # mode. Do not advertise the x86-only compatibility entries.
+ next if $is_aarch64
+ && /^(?:_alloca\s*=|fegetprec\b|fesetprec\b)/;
s/\s+DATA$//o and do {
push @data, $_;
next;
@@ -107,6 +121,15 @@ $fe:
jmp $sigfe_func
.seh_endproc
+EOF
+ }
+ if ($is_aarch64) {
+ $res = <<EOF;
+ .extern $func
+ .global $fe
+$fe:
+ b $func
+
EOF
}
if (!$main::first++) {
diff --git a/winsup/cygwin/scripts/mkimport b/winsup/cygwin/scripts/mkimport
index 9517c4e9e1..3e7aac2d2e 100755
--- a/winsup/cygwin/scripts/mkimport
+++ b/winsup/cygwin/scripts/mkimport
@@ -24,6 +24,7 @@ my %import = ();
my %symfile = ();
my $is_x86_64 = ($cpu eq 'x86_64' ? 1 : 0);
+my $is_aarch64 = ($cpu eq 'aarch64' ? 1 : 0);
# FIXME? Do other (non-32 bit) arches on Windows still use symbol prefixes?
my $sym_prefix = '';
@@ -65,6 +66,16 @@ for my $f (keys %text) {
.global $glob_sym
$glob_sym:
jmp *$imp_sym(%rip)
+EOF
+ } elsif ($is_aarch64) {
+ print $as_fd <<EOF;
+ .text
+ .extern $imp_sym
+ .global $glob_sym
+$glob_sym:
+ adrp x16, $imp_sym
+ ldr x16, [x16, #:lo12:$imp_sym]
+ br x16
EOF
} else {
print $as_fd <<EOF;
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index dda1a71da9..09d5e68507 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -544,7 +544,7 @@ sigproc_init ()
/* sync_proc_subproc is used by proc_subproc. It serializes
access to the children and proc arrays. */
sync_proc_subproc.init ("sync_proc_subproc");
- new cygthread (wait_sig, cygself, "sig");
+ new cygthread ((LPVOID_THREAD_START_ROUTINE) wait_sig, cygself, "sig");
}
/* Exit the current thread very carefully.
@@ -890,7 +890,12 @@ out:
return rc;
}
-int child_info::retry_count = 0;
+int child_info::retry_count =
+#if defined (__aarch64__)
+ 4;
+#else
+ 0;
+#endif
/* Initialize some of the memory block passed to child processes
by fork/spawn/exec. */
@@ -1181,10 +1186,21 @@ child_info::proc_retry (HANDLE h)
sigproc_printf ("STILL_ACTIVE? How'd we get here?");
break;
case STATUS_DLL_NOT_FOUND:
- case STATUS_ACCESS_VIOLATION:
case STATUS_ILLEGAL_INSTRUCTION:
case STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION: /* pseudo-reloc.c specific */
return exit_code;
+ case STATUS_ACCESS_VIOLATION:
+#if defined (__aarch64__)
+ case STATUS_SXS_CORRUPT_ACTIVATION_STACK:
+ /* QEMU can occasionally terminate a newly created ARM64 child while it
+ rebuilds the inherited process state. A fresh CreateProcess attempt
+ is safe before the child has synchronized with its parent. */
+ if (retry-- > 0)
+ exit_code = 0;
+ break;
+#else
+ return exit_code;
+#endif
case STATUS_CONTROL_C_EXIT:
if (saw_ctrl_c ())
return EXITCODE_OK;
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index d410b95756..ee92960a8f 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -79,8 +79,14 @@ pthread_mutex::no_owner()
}
#undef __getreent
+#ifdef __aarch64__
+extern "C" struct _reent *__getreent_export () __asm__ ("__getreent");
+extern "C" struct _reent *
+__getreent_export ()
+#else
extern "C" struct _reent *
__getreent ()
+#endif
{
return &_my_tls.local_clib;
}
@@ -647,6 +653,9 @@ pthread::cancel ()
if ((context.Rsp & 8) == 0)
context.Rsp -= 8;
context.Rip = (ULONG_PTR) pthread::static_cancel_self;
+#elif defined (__aarch64__)
+ context.Sp &= ~0x0fULL;
+ context.Pc = (ULONG_PTR) pthread::static_cancel_self;
#else
#error unimplemented for this target
#endif
@@ -1966,7 +1975,11 @@ pthread_spinlock::lock ()
else if (spins < FAST_SPINS_LIMIT)
{
++spins;
+#ifdef __aarch64__
+ __asm__ volatile ("yield":::);
+#else
__asm__ volatile ("pause":::);
+#endif
}
else
{
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index a9a7aea782..a96be23b12 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -243,7 +243,11 @@ static const wincaps wincap_11 = {
},
};
+#ifdef __aarch64__
+wincapc wincap __attribute__((section (".cygwin_dll_common")));
+#else
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
+#endif
extern IMAGE_DOS_HEADER
__image_base__;
From 55b352c66887f50b4b6c66d1ff94711dc9e342a1 Mon Sep 17 00:00:00 2001
From: Kreijstal <kreijstal@users.noreply.github.com>
Date: Sat, 18 Jul 2026 05:07:06 +0200
Subject: [PATCH 5/7] build: regenerate autotools outputs
Record the generated configure, Makefile, and helper-script outputs used by the cross build. Keeping this mechanical update separate makes the source changes reviewable.
Assisted-by: OpenAI Codex: GPT-5
---
compile | 45 +-
config.guess | 1338 ++++++++++++++++++++++++--------------------
config.sub | 965 ++++++++++++++++++++++++--------
configure | 3 +-
depcomp | 58 +-
install-sh | 180 +++---
missing | 89 +--
mkinstalldirs | 34 +-
newlib/Makefile.in | 214 +++----
newlib/configure | 14 +-
test-driver | 38 +-
11 files changed, 1857 insertions(+), 1121 deletions(-)
diff --git a/compile b/compile
index a85b723c7e..02ff093c33 100755
--- a/compile
+++ b/compile
@@ -1,9 +1,9 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
-scriptversion=2012-10-14.11; # UTC
+scriptversion=2025-06-18.21; # UTC
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2025 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -37,11 +37,11 @@ IFS=" "" $nl"
file_conv=
-# func_file_conv build_file lazy
+# func_file_conv build_file unneeded_conversions
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
-# type is listed in (the comma separated) LAZY, no conversion will
-# take place.
+# type is listed in (the comma separated) UNNEEDED_CONVERSIONS, no
+# conversion will take place.
func_file_conv ()
{
file=$1
@@ -51,9 +51,20 @@ func_file_conv ()
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
- file_conv=mingw
+ if test -n "$MSYSTEM" && (cygpath --version) >/dev/null 2>&1; then
+ # MSYS2 environment.
+ file_conv=cygwin
+ else
+ # Original MinGW environment.
+ file_conv=mingw
+ fi
+ ;;
+ MSYS*)
+ # Old MSYS environment, or MSYS2 with 32-bit MSYS2 shell.
+ file_conv=cygwin
;;
CYGWIN*)
+ # Cygwin environment.
file_conv=cygwin
;;
*)
@@ -63,12 +74,14 @@ func_file_conv ()
fi
case $file_conv/,$2, in
*,$file_conv,*)
+ # This is the optimization mentioned above:
+ # If UNNEEDED_CONVERSIONS contains $file_conv, don't convert.
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
- file=`cygpath -m "$file" || echo "$file"`
+ file=`cygpath -w "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
@@ -143,7 +156,7 @@ func_cl_wrapper ()
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
- *.o | *.[oO][bB][jJ])
+ *.o | *.lo | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
@@ -248,14 +261,18 @@ If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
+GNU Automake home page: <https://www.gnu.org/software/automake/>.
+General help using GNU software: <https://www.gnu.org/gethelp/>.
EOF
exit $?
;;
-v | --v*)
- echo "compile $scriptversion"
+ echo "compile (GNU Automake) $scriptversion"
exit $?
;;
- cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
+ clang-cl | *[/\\]clang-cl | clang-cl.exe | *[/\\]clang-cl.exe | \
+ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
@@ -339,9 +356,9 @@ exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-format: "%Y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/config.guess b/config.guess
index 1972fda8eb..a9d01fde46 100755
--- a/config.guess
+++ b/config.guess
@@ -1,12 +1,14 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2021 Free Software Foundation, Inc.
+# Copyright 1992-2025 Free Software Foundation, Inc.
-timestamp='2021-01-25'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2025-07-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -32,12 +34,20 @@ timestamp='2021-01-25'
# Please send patches to <config-patches@gnu.org>.
-me=$(echo "$0" | sed -e 's,.*/,,')
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
-Output the configuration name of the system \`$me' is run on.
+Output the configuration name of the system '$me' is run on.
Options:
-h, --help print this help, then exit
@@ -50,13 +60,13 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2021 Free Software Foundation, Inc.
+Copyright 1992-2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
-Try \`$me --help' for more information."
+Try '$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -84,13 +94,16 @@ if test $# != 0; then
exit 1
fi
+# Just in case it came from the environment.
+GUESS=
+
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
+# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still
+# use 'HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
@@ -102,17 +115,17 @@ set_cc_for_build() {
# prevent multiple calls if $tmp is already set
test "$tmp" && return 0
: "${TMPDIR=/tmp}"
- # shellcheck disable=SC2039
- { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } ||
+ # shellcheck disable=SC2039,SC3028
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
dummy=$tmp/dummy
case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
,,) echo "int x;" > "$dummy.c"
- for driver in cc gcc c89 c99 ; do
+ for driver in cc gcc c17 c99 c89 ; do
if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$driver"
+ CC_FOR_BUILD=$driver
break
fi
done
@@ -131,17 +144,20 @@ if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH
fi
-UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown
-UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown
-UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown
-UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-case "$UNAME_SYSTEM" in
+case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
LIBC=unknown
set_cc_for_build
cat <<-EOF > "$dummy.c"
+ #if defined(__ANDROID__)
+ LIBC=android
+ #else
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
@@ -149,6 +165,8 @@ Linux|GNU|GNU/*)
LIBC=dietlibc
#elif defined(__GLIBC__)
LIBC=gnu
+ #elif defined(__LLVM_LIBC__)
+ LIBC=llvm
#else
#include <stdarg.h>
/* First heuristic to detect musl libc. */
@@ -156,8 +174,10 @@ Linux|GNU|GNU/*)
LIBC=musl
#endif
#endif
+ #endif
EOF
- eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')"
+ cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval "$cc_set_libc"
# Second heuristic to detect musl libc.
if [ "$LIBC" = unknown ] &&
@@ -176,7 +196,7 @@ esac
# Note: order is significant - the case branches are not exclusive.
-case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
+case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -188,11 +208,11 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
- UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
/usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
- echo unknown))
- case "$UNAME_MACHINE_ARCH" in
+ echo unknown)`
+ case $UNAME_MACHINE_ARCH in
aarch64eb) machine=aarch64_be-unknown ;;
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
@@ -200,15 +220,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
- arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,')
- endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p')
- machine="${arch}${endian}"-unknown
+ arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
;;
- *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
+ *) machine=$UNAME_MACHINE_ARCH-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently (or will in the future) and ABI.
- case "$UNAME_MACHINE_ARCH" in
+ case $UNAME_MACHINE_ARCH in
earm*)
os=netbsdelf
;;
@@ -229,10 +249,10 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
;;
esac
# Determine ABI tags.
- case "$UNAME_MACHINE_ARCH" in
+ case $UNAME_MACHINE_ARCH in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
- abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr")
+ abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
;;
esac
# The OS release
@@ -240,76 +260,82 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
- case "$UNAME_VERSION" in
+ case $UNAME_VERSION in
Debian*)
release='-gnu'
;;
*)
- release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2)
+ release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "$machine-${os}${release}${abi-}"
- exit ;;
+ GUESS=$machine-${os}${release}${abi-}
+ ;;
*:Bitrig:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
+ ;;
*:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
+ ;;
+ *:SecBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
+ ;;
*:LibertyBSD:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
+ ;;
*:MidnightBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
+ ;;
*:ekkoBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
+ ;;
*:SolidBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
+ ;;
*:OS108:*:*)
- echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
+ ;;
macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:MirBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:Sortix:*:*)
- echo "$UNAME_MACHINE"-unknown-sortix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sortix
+ ;;
*:Twizzler:*:*)
- echo "$UNAME_MACHINE"-unknown-twizzler
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-twizzler
+ ;;
*:Redox:*:*)
- echo "$UNAME_MACHINE"-unknown-redox
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-redox
+ ;;
mips:OSF1:*.*)
- echo mips-dec-osf1
- exit ;;
+ GUESS=mips-dec-osf1
+ ;;
alpha:OSF1:*:*)
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ trap '' 0
case $UNAME_RELEASE in
*4.0)
- UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}')
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}')
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1)
- case "$ALPHA_CPU_TYPE" in
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case $ALPHA_CPU_TYPE in
"EV4 (21064)")
UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
@@ -346,68 +372,69 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)"
- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- exitcode=$?
- trap '' 0
- exit $exitcode ;;
+ OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
+ ;;
Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
+ GUESS=m68k-unknown-sysv4
+ ;;
*:[Aa]miga[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-amigaos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-amigaos
+ ;;
*:[Mm]orph[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-morphos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-morphos
+ ;;
*:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
+ GUESS=i370-ibm-openedition
+ ;;
*:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
+ GUESS=s390-ibm-zvmoe
+ ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
+ GUESS=powerpc-ibm-os400
+ ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix"$UNAME_RELEASE"
- exit ;;
+ GUESS=arm-acorn-riscix$UNAME_RELEASE
+ ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
+ GUESS=arm-unknown-riscos
+ ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
+ GUESS=hppa1.1-hitachi-hiuxmpp
+ ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "$( (/bin/universe) 2>/dev/null)" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
+ case `(/bin/universe) 2>/dev/null` in
+ att) GUESS=pyramid-pyramid-sysv3 ;;
+ *) GUESS=pyramid-pyramid-bsd ;;
+ esac
+ ;;
NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
+ GUESS=pyramid-pyramid-svr4
+ ;;
DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
+ GUESS=sparc-icl-nx6
+ ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case $(/usr/bin/uname -p) in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
+ case `/usr/bin/uname -p` in
+ sparc) GUESS=sparc-icl-nx7 ;;
+ esac
+ ;;
s390x:SunOS:*:*)
- echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
+ ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-hal-solaris2$SUN_REL
+ ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris2$SUN_REL
+ ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-pc-auroraux$UNAME_RELEASE
+ ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
set_cc_for_build
SUN_ARCH=i386
@@ -416,47 +443,50 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# This test works for both compilers.
if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH=x86_64
fi
fi
- echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
+ ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris3$SUN_REL
+ ;;
sun4*:SunOS:*:*)
- case "$(/usr/bin/arch -k)" in
+ case `/usr/bin/arch -k` in
Series*|S4*)
- UNAME_RELEASE=$(uname -v)
+ UNAME_RELEASE=`uname -v`
;;
esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')"
- exit ;;
+ # Japanese Language versions have a version number like '4.1.3-JL'.
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
+ GUESS=sparc-sun-sunos$SUN_REL
+ ;;
sun3*:SunOS:*:*)
- echo m68k-sun-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
+ ;;
sun*:*:4.2BSD:*)
- UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
- case "$(/bin/arch)" in
+ case `/bin/arch` in
sun3)
- echo m68k-sun-sunos"$UNAME_RELEASE"
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
;;
sun4)
- echo sparc-sun-sunos"$UNAME_RELEASE"
+ GUESS=sparc-sun-sunos$UNAME_RELEASE
;;
esac
- exit ;;
+ ;;
aushp:SunOS:*:*)
- echo sparc-auspex-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-auspex-sunos$UNAME_RELEASE
+ ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -466,41 +496,41 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-milan-mint$UNAME_RELEASE
+ ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-hades-mint$UNAME_RELEASE
+ ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-mint$UNAME_RELEASE
+ ;;
m68k:machten:*:*)
- echo m68k-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-machten$UNAME_RELEASE
+ ;;
powerpc:machten:*:*)
- echo powerpc-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-machten$UNAME_RELEASE
+ ;;
RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
+ GUESS=mips-dec-mach_bsd4.3
+ ;;
RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dec-ultrix$UNAME_RELEASE
+ ;;
VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=vax-dec-ultrix$UNAME_RELEASE
+ ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix"$UNAME_RELEASE"
- exit ;;
+ GUESS=clipper-intergraph-clix$UNAME_RELEASE
+ ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
@@ -525,85 +555,87 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
- dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') &&
- SYSTEM_NAME=$("$dummy" "$dummyarg") &&
+ dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-mips-riscos$UNAME_RELEASE
+ ;;
Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
+ GUESS=powerpc-motorola-powermax
+ ;;
Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
+ GUESS=powerpc-harris-powerunix
+ ;;
m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
+ GUESS=m88k-harris-cxux7
+ ;;
m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
+ GUESS=m88k-motorola-sysv4
+ ;;
m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=$(/usr/bin/uname -p)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then
if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
test "$TARGET_BINARY_INTERFACE"x = x
then
- echo m88k-dg-dgux"$UNAME_RELEASE"
+ GUESS=m88k-dg-dgux$UNAME_RELEASE
else
- echo m88k-dg-dguxbcs"$UNAME_RELEASE"
+ GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
fi
else
- echo i586-dg-dgux"$UNAME_RELEASE"
+ GUESS=i586-dg-dgux$UNAME_RELEASE
fi
- exit ;;
+ ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
+ GUESS=m88k-dolphin-sysv3
+ ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
+ GUESS=m88k-tektronix-sysv3
+ ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
+ GUESS=m68k-tektronix-bsd
+ ;;
*:IRIX*:*:*)
- echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')"
- exit ;;
+ IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
+ GUESS=mips-sgi-irix$IRIX_REL
+ ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX '
+ GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
+ GUESS=i386-ibm-aix
+ ;;
ia64:AIX:*:*)
if test -x /usr/bin/oslevel ; then
- IBM_REV=$(/usr/bin/oslevel)
+ IBM_REV=`/usr/bin/oslevel`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
+ ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#include <sys/systemcfg.h>
- main()
+ int
+ main ()
{
if (!__power_pc())
exit(1);
@@ -611,68 +643,68 @@ EOF
exit(0);
}
EOF
- if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy")
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
- echo "$SYSTEM_NAME"
+ GUESS=$SYSTEM_NAME
else
- echo rs6000-ibm-aix3.2.5
+ GUESS=rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
+ GUESS=rs6000-ibm-aix3.2.4
else
- echo rs6000-ibm-aix3.2
+ GUESS=rs6000-ibm-aix3.2
fi
- exit ;;
+ ;;
*:AIX:*:[4567])
- IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }')
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if test -x /usr/bin/lslpp ; then
- IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc |
- awk -F: '{ print $3 }' | sed s/[0-9]*$/0/)
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$IBM_ARCH-ibm-aix$IBM_REV
+ ;;
*:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
+ GUESS=rs6000-ibm-aix
+ ;;
ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
+ GUESS=romp-ibm-bsd4.4
+ ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
+ GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to
+ ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
+ GUESS=rs6000-bull-bosx
+ ;;
DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
+ GUESS=m68k-bull-sysv3
+ ;;
9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
+ GUESS=m68k-hp-bsd
+ ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
+ GUESS=m68k-hp-bsd4.4
+ ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
- case "$UNAME_MACHINE" in
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ case $UNAME_MACHINE in
9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if test -x /usr/bin/getconf; then
- sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null)
- sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null)
- case "$sc_cpu_version" in
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case $sc_cpu_version in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
- case "$sc_kernel_bits" in
+ case $sc_kernel_bits in
32) HP_ARCH=hppa2.0n ;;
64) HP_ARCH=hppa2.0w ;;
'') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
@@ -687,7 +719,8 @@ EOF
#include <stdlib.h>
#include <unistd.h>
- int main ()
+ int
+ main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
@@ -714,7 +747,7 @@ EOF
exit (0);
}
EOF
- (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy")
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
@@ -739,12 +772,12 @@ EOF
HP_ARCH=hppa64
fi
fi
- echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
- exit ;;
+ GUESS=$HP_ARCH-hp-hpux$HPUX_REV
+ ;;
ia64:HP-UX:*:*)
- HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
- echo ia64-hp-hpux"$HPUX_REV"
- exit ;;
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ GUESS=ia64-hp-hpux$HPUX_REV
+ ;;
3050*:HI-UX:*:*)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
@@ -772,38 +805,38 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
+ GUESS=unknown-hitachi-hiuxwe2
+ ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
- echo hppa1.1-hp-bsd
- exit ;;
+ GUESS=hppa1.1-hp-bsd
+ ;;
9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
+ GUESS=hppa1.0-hp-bsd
+ ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
+ GUESS=hppa1.0-hp-mpeix
+ ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
- echo hppa1.1-hp-osf
- exit ;;
+ GUESS=hppa1.1-hp-osf
+ ;;
hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
+ GUESS=hppa1.0-hp-osf
+ ;;
i*86:OSF1:*:*)
if test -x /usr/sbin/sysversion ; then
- echo "$UNAME_MACHINE"-unknown-osf1mk
+ GUESS=$UNAME_MACHINE-unknown-osf1mk
else
- echo "$UNAME_MACHINE"-unknown-osf1
+ GUESS=$UNAME_MACHINE-unknown-osf1
fi
- exit ;;
+ ;;
parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
+ GUESS=hppa1.1-hp-lites
+ ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
+ GUESS=c1-convex-bsd
+ ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
@@ -811,17 +844,18 @@ EOF
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
+ GUESS=c34-convex-bsd
+ ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
+ GUESS=c38-convex-bsd
+ ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
+ GUESS=c4-convex-bsd
+ ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=ymp-cray-unicos$CRAY_REL
+ ;;
CRAY*[A-Z]90:*:*:*)
echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
@@ -829,114 +863,155 @@ EOF
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
- echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=t90-cray-unicos$CRAY_REL
+ ;;
CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=alphaev5-cray-unicosmk$CRAY_REL
+ ;;
CRAY*SV1:*:*:*)
- echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=sv1-cray-unicos$CRAY_REL
+ ;;
*:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=craynv-cray-unicosmp$CRAY_REL
+ ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)
- FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
- FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/')
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
+ GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
- FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/')
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
+ ;;
sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-bsdi$UNAME_RELEASE
+ ;;
*:BSD/OS:*:*)
- echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
+ ;;
arm:FreeBSD:*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
set_cc_for_build
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
else
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
fi
- exit ;;
+ ;;
*:FreeBSD:*:*)
- UNAME_PROCESSOR=$(/usr/bin/uname -p)
- case "$UNAME_PROCESSOR" in
+ UNAME_PROCESSOR=`uname -p`
+ case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
i386)
UNAME_PROCESSOR=i586 ;;
esac
- echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
- exit ;;
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
+ ;;
i*:CYGWIN*:*)
- echo "$UNAME_MACHINE"-pc-cygwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-cygwin
+ ;;
*:MINGW64*:*)
- echo "$UNAME_MACHINE"-pc-mingw64
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw64
+ ;;
*:MINGW*:*)
- echo "$UNAME_MACHINE"-pc-mingw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw32
+ ;;
*:MSYS*:*)
- echo "$UNAME_MACHINE"-pc-msys
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msys
+ ;;
i*:PW*:*)
- echo "$UNAME_MACHINE"-pc-pw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-pw32
+ ;;
+ *:SerenityOS:*:*)
+ GUESS=$UNAME_MACHINE-pc-serenity
+ ;;
*:Interix*:*)
- case "$UNAME_MACHINE" in
+ case $UNAME_MACHINE in
x86)
- echo i586-pc-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=i586-pc-interix$UNAME_RELEASE
+ ;;
authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=x86_64-unknown-interix$UNAME_RELEASE
+ ;;
IA64)
- echo ia64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=ia64-unknown-interix$UNAME_RELEASE
+ ;;
esac ;;
i*:UWIN*:*)
- echo "$UNAME_MACHINE"-pc-uwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-uwin
+ ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-pc-cygwin
- exit ;;
+ GUESS=x86_64-pc-cygwin
+ ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=powerpcle-unknown-solaris2$SUN_REL
+ ;;
*:GNU:*:*)
# the GNU system
- echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')"
- exit ;;
+ GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
+ GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
+ ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC"
- exit ;;
+ GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
+ ;;
+ x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
+ GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
+ ;;
+ *:[Mm]anagarm:*:*)
+ GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
+ ;;
*:Minix:*:*)
- echo "$UNAME_MACHINE"-unknown-minix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-minix
+ ;;
aarch64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ set_cc_for_build
+ CPU=$UNAME_MACHINE
+ LIBCABI=$LIBC
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
+ ABI=64
+ sed 's/^ //' << EOF > "$dummy.c"
+ #ifdef __ARM_EABI__
+ #ifdef __ARM_PCS_VFP
+ ABI=eabihf
+ #else
+ ABI=eabi
+ #endif
+ #endif
+EOF
+ cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
+ eval "$cc_set_abi"
+ case $ABI in
+ eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;
+ esac
+ fi
+ GUESS=$CPU-unknown-linux-$LIBCABI
+ ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
alpha:Linux:*:*)
- case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -947,63 +1022,72 @@ EOF
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
- arc:Linux:*:* | arceb:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
arm*:Linux:*:*)
set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
else
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
fi
fi
- exit ;;
+ ;;
avr32*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
cris:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
crisv32:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
e2k:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
frv:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
hexagon:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:Linux:*:*)
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBC
+ ;;
ia64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
k1om:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
- loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ kvx:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ kvx:cos:*:*)
+ GUESS=$UNAME_MACHINE-unknown-cos
+ ;;
+ kvx:mbr:*:*)
+ GUESS=$UNAME_MACHINE-unknown-mbr
+ ;;
+ loongarch32:Linux:*:* | loongarch64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m32r*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m68*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
mips:Linux:*:* | mips64:Linux:*:*)
set_cc_for_build
IS_GLIBC=0
@@ -1048,138 +1132,150 @@ EOF
#endif
#endif
EOF
- eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')"
+ cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
+ eval "$cc_set_vars"
test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;;
mips64el:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
openrisc*:Linux:*:*)
- echo or1k-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=or1k-unknown-linux-$LIBC
+ ;;
or32:Linux:*:* | or1k*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=sparc-unknown-linux-$LIBC
+ ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=hppa64-unknown-linux-$LIBC
+ ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
- case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in
- PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
- PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
- *) echo hppa-unknown-linux-"$LIBC" ;;
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
+ PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
+ *) GUESS=hppa-unknown-linux-$LIBC ;;
esac
- exit ;;
+ ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64-unknown-linux-$LIBC
+ ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc-unknown-linux-$LIBC
+ ;;
ppc64le:Linux:*:*)
- echo powerpc64le-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64le-unknown-linux-$LIBC
+ ;;
ppcle:Linux:*:*)
- echo powerpcle-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpcle-unknown-linux-$LIBC
+ ;;
riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
+ ;;
sh64*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sh*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
tile*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
vax:Linux:*:*)
- echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-dec-linux-$LIBC
+ ;;
x86_64:Linux:*:*)
set_cc_for_build
+ CPU=$UNAME_MACHINE
LIBCABI=$LIBC
if test "$CC_FOR_BUILD" != no_compiler_found; then
- if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_X32 >/dev/null
- then
- LIBCABI="$LIBC"x32
- fi
+ ABI=64
+ sed 's/^ //' << EOF > "$dummy.c"
+ #ifdef __i386__
+ ABI=x86
+ #else
+ #ifdef __ILP32__
+ ABI=x32
+ #endif
+ #endif
+EOF
+ cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
+ eval "$cc_set_abi"
+ case $ABI in
+ x86) CPU=i686 ;;
+ x32) LIBCABI=${LIBC}x32 ;;
+ esac
fi
- echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI"
- exit ;;
+ GUESS=$CPU-pc-linux-$LIBCABI
+ ;;
xtensa*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
+ GUESS=i386-sequent-sysv4
+ ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
- echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
+ ;;
i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
+ # If we were able to find 'uname', then EMX Unix compatibility
# is probably installed.
- echo "$UNAME_MACHINE"-pc-os2-emx
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-os2-emx
+ ;;
i*86:XTS-300:*:STOP)
- echo "$UNAME_MACHINE"-unknown-stop
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-stop
+ ;;
i*86:atheos:*:*)
- echo "$UNAME_MACHINE"-unknown-atheos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-atheos
+ ;;
i*86:syllable:*:*)
- echo "$UNAME_MACHINE"-pc-syllable
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-syllable
+ ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-unknown-lynxos$UNAME_RELEASE
+ ;;
i*86:*DOS:*:*)
- echo "$UNAME_MACHINE"-pc-msdosdjgpp
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msdosdjgpp
+ ;;
i*86:*:4.*:*)
- UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//')
+ UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
fi
- exit ;;
+ ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
- case $(/bin/uname -X | grep "^Machine") in
+ case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
- echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
- UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)
- echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //'))
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
@@ -1187,11 +1283,11 @@ EOF
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
- echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv32
+ GUESS=$UNAME_MACHINE-pc-sysv32
fi
- exit ;;
+ ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -1199,37 +1295,37 @@ EOF
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
+ GUESS=i586-pc-msdosdjgpp
+ ;;
Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
+ GUESS=i386-pc-mach3
+ ;;
paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
+ GUESS=i860-intel-osf1
+ ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
+ GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4
+ GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4
fi
- exit ;;
+ ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
- echo m68010-convergent-sysv
- exit ;;
+ GUESS=m68010-convergent-sysv
+ ;;
mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
+ GUESS=m68k-convergent-sysv
+ ;;
M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
+ GUESS=m68k-diab-dnix
+ ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
- && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1240,7 +1336,7 @@ EOF
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
- && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1248,118 +1344,121 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-lynxos$UNAME_RELEASE
+ ;;
mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
+ GUESS=m68k-atari-sysv4
+ ;;
TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-lynxos$UNAME_RELEASE
+ ;;
rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
+ ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
+ ;;
SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dde-sysv$UNAME_RELEASE
+ ;;
RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=$( (uname -p) 2>/dev/null)
- echo "$UNAME_MACHINE"-sni-sysv4
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ GUESS=$UNAME_MACHINE-sni-sysv4
else
- echo ns32k-sni-sysv
+ GUESS=ns32k-sni-sysv
fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ ;;
+ PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ GUESS=i586-unisys-sysv4
+ ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
+ GUESS=hppa1.1-stratus-sysv4
+ ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
+ GUESS=i860-stratus-sysv4
+ ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
- echo "$UNAME_MACHINE"-stratus-vos
- exit ;;
+ GUESS=$UNAME_MACHINE-stratus-vos
+ ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
+ GUESS=hppa1.1-stratus-vos
+ ;;
mc68*:A/UX:*:*)
- echo m68k-apple-aux"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-aux$UNAME_RELEASE
+ ;;
news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
+ GUESS=mips-sony-newsos6
+ ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if test -d /usr/nec; then
- echo mips-nec-sysv"$UNAME_RELEASE"
+ GUESS=mips-nec-sysv$UNAME_RELEASE
else
- echo mips-unknown-sysv"$UNAME_RELEASE"
+ GUESS=mips-unknown-sysv$UNAME_RELEASE
fi
- exit ;;
+ ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
+ GUESS=powerpc-be-beos
+ ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
+ GUESS=powerpc-apple-beos
+ ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
+ GUESS=i586-pc-beos
+ ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
+ GUESS=i586-pc-haiku
+ ;;
+ ppc:Haiku:*:*) # Haiku running on Apple PowerPC
+ GUESS=powerpc-apple-haiku
+ ;;
+ *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat)
+ GUESS=$UNAME_MACHINE-unknown-haiku
+ ;;
SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx4-nec-superux$UNAME_RELEASE
+ ;;
SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx5-nec-superux$UNAME_RELEASE
+ ;;
SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx6-nec-superux$UNAME_RELEASE
+ ;;
SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx7-nec-superux$UNAME_RELEASE
+ ;;
SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8-nec-superux$UNAME_RELEASE
+ ;;
SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8r-nec-superux$UNAME_RELEASE
+ ;;
SX-ACE:SUPER-UX:*:*)
- echo sxace-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sxace-nec-superux$UNAME_RELEASE
+ ;;
Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
+ ;;
*:Rhapsody:*:*)
- echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
+ ;;
arm64:Darwin:*:*)
- echo aarch64-apple-darwin"$UNAME_RELEASE"
- exit ;;
+ GUESS=aarch64-apple-darwin$UNAME_RELEASE
+ ;;
*:Darwin:*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
@@ -1393,109 +1492,125 @@ EOF
# uname -m returns i386 or x86_64
UNAME_PROCESSOR=$UNAME_MACHINE
fi
- echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
+ ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
+ ;;
*:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
+ GUESS=i386-pc-qnx
+ ;;
NEO-*:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=neo-tandem-nsk$UNAME_RELEASE
+ ;;
NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nse-tandem-nsk$UNAME_RELEASE
+ ;;
NSR-*:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsr-tandem-nsk$UNAME_RELEASE
+ ;;
NSV-*:NONSTOP_KERNEL:*:*)
- echo nsv-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsv-tandem-nsk$UNAME_RELEASE
+ ;;
NSX-*:NONSTOP_KERNEL:*:*)
- echo nsx-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsx-tandem-nsk$UNAME_RELEASE
+ ;;
*:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
+ GUESS=mips-compaq-nonstopux
+ ;;
BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
+ GUESS=bs2000-siemens-sysv
+ ;;
DS/*:UNIX_System_V:*:*)
- echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
+ ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- # shellcheck disable=SC2154
- if test "$cputype" = 386; then
+ if test "${cputype-}" = 386; then
UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
+ elif test "x${cputype-}" != x; then
+ UNAME_MACHINE=$cputype
fi
- echo "$UNAME_MACHINE"-unknown-plan9
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-plan9
+ ;;
*:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
+ GUESS=pdp10-unknown-tops10
+ ;;
*:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
+ GUESS=pdp10-unknown-tenex
+ ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
+ GUESS=pdp10-dec-tops20
+ ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
+ GUESS=pdp10-xkl-tops20
+ ;;
*:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
+ GUESS=pdp10-unknown-tops20
+ ;;
*:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
+ GUESS=pdp10-unknown-its
+ ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-sei-seiux$UNAME_RELEASE
+ ;;
*:DragonFly:*:*)
- echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
- exit ;;
+ DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
+ ;;
*:*VMS:*:*)
- UNAME_MACHINE=$( (uname -p) 2>/dev/null)
- case "$UNAME_MACHINE" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case $UNAME_MACHINE in
+ A*) GUESS=alpha-dec-vms ;;
+ I*) GUESS=ia64-dec-vms ;;
+ V*) GUESS=vax-dec-vms ;;
esac ;;
*:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
+ GUESS=i386-pc-xenix
+ ;;
i*86:skyos:*:*)
- echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')"
- exit ;;
+ SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
+ GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
+ ;;
i*86:rdos:*:*)
- echo "$UNAME_MACHINE"-pc-rdos
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-rdos
+ ;;
+ i*86:Fiwix:*:*)
+ GUESS=$UNAME_MACHINE-pc-fiwix
+ ;;
*:AROS:*:*)
- echo "$UNAME_MACHINE"-unknown-aros
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-aros
+ ;;
x86_64:VMkernel:*:*)
- echo "$UNAME_MACHINE"-unknown-esx
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-esx
+ ;;
amd64:Isilon\ OneFS:*:*)
- echo x86_64-unknown-onefs
- exit ;;
+ GUESS=x86_64-unknown-onefs
+ ;;
*:Unleashed:*:*)
- echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
+ ;;
+ x86_64:[Ii]ronclad:*:*|i?86:[Ii]ronclad:*:*)
+ GUESS=$UNAME_MACHINE-pc-ironclad-mlibc
+ ;;
+ *:[Ii]ronclad:*:*)
+ GUESS=$UNAME_MACHINE-unknown-ironclad-mlibc
+ ;;
esac
+# Do we have a guess based on uname results?
+if test "x$GUESS" != x; then
+ echo "$GUESS"
+ exit
+fi
+
# No uname command or uname output not recognized.
set_cc_for_build
cat > "$dummy.c" <<EOF
@@ -1511,6 +1626,7 @@ cat > "$dummy.c" <<EOF
#endif
#endif
#endif
+int
main ()
{
#if defined (sony)
@@ -1535,7 +1651,7 @@ main ()
#define __ARCHITECTURE__ "m68k"
#endif
int version;
- version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
@@ -1627,7 +1743,7 @@ main ()
}
EOF
-$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) &&
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
@@ -1635,7 +1751,7 @@ test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
echo "$0: unable to guess system type" >&2
-case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+case $UNAME_MACHINE:$UNAME_SYSTEM in
mips:Linux | mips64:Linux)
# If we got here on MIPS GNU/Linux, output extra information.
cat >&2 <<EOF
@@ -1657,9 +1773,11 @@ and
https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
EOF
-year=$(echo $timestamp | sed 's,-.*,,')
+our_year=`echo $timestamp | sed 's,-.*,,'`
+thisyear=`date +%Y`
# shellcheck disable=SC2003
-if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then
+script_age=`expr "$thisyear" - "$our_year"`
+if test "$script_age" -lt 3 ; then
cat >&2 <<EOF
If $0 has already been updated, send the following data and any
@@ -1668,20 +1786,20 @@ provide the necessary information to handle your system.
config.guess timestamp = $timestamp
-uname -m = $( (uname -m) 2>/dev/null || echo unknown)
-uname -r = $( (uname -r) 2>/dev/null || echo unknown)
-uname -s = $( (uname -s) 2>/dev/null || echo unknown)
-uname -v = $( (uname -v) 2>/dev/null || echo unknown)
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
-/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null)
-/bin/uname -X = $( (/bin/uname -X) 2>/dev/null)
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-hostinfo = $( (hostinfo) 2>/dev/null)
-/bin/universe = $( (/bin/universe) 2>/dev/null)
-/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null)
-/bin/arch = $( (/bin/arch) 2>/dev/null)
-/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null)
-/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null)
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE"
@@ -1693,8 +1811,8 @@ fi
exit 1
# Local variables:
-# eval: (add-hook 'before-save-hook 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-format: "%Y-%02m-%02d"
# time-stamp-end: "'"
# End:
diff --git a/config.sub b/config.sub
index 38f3d037a7..3d35cde174 100755
--- a/config.sub
+++ b/config.sub
@@ -1,14 +1,14 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2021 Free Software Foundation, Inc.
+# Copyright 1992-2025 Free Software Foundation, Inc.
-# shellcheck disable=SC2006,SC2268 # see below for rationale
+# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale
-timestamp='2021-10-27'
+timestamp='2025-07-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -76,13 +76,13 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2021 Free Software Foundation, Inc.
+Copyright 1992-2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
-Try \`$me --help' for more information."
+Try '$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -120,7 +120,6 @@ case $# in
esac
# Split fields of configuration type
-# shellcheck disable=SC2162
saved_IFS=$IFS
IFS="-" read field1 field2 field3 field4 <<EOF
$1
@@ -130,7 +129,7 @@ IFS=$saved_IFS
# Separate into logical components for further validation
case $1 in
*-*-*-*-*)
- echo Invalid configuration \`"$1"\': more than four components >&2
+ echo "Invalid configuration '$1': more than four components" >&2
exit 1
;;
*-*-*-*)
@@ -142,10 +141,22 @@ case $1 in
# parts
maybe_os=$field2-$field3
case $maybe_os in
- nto-qnx* | linux-* | uclinux-uclibc* \
- | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
- | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
- | storm-chaos* | os2-emx* | rtmk-nova*)
+ cloudabi*-eabi* \
+ | kfreebsd*-gnu* \
+ | knetbsd*-gnu* \
+ | kopensolaris*-gnu* \
+ | ironclad-* \
+ | linux-* \
+ | managarm-* \
+ | netbsd*-eabi* \
+ | netbsd*-gnu* \
+ | nto-qnx* \
+ | os2-emx* \
+ | rtmk-nova* \
+ | storm-chaos* \
+ | uclinux-gnu* \
+ | uclinux-uclibc* \
+ | windows-* )
basic_machine=$field1
basic_os=$maybe_os
;;
@@ -160,8 +171,12 @@ case $1 in
esac
;;
*-*)
- # A lone config we happen to match not fitting any pattern
case $field1-$field2 in
+ # Shorthands that happen to contain a single dash
+ convex-c[12] | convex-c3[248])
+ basic_machine=$field2-convex
+ basic_os=
+ ;;
decstation-3100)
basic_machine=mips-dec
basic_os=
@@ -169,28 +184,87 @@ case $1 in
*-*)
# Second component is usually, but not always the OS
case $field2 in
- # Prevent following clause from handling this valid os
+ # Do not treat sunos as a manufacturer
sun*os*)
basic_machine=$field1
basic_os=$field2
;;
- zephyr*)
- basic_machine=$field1-unknown
- basic_os=$field2
- ;;
# Manufacturers
- dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
- | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
- | unicom* | ibm* | next | hp | isi* | apollo | altos* \
- | convergent* | ncr* | news | 32* | 3600* | 3100* \
- | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
- | ultra | tti* | harris | dolphin | highlevel | gould \
- | cbm | ns | masscomp | apple | axis | knuth | cray \
- | microblaze* | sim | cisco \
- | oki | wec | wrs | winbond)
+ 3100* \
+ | 32* \
+ | 3300* \
+ | 3600* \
+ | 7300* \
+ | acorn \
+ | altos* \
+ | apollo \
+ | apple \
+ | atari \
+ | att* \
+ | axis \
+ | be \
+ | bull \
+ | cbm \
+ | ccur \
+ | cisco \
+ | commodore \
+ | convergent* \
+ | convex* \
+ | cray \
+ | crds \
+ | dec* \
+ | delta* \
+ | dg \
+ | digital \
+ | dolphin \
+ | encore* \
+ | gould \
+ | harris \
+ | highlevel \
+ | hitachi* \
+ | hp \
+ | ibm* \
+ | intergraph \
+ | isi* \
+ | knuth \
+ | masscomp \
+ | microblaze* \
+ | mips* \
+ | motorola* \
+ | ncr* \
+ | news \
+ | next \
+ | ns \
+ | oki \
+ | omron* \
+ | pc533* \
+ | rebel \
+ | rom68k \
+ | rombug \
+ | semi \
+ | sequent* \
+ | sgi* \
+ | siemens \
+ | sim \
+ | sni \
+ | sony* \
+ | stratus \
+ | sun \
+ | sun[234]* \
+ | tektronix \
+ | tti* \
+ | ultra \
+ | unicom* \
+ | wec \
+ | winbond \
+ | wrs)
basic_machine=$field1-$field2
basic_os=
;;
+ tock* | zephyr*)
+ basic_machine=$field1-unknown
+ basic_os=$field2
+ ;;
*)
basic_machine=$field1
basic_os=$field2
@@ -271,26 +345,6 @@ case $1 in
basic_machine=arm-unknown
basic_os=cegcc
;;
- convex-c1)
- basic_machine=c1-convex
- basic_os=bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- basic_os=bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- basic_os=bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- basic_os=bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- basic_os=bsd
- ;;
cray)
basic_machine=j90-cray
basic_os=unicos
@@ -713,15 +767,26 @@ case $basic_machine in
vendor=dec
basic_os=tops20
;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
+ delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300)
cpu=m68k
vendor=motorola
;;
- dpx2*)
+ # This used to be dpx2*, but that gets the RS6000-based
+ # DPX/20 and the x86-based DPX/2-100 wrong. See
+ # https://oldskool.silicium.org/stations/bull_dpx20.htm
+ # https://www.feb-patrimoine.com/english/bull_dpx2.htm
+ # https://www.feb-patrimoine.com/english/unix_and_bull.htm
+ dpx2 | dpx2[23]00 | dpx2[23]xx)
cpu=m68k
vendor=bull
- basic_os=sysv3
+ ;;
+ dpx2100 | dpx21xx)
+ cpu=i386
+ vendor=bull
+ ;;
+ dpx20)
+ cpu=rs6000
+ vendor=bull
;;
encore | umax | mmax)
cpu=ns32k
@@ -836,18 +901,6 @@ case $basic_machine in
next | m*-next)
cpu=m68k
vendor=next
- case $basic_os in
- openstep*)
- ;;
- nextstep*)
- ;;
- ns2*)
- basic_os=nextstep2
- ;;
- *)
- basic_os=nextstep3
- ;;
- esac
;;
np1)
cpu=np1
@@ -936,14 +989,13 @@ case $basic_machine in
;;
*-*)
- # shellcheck disable=SC2162
saved_IFS=$IFS
IFS="-" read cpu vendor <<EOF
$basic_machine
EOF
IFS=$saved_IFS
;;
- # We use `pc' rather than `unknown'
+ # We use 'pc' rather than 'unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
@@ -971,15 +1023,19 @@ unset -v basic_machine
# Decode basic machines in the full and proper CPU-Company form.
case $cpu-$vendor in
- # Here we handle the default manufacturer of certain CPU types in canonical form. It is in
- # some cases the only manufacturer, in others, it is the most popular.
+ # Here we handle the default manufacturer of certain CPU types in canonical form.
+ # It is in some cases the only manufacturer, in others, it is the most popular.
+ c[12]-convex | c[12]-unknown | c3[248]-convex | c3[248]-unknown)
+ vendor=convex
+ basic_os=${basic_os:-bsd}
+ ;;
craynv-unknown)
vendor=cray
basic_os=${basic_os:-unicosmp}
;;
c90-unknown | c90-cray)
vendor=cray
- basic_os=${Basic_os:-unicos}
+ basic_os=${basic_os:-unicos}
;;
fx80-unknown)
vendor=alliant
@@ -1020,11 +1076,34 @@ case $cpu-$vendor in
;;
# Here we normalize CPU types with a missing or matching vendor
- dpx20-unknown | dpx20-bull)
- cpu=rs6000
- vendor=bull
+ armh-unknown | armh-alt)
+ cpu=armv7l
+ vendor=alt
+ basic_os=${basic_os:-linux-gnueabihf}
+ ;;
+
+ # Normalized CPU+vendor pairs that imply an OS, if not otherwise specified
+ m68k-isi)
+ basic_os=${basic_os:-sysv}
+ ;;
+ m68k-sony)
+ basic_os=${basic_os:-newsos}
+ ;;
+ m68k-tektronix)
+ basic_os=${basic_os:-bsd}
+ ;;
+ m88k-harris)
+ basic_os=${basic_os:-sysv3}
+ ;;
+ i386-bull | m68k-bull)
+ basic_os=${basic_os:-sysv3}
+ ;;
+ rs6000-bull)
basic_os=${basic_os:-bosx}
;;
+ mips-sni)
+ basic_os=${basic_os:-sysv4}
+ ;;
# Here we normalize CPU types irrespective of the vendor
amd64-*)
@@ -1032,7 +1111,7 @@ case $cpu-$vendor in
;;
blackfin-*)
cpu=bfin
- basic_os=linux
+ basic_os=${basic_os:-linux}
;;
c54x-*)
cpu=tic54x
@@ -1055,7 +1134,7 @@ case $cpu-$vendor in
;;
m68knommu-*)
cpu=m68k
- basic_os=linux
+ basic_os=${basic_os:-linux}
;;
m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
cpu=s12z
@@ -1065,12 +1144,12 @@ case $cpu-$vendor in
;;
parisc-*)
cpu=hppa
- basic_os=linux
+ basic_os=${basic_os:-linux}
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
cpu=i586
;;
- pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+ pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*)
cpu=i686
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
@@ -1079,9 +1158,6 @@ case $cpu-$vendor in
pentium4-*)
cpu=i786
;;
- pc98-*)
- cpu=i386
- ;;
ppc-* | ppcbe-*)
cpu=powerpc
;;
@@ -1115,13 +1191,10 @@ case $cpu-$vendor in
tx39el-*)
cpu=mipstx39el
;;
- x64-*)
- cpu=x86_64
- ;;
xscale-* | xscalee[bl]-*)
cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;;
- arm64-*)
+ arm64-* | aarch64le-* | arm64_32-*)
cpu=aarch64
;;
@@ -1173,114 +1246,232 @@ case $cpu-$vendor in
# Recognize the canonical CPU types that are allowed with any
# company name.
case $cpu in
- 1750a | 580 \
+ 1750a \
+ | 580 \
+ | [cjt]90 \
| a29k \
- | aarch64 | aarch64_be \
+ | aarch64 \
+ | aarch64_be \
+ | aarch64c \
| abacus \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
- | alphapca5[67] | alpha64pca5[67] \
+ | alpha \
+ | alpha64 \
+ | alpha64ev56 \
+ | alpha64ev6[78] \
+ | alpha64ev[4-8] \
+ | alpha64pca5[67] \
+ | alphaev56 \
+ | alphaev6[78] \
+ | alphaev[4-8] \
+ | alphapca5[67] \
| am33_2.0 \
| amdgcn \
- | arc | arceb | arc32 | arc64 \
- | arm | arm[lb]e | arme[lb] | armv* \
- | avr | avr32 \
+ | arc \
+ | arc32 \
+ | arc64 \
+ | arceb \
+ | arm \
+ | arm64e \
+ | arm64ec \
+ | arm[lb]e \
+ | arme[lb] \
+ | armv* \
| asmjs \
+ | avr \
+ | avr32 \
| ba \
- | be32 | be64 \
- | bfin | bpf | bs2000 \
- | c[123]* | c30 | [cjt]90 | c4x \
- | c8051 | clipper | craynv | csky | cydra \
- | d10v | d30v | dlx | dsp16xx \
- | e2k | elxsi | epiphany \
- | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
- | h8300 | h8500 \
- | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | be32 \
+ | be64 \
+ | bfin \
+ | bpf \
+ | bs2000 \
+ | c30 \
+ | c4x \
+ | c8051 \
+ | c[123]* \
+ | clipper \
+ | craynv \
+ | csky \
+ | cydra \
+ | d10v \
+ | d30v \
+ | dlx \
+ | dsp16xx \
+ | e2k \
+ | elxsi \
+ | epiphany \
+ | f30[01] \
+ | f700 \
+ | fido \
+ | fr30 \
+ | frv \
+ | ft32 \
+ | fx80 \
+ | h8300 \
+ | h8500 \
| hexagon \
- | i370 | i*86 | i860 | i960 | ia16 | ia64 \
- | ip2k | iq2000 \
+ | hppa \
+ | hppa1.[01] \
+ | hppa2.0 \
+ | hppa2.0[nw] \
+ | hppa64 \
+ | i*86 \
+ | i370 \
+ | i860 \
+ | i960 \
+ | ia16 \
+ | ia64 \
+ | intelgt \
+ | ip2k \
+ | iq2000 \
+ | javascript \
| k1om \
- | le32 | le64 \
+ | kvx \
+ | le32 \
+ | le64 \
| lm32 \
- | loongarch32 | loongarch64 | loongarchx32 \
- | m32c | m32r | m32rle \
- | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
- | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
- | m88110 | m88k | maxq | mb | mcore | mep | metag \
- | microblaze | microblazeel \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64eb | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa32r3 | mipsisa32r3el \
- | mipsisa32r5 | mipsisa32r5el \
- | mipsisa32r6 | mipsisa32r6el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64r3 | mipsisa64r3el \
- | mipsisa64r5 | mipsisa64r5el \
- | mipsisa64r6 | mipsisa64r6el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipsr5900 | mipsr5900el \
- | mipstx39 | mipstx39el \
+ | loongarch32 \
+ | loongarch64 \
+ | m32c \
+ | m32r \
+ | m32rle \
+ | m5200 \
+ | m68000 \
+ | m680[012346]0 \
+ | m6811 \
+ | m6812 \
+ | m68360 \
+ | m683?2 \
+ | m68hc11 \
+ | m68hc12 \
+ | m68hcs12x \
+ | m68k \
+ | m88110 \
+ | m88k \
+ | maxq \
+ | mb \
+ | mcore \
+ | mep \
+ | metag \
+ | microblaze \
+ | microblazeel \
+ | mips* \
| mmix \
- | mn10200 | mn10300 \
+ | mn10200 \
+ | mn10300 \
| moxie \
- | mt \
| msp430 \
- | nds32 | nds32le | nds32be \
+ | mt \
+ | nanomips* \
+ | nds32 \
+ | nds32be \
+ | nds32le \
| nfp \
- | nios | nios2 | nios2eb | nios2el \
- | none | np1 | ns16k | ns32k | nvptx \
+ | nios \
+ | nios2 \
+ | nios2eb \
+ | nios2el \
+ | none \
+ | np1 \
+ | ns16k \
+ | ns32k \
+ | nvptx \
| open8 \
| or1k* \
| or32 \
| orion \
+ | pdp10 \
+ | pdp11 \
| picochip \
- | pdp10 | pdp11 | pj | pjl | pn | power \
- | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+ | pj \
+ | pjl \
+ | pn \
+ | power \
+ | powerpc \
+ | powerpc64 \
+ | powerpc64le \
+ | powerpcle \
+ | powerpcspe \
| pru \
| pyramid \
- | riscv | riscv32 | riscv32be | riscv64 | riscv64be \
- | rl78 | romp | rs6000 | rx \
- | s390 | s390x \
+ | riscv \
+ | riscv32 \
+ | riscv32be \
+ | riscv64 \
+ | riscv64be \
+ | rl78 \
+ | romp \
+ | rs6000 \
+ | rx \
+ | s390 \
+ | s390x \
| score \
- | sh | shl \
- | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
- | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+ | sh \
+ | sh64 \
+ | sh64le \
+ | sh[12345][lb]e \
+ | sh[1234] \
+ | sh[1234]e[lb] \
+ | sh[23]e \
+ | sh[23]ele \
+ | sh[24]a \
+ | sh[24]ae[lb] \
+ | sh[lb]e \
+ | she[lb] \
+ | shl \
+ | sparc \
+ | sparc64 \
+ | sparc64b \
+ | sparc64v \
+ | sparc86x \
+ | sparclet \
| sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+ | sparcv8 \
+ | sparcv9 \
+ | sparcv9b \
+ | sparcv9v \
| spu \
+ | sv1 \
+ | sx* \
| tahoe \
| thumbv7* \
- | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+ | tic30 \
+ | tic4x \
+ | tic54x \
+ | tic55x \
+ | tic6x \
+ | tic80 \
| tron \
| ubicom32 \
- | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+ | v70 \
+ | v810 \
+ | v850 \
+ | v850e \
+ | v850e1 \
+ | v850e2 \
+ | v850e2v3 \
+ | v850es \
| vax \
+ | vc4 \
| visium \
| w65 \
- | wasm32 | wasm64 \
+ | wasm32 \
+ | wasm64 \
| we32k \
- | x86 | x86_64 | xc16x | xgate | xps100 \
- | xstormy16 | xtensa* \
+ | x86 \
+ | x86_64 \
+ | xc16x \
+ | xgate \
+ | xps100 \
+ | xstormy16 \
+ | xtensa* \
| ymp \
- | z8k | z80)
+ | z80 \
+ | z8k)
;;
*)
- echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+ echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2
exit 1
;;
esac
@@ -1301,11 +1492,12 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
-if test x$basic_os != x
+if test x"$basic_os" != x
then
# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
# set os.
+obj=
case $basic_os in
gnu/linux*)
kernel=linux
@@ -1320,7 +1512,6 @@ case $basic_os in
os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
;;
*-*)
- # shellcheck disable=SC2162
saved_IFS=$IFS
IFS="-" read kernel os <<EOF
$basic_os
@@ -1332,10 +1523,18 @@ EOF
kernel=nto
os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
;;
+ ironclad*)
+ kernel=ironclad
+ os=`echo "$basic_os" | sed -e 's|ironclad|mlibc|'`
+ ;;
linux*)
kernel=linux
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
;;
+ managarm*)
+ kernel=managarm
+ os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
+ ;;
*)
kernel=
os=$basic_os
@@ -1363,6 +1562,23 @@ case $os in
unixware*)
os=sysv4.2uw
;;
+ # The marketing names for NeXT's operating systems were
+ # NeXTSTEP, NeXTSTEP 2, OpenSTEP 3, OpenSTEP 4. 'openstep' is
+ # mapped to 'openstep3', but 'openstep1' and 'openstep2' are
+ # mapped to 'nextstep' and 'nextstep2', consistent with the
+ # treatment of SunOS/Solaris.
+ ns | ns1 | nextstep | nextstep1 | openstep1)
+ os=nextstep
+ ;;
+ ns2 | nextstep2 | openstep2)
+ os=nextstep2
+ ;;
+ ns3 | nextstep3 | openstep | openstep3)
+ os=openstep3
+ ;;
+ ns4 | nextstep4 | openstep4)
+ os=openstep4
+ ;;
# es1800 is here to avoid being matched by es* (a different OS)
es1800*)
os=ose
@@ -1433,6 +1649,7 @@ case $os in
;;
utek*)
os=bsd
+ vendor=`echo "$vendor" | sed -e 's|^unknown$|tektronix|'`
;;
dynix*)
os=bsd
@@ -1449,21 +1666,25 @@ case $os in
386bsd)
os=bsd
;;
- ctix* | uts*)
+ ctix*)
os=sysv
+ vendor=`echo "$vendor" | sed -e 's|^unknown$|convergent|'`
;;
- nova*)
- os=rtmk-nova
+ uts*)
+ os=sysv
;;
- ns2)
- os=nextstep2
+ nova*)
+ kernel=rtmk
+ os=nova
;;
# Preserve the version number of sinix5.
sinix5.*)
os=`echo "$os" | sed -e 's|sinix|sysv|'`
+ vendor=`echo "$vendor" | sed -e 's|^unknown$|sni|'`
;;
sinix*)
os=sysv4
+ vendor=`echo "$vendor" | sed -e 's|^unknown$|sni|'`
;;
tpf*)
os=tpf
@@ -1501,10 +1722,16 @@ case $os in
os=eabi
;;
*)
- os=elf
+ os=
+ obj=elf
;;
esac
;;
+ aout* | coff* | elf* | pe*)
+ # These are machine code file formats, not OSes
+ obj=$os
+ os=
+ ;;
*)
# No normalization, but not necessarily accepted, that comes below.
;;
@@ -1523,12 +1750,15 @@ else
# system, and we'll never get to this point.
kernel=
+obj=
case $cpu-$vendor in
score-*)
- os=elf
+ os=
+ obj=elf
;;
spu-*)
- os=elf
+ os=
+ obj=elf
;;
*-acorn)
os=riscix1.2
@@ -1538,28 +1768,35 @@ case $cpu-$vendor in
os=gnu
;;
arm*-semi)
- os=aout
+ os=
+ obj=aout
;;
c4x-* | tic4x-*)
- os=coff
+ os=
+ obj=coff
;;
c8051-*)
- os=elf
+ os=
+ obj=elf
;;
clipper-intergraph)
os=clix
;;
hexagon-*)
- os=elf
+ os=
+ obj=elf
;;
tic54x-*)
- os=coff
+ os=
+ obj=coff
;;
tic55x-*)
- os=coff
+ os=
+ obj=coff
;;
tic6x-*)
- os=coff
+ os=
+ obj=coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1581,28 +1818,43 @@ case $cpu-$vendor in
os=sunos3
;;
m68*-cisco)
- os=aout
+ os=
+ obj=aout
;;
mep-*)
- os=elf
+ os=
+ obj=elf
+ ;;
+ # The -sgi and -siemens entries must be before the mips- entry
+ # or we get the wrong os.
+ *-sgi)
+ os=irix
+ ;;
+ *-siemens)
+ os=sysv4
;;
mips*-cisco)
- os=elf
+ os=
+ obj=elf
;;
- mips*-*)
- os=elf
+ mips*-*|nanomips*-*)
+ os=
+ obj=elf
;;
or32-*)
- os=coff
+ os=
+ obj=coff
;;
- *-tti) # must be before sparc entry or we get the wrong os.
+ # This must be before the sparc-* entry or we get the wrong os.
+ *-tti)
os=sysv3
;;
sparc-* | *-sun)
os=sunos4.1.1
;;
pru-*)
- os=elf
+ os=
+ obj=elf
;;
*-be)
os=beos
@@ -1626,7 +1878,7 @@ case $cpu-$vendor in
os=hpux
;;
*-hitachi)
- os=hiux
+ os=hiuxwe2
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=sysv
@@ -1670,12 +1922,6 @@ case $cpu-$vendor in
*-encore)
os=bsd
;;
- *-sgi)
- os=irix
- ;;
- *-siemens)
- os=sysv4
- ;;
*-masscomp)
os=rtu
;;
@@ -1683,10 +1929,12 @@ case $cpu-$vendor in
os=uxpv
;;
*-rom68k)
- os=coff
+ os=
+ obj=coff
;;
*-*bug)
- os=coff
+ os=
+ obj=coff
;;
*-apple)
os=macos
@@ -1704,10 +1952,11 @@ esac
fi
-# Now, validate our (potentially fixed-up) OS.
+# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ).
+
case $os in
# Sometimes we do "kernel-libc", so those need to count as OSes.
- musl* | newlib* | relibc* | uclibc*)
+ llvm* | musl* | newlib* | relibc* | uclibc*)
;;
# Likewise for "kernel-abi"
eabi* | gnueabi*)
@@ -1715,83 +1964,313 @@ case $os in
# VxWorks passes extra cpu info in the 4th filed.
simlinux | simwindows | spe)
;;
+ # See `case $cpu-$os` validation below
+ ghcjs)
+ ;;
# Now accept the basic system types.
- # The portable systems comes first.
# Each alternative MUST end in a * to match a version number.
- gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
- | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \
- | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
- | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
- | hiux* | abug | nacl* | netware* | windows* \
- | os9* | macos* | osx* | ios* \
- | mpw* | magic* | mmixware* | mon960* | lnews* \
- | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
- | aos* | aros* | cloudabi* | sortix* | twizzler* \
- | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
- | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
- | mirbsd* | netbsd* | dicos* | openedition* | ose* \
- | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
- | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
- | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
- | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
- | udi* | lites* | ieee* | go32* | aux* | hcos* \
- | chorusrdb* | cegcc* | glidix* | serenity* \
- | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
- | midipix* | mingw32* | mingw64* | mint* \
- | uxpv* | beos* | mpeix* | udk* | moxiebox* \
- | interix* | uwin* | mks* | rhapsody* | darwin* \
- | openstep* | oskit* | conix* | pw32* | nonstopux* \
- | storm-chaos* | tops10* | tenex* | tops20* | its* \
- | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \
- | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \
- | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
- | skyos* | haiku* | rdos* | toppers* | drops* | es* \
- | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
- | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
- | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* )
+ abug \
+ | aix* \
+ | amdhsa* \
+ | amigados* \
+ | amigaos* \
+ | android* \
+ | aof* \
+ | aos* \
+ | aros* \
+ | atheos* \
+ | auroraux* \
+ | aux* \
+ | banan_os* \
+ | beos* \
+ | bitrig* \
+ | bme* \
+ | bosx* \
+ | bsd* \
+ | cegcc* \
+ | chorusos* \
+ | chorusrdb* \
+ | clix* \
+ | cloudabi* \
+ | cnk* \
+ | conix* \
+ | cos* \
+ | cxux* \
+ | cygwin* \
+ | darwin* \
+ | dgux* \
+ | dicos* \
+ | dnix* \
+ | domain* \
+ | dragonfly* \
+ | drops* \
+ | ebmon* \
+ | ecoff* \
+ | ekkobsd* \
+ | emscripten* \
+ | emx* \
+ | es* \
+ | fiwix* \
+ | freebsd* \
+ | fuchsia* \
+ | genix* \
+ | genode* \
+ | glidix* \
+ | gnu* \
+ | go32* \
+ | haiku* \
+ | hcos* \
+ | hiux* \
+ | hms* \
+ | hpux* \
+ | ieee* \
+ | interix* \
+ | ios* \
+ | iris* \
+ | irix* \
+ | isc* \
+ | its* \
+ | l4re* \
+ | libertybsd* \
+ | lites* \
+ | lnews* \
+ | luna* \
+ | lynxos* \
+ | mach* \
+ | macos* \
+ | magic* \
+ | mbr* \
+ | midipix* \
+ | midnightbsd* \
+ | mingw32* \
+ | mingw64* \
+ | minix* \
+ | mint* \
+ | mirbsd* \
+ | mks* \
+ | mlibc* \
+ | mmixware* \
+ | mon960* \
+ | morphos* \
+ | moss* \
+ | moxiebox* \
+ | mpeix* \
+ | mpw* \
+ | msdos* \
+ | msys* \
+ | mvs* \
+ | nacl* \
+ | netbsd* \
+ | netware* \
+ | newsos* \
+ | nextstep* \
+ | nindy* \
+ | nonstopux* \
+ | nova* \
+ | nsk* \
+ | nucleus* \
+ | nx6 \
+ | nx7 \
+ | oabi* \
+ | ohos* \
+ | onefs* \
+ | openbsd* \
+ | openedition* \
+ | openstep* \
+ | os108* \
+ | os2* \
+ | os400* \
+ | os68k* \
+ | os9* \
+ | ose* \
+ | osf* \
+ | oskit* \
+ | osx* \
+ | palmos* \
+ | phoenix* \
+ | plan9* \
+ | powermax* \
+ | powerunix* \
+ | proelf* \
+ | psos* \
+ | psp* \
+ | ptx* \
+ | pw32* \
+ | qnx* \
+ | rdos* \
+ | redox* \
+ | rhapsody* \
+ | riscix* \
+ | riscos* \
+ | rtems* \
+ | rtmk* \
+ | rtu* \
+ | scout* \
+ | secbsd* \
+ | sei* \
+ | serenity* \
+ | sim* \
+ | skyos* \
+ | solaris* \
+ | solidbsd* \
+ | sortix* \
+ | storm-chaos* \
+ | sunos \
+ | sunos[34]* \
+ | superux* \
+ | syllable* \
+ | sym* \
+ | sysv* \
+ | tenex* \
+ | tirtos* \
+ | tock* \
+ | toppers* \
+ | tops10* \
+ | tops20* \
+ | tpf* \
+ | tvos* \
+ | twizzler* \
+ | uclinux* \
+ | udi* \
+ | udk* \
+ | ultrix* \
+ | unicos* \
+ | uniplus* \
+ | unleashed* \
+ | unos* \
+ | uwin* \
+ | uxpv* \
+ | v88r* \
+ |*vms* \
+ | vos* \
+ | vsta* \
+ | vxsim* \
+ | vxworks* \
+ | wasi* \
+ | watchos* \
+ | wince* \
+ | windiss* \
+ | windows* \
+ | winnt* \
+ | xenix* \
+ | xray* \
+ | zephyr* \
+ | zvmoe* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
;;
+ # This refers to builds using the UEFI calling convention
+ # (which depends on the architecture) and PE file format.
+ # Note that this is both a different calling convention and
+ # different file format than that of GNU-EFI
+ # (x86_64-w64-mingw32).
+ uefi)
+ ;;
none)
;;
+ kernel* | msvc* )
+ # Restricted further below
+ ;;
+ '')
+ if test x"$obj" = x
+ then
+ echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2
+ fi
+ ;;
*)
- echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
+ echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2
+ exit 1
+ ;;
+esac
+
+case $obj in
+ aout* | coff* | elf* | pe*)
+ ;;
+ '')
+ # empty is fine
+ ;;
+ *)
+ echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we handle the constraint that a (synthetic) cpu and os are
+# valid only in combination with each other and nowhere else.
+case $cpu-$os in
+ # The "javascript-unknown-ghcjs" triple is used by GHC; we
+ # accept it here in order to tolerate that, but reject any
+ # variations.
+ javascript-ghcjs)
+ ;;
+ javascript-* | *-ghcjs)
+ echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2
exit 1
;;
esac
# As a final step for OS-related things, validate the OS-kernel combination
# (given a valid OS), if there is a kernel.
-case $kernel-$os in
- linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
- | linux-musl* | linux-relibc* | linux-uclibc* )
+case $kernel-$os-$obj in
+ linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \
+ | linux-mlibc*- | linux-musl*- | linux-newlib*- \
+ | linux-relibc*- | linux-uclibc*- | linux-ohos*- )
+ ;;
+ uclinux-uclibc*- | uclinux-gnu*- )
;;
- uclinux-uclibc* )
+ ironclad-mlibc*-)
;;
- -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
+ managarm-mlibc*- | managarm-kernel*- )
+ ;;
+ windows*-msvc*-)
+ ;;
+ -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \
+ | -uclibc*- )
# These are just libc implementations, not actual OSes, and thus
# require a kernel.
- echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
+ echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2
exit 1
;;
- kfreebsd*-gnu* | kopensolaris*-gnu*)
+ -kernel*- )
+ echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2
+ exit 1
;;
- vxworks-simlinux | vxworks-simwindows | vxworks-spe)
+ *-kernel*- )
+ echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2
+ exit 1
;;
- nto-qnx*)
+ *-msvc*- )
+ echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2
+ exit 1
;;
- os2-emx)
+ kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-)
+ ;;
+ vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-)
+ ;;
+ nto-qnx*-)
+ ;;
+ os2-emx-)
;;
- *-eabi* | *-gnueabi*)
+ rtmk-nova-)
;;
- -*)
+ *-eabi*- | *-gnueabi*-)
+ ;;
+ ios*-simulator- | tvos*-simulator- | watchos*-simulator- )
+ ;;
+ none--*)
+ # None (no kernel, i.e. freestanding / bare metal),
+ # can be paired with an machine code file format
+ ;;
+ -*-)
# Blank kernel with real OS is always fine.
;;
- *-*)
- echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
+ --*)
+ # Blank kernel and OS with real machine code file format is always fine.
+ ;;
+ *-*-*)
+ echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2
exit 1
;;
esac
@@ -1804,7 +2283,7 @@ case $vendor in
*-riscix*)
vendor=acorn
;;
- *-sunos*)
+ *-sunos* | *-solaris*)
vendor=sun
;;
*-cnk* | *-aix*)
@@ -1874,12 +2353,12 @@ case $vendor in
;;
esac
-echo "$cpu-$vendor-${kernel:+$kernel-}$os"
+echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
exit
# Local variables:
-# eval: (add-hook 'before-save-hook 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-format: "%Y-%02m-%02d"
# time-stamp-end: "'"
# End:
diff --git a/configure b/configure
index 9477153056..5a31139ce0 100755
--- a/configure
+++ b/configure
@@ -3894,7 +3894,7 @@ case "${target}" in
i[3456789]86-*-mingw*)
target_configdirs="$target_configdirs target-winsup"
;;
- *-*-cygwin*)
+ *-*-cygwin* | *-*-msys*)
target_configdirs="$target_configdirs target-libtermcap target-winsup"
noconfigdirs="$noconfigdirs target-libgloss"
# always build newlib if winsup directory is present.
@@ -16379,4 +16379,3 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
-
diff --git a/depcomp b/depcomp
index 4e70ff0bbc..9f6725b9e0 100755
--- a/depcomp
+++ b/depcomp
@@ -1,9 +1,9 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
-scriptversion=2013-05-30.07; # UTC
+scriptversion=2025-06-18.21; # UTC
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2025 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@ scriptversion=2013-05-30.07; # UTC
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -47,11 +47,13 @@ Environment variables:
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
+GNU Automake home page: <https://www.gnu.org/software/automake/>.
+General help using GNU software: <https://www.gnu.org/gethelp/>.
EOF
exit $?
;;
-v | --v*)
- echo "depcomp $scriptversion"
+ echo "depcomp (GNU Automake) $scriptversion"
exit $?
;;
esac
@@ -113,7 +115,6 @@ nl='
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
-digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
@@ -128,7 +129,7 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
-# Avoid interferences from the environment.
+# Avoid interference from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
@@ -198,8 +199,8 @@ gcc3)
;;
gcc)
-## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
-## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## Note that this doesn't just cater to obsolete pre-3.x GCC compilers.
+## but also to in-use compilers like IBM xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
@@ -251,6 +252,41 @@ hp)
exit 1
;;
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like '#:fec' to the end of the
+ # dependency line.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
@@ -748,9 +784,9 @@ exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-format: "%Y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/install-sh b/install-sh
index 0b0fdcbba6..1d8d966964 100755
--- a/install-sh
+++ b/install-sh
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2013-12-25.23; # UTC
+scriptversion=2025-06-18.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -69,6 +69,11 @@ posix_mkdir=
# Desired mode of installed file.
mode=0755
+# Create dirs (including intermediate dirs) using mode 755.
+# This is like GNU 'install' as of coreutils 8.32 (2020).
+mkdir_umask=22
+
+backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
@@ -99,19 +104,29 @@ Options:
--version display version info and exit.
-c (ignored)
- -C install only if different (preserve the last data modification time)
+ -C install only if different (preserve data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
+ -p pass -p to $cpprog.
-s $stripprog installed files.
+ -S SUFFIX attempt to back up existing files, with suffix SUFFIX.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
-"
+
+By default, rm is invoked with -f; when overridden with RMPROG,
+it's up to you to specify -f if you want it.
+
+If -S is not specified, no backups are attempted.
+
+Report bugs to <bug-automake@gnu.org>.
+GNU Automake home page: <https://www.gnu.org/software/automake/>.
+General help using GNU software: <https://www.gnu.org/gethelp/>."
while test $# -ne 0; do
case $1 in
@@ -137,8 +152,13 @@ while test $# -ne 0; do
-o) chowncmd="$chownprog $2"
shift;;
+ -p) cpprog="$cpprog -p";;
+
-s) stripcmd=$stripprog;;
+ -S) backupsuffix="$2"
+ shift;;
+
-t)
is_target_a_directory=always
dst_arg=$2
@@ -150,7 +170,7 @@ while test $# -ne 0; do
-T) is_target_a_directory=never;;
- --version) echo "$0 $scriptversion"; exit $?;;
+ --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;;
--) shift
break;;
@@ -255,6 +275,10 @@ do
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
+ # Don't chown directories that already exist.
+ if test $dstdir_status = 0; then
+ chowncmd=""
+ fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
@@ -271,15 +295,18 @@ do
fi
dst=$dst_arg
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
+ # If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
- dst=$dstdir/`basename "$src"`
+ dstbase=`basename "$src"`
+ case $dst in
+ */) dst=$dst$dstbase;;
+ *) dst=$dst/$dstbase;;
+ esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
@@ -288,27 +315,16 @@ do
fi
fi
+ case $dstdir in
+ */) dstdirslash=$dstdir;;
+ *) dstdirslash=$dstdir/;;
+ esac
+
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
@@ -318,43 +334,49 @@ do
fi
posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
+ # The $RANDOM variable is not portable (e.g., dash). Use it
+ # here however when possible just to lower collision chance.
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
+ trap '
+ ret=$?
+ rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
+ exit $ret
+ ' 0
+
+ # Because "mkdir -p" follows existing symlinks and we likely work
+ # directly in world-writable /tmp, make sure that the '$tmpdir'
+ # directory is successfully created first before we actually test
+ # 'mkdir -p'.
+ if (umask $mkdir_umask &&
+ $mkdirprog $mkdir_mode "$tmpdir" &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibility with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ test_tmpdir="$tmpdir/a"
+ ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+ fi
+ trap '' 0;;
esac
if
@@ -365,7 +387,7 @@ do
then :
else
- # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
@@ -394,7 +416,7 @@ do
prefixes=
else
if $posix_mkdir; then
- (umask=$mkdir_umask &&
+ (umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
@@ -427,14 +449,25 @@ do
else
# Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
+ dsttmp=${dstdirslash}_inst.$$_
+ rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+ (umask $cp_umask &&
+ { test -z "$stripcmd" || {
+ # Create $dsttmp read-write so that cp doesn't create it read-only,
+ # which would cause strip to fail.
+ if test -z "$doit"; then
+ : >"$dsttmp" # No need to fork-exec 'touch'.
+ else
+ $doit touch "$dsttmp"
+ fi
+ }
+ } &&
+ $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
@@ -460,6 +493,13 @@ do
then
rm -f "$dsttmp"
else
+ # If $backupsuffix is set, and the file being installed
+ # already exists, attempt a backup. Don't worry if it fails,
+ # e.g., if mv doesn't support -f.
+ if test -n "$backupsuffix" && test -f "$dst"; then
+ $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
+ fi
+
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
@@ -474,9 +514,9 @@ do
# file should still install successfully.
{
test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
+ $doit $rmcmd "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
@@ -493,9 +533,9 @@ do
done
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-format: "%Y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/missing b/missing
index f62bbae306..5e450bab3c 100755
--- a/missing
+++ b/missing
@@ -1,9 +1,11 @@
#! /bin/sh
-# Common wrapper for a few potentially missing GNU programs.
+# Common wrapper for a few potentially missing GNU and other programs.
-scriptversion=2013-10-28.13; # UTC
+scriptversion=2025-06-18.21; # UTC
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# shellcheck disable=SC2006,SC2268 # we must support pre-POSIX shells
+
+# Copyright (C) 1996-2025 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
@@ -17,7 +19,7 @@ scriptversion=2013-10-28.13; # UTC
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -54,18 +56,20 @@ Options:
-v, --version output version information and exit
Supported PROGRAM values:
- aclocal autoconf autoheader autom4te automake makeinfo
- bison yacc flex lex help2man
+aclocal autoconf autogen autoheader autom4te automake autoreconf
+bison flex help2man lex makeinfo perl yacc
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
-Send bug reports to <bug-automake@gnu.org>."
+Report bugs to <bug-automake@gnu.org>.
+GNU Automake home page: <https://www.gnu.org/software/automake/>.
+General help using GNU software: <https://www.gnu.org/gethelp/>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
- echo "missing $scriptversion (GNU Automake)"
+ echo "missing (GNU Automake) $scriptversion"
exit $?
;;
@@ -101,14 +105,14 @@ else
exit $st
fi
-perl_URL=http://www.perl.org/
-flex_URL=http://flex.sourceforge.net/
-gnu_software_URL=http://www.gnu.org/software
+perl_URL=https://www.perl.org/
+flex_URL=https://github.com/westes/flex
+gnu_software_URL=https://www.gnu.org/software
program_details ()
{
case $1 in
- aclocal|automake)
+ aclocal|automake|autoreconf)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
@@ -123,6 +127,9 @@ program_details ()
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
+ *)
+ :
+ ;;
esac
}
@@ -137,48 +144,55 @@ give_advice ()
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ autoheader_deps="'acconfig.h'"
+ automake_deps="'Makefile.am'"
+ aclocal_deps="'acinclude.m4'"
case $normalized_program in
+ aclocal*)
+ echo "You should only need it if you modified $aclocal_deps or"
+ echo "$configure_deps."
+ ;;
autoconf*)
- echo "You should only need it if you modified 'configure.ac',"
- echo "or m4 files included by it."
- program_details 'autoconf'
+ echo "You should only need it if you modified $configure_deps."
+ ;;
+ autogen*)
+ echo "You should only need it if you modified a '.def' or '.tpl' file."
+ echo "You may want to install the GNU AutoGen package:"
+ echo "<$gnu_software_URL/autogen/>"
;;
autoheader*)
- echo "You should only need it if you modified 'acconfig.h' or"
+ echo "You should only need it if you modified $autoheader_deps or"
echo "$configure_deps."
- program_details 'autoheader'
;;
automake*)
- echo "You should only need it if you modified 'Makefile.am' or"
- echo "$configure_deps."
- program_details 'automake'
- ;;
- aclocal*)
- echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "You should only need it if you modified $automake_deps or"
echo "$configure_deps."
- program_details 'aclocal'
;;
- autom4te*)
+ autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'autom4te' program to be rebuilt."
- program_details 'autom4te'
+ ;;
+ autoreconf*)
+ echo "You should only need it if you modified $aclocal_deps or"
+ echo "$automake_deps or $autoheader_deps or $automake_deps or"
+ echo "$configure_deps."
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
- lex*|flex*)
- echo "You should only need it if you modified a '.l' file."
- echo "You may want to install the Fast Lexical Analyzer package:"
- echo "<$flex_URL>"
- ;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
@@ -189,6 +203,12 @@ give_advice ()
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
+ perl*)
+ echo "You should only need it to run GNU Autoconf, GNU Automake, "
+ echo " assorted other tools, or if you modified a Perl source file."
+ echo "You may want to install the Perl 5 language interpreter:"
+ echo "<$perl_URL>"
+ ;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
@@ -197,6 +217,7 @@ give_advice ()
echo "case some other package contains this missing '$1' program."
;;
esac
+ program_details "$normalized_program"
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
@@ -207,9 +228,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \
exit $st
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-format: "%Y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/mkinstalldirs b/mkinstalldirs
index 55d537f872..498a641d25 100755
--- a/mkinstalldirs
+++ b/mkinstalldirs
@@ -1,7 +1,7 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2025-06-18.21; # UTC
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
@@ -23,7 +23,9 @@ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
-Report bugs to <bug-automake@gnu.org>."
+Report bugs to <bug-automake@gnu.org>.
+GNU Automake home page: <https://www.gnu.org/software/automake/>.
+General help using GNU software: <https://www.gnu.org/gethelp/>."
# process command line arguments
while test $# -gt 0 ; do
@@ -39,7 +41,7 @@ while test $# -gt 0 ; do
shift
;;
--version)
- echo "$0 $scriptversion"
+ echo "$0 (GNU Automake) $scriptversion"
exit $?
;;
--) # stop option processing
@@ -92,6 +94,8 @@ case $dirmode in
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
+ echo "umask 22"
+ umask 22
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
@@ -104,6 +108,9 @@ case $dirmode in
;;
esac
+echo "umask 22"
+umask 22
+
for file
do
case $file in
@@ -132,21 +139,16 @@ do
if test ! -d "$pathcomp"; then
errstatus=$lasterr
- else
- if test ! -z "$dirmode"; then
- echo "chmod $dirmode $pathcomp"
- lasterr=
- chmod "$dirmode" "$pathcomp" || lasterr=$?
-
- if test ! -z "$lasterr"; then
- errstatus=$lasterr
- fi
- fi
fi
fi
pathcomp=$pathcomp/
done
+
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $file"
+ chmod "$dirmode" "$file" || errstatus=$?
+ fi
done
exit $errstatus
@@ -154,9 +156,9 @@ exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-format: "%Y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/newlib/Makefile.in b/newlib/Makefile.in
index a1319a863b..109cb5fea0 100644
--- a/newlib/Makefile.in
+++ b/newlib/Makefile.in
@@ -3084,51 +3084,51 @@ am__objects_152 = libm/common/libm_a-atanl.$(OBJEXT) \
libm/common/libm_a-sl_finite.$(OBJEXT)
@HAVE_LONG_DOUBLE_TRUE@am__objects_153 = $(am__objects_152)
@HAVE_FPMATH_H_TRUE@am__objects_154 = \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_acoshl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_acosl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_asinl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_atan2l.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_atanhl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_coshl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_fmodl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_lgammal.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_remainderl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-e_sinhl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_asinhl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_atanl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_cbrtl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_ceill.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_copysignl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_cosl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_fabsl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-fdiml.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_floorl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_fmal.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_fmaxl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_fminl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_frexpl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_ilogbl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_llrintl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_llroundl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_logbl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_lrint.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_lrintl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_lround.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_lroundl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_modfl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_nearbyintl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_nextafterl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_nexttoward.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_nexttowardf.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_remquol.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_rintl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_roundl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-scalblnl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_scalbnl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_sinl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_tanhl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_tanl.$(OBJEXT) \
-@HAVE_FPMATH_H_TRUE@ libm/ld/libm_a-s_truncl.$(OBJEXT)
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_acoshl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_acosl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_asinl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_atan2l.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_atanhl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_coshl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_fmodl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_lgammal.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_remainderl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-e_sinhl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_asinhl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_atanl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_cbrtl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_ceill.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_copysignl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_cosl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_fabsl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-fdiml.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_floorl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_fmal.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_fmaxl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_fminl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_frexpl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_ilogbl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_llrintl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_llroundl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_logbl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_lrint.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_lrintl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_lround.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_lroundl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_modfl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_nearbyintl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_nextafterl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_nexttoward.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_nexttowardf.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_remquol.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_rintl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_roundl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-scalblnl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_scalbnl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_sinl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_tanhl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_tanl.$(OBJEXT) \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/libm_a-s_truncl.$(OBJEXT)
@HAVE_FPMATH_H_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__objects_155 = \
@HAVE_FPMATH_H_TRUE@@HAVE_LONG_DOUBLE_TRUE@ $(am__objects_154)
am__objects_156 = libm/complex/libm_a-cabs.$(OBJEXT) \
@@ -3270,19 +3270,19 @@ am__objects_159 = libm/fenv/libm_a-feclearexcept.$(OBJEXT) \
@HAVE_LIBM_MACHINE_AARCH64_FALSE@@HAVE_LIBM_MACHINE_RISCV_TRUE@ libm/ld128/libm_a-k_tanl.$(OBJEXT) \
@HAVE_LIBM_MACHINE_AARCH64_FALSE@@HAVE_LIBM_MACHINE_RISCV_TRUE@ libm/ld128/libm_a-s_sinpil.$(OBJEXT) \
@HAVE_LIBM_MACHINE_AARCH64_FALSE@@HAVE_LIBM_MACHINE_RISCV_TRUE@ libm/ld128/libm_a-s_cospil.$(OBJEXT)
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@am__objects_162 = libm/ld128/libm_a-e_powl.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-s_erfl.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-s_exp2l.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-s_expl.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-s_logl.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-b_tgammal.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-invtrig.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-e_lgammal_r.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-k_cosl.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-k_sinl.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-k_tanl.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-s_sinpil.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/libm_a-s_cospil.$(OBJEXT)
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@am__objects_162 = libm/ld128/libm_a-e_powl.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-s_erfl.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-s_exp2l.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-s_expl.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-s_logl.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-b_tgammal.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-invtrig.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-e_lgammal_r.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-k_cosl.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-k_sinl.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-k_tanl.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-s_sinpil.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/libm_a-s_cospil.$(OBJEXT)
@HAVE_LIBM_MACHINE_AARCH64_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__objects_163 = $(am__objects_162)
@HAVE_LIBM_MACHINE_AMDGCN_TRUE@am__objects_164 = libm/machine/amdgcn/libm_a-v64_mathcnst.$(OBJEXT) \
@HAVE_LIBM_MACHINE_AMDGCN_TRUE@ libm/machine/amdgcn/libm_a-v64_reent.$(OBJEXT) \
@@ -4895,51 +4895,51 @@ libm_common_lsrc = \
libm_a_CFLAGS_libm_common = -fbuiltin -fno-math-errno
@HAVE_FPMATH_H_TRUE@libm_ld_lsrc = \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_acoshl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_acosl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_asinl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_atan2l.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_atanhl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_coshl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_fmodl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_lgammal.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_remainderl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/e_sinhl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_asinhl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_atanl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_cbrtl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_ceill.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_copysignl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_cosl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_fabsl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/fdiml.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_floorl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_fmal.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_fmaxl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_fminl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_frexpl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_ilogbl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_llrintl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_llroundl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_logbl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_lrint.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_lrintl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_lround.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_lroundl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_modfl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_nearbyintl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_nextafterl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_nexttoward.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_nexttowardf.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_remquol.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_rintl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_roundl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/scalblnl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_scalbnl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_sinl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_tanhl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_tanl.c \
-@HAVE_FPMATH_H_TRUE@ libm/ld/s_truncl.c
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_acoshl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_acosl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_asinl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_atan2l.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_atanhl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_coshl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_fmodl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_lgammal.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_remainderl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/e_sinhl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_asinhl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_atanl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_cbrtl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_ceill.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_copysignl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_cosl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_fabsl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/fdiml.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_floorl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_fmal.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_fmaxl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_fminl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_frexpl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_ilogbl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_llrintl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_llroundl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_logbl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_lrint.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_lrintl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_lround.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_lroundl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_modfl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_nearbyintl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_nextafterl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_nexttoward.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_nexttowardf.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_remquol.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_rintl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_roundl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/scalblnl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_scalbnl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_sinl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_tanhl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_tanl.c \
+@HAVE_FPMATH_H_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld/s_truncl.c
@HAVE_FPMATH_H_TRUE@libm_a_CFLAGS_libm_ld = -fbuiltin -fno-math-errno
libm_complex_src = \
@@ -5094,10 +5094,10 @@ libm_test_test_LDADD = $(CRT0) libm.a libc.a
@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/machine/aarch64/feupdateenv.c
@HAVE_LIBM_MACHINE_AARCH64_TRUE@libm_ld128_lsrc = \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/e_powl.c libm/ld128/s_erfl.c libm/ld128/s_exp2l.c libm/ld128/s_expl.c \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/s_logl.c libm/ld128/b_tgammal.c libm/ld128/invtrig.c \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/e_lgammal_r.c libm/ld128/k_cosl.c libm/ld128/k_sinl.c \
-@HAVE_LIBM_MACHINE_AARCH64_TRUE@ libm/ld128/k_tanl.c libm/ld128/s_sinpil.c libm/ld128/s_cospil.c
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/e_powl.c libm/ld128/s_erfl.c libm/ld128/s_exp2l.c libm/ld128/s_expl.c \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/s_logl.c libm/ld128/b_tgammal.c libm/ld128/invtrig.c \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/e_lgammal_r.c libm/ld128/k_cosl.c libm/ld128/k_sinl.c \
+@HAVE_LIBM_MACHINE_AARCH64_TRUE@@LDBL_EQ_DBL_FALSE@ libm/ld128/k_tanl.c libm/ld128/s_sinpil.c libm/ld128/s_cospil.c
@HAVE_LIBM_MACHINE_RISCV_TRUE@libm_ld128_lsrc = \
@HAVE_LIBM_MACHINE_RISCV_TRUE@ libm/ld128/e_powl.c libm/ld128/s_erfl.c libm/ld128/s_exp2l.c libm/ld128/s_expl.c \
diff --git a/newlib/configure b/newlib/configure
index 33a2ed1c56..e273cf5f69 100755
--- a/newlib/configure
+++ b/newlib/configure
@@ -638,6 +638,8 @@ HAS_NDS32_FPU_SP_TRUE
MACH_ADD_SETJMP_FALSE
MACH_ADD_SETJMP_TRUE
HAVE_FPMATH_H_FALSE
+LDBL_EQ_DBL_FALSE
+LDBL_EQ_DBL_TRUE
HAVE_FPMATH_H_TRUE
HAVE_LIBC_MACHINE_Z8K_FALSE
HAVE_LIBC_MACHINE_Z8K_TRUE
@@ -7480,6 +7482,14 @@ if test $newlib_cv_ldbl_eq_dbl = yes; then
$as_echo "#define _LDBL_EQ_DBL 1" >>confdefs.h
+fi
+
+ if test x"$newlib_cv_ldbl_eq_dbl" = x"yes"; then
+ LDBL_EQ_DBL_TRUE=
+ LDBL_EQ_DBL_FALSE='#'
+else
+ LDBL_EQ_DBL_TRUE='#'
+ LDBL_EQ_DBL_FALSE=
fi
ac_config_files="$ac_config_files Makefile"
@@ -8061,6 +8071,9 @@ if test -z "${HAVE_FPMATH_H_TRUE}" && test -z "${HAVE_FPMATH_H_FALSE}"; then
as_fn_error $? "conditional \"HAVE_FPMATH_H\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${LDBL_EQ_DBL_TRUE}" && test -z "${LDBL_EQ_DBL_FALSE}"; then
+ as_fn_error $? "conditional \"LDBL_EQ_DBL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${MACH_ADD_SETJMP_TRUE}" && test -z "${MACH_ADD_SETJMP_FALSE}"; then
as_fn_error $? "conditional \"MACH_ADD_SETJMP\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -9490,4 +9503,3 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
-
diff --git a/test-driver b/test-driver
index 0218a01f61..d81fba79cd 100755
--- a/test-driver
+++ b/test-driver
@@ -1,9 +1,9 @@
#! /bin/sh
# test-driver - basic testsuite driver script.
-scriptversion=2016-01-11.22; # UTC
+scriptversion=2025-06-18.21; # UTC
-# Copyright (C) 2011-2017 Free Software Foundation, Inc.
+# Copyright (C) 2011-2025 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@ scriptversion=2016-01-11.22; # UTC
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -42,11 +42,18 @@ print_usage ()
{
cat <<END
Usage:
- test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
- [--expect-failure={yes|no}] [--color-tests={yes|no}]
- [--enable-hard-errors={yes|no}] [--]
+ test-driver --test-name NAME --log-file PATH --trs-file PATH
+ [--expect-failure {yes|no}] [--color-tests {yes|no}]
+ [--collect-skipped-logs {yes|no}]
+ [--enable-hard-errors {yes|no}] [--]
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+See the GNU Automake documentation for information.
+
+Report bugs to <bug-automake@gnu.org>.
+GNU Automake home page: <https://www.gnu.org/software/automake/>.
+General help using GNU software: <https://www.gnu.org/gethelp/>.
END
}
@@ -55,15 +62,17 @@ log_file= # Where to save the output of the test script.
trs_file= # Where to save the metadata of the test run.
expect_failure=no
color_tests=no
+collect_skipped_logs=yes
enable_hard_errors=yes
while test $# -gt 0; do
case $1 in
--help) print_usage; exit $?;;
- --version) echo "test-driver $scriptversion"; exit $?;;
+ --version) echo "test-driver (GNU Automake) $scriptversion"; exit $?;;
--test-name) test_name=$2; shift;;
--log-file) log_file=$2; shift;;
--trs-file) trs_file=$2; shift;;
--color-tests) color_tests=$2; shift;;
+ --collect-skipped-logs) collect_skipped_logs=$2; shift;;
--expect-failure) expect_failure=$2; shift;;
--enable-hard-errors) enable_hard_errors=$2; shift;;
--) shift; break;;
@@ -103,8 +112,11 @@ trap "st=130; $do_exit" 2
trap "st=141; $do_exit" 13
trap "st=143; $do_exit" 15
-# Test script is run here.
-"$@" >$log_file 2>&1
+# Test script is run here. We create the file first, then append to it,
+# to ameliorate tests themselves also writing to the log file. Our tests
+# don't, but others can (automake bug#35762).
+: >"$log_file"
+"$@" >>"$log_file" 2>&1
estatus=$?
if test $enable_hard_errors = no && test $estatus -eq 99; then
@@ -116,7 +128,7 @@ fi
case $tweaked_estatus:$expect_failure in
0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
0:*) col=$grn res=PASS recheck=no gcopy=no;;
- 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
+ 77:*) col=$blu res=SKIP recheck=no gcopy=$collect_skipped_logs;;
99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
*:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
*:*) col=$red res=FAIL recheck=yes gcopy=yes;;
@@ -126,7 +138,7 @@ esac
# know whether the test passed or failed simply by looking at the '.log'
# file, without the need of also peaking into the corresponding '.trs'
# file (automake bug#11814).
-echo "$res $test_name (exit status: $estatus)" >>$log_file
+echo "$res $test_name (exit status: $estatus)" >>"$log_file"
# Report outcome to console.
echo "${col}${res}${std}: $test_name"
@@ -140,9 +152,9 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file
# Local Variables:
# mode: shell-script
# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-format: "%Y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
From 82750f0f98724f3c21c2f2c228124d000be38a8d Mon Sep 17 00:00:00 2001
From: Kreijstal <kreijstal@users.noreply.github.com>
Date: Sat, 18 Jul 2026 05:07:06 +0200
Subject: [PATCH 6/7] docs: record the ARM64 Clang porting procedure
Document the cross-toolchain layout, configure arguments, support libraries, and known limitations for reproducing the Windows ARM64 runtime.
Assisted-by: OpenAI Codex: GPT-5
---
PORTING_ARM64_CLANG.md | 113 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 113 insertions(+)
create mode 100644 PORTING_ARM64_CLANG.md
diff --git a/PORTING_ARM64_CLANG.md b/PORTING_ARM64_CLANG.md
new file mode 100644
index 0000000000..63ab4fff91
--- /dev/null
+++ b/PORTING_ARM64_CLANG.md
@@ -0,0 +1,113 @@
+# MSYS2 runtime ARM64/Clang port attempt
+
+Target: native Windows ARM64 (`aarch64-pc-msys`) using LLVM-MinGW Clang.
+
+## Bootstrap order
+
+1. Build GNU binutils for `aarch64-w64-mingw32`.
+2. Use Clang as the C/C++ frontend with the ARM64 PE/COFF target.
+3. Build newlib plus the MSYS/Cygwin public headers and w32api surface.
+4. Build and link `msys-2.0.dll`.
+5. Build the shell and core packages against that runtime.
+
+GNU binutils was cloned separately from sourceware because the MSYS2 runtime
+repository does not carry the `bfd`, `gas`, `ld`, or `binutils` source trees.
+Upstream binutils commit `ebf22fc26326ad138bea9dee536cf081e46dd6e1`
+built successfully on macOS for `aarch64-w64-mingw32`. The resulting GNU ld
+2.46.50 exposes both `aarch64pe` and `arm64pe` emulations, along with GAS,
+`dlltool`, `windres`, `objcopy`, `objdump`, `nm`, and archive tools.
+
+## Baseline
+
+- Upstream commit: `01d6c708f9221334d18ab332621b6d87eb12d37e`
+- The top-level configure accepts `aarch64-pc-msys` when Clang is supplied as
+ `CC_FOR_TARGET`.
+- ARM64 newlib compiles substantially before the first failure.
+
+## First failure
+
+LLVM-MinGW's compiler wrapper injects its UCRT sysroot while the runtime build
+also injects newlib. The two header worlds disagree about `ssize_t` on LLP64:
+
+```text
+LLVM-MinGW corecrt.h: typedef __int64 ssize_t;
+newlib sys/types.h: typedef long _ssize_t;
+```
+
+The port toolchain wrapper uses LLVM's ARM64 PE/COFF backend and builtin headers
+but suppresses the UCRT include tree with `-nostdinc`.
+
+## Second failure
+
+The generic LLVM-MinGW ARM64 target follows the Windows ABI and uses 64-bit
+`long double`. That bootstrap exposed a newlib source-selection bug: after
+detecting `_LDBL_EQ_DBL`, newlib still selected `libm/ld` sources requiring
+an extended `fpmath.h` layout. The added Automake conditional skips those
+sources whenever the compiler reports identical double representations.
+
+The final `CygwinARM64TargetInfo` deliberately exposes an LP64 Unix ABI with
+IEEE binary128 `long double`; it therefore selects AArch64's `libm/ld128`
+sources. Compiler, newlib, and support libraries must agree on that choice.
+
+## Explicit upstream architecture gates found
+
+- `winsup/configure.ac` rejected every target except `x86_64`.
+- MinGW helper discovery required GCC-named executables.
+- `winsup/cygwin/cygwin.sc.in` only emitted `pei-x86-64`.
+- Runtime startup, context switching, TLS, exception unwinding, fork, and math
+ still contain numerous x86-64 assembly and register-layout assumptions.
+
+This is an early bring-up branch, not yet a production runtime.
+
+## Third failure
+
+After excluding UCRT, newlib reaches its MSYS/Windows allocator and requires
+`windows.h`. The wrapper therefore searches LLVM-MinGW's Win32 headers with
+`-idirafter` (after newlib), while defining the UCRT compatibility guards for
+the ABI types already owned by newlib.
+
+Generic LLVM-MinGW also defines the build as ordinary Win32, selecting
+newlib's obsolete 32-bit `VirtualAlloc`-based `wsbrk`. The port driver defines
+the Cygwin/MSYS target macros so newlib follows the runtime-provided `sbrk`
+path, matching what an eventual `aarch64-pc-msys-clang` target should do
+natively inside Clang.
+
+Defining the runtime identity also makes newlib include `cygwin/config.h`, so
+the bootstrap driver stages `winsup/cygwin/include` before the full winsup
+install exists.
+
+## First runtime architecture primitive
+
+`cygwin/config.h::__getreent()` obtains the per-thread newlib state through
+the Windows TEB. x86-64 reads `GS:8`; Windows ARM64 reserves `x18` as the TEB
+pointer, so the ARM64 implementation loads the corresponding pointer from
+`x18 + 8` before applying `__CYGTLS_PADSIZE__`.
+
+The next newlib dependency is the public signal/ucontext ABI. The port adds an
+ARM64 `__mcontext` matching Windows `ARM64_NT_CONTEXT` (X0-X30, SP, PC, NEON,
+FP status/control, breakpoint and watchpoint registers), followed by Cygwin's
+`oldmask` and `cr2` extension fields.
+
+## Current result
+
+The paired LLVM patch provides an LP64 `CygwinARM64TargetInfo`, and the patched
+newlib and winsup sources produce a native ARM64 `msys-2.0.dll`. The tested
+runtime loads natively and runs Bash 5.3, fork, pipe-fork, command substitution,
+subshell status, and external-process probes in Windows 11 ARM64 under QEMU.
+
+This remains bring-up validation rather than production support. Long Bash
+argument vectors can be corrupted, `/tmp` setup emits a warning, transient
+child-start faults are retried, and the full runtime testsuite is not green.
+The reproducibility bundle records exact hashes and observed probe output.
+
+## MSYS newlib target recognition
+
+`newlib/configure.host` carried Cygwin-specific runtime flags only for
+`*-*-cygwin*`; the `aarch64-pc-msys` target therefore tried to compile its own
+allocator and syscalls. MSYS uses the same integration contract, so the MSYS
+patterns now receive `MALLOC_PROVIDED`, `GETREENT_PROVIDED`, signal/syscall
+flags, POSIX/XDR directories, and the winsup include staging.
+
+Clang's resource headers are placed with `-idirafter`. Its builtin `float.h`
+uses `include_next` and otherwise reaches LLVM-MinGW's UCRT `float.h` ahead of
+newlib, causing macro and ABI collisions.
From 8e82becb50b8bf02fa0d0dd9cd6d53671d3a1347 Mon Sep 17 00:00:00 2001
From: Kreijstal <kreijstal@users.noreply.github.com>
Date: Sat, 18 Jul 2026 05:36:41 +0200
Subject: [PATCH 7/7] docs: frame the port as WOA QEMU validation
Credit the Windows-on-ARM-Experiments runtime foundation and state that the tested QEMU path is the primary result.
Assisted-by: OpenAI Codex: GPT-5
---
PORTING_ARM64_CLANG.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/PORTING_ARM64_CLANG.md b/PORTING_ARM64_CLANG.md
index 63ab4fff91..6b34ebc4e4 100644
--- a/PORTING_ARM64_CLANG.md
+++ b/PORTING_ARM64_CLANG.md
@@ -2,6 +2,12 @@
Target: native Windows ARM64 (`aarch64-pc-msys`) using LLVM-MinGW Clang.
+The ARM64 runtime foundation comes from the
+[Windows-on-ARM-Experiments](https://github.com/Windows-on-ARM-Experiments)
+Cygwin work. This branch adapts that direction to the MSYS2/Clang build and
+records reproducible validation in a Windows 11 ARM64 QEMU VM. Its primary
+result is the tested QEMU path, not an independently completed runtime port.
+
## Bootstrap order
1. Build GNU binutils for `aarch64-w64-mingw32`.
#!/usr/bin/env bash
set -euo pipefail
: "${CYGWIN_CLANG_ROOT:?set CYGWIN_CLANG_ROOT to the patched Clang install}"
: "${LLVM_MINGW_ROOT:?set LLVM_MINGW_ROOT to an LLVM-MinGW ARM64 distribution}"
: "${MSYS2_RUNTIME_ROOT:?set MSYS2_RUNTIME_ROOT to the patched runtime source}"
: "${MSYS2_TOOLCHAIN_INCLUDE:?set MSYS2_TOOLCHAIN_INCLUDE to the shim include directory}"
resource_dir="${CLANG_RESOURCE_DIR:-$($CYGWIN_CLANG_ROOT/bin/clang -print-resource-dir)}"
w32api_include=()
if [[ -n "${MSYS2_W32API_PARENT:-}" ]]; then
w32api_include=(-isystem "$MSYS2_W32API_PARENT")
fi
exec "$CYGWIN_CLANG_ROOT/bin/clang" \
--target=aarch64-pc-cygwin \
-ffixed-x18 \
-ffreestanding \
-nostdinc \
-isystem "$MSYS2_TOOLCHAIN_INCLUDE" \
"${w32api_include[@]}" \
-idirafter "$resource_dir/include" \
-isystem "$MSYS2_RUNTIME_ROOT/winsup/cygwin/include" \
-idirafter "$LLVM_MINGW_ROOT/aarch64-w64-mingw32/include" \
-D_SIZE_T_DEFINED \
-D_SSIZE_T_DEFINED \
-D__CYGWIN__ \
-D__MSYS__ \
-Wno-error=ignored-optimization-argument \
-Wno-error=unknown-warning-option \
"$@"
#!/usr/bin/env bash
set -euo pipefail
: "${CYGWIN_CLANG_ROOT:?set CYGWIN_CLANG_ROOT to the patched Clang install}"
: "${LLVM_MINGW_ROOT:?set LLVM_MINGW_ROOT to an LLVM-MinGW ARM64 distribution}"
: "${MSYS2_RUNTIME_ROOT:?set MSYS2_RUNTIME_ROOT to the patched runtime source}"
: "${MSYS2_TOOLCHAIN_INCLUDE:?set MSYS2_TOOLCHAIN_INCLUDE to the shim include directory}"
resource_dir="${CLANG_RESOURCE_DIR:-$($CYGWIN_CLANG_ROOT/bin/clang -print-resource-dir)}"
w32api_include=()
if [[ -n "${MSYS2_W32API_PARENT:-}" ]]; then
w32api_include=(-isystem "$MSYS2_W32API_PARENT")
fi
exec "$CYGWIN_CLANG_ROOT/bin/clang++" \
--target=aarch64-pc-cygwin \
-ffixed-x18 \
-fms-extensions \
-ffreestanding \
-nostdinc \
-isystem "$MSYS2_TOOLCHAIN_INCLUDE" \
"${w32api_include[@]}" \
-idirafter "$resource_dir/include" \
-isystem "$LLVM_MINGW_ROOT/generic-w64-mingw32/include/c++/v1" \
-isystem "$MSYS2_RUNTIME_ROOT/winsup/cygwin/include" \
-idirafter "$LLVM_MINGW_ROOT/aarch64-w64-mingw32/include" \
-D_SIZE_T_DEFINED \
-D_SSIZE_T_DEFINED \
-D__CYGWIN__ \
-D__MSYS__ \
-D__MSYS_CLANG_MS_EXTENSIONS__ \
-Wno-error=ignored-optimization-argument \
-Wno-error=unknown-warning-option \
-Wno-error=mismatched-tags \
-Wno-error=nontrivial-memcall \
-Wno-error=vla-cxx-extension \
-Wno-error=gnu-designator \
-Wno-error=missing-braces \
-Wno-error=unused-const-variable \
-Wno-error=unused-variable \
-Wno-error=varargs \
"$@"
#!/usr/bin/env python3
import hashlib
import struct
import sys
from pathlib import Path
IMAGE_BASE = 0x180000000
TEXT_RVA = 0x1000
TEXT_RAW = 0x800
def text_offset(va: int) -> int:
return TEXT_RAW + (va - IMAGE_BASE - TEXT_RVA)
def replace(data: bytearray, offset: int, expected: bytes, replacement: bytes) -> None:
actual = bytes(data[offset : offset + len(expected)])
if actual != expected:
raise SystemExit(
f"unexpected bytes at {offset:#x}: {actual.hex()} != {expected.hex()}"
)
data[offset : offset + len(replacement)] = replacement
def encode_bl(pc: int, target: int) -> bytes:
displacement = target - pc
if displacement % 4:
raise SystemExit("unaligned branch")
return struct.pack("<I", 0x94000000 | ((displacement // 4) & 0x03FFFFFF))
def main() -> None:
if len(sys.argv) != 4:
raise SystemExit(f"usage: {sys.argv[0]} INPUT OUTPUT HELPER_TEXT")
source, output, helper_path = map(Path, sys.argv[1:])
data = bytearray(source.read_bytes())
digest = hashlib.sha256(data).hexdigest()
expected_digest = "48e9a68cd12bce1312e44e0706bc92f8aeafb217242fb5301f32cb0e287980cf"
if digest != expected_digest:
raise SystemExit(f"unexpected input hash: {digest}")
# Early dlmalloc calls can happen before the normal user heap exists. If
# sbrk fails, fall back to one deterministic 64 KiB arena at 0x10000000.
# Fork copies this arena explicitly below, after the normal user heap.
allocator_helper = bytes.fromhex(
"f37bbfa9f30300aa4697fd971f0000f10c010054e10313aa"
"0000a2d20200865283008052a80300d008e145f900013fd6"
"f37bc1a8c0035fd6"
)
replace(data, 0x1A1ED0, b"\xcc" * len(allocator_helper), allocator_helper)
replace(
data,
0x108464,
bytes.fromhex("e0031faa08e145f9e10314aa0202a0728300805200013fd6"),
bytes.fromhex("e00314aa08e145f9e10314aa0202a0728300805296660294"),
)
replace(
data,
0x1085E0,
bytes.fromhex("e0031faae10314aa08e145f9020086528300805200013fd6"),
bytes.fromhex("e00314aae10314aa08e145f9020086528300805237660294"),
)
helper_va = 0x1801A2710
helper = bytearray(helper_path.read_bytes())
if len(helper) != 0xC0:
raise SystemExit(f"unexpected helper size: {len(helper):#x}")
helper[0x14:0x18] = encode_bl(helper_va + 0x14, 0x180026BA4)
helper[0x2C:0x30] = encode_bl(helper_va + 0x2C, 0x1801A186C)
helper[0xAC:0xB0] = encode_bl(helper_va + 0xAC, 0x1801A1C50)
helper_offset = text_offset(helper_va)
replace(data, helper_offset, b"\xcc" * len(helper), helper)
# Expand the caller frame so a fourth variadic copy range fits after the
# existing dll-data, dll-bss, and user-heap ranges.
frame_patches = (
(0x180006478, "ff4301d1", "ffc301d1"),
(0x18000647C, "f35303a9", "f35305a9"),
(0x180006488, "fe2300f9", "fe3300f9"),
(0x180006590, "f35343a9", "f35345a9"),
(0x180006594, "fe2340f9", "fe3340f9"),
(0x180006598, "ff430191", "ffc30191"),
)
for va, expected, replacement in frame_patches:
replace(data, text_offset(va), bytes.fromhex(expected), bytes.fromhex(replacement))
# The helper appends bootstrap label/base/end/NULL on the expanded frame,
# then makes the original child_copy call in one pass.
call_va = 0x180006514
branch = encode_bl(call_va, helper_va)
replace(data, text_offset(call_va), bytes.fromhex("ff1300f9"), branch)
replace(data, text_offset(0x180006518), bytes.fromhex("a3810094"), struct.pack("<I", 0xD503201F))
# pinfo::thisproc marks the forkee's process mapping as removable. The
# normal exit path runs the global pinfo destructor before do_exit, which
# otherwise clears `myself` and crashes. Match pinfo_init by preserving it.
replace(
data,
text_offset(0x1800064A8),
bytes.fromhex("680e40f9"),
encode_bl(0x1800064A8, helper_va + 0x3C),
)
# Fork does not initialize child_info::parent_winpid. Record the current
# PID immediately before CreateProcessW so the child can reopen its parent.
replace(
data,
text_offset(0x1800264C8),
bytes.fromhex("7fb600f9"),
encode_bl(0x1800264C8, helper_va + 0x20),
)
# handle_spawn normally trusts an inherited parent handle when the DLL is
# linked normally. Force its existing OpenProcess(parent_winpid) path so
# ARM64 spawn/exec receives a valid process handle too.
replace(
data,
text_offset(0x180006604),
bytes.fromhex("e8000034"),
struct.pack("<I", 0xD503201F),
)
child_helper_va = helper_va + 0x8C
replace(
data,
text_offset(0x1801063CC),
bytes.fromhex("d62646f9"),
encode_bl(0x1801063CC, child_helper_va),
)
# Include the allocator and fork helpers in the executable portion of
# .text. llvm-objcopy pre-fills the available padding with 0xcc.
replace(
data,
0x188,
struct.pack("<I", 0x1A16D0),
struct.pack("<I", 0x1A17D0),
)
output.write_bytes(data)
print(f"{output}: {hashlib.sha256(data).hexdigest()}")
if __name__ == "__main__":
main()
.text
.globl arm64_fork_bootstrap_copy
arm64_fork_bootstrap_copy:
movz x10, #0x1000, lsl #16
movz x8, #0x1001, lsl #16
stp x9, x10, [sp, #32]
stp x8, xzr, [sp, #48]
str x30, [sp, #72]
bl arm64_child_copy
ldr x30, [sp, #72]
ret
arm64_child_copy:
.globl arm64_parent_handle_inherit
arm64_parent_handle_inherit:
str xzr, [x19, #360]
stp x29, x30, [sp, #-16]!
mov x29, sp
bl arm64_get_current_process_id
str w0, [x19, #104]
ldp x29, x30, [sp], #16
ret
.globl arm64_preserve_myself
arm64_preserve_myself:
strb wzr, [x20, #24]
ldr x8, [x19, #24]
ret
// Keep the child helper at its established binary-patch offset.
.rept 17
nop
.endr
arm64_get_current_process_id:
.globl arm64_child_open_parent
arm64_child_open_parent:
ldr x22, [x22, #3144]
cbnz w19, arm64_child_open_parent_done
mov x20, x30
ldr x8, [x22]
ldr w2, [x8, #88]
movz w0, #0x1058
movk w0, #0x10, lsl #16
mov w1, wzr
bl arm64_child_open_process
ldr x8, [x22]
str x0, [x8, #80]
mov x30, x20
arm64_child_open_parent_done:
ret
arm64_child_open_process:
#define FE_ALL_EXCEPT 0x1f
int
feenableexcept (int mask)
{
unsigned long old_fpcr;
unsigned long new_fpcr;
__asm__ volatile ("mrs %0, fpcr" : "=r" (old_fpcr));
new_fpcr = old_fpcr | ((unsigned long) (mask & FE_ALL_EXCEPT) << 8);
__asm__ volatile ("msr fpcr, %0" : : "r" (new_fpcr));
return (old_fpcr >> 8) & FE_ALL_EXCEPT;
}
#!/usr/bin/env bash
printf 'STATUS_TEST_START\n'
child=$(printf child-ok)
child_status=$?
printf 'COMMAND_SUBSTITUTION=%s STATUS=%s\n' "$child" "$child_status"
(exit 0)
printf 'SUBSHELL_ZERO_STATUS=%s\n' "$?"
(exit 7)
printf 'SUBSHELL_SEVEN_STATUS=%s\n' "$?"
printf 'STATUS_TEST_DONE\n'
#!/usr/bin/env bash
printf 'BASH_VERSION=%s\n' "$BASH_VERSION"
printf 'BASH_MACHTYPE=%s\n' "$MACHTYPE"
child=$(printf child-ok)
printf 'BASH_CHILD=%s\n' "$child"
(exit 7)
printf 'SUBSHELL_EXIT=%s\n' "$?"
./msys-runtime-smoke-arm64-fixed.exe
printf 'EXTERNAL_EXIT=%s\n' "$?"
#!/usr/bin/env bash
set -euo pipefail
: "${MSYS_CC:?set MSYS_CC to aarch64-pc-msys-clang}"
: "${MSYS_AR:?set MSYS_AR to aarch64-w64-mingw32-ar}"
: "${MSYS_RANLIB:?set MSYS_RANLIB to aarch64-w64-mingw32-ranlib}"
: "${LLVM_SOURCE:?set LLVM_SOURCE to the patched llvm-project checkout}"
: "${MSYS2_RUNTIME_ROOT:?set MSYS2_RUNTIME_ROOT to the patched runtime checkout}"
: "${RUNTIME_BUILD:?set RUNTIME_BUILD to the aarch64-pc-msys target build directory}"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
OUT="${SUPPORT_OUT:-$PWD/arm64-support}"
BUILTINS="$LLVM_SOURCE/compiler-rt/lib/builtins"
NEWLIB="$MSYS2_RUNTIME_ROOT/newlib"
mkdir -p "$OUT/compiler-rt" "$OUT/math"
target_includes=(
-isystem "$RUNTIME_BUILD/newlib/targ-include"
-isystem "$MSYS2_RUNTIME_ROOT/newlib/libc/include"
)
builtins=(
addtf3 comparetf2 divtc3 divtf3 extenddftf2 extendsftf2 fixtfdi
fixtfsi floatsitf multc3 multf3 subtf3 trunctfdf2 trunctfsf2
)
for name in "${builtins[@]}"; do
"$MSYS_CC" "${target_includes[@]}" -O2 -I"$BUILTINS" -c "$BUILTINS/$name.c" \
-o "$OUT/compiler-rt/$name.o"
done
"$MSYS_CC" "${target_includes[@]}" -O2 -I"$BUILTINS" -c "$BUILTINS/aarch64/fp_mode.c" \
-o "$OUT/compiler-rt/fp_mode.o"
"$MSYS_CC" "${target_includes[@]}" -O2 -c "$ROOT/arm64_fenv_excepts.c" \
-o "$OUT/compiler-rt/arm64_fenv_excepts.o"
"$MSYS_CC" "${target_includes[@]}" -O2 -I"$NEWLIB/libm/common" -I"$NEWLIB/libm/machine/aarch64" \
-c "$NEWLIB/libm/machine/aarch64/fenv.c" -o "$OUT/compiler-rt/fenv.o"
"$MSYS_AR" rcsD "$OUT/libclang_rt.tf-aarch64.a" "$OUT/compiler-rt"/*.o
"$MSYS_RANLIB" -D "$OUT/libclang_rt.tf-aarch64.a"
"$MSYS_CC" "${target_includes[@]}" -O2 -I"$NEWLIB/libm/complex" -c "$ROOT/arm64_link_support.c" \
-o "$OUT/math/arm64_link_support.o"
"$MSYS_CC" "${target_includes[@]}" -O2 \
-I"$MSYS2_RUNTIME_ROOT/winsup/cygwin/math" -I"$NEWLIB/libm/complex" \
-c "$ROOT/catanl_only.c" \
-o "$OUT/math/catanl_only.o"
winsup_complex=(ccosl cexpl clogl cpowl cprojl csinl csqrtl ctanl)
for name in "${winsup_complex[@]}"; do
"$MSYS_CC" "${target_includes[@]}" -O2 -D_NEW_COMPLEX_LDOUBLE=1 \
-I"$MSYS2_RUNTIME_ROOT/winsup/cygwin/math" \
-I"$NEWLIB/libm/complex" -I"$NEWLIB/libm/common" \
-c "$MSYS2_RUNTIME_ROOT/winsup/cygwin/math/$name.c" -o "$OUT/math/$name.o"
done
winsup_math=(cargl clog10l exp10l pow10l tgammal)
for name in "${winsup_math[@]}"; do
"$MSYS_CC" "${target_includes[@]}" -O2 -I"$NEWLIB/libm/complex" -I"$NEWLIB/libm/common" \
-c "$MSYS2_RUNTIME_ROOT/winsup/cygwin/math/$name.c" \
-o "$OUT/math/$name.o"
done
"$MSYS_AR" rcsD "$OUT/libmsys-math-arm64.a" "$OUT/math"/*.o
"$MSYS_RANLIB" -D "$OUT/libmsys-math-arm64.a"
shasum -a 256 "$OUT/libclang_rt.tf-aarch64.a" "$OUT/libmsys-math-arm64.a"
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
LLVM_BIN="${LLVM_BIN:-$(brew --prefix llvm)/bin}"
LLD_LINK="${LLD_LINK:-$(command -v lld-link)}"
BUILD="work/probe-build"
mkdir -p "$BUILD" artifacts
"$LLVM_BIN/llvm-dlltool" -m arm64 \
-d tools/kernel32-probe.def \
-l "$BUILD/kernel32.lib"
"$LLVM_BIN/clang" \
--target=aarch64-pc-windows-msvc \
-ffreestanding \
-fno-stack-protector \
-fno-builtin \
-c tools/msys-loader-probe.c \
-o "$BUILD/msys-loader-probe.obj"
"$LLD_LINK" \
/machine:arm64 \
/subsystem:console \
/entry:mainCRTStartup \
/nodefaultlib \
"$BUILD/msys-loader-probe.obj" \
"$BUILD/kernel32.lib" \
/out:artifacts/msys-loader-probe.exe
file artifacts/msys-loader-probe.exe
#define _NEW_COMPLEX_LDOUBLE 1
#include "complex_internal.h"
#include "catan.def.h"
#!/usr/bin/env python3
import struct
import sys
from pathlib import Path
def sign_extend(value: int, bits: int) -> int:
sign = 1 << (bits - 1)
return (value ^ sign) - sign
def encode_adr(rd: int, pc: int, target: int) -> int:
immediate = target - pc
if not -(1 << 20) <= immediate < (1 << 20):
raise SystemExit("CRT target is outside ADR range")
encoded = immediate & 0x1FFFFF
return 0x10000000 | ((encoded & 3) << 29) | ((encoded >> 2) << 5) | rd
def main() -> None:
if len(sys.argv) != 2:
raise SystemExit(f"usage: {sys.argv[0]} PE_FILE")
path = Path(sys.argv[1])
data = bytearray(path.read_bytes())
pe = struct.unpack_from("<I", data, 0x3C)[0]
section_count = struct.unpack_from("<H", data, pe + 6)[0]
optional_size = struct.unpack_from("<H", data, pe + 20)[0]
section_table = pe + 24 + optional_size
text = None
for index in range(section_count):
offset = section_table + index * 40
name = bytes(data[offset : offset + 8]).rstrip(b"\0")
if name == b".text":
virtual_size, rva, raw_size, raw = struct.unpack_from("<IIII", data, offset + 8)
text = (rva, raw, min(virtual_size, raw_size))
break
if text is None:
raise SystemExit("PE has no .text section")
text_rva, text_raw, text_size = text
matches = []
for offset in range(text_raw, text_raw + text_size - 12, 4):
store, adrp, add = struct.unpack_from("<III", data, offset)
if store != 0xF9000128:
continue
if adrp & 0x9F00001F != 0x90000008:
continue
if add & 0xFFC003FF != 0x91000108:
continue
matches.append((offset, adrp, add))
if len(matches) != 1:
raise SystemExit(f"expected one ARM64 CRT refptr sequence, found {len(matches)}")
offset, adrp, add = matches[0]
adrp_pc = text_rva + (offset + 4 - text_raw)
immediate = (((adrp >> 5) & 0x7FFFF) << 2) | ((adrp >> 29) & 3)
page = (adrp_pc & ~0xFFF) + sign_extend(immediate, 21) * 0x1000
target = page + ((add >> 10) & 0xFFF)
adr_pc = text_rva + (offset + 8 - text_raw)
struct.pack_into("<III", data, offset,
0xF9400129, 0xF9000128, encode_adr(8, adr_pc, target))
path.write_bytes(data)
print(f"patched ARM64 CRT refptr at RVA {text_rva + offset - text_raw:#x}")
if __name__ == "__main__":
main()

Windows 11 ARM64 on QEMU/HVF, unattended qcow2 install

This gist contains the reproducible scripts used to create and boot a Windows 11 ARM64 VM on Apple Silicon macOS with QEMU, HVF, EDK2, TPM, NVMe storage, and VirtIO networking.

Files

  • reinstall-win11-arm64-qcow2.sh: downloads the pinned Windows 11 ARM64 ISO and ARM64 VirtIO drivers, verifies both SHA256 values, patches the installer with autounattend.xml, creates one 50 GiB qcow2 disk, installs Windows unattended, switches from installer media to disk-only boot when EDK2 stalls after the first Windows setup phase, and verifies both RDP authentication and the OpenSSH banner through QEMU port forwarding.
  • run-win11.sh: boots the installed qcow2 with fresh EDK2 vars and QEMU/HVF. It supports isolated user-mode NAT with RDP and SSH forwarding, or Apple vmnet-bridged networking that exposes the VM directly to the LAN.
  • MSYS2_ARM64_README.md: pinned, reproducible notes for the experimental MSYS2 runtime and Bash port to native Windows ARM64.
  • WOA_COMPARISON.md: overlap and delta analysis against the Windows-on-ARM-Experiments GNU/Cygwin port.
  • llvm-ms-builtins-long-long.patch: cross-target Clang change spelling MS builtin 64-bit prototypes as long long; apply before the target patch.
  • llvm-aarch64-cygwin-target.patch: Clang target patch for LP64 aarch64-pc-cygwin PE/COFF (target, defines, lit tests).
  • The same LLVM series is pushed to Kreijstal/llvm-project, branch aarch64-cygwin-msys-experiment at commit 1e644a04.
  • msys2-runtime-series and 0001 through 0007: ordered experimental runtime/newlib patches matching draft PR #348 at commit 8e82becb.
  • sigjmp-mask-probe.c: direct verification of ARM64 sigsetjmp signal-mask save and restore behavior.
  • prepare-msys2-arm64-dll.sh and add-msys2-arm64-bootstrap-fork-copy.py: deterministic post-link steps that reproduce the Windows-tested DLL byte for byte.

MSYS2 runtime on ARM64

The gist also contains the full experimental MSYS2 runtime port used in this VM. Start with MSYS2_ARM64_README.md; it records exact source commits, toolchain setup, patch hashes, build commands, the verified Bash/fork output, and known limitations. The DLL rebuilt from draft PR #348 at commit 8e82becb and tested in Windows ARM64 has SHA256 e69dd757dab8ca0148dbf0f0e95278afab70e56f527b1406bf9eb1d86ba653ed. The separate deterministic post-link example produces the older 773f3cafd7d94b85284a260daf9a3b266db980ece7a720be51ad1855c3e8ece8 artifact from its hash-identified first-link input.

This is a Clang/MSYS2 adaptation and QEMU validation of the ARM64 foundation developed by Windows-on-ARM-Experiments, not a replacement runtime port. Read WOA_COMPARISON.md before reusing or proposing runtime changes upstream.

Usage

Clone the gist as the workspace's scripts/ directory, then run the installer:

mkdir win11-arm64-qemu
cd win11-arm64-qemu
git clone https://gist.github.com/1cd0bd27e12111a5b5ccb16189e31724.git scripts
./scripts/reinstall-win11-arm64-qcow2.sh
./scripts/run-win11.sh

The installer leaves only:

outputs/win11-arm64-50g.qcow2

No .raw, .img, or temporary .iso files are kept after a successful run.

Defaults

  • Windows user: codex
  • Windows password: Passw0rd!
  • Disk: outputs/win11-arm64-50g.qcow2
  • Virtual disk size: 50G
  • RAM: 8G
  • vCPUs: 4
  • RDP host port: 3390
  • SSH host port: 2222
  • Network mode: user

Override with environment variables, for example:

USERNAME=me PASSWORD='ChangeMe123!' RAM_SIZE=6G CPU_CORES=4 ./scripts/reinstall-win11-arm64-qcow2.sh
RDP_PORT=3391 SSH_PORT=2223 ./scripts/run-win11.sh

The verified macOS tool versions were QEMU 11.0.1, FreeRDP 3.26.0, wimlib 1.14.5, swtpm 0.10.1, socat 1.8.1.1, and cdrtools 3.02a09. The installer obtains them through Homebrew when they are absent.

PowerShell over SSH

New unattended installs enable Windows OpenSSH Server, allow TCP port 22 for every firewall profile, and use Windows PowerShell as the SSH default shell.

With the default user-mode network:

ssh -p 2222 codex@127.0.0.1
ssh-copy-id -p 2222 codex@127.0.0.1

The first command works with the unattended-install password; the second adds the host's default public key for subsequent passwordless access.

For an existing Windows image, run once in an Administrator PowerShell:

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Set-Service sshd -StartupType Automatic
Start-Service sshd
Enable-NetFirewallRule -Name OpenSSH-Server-In-TCP
Set-NetFirewallRule -Name OpenSSH-Server-In-TCP -Profile Any
New-Item -Path "HKLM:\SOFTWARE\OpenSSH" -Force | Out-Null
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
Restart-Service sshd

Direct LAN access with Apple vmnet bridging

Homebrew QEMU supports vmnet-bridged, but macOS requires root or the restricted com.apple.vm.networking entitlement. A narrowly scoped sudoers rule avoids running unrelated commands passwordlessly:

kreijstal ALL=(root) NOPASSWD: /opt/homebrew/bin/qemu-system-aarch64

Install that line as a mode-0440 file in /etc/sudoers.d/, then start the VM on the active Mac interface (here en0):

NETWORK_MODE=bridged BRIDGE_IF=en0 ./scripts/run-win11.sh

Windows receives a normal DHCP address on the LAN. Find it by its fixed VM MAC address 52:54:00:12:34:59, then connect directly:

ssh codex@192.168.188.x

Bridged mode deliberately removes the host-only 3390 and 2222 forwards; use the guest's LAN address for both RDP and SSH.

Troubleshooting: QEMU display looks extremely zoomed

Do not assume this is Windows percentage scaling. Check Settings → System → Display → Advanced display. A seen failure mode with the Red Hat VirtIO GPU DOD controller is:

Desktop mode:       640 x 360
Active signal mode: -1 x -1, Unknown

In that state the guest framebuffer itself is only 640x360. QEMU's Cocoa window enlarges that small framebuffer, so the desktop looks extremely zoomed. The launcher requests 1920x1080 through:

-device virtio-gpu-pci,xres=1920,yres=1080,edid=on
-display cocoa,zoom-to-fit=on

The command-line xres and yres values are only the requested initial dimensions. Stock QEMU's Cocoa backend subsequently reports the current macOS drawable size through dpy_set_ui_info(). If the initial Cocoa content area is 640x360, that UI-info feedback can replace the requested 1920x1080, and the Windows VirtIO GPU DOD driver adopts the tiny mode. Changing Windows Scale alone does not fix this because the framebuffer resolution itself is wrong.

Reproduced local fix

The working fix was a custom QEMU 11.0.1 Cocoa build using qemu-11.0.1-cocoa-force-1920x1080-uiinfo.patch, included in this gist. It changes ui/cocoa.m so the UI information advertised to the guest is always:

info.width = 1920;
info.height = 1080;
info.width_mm = 480;
info.height_mm = 270;

The launcher prefers this patched build when present:

$HOME/opt/qemu-cocoa-proper/bin/qemu-system-aarch64

An observed regression happened after moving the VM workspace between macOS user accounts: the patched QEMU remained under the old user's ~/opt, so the new user's launcher silently fell back to stock Homebrew QEMU and Windows returned to 640x360. Copying the patched build into the active user's $HOME/opt/qemu-cocoa-proper and restarting the VM restored a large framebuffer. The live verified result was 1810x1018—the usable Cocoa content area at the same 16:9 ratio—instead of 640x360.

Confirm which binary is running with:

ps -axo pid,user,command | grep '[q]emu-system-aarch64'

To capture the actual QEMU framebuffer rather than the macOS window, use the HMP monitor:

printf 'screendump /tmp/qemu-screen.ppm\n' | \
  socat - UNIX-CONNECT:work/vm/qemu-monitor.sock

When bridged QEMU runs through sudo, its monitor socket and screenshot may be root-owned. Grant the current user access to the socket before capturing, or configure a TCP monitor restricted to loopback on the next launch.

Verified result

The install completed successfully on macOS Apple Silicon:

  • Windows 11 ARM64 installed into outputs/win11-arm64-50g.qcow2
  • qcow2 virtual size: 50 GiB
  • allocated size after install: about 9.56 GiB
  • VirtIO networking passed by authenticating to RDP on 127.0.0.1:3390
  • standalone qcow2-only boot test also opened RDP
  • Windows OpenSSH verified with a direct PowerShell login
  • Apple vmnet-bridged verified on macOS using en0
LIBRARY KERNEL32.dll
EXPORTS
AddVectoredExceptionHandler
CloseHandle
ContinueDebugEvent
CreateProcessW
ExitProcess
FreeLibrary
GetEnvironmentVariableW
GetLastError
GetModuleHandleA
GetProcAddress
GetStdHandle
LoadLibraryW
LoadLibraryExW
MoveFileExA
WriteFile
WaitForDebugEvent
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kreijstal <kreijstal@users.noreply.github.com>
Date: Sat, 18 Jul 2026 11:10:58 +0200
Subject: [PATCH 2/2] clang: add the LP64 aarch64-pc-cygwin target
Add CygwinARM64TargetInfo for Cygwin and MSYS on Windows ARM64. The
target keeps the Windows ARM64 calling convention and PE/COFF object
format but exposes the LP64 Unix ABI established by x86_64 Cygwin,
with IEEE binary128 long double and the Itanium C++ ABI.
The preprocessor test checks the target defines; the Sema test pins
the LP64 and long double ABI decisions.
Assisted-by: OpenAI Codex: GPT-5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---
clang/lib/Basic/Targets.cpp | 2 ++
clang/lib/Basic/Targets/AArch64.cpp | 31 +++++++++++++++++++
clang/lib/Basic/Targets/AArch64.h | 12 +++++++
clang/test/Preprocessor/init-aarch64-cygwin.c | 11 +++++++
clang/test/Sema/aarch64-cygwin-abi.c | 7 +++++
5 files changed, 63 insertions(+)
create mode 100644 clang/test/Preprocessor/init-aarch64-cygwin.c
create mode 100644 clang/test/Sema/aarch64-cygwin-abi.c
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 8c01cfc..c831c98 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -184,6 +184,8 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
Opts);
case llvm::Triple::Win32:
switch (Triple.getEnvironment()) {
+ case llvm::Triple::Cygnus:
+ return std::make_unique<CygwinARM64TargetInfo>(Triple, Opts);
case llvm::Triple::GNU:
return std::make_unique<MinGWARM64TargetInfo>(Triple, Opts);
case llvm::Triple::MSVC:
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index debf3ec..490287b 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -1858,6 +1858,37 @@ MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
TheCXXABI.set(TargetCXXABI::GenericAArch64);
}
+CygwinARM64TargetInfo::CygwinARM64TargetInfo(const llvm::Triple &Triple,
+ const TargetOptions &Opts)
+ : WindowsARM64TargetInfo(Triple, Opts) {
+ // Cygwin and MSYS expose LP64 even though calls into Win32 use the Windows
+ // ARM64 calling convention. Match the established x86_64 Cygwin ABI.
+ LongWidth = LongAlign = 64;
+ LongDoubleWidth = LongDoubleAlign = 128;
+ LongDoubleFormat = &llvm::APFloat::IEEEquad();
+ IntMaxType = SignedLong;
+ Int64Type = SignedLong;
+ SizeType = UnsignedLong;
+ PtrDiffType = SignedLong;
+ IntPtrType = SignedLong;
+ WCharType = UnsignedShort;
+ WIntType = UnsignedInt;
+ // Unlike x86 Cygwin, ARM64 has no stdcall-style symbol decorations, so
+ // Microsoft C mangling is deliberately not enabled, matching MinGW ARM64.
+ TheCXXABI.set(TargetCXXABI::GenericAArch64);
+}
+
+void CygwinARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
+ Builder.defineMacro("__CYGWIN__");
+ Builder.defineMacro("__CYGWIN64__");
+ addCygMingDefines(Opts, Builder);
+ DefineStd(Builder, "unix", Opts);
+ if (Opts.CPlusPlus)
+ Builder.defineMacro("_GNU_SOURCE");
+}
+
AppleMachOAArch64TargetInfo::AppleMachOAArch64TargetInfo(
const llvm::Triple &Triple, const TargetOptions &Opts)
: AppleMachOTargetInfo<AArch64leTargetInfo>(Triple, Opts) {}
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index b6e707d..702b2d0 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -342,6 +342,18 @@ public:
MinGWARM64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
};
+// ARM64 Cygwin/MSYS target. Windows ARM64 calling conventions and PE/COFF
+// are retained, but the Unix-facing ABI is LP64 like x86_64 Cygwin.
+class LLVM_LIBRARY_VISIBILITY CygwinARM64TargetInfo
+ : public WindowsARM64TargetInfo {
+public:
+ CygwinARM64TargetInfo(const llvm::Triple &Triple,
+ const TargetOptions &Opts);
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
class LLVM_LIBRARY_VISIBILITY AArch64beTargetInfo : public AArch64TargetInfo {
public:
AArch64beTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
diff --git a/clang/test/Preprocessor/init-aarch64-cygwin.c b/clang/test/Preprocessor/init-aarch64-cygwin.c
new file mode 100644
index 0000000..2eb1b29
--- /dev/null
+++ b/clang/test/Preprocessor/init-aarch64-cygwin.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -E -dM -triple=aarch64-pc-cygwin -x c /dev/null | FileCheck %s
+
+// CHECK-DAG: #define __CYGWIN__ 1
+// CHECK-DAG: #define __CYGWIN64__ 1
+// CHECK-DAG: #define __SIZEOF_POINTER__ 8
+// CHECK-DAG: #define __SIZEOF_LONG__ 8
+// CHECK-DAG: #define __SIZEOF_LONG_DOUBLE__ 16
+// CHECK-DAG: #define __SIZEOF_WCHAR_T__ 2
+// CHECK-DAG: #define __INT64_TYPE__ long int
+// CHECK-DAG: #define __SIZE_TYPE__ long unsigned int
+// CHECK-DAG: #define __WCHAR_TYPE__ unsigned short
diff --git a/clang/test/Sema/aarch64-cygwin-abi.c b/clang/test/Sema/aarch64-cygwin-abi.c
new file mode 100644
index 0000000..46ec754
--- /dev/null
+++ b/clang/test/Sema/aarch64-cygwin-abi.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple aarch64-pc-cygwin -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+_Static_assert(sizeof(long) == 8, "Cygwin ARM64 must be LP64");
+_Static_assert(sizeof(void *) == 8, "Cygwin ARM64 pointer width");
+_Static_assert(sizeof(long double) == 16, "Cygwin ARM64 long double ABI");
+_Static_assert(_Alignof(long double) == 16, "Cygwin ARM64 long double alignment");
--
2.54.0
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kreijstal <kreijstal@users.noreply.github.com>
Date: Sat, 18 Jul 2026 11:10:58 +0200
Subject: [PATCH 1/2] clang: spell MS builtin 64-bit prototypes as long long
The Microsoft builtin prototypes model MSVC declarations whose 64-bit
type is always __int64, i.e. long long on every Windows ABI. Spelling
them int64_t makes the prototypes target-dependent: on LP64 Cygwin
targets int64_t resolves to long, so the builtins collide with the
__int64-based declarations in the MinGW intrinsic headers.
This is a no-op for MSVC and MinGW targets, where int64_t already is
long long. On LP64 Cygwin targets with -fms-extensions the prototype
types change identity from long to long long, intentionally matching
the headers.
Assisted-by: OpenAI Codex: GPT-5
---
clang/include/clang/Basic/Builtins.td | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 344a712..829728c 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -53,10 +53,10 @@ class MSInt16_32Template : Template<["short", "msint32_t"],
["16", ""]>;
class MSUInt16_32_64Template :
- Template<["unsigned short", "unsigned int", "uint64_t"],
+ Template<["unsigned short", "unsigned int", "unsigned long long int"],
["16", "", "64"]>;
-class MSInt32_64Template : Template<["msint32_t", "int64_t"],
+class MSInt32_64Template : Template<["msint32_t", "long long int"],
["", "64"]>;
class FloatDoubleTemplate : Template<["float", "double"],
@@ -3020,19 +3020,19 @@ def InterlockedBittestAndReset_rel : MSLangBuiltin {
def InterlockedBittestAndReset64_acq : MSLangBuiltin {
let Spellings = ["_interlockedbittestandreset64_acq"];
let Attributes = [NoThrow];
- let Prototype = "unsigned char(int64_t volatile*, int64_t)";
+ let Prototype = "unsigned char(long long int volatile*, long long int)";
}
def InterlockedBittestAndReset64_nf : MSLangBuiltin {
let Spellings = ["_interlockedbittestandreset64_nf"];
let Attributes = [NoThrow];
- let Prototype = "unsigned char(int64_t volatile*, int64_t)";
+ let Prototype = "unsigned char(long long int volatile*, long long int)";
}
def InterlockedBittestAndReset64_rel : MSLangBuiltin {
let Spellings = ["_interlockedbittestandreset64_rel"];
let Attributes = [NoThrow];
- let Prototype = "unsigned char(int64_t volatile*, int64_t)";
+ let Prototype = "unsigned char(long long int volatile*, long long int)";
}
def InterlockedBittestAndSet : MSLangBuiltin, MSInt32_64Template {
@@ -3062,19 +3062,19 @@ def InterlockedBittestAndSet_rel : MSLangBuiltin {
def InterlockedBittestAndSet64_acq : MSLangBuiltin {
let Spellings = ["_interlockedbittestandset64_acq"];
let Attributes = [NoThrow];
- let Prototype = "unsigned char(int64_t volatile*, int64_t)";
+ let Prototype = "unsigned char(long long int volatile*, long long int)";
}
def InterlockedBittestAndSet64_nf : MSLangBuiltin {
let Spellings = ["_interlockedbittestandset64_nf"];
let Attributes = [NoThrow];
- let Prototype = "unsigned char(int64_t volatile*, int64_t)";
+ let Prototype = "unsigned char(long long int volatile*, long long int)";
}
def InterlockedBittestAndSet64_rel : MSLangBuiltin {
let Spellings = ["_interlockedbittestandset64_rel"];
let Attributes = [NoThrow];
- let Prototype = "unsigned char(int64_t volatile*, int64_t)";
+ let Prototype = "unsigned char(long long int volatile*, long long int)";
}
def IsoVolatileLoad : MSLangBuiltin, Int8_16_32_64Template {
@@ -3140,7 +3140,7 @@ def Lrotl : MSLangBuiltin {
def Rotl64 : MSLangBuiltin {
let Spellings = ["_rotl64"];
let Attributes = [NoThrow, Constexpr];
- let Prototype = "uint64_t(uint64_t, int)";
+ let Prototype = "unsigned long long int(unsigned long long int, int)";
}
def Rotr8 : MSLangBuiltin {
@@ -3170,7 +3170,7 @@ def Lrotr : MSLangBuiltin {
def Rotr64 : MSLangBuiltin {
let Spellings = ["_rotr64"];
let Attributes = [NoThrow, Constexpr];
- let Prototype = "uint64_t(uint64_t, int)";
+ let Prototype = "unsigned long long int(unsigned long long int, int)";
}
def MSva_start : MSLangBuiltin {
--
2.54.0
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
extern char **environ;
int
main (void)
{
printf ("FORK_PROBE_PARENT pid=%ld environ=%p first=%p brk=%p\n",
(long) getpid (), (void *) environ,
environ ? (void *) environ[0] : NULL, sbrk (0));
fflush (stdout);
pid_t child = fork ();
if (child < 0)
{
perror ("fork");
return 2;
}
if (child == 0)
{
printf ("FORK_PROBE_CHILD pid=%ld environ=%p first=%p brk=%p\n",
(long) getpid (), (void *) environ,
environ ? (void *) environ[0] : NULL, sbrk (0));
fflush (stdout);
_exit (0);
}
int status = 0;
if (waitpid (child, &status, 0) < 0)
{
perror ("waitpid");
return 3;
}
printf ("FORK_PROBE_WAIT status=0x%x exited=%d code=%d signaled=%d signal=%d\n",
status, WIFEXITED (status), WIFEXITED (status) ? WEXITSTATUS (status) : -1,
WIFSIGNALED (status), WIFSIGNALED (status) ? WTERMSIG (status) : -1);
return WIFEXITED (status) && WEXITSTATUS (status) == 0 ? 0 : 4;
}
typedef unsigned long DWORD;
typedef int BOOL;
typedef void *HANDLE;
typedef void *HMODULE;
typedef const unsigned short *LPCWSTR;
typedef long LONG;
typedef unsigned long long ULONG_PTR;
typedef struct exception_record {
DWORD code;
DWORD flags;
struct exception_record *record;
void *address;
DWORD parameter_count;
ULONG_PTR information[15];
} EXCEPTION_RECORD;
typedef struct {
EXCEPTION_RECORD *record;
void *context;
} EXCEPTION_POINTERS;
typedef struct {
DWORD size;
unsigned short *reserved;
unsigned short *desktop;
unsigned short *title;
DWORD x;
DWORD y;
DWORD x_size;
DWORD y_size;
DWORD x_chars;
DWORD y_chars;
DWORD fill_attribute;
DWORD flags;
unsigned short show_window;
unsigned short reserved_size;
unsigned char *reserved_data;
HANDLE input;
HANDLE output;
HANDLE error;
} STARTUP_INFO;
typedef struct {
HANDLE process;
HANDLE thread;
DWORD process_id;
DWORD thread_id;
} PROCESS_INFO;
typedef struct {
DWORD code;
DWORD process_id;
DWORD thread_id;
DWORD padding;
unsigned char info[176];
} DEBUG_EVENT;
__declspec(dllimport) HMODULE LoadLibraryW(LPCWSTR name);
__declspec(dllimport) HMODULE LoadLibraryExW(LPCWSTR name, HANDLE file, DWORD flags);
__declspec(dllimport) BOOL FreeLibrary(HMODULE module);
__declspec(dllimport) void *GetProcAddress(HMODULE module, const char *name);
__declspec(dllimport) DWORD GetEnvironmentVariableW(LPCWSTR name,
unsigned short *value,
DWORD size);
__declspec(dllimport) DWORD GetLastError(void);
__declspec(dllimport) HANDLE GetStdHandle(DWORD id);
__declspec(dllimport) BOOL WriteFile(HANDLE file, const void *buffer,
DWORD length, DWORD *written, void *overlapped);
__declspec(dllimport) void ExitProcess(DWORD code);
__declspec(dllimport) BOOL CloseHandle(HANDLE object);
__declspec(dllimport) BOOL ContinueDebugEvent(DWORD process_id, DWORD thread_id,
DWORD status);
__declspec(dllimport) BOOL CreateProcessW(
LPCWSTR app, unsigned short *command, void *process_attributes,
void *thread_attributes, BOOL inherit_handles, DWORD flags,
void *environment, LPCWSTR directory, STARTUP_INFO *startup,
PROCESS_INFO *process);
__declspec(dllimport) BOOL WaitForDebugEvent(DEBUG_EVENT *event, DWORD timeout);
__declspec(dllimport) void *AddVectoredExceptionHandler(
DWORD first, LONG (*handler)(EXCEPTION_POINTERS *exception));
static DWORD length(const char *text) {
DWORD size = 0;
while (text[size])
++size;
return size;
}
static void write_text(const char *text) {
DWORD written;
WriteFile(GetStdHandle((DWORD)-11), text, length(text), &written, 0);
}
static void write_hex(unsigned long long value) {
static const char digits[] = "0123456789ABCDEF";
char output[19];
output[0] = '0';
output[1] = 'x';
for (int index = 0; index < 16; ++index)
output[index + 2] = digits[(value >> ((15 - index) * 4)) & 15];
output[18] = 0;
write_text(output);
}
static void copy_wide(unsigned short *destination, const unsigned short *source,
DWORD capacity) {
DWORD index = 0;
while (index + 1 < capacity && source[index]) {
destination[index] = source[index];
++index;
}
destination[index] = 0;
}
static LONG exception_handler(EXCEPTION_POINTERS *exception) {
write_text("EXCEPTION_CODE=");
write_hex(exception->record->code);
write_text("\r\nEXCEPTION_ADDRESS=");
write_hex((unsigned long long)exception->record->address);
if (exception->record->parameter_count >= 2) {
write_text("\r\nEXCEPTION_OPERATION=");
write_hex(exception->record->information[0]);
write_text("\r\nEXCEPTION_FAULT_ADDRESS=");
write_hex(exception->record->information[1]);
}
write_text("\r\n");
return 0;
}
static void debug_smoke(void) {
static unsigned short command[32768];
static const unsigned short default_command[] =
L"X:\\msys64\\usr\\bin\\bash.exe --noprofile --norc /usr/bin/bash-arm64-smoke.sh";
static STARTUP_INFO startup;
static PROCESS_INFO process;
DEBUG_EVENT event;
DWORD command_size = GetEnvironmentVariableW(
L"MSYS_PROBE_COMMAND", command, sizeof(command) / sizeof(command[0]));
if (!command_size || command_size >= sizeof(command) / sizeof(command[0]))
copy_wide(command, default_command, sizeof(command) / sizeof(command[0]));
startup.size = sizeof(startup);
write_text("DEBUG_CREATE_PROCESS=");
if (!CreateProcessW(0, command, 0, 0, 1, 1, 0, 0, &startup, &process)) {
write_hex(GetLastError());
write_text("\r\n");
return;
}
write_text("OK\r\n");
while (WaitForDebugEvent(&event, 30000)) {
DWORD status = 0x00010002;
if (event.code == 1) {
EXCEPTION_RECORD *record = (EXCEPTION_RECORD *)event.info;
DWORD first_chance = *(DWORD *)(event.info + sizeof(EXCEPTION_RECORD));
write_text("DEBUG_EXCEPTION_PROCESS=");
write_hex(event.process_id);
write_text("\r\nDEBUG_EXCEPTION_CODE=");
write_hex(record->code);
write_text("\r\nDEBUG_EXCEPTION_ADDRESS=");
write_hex((unsigned long long)record->address);
write_text("\r\nDEBUG_EXCEPTION_FAULT_ADDRESS=");
write_hex(record->parameter_count > 1 ? record->information[1] : 0);
write_text("\r\nDEBUG_FIRST_CHANCE=");
write_hex(first_chance);
write_text("\r\n");
if (record->code != 0x80000003)
status = 0x80010001;
} else if (event.code == 3) {
void *base = *(void **)(event.info + 24);
write_text("DEBUG_EXE_PROCESS=");
write_hex(event.process_id);
write_text("\r\nDEBUG_EXE_BASE=");
write_hex((unsigned long long)base);
write_text("\r\n");
} else if (event.code == 5) {
DWORD exit_code = *(DWORD *)event.info;
write_text("DEBUG_EXIT_PROCESS=");
write_hex(event.process_id);
write_text("\r\nDEBUG_PROCESS_EXIT=");
write_hex(exit_code);
write_text("\r\n");
if (event.process_id == process.process_id) {
ContinueDebugEvent(event.process_id, event.thread_id, status);
break;
}
} else if (event.code == 6) {
void *base = *(void **)(event.info + 8);
write_text("DEBUG_DLL_PROCESS=");
write_hex(event.process_id);
write_text("\r\nDEBUG_DLL_BASE=");
write_hex((unsigned long long)base);
write_text("\r\n");
}
ContinueDebugEvent(event.process_id, event.thread_id, status);
}
CloseHandle(process.thread);
CloseHandle(process.process);
}
void mainCRTStartup(void) {
static unsigned short dll_path[1024];
static const unsigned short default_dll_path[] =
L"X:\\msys64\\usr\\bin\\msys-2.0.dll";
HMODULE module;
HMODULE mapped;
void *entry;
DWORD dll_path_size = GetEnvironmentVariableW(
L"MSYS_PROBE_DLL", dll_path, sizeof(dll_path) / sizeof(dll_path[0]));
if (!dll_path_size || dll_path_size >= sizeof(dll_path) / sizeof(dll_path[0]))
copy_wide(dll_path, default_dll_path,
sizeof(dll_path) / sizeof(dll_path[0]));
write_text("LOADER_PROBE=ARM64_NATIVE\r\nBEFORE_LOAD_LIBRARY\r\n");
AddVectoredExceptionHandler(1, exception_handler);
mapped = LoadLibraryExW(dll_path, 0, 1);
write_text("DLL_IMAGE_BASE=");
write_hex((unsigned long long)mapped);
write_text("\r\n");
if (mapped)
FreeLibrary(mapped);
module = LoadLibraryW(dll_path);
write_text("AFTER_LOAD_LIBRARY=");
write_hex((unsigned long long)module);
write_text("\r\nLAST_ERROR=");
write_hex(GetLastError());
write_text("\r\n");
if (!module)
ExitProcess(3);
entry = GetProcAddress(module, "_dll_crt0");
write_text("DLL_CRT0=");
write_hex((unsigned long long)entry);
write_text("\r\n");
debug_smoke();
ExitProcess(entry ? 0 : 4);
}
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
extern char **environ;
int
main (void)
{
int fds[2];
if (pipe (fds) < 0)
{
perror ("pipe");
return 2;
}
printf ("PIPE_FORK_PARENT pid=%ld read=%d write=%d environ=%p brk=%p\n",
(long) getpid (), fds[0], fds[1], (void *) environ, sbrk (0));
fflush (stdout);
pid_t child = fork ();
if (child < 0)
{
perror ("fork");
return 3;
}
if (child == 0)
{
close (fds[0]);
if (write (fds[1], "child-ok\n", 9) != 9)
_exit (5);
close (fds[1]);
_exit (0);
}
close (fds[1]);
char result[32] = {0};
ssize_t count = read (fds[0], result, sizeof (result) - 1);
close (fds[0]);
int status = 0;
if (waitpid (child, &status, 0) < 0)
{
perror ("waitpid");
return 4;
}
printf ("PIPE_FORK_WAIT read=%ld result=%s status=0x%x exited=%d code=%d\n",
(long) count, count > 0 ? result : "", status, WIFEXITED (status),
WIFEXITED (status) ? WEXITSTATUS (status) : -1);
return count == 9 && WIFEXITED (status) && WEXITSTATUS (status) == 0 ? 0 : 6;
}
/* Cygwin is LP64, while mingw-w64's excpt.h declares _exception_code with
Windows' 32-bit unsigned long assumption. Keep the public macro spelling,
but hide that incompatible declaration from Clang's SEH builtin. */
#pragma once
#define _exception_code __msys_w32api_exception_code
#include_next <excpt.h>
#undef _exception_code
#pragma once
/* Cygwin/MSYS installs Windows API headers below a w32api/ prefix. The
LLVM-MinGW sysroot installs the same mingw-w64 header at the include root. */
#include <ntstatus.h>
0001-build-recognize-the-AArch64-MSYS-target.patch
0002-winsup-make-shared-sources-compile-cleanly-with-Clan.patch
0003-newlib-support-the-AArch64-MSYS-PE-ABI.patch
0004-winsup-add-the-Windows-ARM64-runtime-implementation.patch
0005-build-regenerate-autotools-outputs.patch
0006-docs-record-the-ARM64-Clang-porting-procedure.patch
0007-docs-frame-the-port-as-WOA-QEMU-validation.patch

MSYS2 runtime and Bash on Windows ARM64

This directory records a Clang/MSYS2 adaptation and QEMU validation of the Windows-on-ARM-Experiments ARM64 runtime work. It includes the Clang target patch, an ordered runtime patch series, support libraries, compiler wrappers, PE fixups, probes, and the exact post-link patch that produced the tested DLL.

This is experimental validation evidence, not an upstream-ready runtime series. The broader GNU/Cygwin ARM64 port in Windows-on-ARM-Experiments/newlib-cygwin predates this work and provides its ARM64 runtime foundation. See WOA_COMPARISON.md for the adaptation, validation, and contribution plan.

Verification status

Two distinct reproduction paths are recorded:

  1. Tested binary transformation: starting from the first-link DLL identified by the hash below, prepare-msys2-arm64-dll.sh and add-msys2-arm64-bootstrap-fork-copy.py reproduce the tested final DLL byte for byte. That first-link binary is not stored in this gist, so retain it if this historical byte-for-byte path matters. Bash, fork, pipes, command substitution, and exit status were verified in native Windows ARM64 under QEMU.
  2. Source path: commit 8e82becb50b8bf02fa0d0dd9cd6d53671d3a1347, rebuilt from the pinned inputs below, produces a runtime-verified DLL. The prepared DLL SHA256 is e69dd757dab8ca0148dbf0f0e95278afab70e56f527b1406bf9eb1d86ba653ed. It passed native loading, Bash, fork and pipe-fork probes, and direct sigsetjmp signal-mask checks in Windows ARM64 under QEMU. The source port retries up to four transient ARM64 child-start faults before the child synchronizes with its parent, so this is functional validation rather than a QEMU stability claim.

Pinned inputs

llvm-project  5742a30a749a5cc9271bd5bd8945c3033285c775
msys2-runtime 01d6c708f9221334d18ab332621b6d87eb12d37e
mingw-w64     c9bd2c0cd21c5b0eae70310f7e01bce56fadbba5
binutils      ebf22fc26326ad138bea9dee536cf081e46dd6e1
LLVM-MinGW    20260616, Clang 22.1.8

The LLVM-MinGW macOS universal archive used locally had SHA256:

2cab02a2e964bd4aae981150a45985d07c657cfa8d244959eb9e2dcc5eedd7b1

The LLVM patch SHA256 values are:

145367e0a03a107e6d84bddfe6e31dea43cb712195a4129ba14b8422e025edb7  llvm-ms-builtins-long-long.patch
5dc73f3d5da93571c36bde41eb6c09e61e802ab507e8e1dc1e2b8052cbe12ba2  llvm-aarch64-cygwin-target.patch

The same two commits are also available on Kreijstal/llvm-project, branch aarch64-cygwin-msys-experiment, whose verified head is 1e644a04d51a50a5b20d9208b05fd2a0ac1814da.

The seven runtime patch hashes and their application order are recorded in SHA256SUMS and msys2-runtime-series.

Apply the patches

git -C llvm-project checkout 5742a30a749a5cc9271bd5bd8945c3033285c775
git -C llvm-project am ../llvm-ms-builtins-long-long.patch \
  ../llvm-aarch64-cygwin-target.patch

git -C msys2-runtime checkout 01d6c708f9221334d18ab332621b6d87eb12d37e
(cd msys2-runtime && while read -r patch; do git am "../$patch"; done \
  < ../msys2-runtime-series)

# winsup/configure is generated rather than tracked.  Generate it before the
# top-level configure so winsup is not silently omitted from target_configdirs.
(cd msys2-runtime/winsup && autoreconf -fiv)

The LLVM patch adds LP64 ARM64 Cygwin/MSYS target support using the Windows ARM64 calling convention and PE/COFF object format. The public build tuple is aarch64-pc-msys; LLVM normalizes it internally to aarch64-pc-windows-cygnus. The runtime series is split into target plumbing, shared Clang compatibility, newlib ARM64 ABI support, the ARM64 winsup runtime, generated Autotools files, and porting documentation. The wrappers reserve x18, which Windows ARM64 uses as the TEB register.

The experimental target's Unix-facing ABI is LP64: long, pointers, and size_t are 64-bit. It deliberately uses IEEE binary128 long double, while ordinary LLVM-MinGW follows the Windows ARM64 ABI and uses 64-bit long double. The target patch includes compile-time tests for these choices.

Patch 0002 contains architecture-independent source fixes required by the Clang bootstrap. Patch 0004 contains the runtime behavior specific to ARM64; its architecture-dependent paths are guarded from x86_64. Keeping these separate makes AMD64 review and regression testing explicit.

Before any upstream submission, each runtime hunk must be compared against the WOA implementation and its original authorship preserved where code or design is adopted. The intended contribution is the Clang target/toolchain adaptation and reproducible QEMU Bash/fork validation, not a competing ARM64 runtime fork.

Build the cross tools

Build GNU binutils for the PE target:

mkdir binutils-build && cd binutils-build
../binutils/configure \
  --target=aarch64-w64-mingw32 \
  --prefix="$BINUTILS_ROOT" \
  --disable-nls --disable-werror \
  --disable-gdb --disable-gdbserver --disable-sim \
  --disable-libdecnumber --disable-readline --without-zstd
make -j"$(sysctl -n hw.ncpu)"
make install

Build patched Clang:

cmake -S llvm-project/llvm -B llvm-build -G Ninja \
  -DLLVM_ENABLE_PROJECTS=clang \
  -DLLVM_TARGETS_TO_BUILD=AArch64 \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX="$CYGWIN_CLANG_ROOT"
cmake --build llvm-build
cmake --install llvm-build

Build the ARM64 mingw-w64 headers and CRT used for Windows imports:

mkdir w32api-headers-build && cd w32api-headers-build
../mingw-w64/mingw-w64-headers/configure \
  --host=aarch64-w64-mingw32 \
  --prefix="$W32API_ROOT" \
  --enable-sdk=all
make install

mkdir ../w32api-crt-build && cd ../w32api-crt-build
../mingw-w64/mingw-w64-crt/configure \
  --host=aarch64-w64-mingw32 \
  --prefix="$W32API_ROOT" \
  --with-sysroot="$W32API_ROOT" \
  --disable-lib32 --disable-lib64 --enable-libarm64 \
  CC="$LLVM_MINGW_ROOT/bin/aarch64-w64-mingw32-clang" \
  CXX="$LLVM_MINGW_ROOT/bin/aarch64-w64-mingw32-clang++" \
  AS="$BINUTILS_ROOT/bin/aarch64-w64-mingw32-as" \
  AR="$BINUTILS_ROOT/bin/aarch64-w64-mingw32-ar" \
  RANLIB="$BINUTILS_ROOT/bin/aarch64-w64-mingw32-ranlib" \
  DLLTOOL="$BINUTILS_ROOT/bin/aarch64-w64-mingw32-dlltool"
make -j"$(sysctl -n hw.ncpu)"
make install

Compiler wrappers

Place aarch64-pc-msys-clang and aarch64-pc-msys-clang++ on PATH, make them executable, and export:

export CYGWIN_CLANG_ROOT=/path/to/patched-clang
export LLVM_MINGW_ROOT=/path/to/llvm-mingw-20260616-ucrt-macos-universal
export MSYS2_RUNTIME_ROOT=/path/to/patched/msys2-runtime
export MSYS2_TOOLCHAIN_INCLUDE=/path/to/shim-include
export MSYS2_W32API_PARENT=/path/to/w32api-parent
export PATH="/path/to/this-directory:$BINUTILS_ROOT/bin:$PATH"

Create the w32api include layout expected by winsup, then install the two shim headers. The wrapper searches the shim directory first, so its ntstatus.h overrides the mingw-w64 copy:

mkdir -p "$MSYS2_TOOLCHAIN_INCLUDE/w32api" "$MSYS2_W32API_PARENT"
ln -s "$W32API_ROOT/include" "$MSYS2_W32API_PARENT/w32api"
cp msys-toolchain-excpt.h "$MSYS2_TOOLCHAIN_INCLUDE/excpt.h"
cp msys-toolchain-w32api-ntstatus.h \
  "$MSYS2_TOOLCHAIN_INCLUDE/w32api/ntstatus.h"

Configure and compile the runtime

mkdir msys2-build-aarch64 && cd msys2-build-aarch64
../msys2-runtime/configure \
  --build=aarch64-apple-darwin \
  --host=aarch64-apple-darwin \
  --target=aarch64-pc-msys \
  --disable-doc --with-cross-bootstrap \
  CC=/usr/bin/clang CXX=/usr/bin/clang++ \
  CC_FOR_TARGET=aarch64-pc-msys-clang \
  CXX_FOR_TARGET=aarch64-pc-msys-clang++ \
  AR_FOR_TARGET=aarch64-w64-mingw32-ar \
  AS_FOR_TARGET=aarch64-w64-mingw32-as \
  LD_FOR_TARGET=aarch64-w64-mingw32-ld \
  NM_FOR_TARGET=aarch64-w64-mingw32-nm \
  OBJCOPY_FOR_TARGET=aarch64-w64-mingw32-objcopy \
  RANLIB_FOR_TARGET=aarch64-w64-mingw32-ranlib \
  READELF_FOR_TARGET=aarch64-w64-mingw32-readelf \
  STRIP_FOR_TARGET=aarch64-w64-mingw32-strip \
  WINDRES_FOR_TARGET=aarch64-w64-mingw32-windres

make -j4 all-target-newlib

Build the missing quad-precision and long-double support archives:

export MSYS_CC=aarch64-pc-msys-clang
export MSYS_AR=aarch64-w64-mingw32-ar
export MSYS_RANLIB=aarch64-w64-mingw32-ranlib
export LLVM_SOURCE=/path/to/patched/llvm-project
export RUNTIME_BUILD="$PWD/aarch64-pc-msys"
export SUPPORT_OUT="$PWD/arm64-support"
/path/to/this-directory/build-arm64-support-libs.sh

Build winsup with the ARM64 Windows import libraries and support archives:

ac_cv_lib_sframe_sframe_decode=no \
ac_cv_lib_zstd_ZSTD_isError=no \
make -j4 all-target-winsup \
  ARM64_WINDOWS_LIBDIR="$W32API_ROOT/lib" \
  ARM64_RUNTIME_LIBS="$SUPPORT_OUT/libmsys-math-arm64.a \
$SUPPORT_OUT/libclang_rt.tf-aarch64.a \
$LLVM_MINGW_ROOT/lib/clang/22/lib/windows/libclang_rt.builtins-aarch64.a"

The runtime DLL is emitted before the build proceeds into optional cygserver; with Clang 22 the latter currently fails on mixed host/newlib C++ headers. The runtime-only target can be resumed with:

make -C aarch64-pc-msys/winsup/cygwin -j4 all \
  ARM64_WINDOWS_LIBDIR="$W32API_ROOT/lib" \
  ARM64_RUNTIME_LIBS="$SUPPORT_OUT/libmsys-math-arm64.a \
$SUPPORT_OUT/libclang_rt.tf-aarch64.a \
$LLVM_MINGW_ROOT/lib/clang/22/lib/windows/libclang_rt.builtins-aarch64.a"

Prepare writable autoload slots in any newly linked DLL:

OBJCOPY="$LLVM_MINGW_ROOT/bin/llvm-objcopy" \
  ./prepare-msys2-arm64-dll.sh \
  aarch64-pc-msys/winsup/cygwin/new-msys-2.0.dll \
  msys-2.0.dll

Reproduce the tested post-link transformation exactly

The first linked artifact used for the verified binary path is:

9f69c610b5576a2cd5fb29e2357c4ea1aefee43da5bc08159e8b87df98a22660  msys-2.0.dll

First make the autoload slots writable and apply the hash-gated early malloc_init bootstrap fix:

OBJCOPY="$LLVM_MINGW_ROOT/bin/llvm-objcopy" \
  ./prepare-msys2-arm64-dll.sh \
  msys-2.0.dll msys-2.0-arm64-fixed2.dll

Expected intermediate hash:

48e9a68cd12bce1312e44e0706bc92f8aeafb217242fb5301f32cb0e287980cf  msys-2.0-arm64-fixed2.dll

Build the 192-byte helper text and apply the allocator, fork, spawn, and exit fixes:

"$LLVM_MINGW_ROOT/bin/aarch64-w64-mingw32-clang" \
  -c arm64-fork-bootstrap-copy.S -o arm64-fork-bootstrap-copy.obj
"$LLVM_MINGW_ROOT/bin/llvm-objcopy" \
  --dump-section .text=arm64-fork-bootstrap-copy.text \
  arm64-fork-bootstrap-copy.obj

python3 add-msys2-arm64-bootstrap-fork-copy.py \
  msys-2.0-arm64-fixed2.dll \
  msys-2.0-arm64-final.dll \
  arm64-fork-bootstrap-copy.text

Expected final hash:

773f3cafd7d94b85284a260daf9a3b266db980ece7a720be51ad1855c3e8ece8  msys-2.0-arm64-final.dll

This final file was compared byte for byte with the DLL tested in Windows.

Bash and executable CRT fix

Link Bash against libmsys-2.0.a. If the generated ARM64 executable contains the _impure_ptr refptr sequence from this toolchain, run:

python3 fix-msys-arm64-crt.py bash.exe bash-arm64.exe

For testing, pipe scripts over standard input. Long command-line argument strings can still be corrupted in this port:

type bash-arm64-win11-smoke.sh | bash-arm64.exe
type bash-arm64-win11-fork-status.sh | bash-arm64.exe

Verified Windows ARM64 result

The following was run with the prepared commit 8e82becb DLL whose SHA256 is e69dd757dab8ca0148dbf0f0e95278afab70e56f527b1406bf9eb1d86ba653ed:

LOADER_PROBE=ARM64_NATIVE
PROBE_EXIT=0
FORK_EXIT=0
PIPE_EXIT=0
COMMAND_SUBSTITUTION=child-ok STATUS=0
SUBSHELL_ZERO_STATUS=0
SUBSHELL_SEVEN_STATUS=7
BASH_VERSION=5.3.0(1)-release
BASH_MACHTYPE=aarch64-pc-cygwin
BASH_CHILD=child-ok
SUBSHELL_EXIT=7
EXTERNAL_EXIT=0
SMOKE_EXIT=0
SIGJMP_MASK_RESTORED=1
SIGJMP_MASK_UNCHANGED=1

The final repetition sweep passed native fork and pipe-fork 10/10, Bash smoke 5/5, Bash command-substitution and status checks 6/6, and the focused sigjmp-mask-probe.c test 5/5. One earlier Bash status invocation ended with 0xc0000005; one fork sweep iteration reported Win32 error 299 and then succeeded through the runtime retry path.

Known limitations are intermittent corruption of long Bash argv strings and a /tmp setup warning. On longer QEMU runs, a standalone process can rarely fail with 0xc0000005 before the MSYS runtime loads; no runtime retry can cover that boundary. The runtime retries transient fork-child start failures and the canonical fork, pipes, command substitution, subshell status, and external process checks pass when scripts are supplied on stdin.

#!/usr/bin/env bash
set -euo pipefail
if [[ $# -ne 2 ]]; then
echo "usage: $0 INPUT_DLL OUTPUT_DLL" >&2
exit 2
fi
input=$1
output=$2
if [[ ! -f "$input" ]]; then
echo "input DLL not found: $input" >&2
exit 1
fi
input_sha=$(shasum -a 256 "$input" | awk '{print $1}')
if [[ "$input" == "$output" ]]; then
echo "input and output paths must differ" >&2
exit 1
fi
if [[ -n "${OBJCOPY:-}" ]]; then
objcopy=$OBJCOPY
elif command -v llvm-objcopy >/dev/null 2>&1; then
objcopy=$(command -v llvm-objcopy)
elif command -v brew >/dev/null 2>&1; then
objcopy="$(brew --prefix llvm)/bin/llvm-objcopy"
else
echo "set OBJCOPY to llvm-objcopy" >&2
exit 1
fi
# The autoload resolver writes the resolved function address into each slot.
# LLVM's ARM64 PE port must therefore emit these sections as writable code.
autoload_sections=(
.autoload_text
.KernelB .advapi3 .authz_a .dnsapi_ .gdi32_a .iphlpap .kernel3
.mpr_aut .netapi3 .ntdll_a .ole32_a .pdh_aut .psapi_a .secur32
.shell32 .user32_ .userenv .winmm_a .wldap32 .ws2_32_
)
section_args=()
for section in "${autoload_sections[@]}"; do
section_args+=(--set-section-flags "$section=alloc,code,contents,data,load")
done
cp "$input" "$output"
"$objcopy" "${section_args[@]}" "$output"
# The first reproducible ARM64 link called malloc_init before the user heap
# existed. Apply its exact bootstrap fix only to that byte-identical input;
# source builds with any other hash are left untouched.
if [[ "$input_sha" == 9f69c610b5576a2cd5fb29e2357c4ea1aefee43da5bc08159e8b87df98a22660 ]]; then
python3 - "$output" <<'PY'
from pathlib import Path
import sys
path = Path(sys.argv[1])
data = bytearray(path.read_bytes())
offset = 0x10CA10
expected = bytes.fromhex("f37bbfa9")
replacement = bytes.fromhex("c0035fd6")
if data[offset:offset + 4] != expected:
raise SystemExit("unexpected malloc_init bytes")
data[offset:offset + 4] = replacement
path.write_bytes(data)
PY
fi
file "$output"
shasum -a 256 "$output"
--- a/ui/cocoa.m 2026-05-27 18:39:40
+++ b/ui/cocoa.m 2026-06-24 21:21:16
@@ -688,8 +688,22 @@
info.xoff = 0;
info.yoff = 0;
- info.width = frameSize.width * [[self window] backingScaleFactor];
- info.height = frameSize.height * [[self window] backingScaleFactor];
+ /*
+ * Local hack for Windows-on-Apple-Silicon guests:
+ *
+ * The Cocoa window can be resized by macOS, but the guest may keep using
+ * a small framebuffer because QEMU reports the current scaled view size
+ * back to the display device. Force the UI-info size advertised to the
+ * guest display device so virtio-gpu EDID/display-change notifications
+ * prefer 1920x1080 instead of the tiny Cocoa console size.
+ */
+ info.width = 1920;
+ info.height = 1080;
+
+ if (!info.width_mm || !info.height_mm) {
+ info.width_mm = 480;
+ info.height_mm = 270;
+ }
dpy_set_ui_info(dcl.con, &info, TRUE);
}
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
TARGET="${TARGET:-outputs/win11-arm64-50g.qcow2}"
DISK_SIZE="${DISK_SIZE:-50G}"
USERNAME="${USERNAME:-codex}"
PASSWORD="${PASSWORD:-Passw0rd!}"
RAM_SIZE="${RAM_SIZE:-8G}"
CPU_CORES="${CPU_CORES:-4}"
RDP_PORT="${RDP_PORT:-3390}"
SSH_PORT="${SSH_PORT:-2222}"
INSTALL_TIMEOUT_MINUTES="${INSTALL_TIMEOUT_MINUTES:-90}"
FIRMWARE_STALL_SECONDS="${FIRMWARE_STALL_SECONDS:-60}"
DISK_BOOT_CYCLES="${DISK_BOOT_CYCLES:-8}"
WIN_ISO_URL="${WIN_ISO_URL:-https://software-static.download.prss.microsoft.com/dbazure/888969d5-f34g-4e03-ac9d-1f9786c66749/26200.6584.250915-1905.25h2_ge_release_svc_refresh_CLIENT_CONSUMER_a64fre_en-us.iso}"
WIN_ISO_SHA256="${WIN_ISO_SHA256:-32cde0071ed8086b29bb6c8c3bf17ba9e3cdf43200537434a811a9b6cc2711a1}"
VIRTIO_ARM_URL="${VIRTIO_ARM_URL:-https://github.com/qemus/virtiso-arm/releases/download/v0.1.285-1/virtio-win-0.1.285.tar.xz}"
VIRTIO_ARM_SHA256="${VIRTIO_ARM_SHA256:-c6712f8d5730c09c1212be9fc3baa18b78534f3c8c136cf02b2cca46515ca310}"
QEMU_SHARE="$(brew --prefix qemu)/share/qemu"
EDK2_CODE="$QEMU_SHARE/edk2-aarch64-code.fd"
EDK2_VARS_TEMPLATE="$QEMU_SHARE/edk2-arm-vars.fd"
VARS="work/vm/edk2-arm-vars.fd"
MONITOR="work/vm/qemu-monitor.sock"
TPM_SOCK="work/vm/swtpm-sock"
TPM_STATE="work/vm/swtpm-state"
QEMU_LOG="work/vm/qemu-install.log"
TMP_ROOT=""
QEMU_PID=""
cleanup() {
set +e
if [ -n "${QEMU_PID:-}" ] && kill -0 "$QEMU_PID" 2>/dev/null; then
[ -S "$MONITOR" ] && printf 'system_powerdown\n' | socat - UNIX-CONNECT:"$MONITOR" >/dev/null 2>&1
for _ in $(seq 1 30); do
kill -0 "$QEMU_PID" 2>/dev/null || break
sleep 1
done
kill -0 "$QEMU_PID" 2>/dev/null && kill "$QEMU_PID" 2>/dev/null
fi
pkill -f "swtpm.*$TPM_SOCK" >/dev/null 2>&1 || true
if [ -n "${TMP_ROOT:-}" ] && [ -d "$TMP_ROOT" ]; then
chmod -R u+w "$TMP_ROOT" >/dev/null 2>&1 || true
rm -rf "$TMP_ROOT"
fi
}
trap cleanup EXIT
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "Missing command: $1" >&2
return 1
}
}
install_deps() {
local missing=()
for cmd in qemu-system-aarch64 qemu-img wimlib-imagex mkisofs swtpm curl aria2c python3 socat xfreerdp; do
command -v "$cmd" >/dev/null 2>&1 || missing+=("$cmd")
done
if [ "${#missing[@]}" -eq 0 ]; then
return 0
fi
echo "Installing missing Homebrew dependencies: ${missing[*]}"
brew install aria2 qemu wimlib cdrtools swtpm socat freerdp python
}
assert_clean_images() {
mkdir -p outputs work/vm
find . -type f \( -name '*.raw' -o -name '*.img' \) -print -delete
while IFS= read -r file; do
[ "$file" = "./$TARGET" ] && continue
echo "Removing stale QCOW2: $file"
rm -f "$file"
done < <(find . -type f -name '*.qcow2' -print)
}
download_once() {
local url="$1"
local out="$2"
if command -v aria2c >/dev/null 2>&1; then
aria2c \
--allow-overwrite=true \
--auto-file-renaming=false \
--connect-timeout=30 \
--continue=true \
--enable-color=false \
--file-allocation=none \
--max-connection-per-server=16 \
--max-tries=10 \
--min-split-size=1M \
--retry-wait=10 \
--split=16 \
--summary-interval=20 \
--timeout=60 \
--dir "$(dirname "$out")" \
--out "$(basename "$out")" \
"$url"
else
curl -L --fail --retry 20 --retry-delay 10 --continue-at - -o "$out" "$url"
fi
}
download() {
local url="$1"
local out="$2"
local attempt
for attempt in $(seq 1 10); do
if download_once "$url" "$out"; then
return 0
fi
echo "Download attempt $attempt failed; retrying in 15 seconds..." >&2
sleep 15
done
echo "Download failed after 10 attempts: $url" >&2
return 1
}
sha256_check() {
local expected="$1"
local file="$2"
local actual
actual="$(shasum -a 256 "$file" | awk '{print $1}')"
if [ "$actual" != "$expected" ]; then
echo "SHA256 mismatch for $file" >&2
echo "Expected: $expected" >&2
echo "Actual: $actual" >&2
return 1
fi
echo "Verified SHA256: $actual"
}
make_answer_file() {
local out="$1"
python3 - "$out" "$USERNAME" "$PASSWORD" <<'PY'
from pathlib import Path
import sys
out, username, password = sys.argv[1:4]
xml = f'''<?xml version="1.0" encoding="UTF-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<settings pass="windowsPE">
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SetupUILanguage><UILanguage>en-US</UILanguage></SetupUILanguage>
<InputLocale>0409:00000409</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UILanguage>en-US</UILanguage>
<UserLocale>en-US</UserLocale>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DiskConfiguration>
<Disk wcm:action="add">
<DiskID>0</DiskID>
<WillWipeDisk>true</WillWipeDisk>
<CreatePartitions>
<CreatePartition wcm:action="add"><Order>1</Order><Type>EFI</Type><Size>128</Size></CreatePartition>
<CreatePartition wcm:action="add"><Order>2</Order><Type>MSR</Type><Size>128</Size></CreatePartition>
<CreatePartition wcm:action="add"><Order>3</Order><Type>Primary</Type><Extend>true</Extend></CreatePartition>
</CreatePartitions>
<ModifyPartitions>
<ModifyPartition wcm:action="add"><Order>1</Order><PartitionID>1</PartitionID><Label>System</Label><Format>FAT32</Format></ModifyPartition>
<ModifyPartition wcm:action="add"><Order>2</Order><PartitionID>2</PartitionID></ModifyPartition>
<ModifyPartition wcm:action="add"><Order>3</Order><PartitionID>3</PartitionID><Label>Windows</Label><Letter>C</Letter><Format>NTFS</Format></ModifyPartition>
</ModifyPartitions>
</Disk>
</DiskConfiguration>
<ImageInstall>
<OSImage>
<InstallTo><DiskID>0</DiskID><PartitionID>3</PartitionID></InstallTo>
<InstallToAvailablePartition>false</InstallToAvailablePartition>
</OSImage>
</ImageInstall>
<DynamicUpdate><Enable>false</Enable><WillShowUI>Never</WillShowUI></DynamicUpdate>
<UpgradeData><Upgrade>false</Upgrade><WillShowUI>Never</WillShowUI></UpgradeData>
<UserData>
<AcceptEula>true</AcceptEula>
<FullName>{username}</FullName>
<Organization>Codex</Organization>
<ProductKey><Key>VK7JG-NPHTM-C97JM-9MPGT-3V66T</Key><WillShowUI>OnError</WillShowUI></ProductKey>
</UserData>
<EnableFirewall>false</EnableFirewall>
<RunSynchronous>
<RunSynchronousCommand wcm:action="add"><Order>1</Order><Path>reg.exe add "HKLM\\SYSTEM\\Setup\\LabConfig" /v BypassTPMCheck /t REG_DWORD /d 1 /f</Path></RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add"><Order>2</Order><Path>reg.exe add "HKLM\\SYSTEM\\Setup\\LabConfig" /v BypassSecureBootCheck /t REG_DWORD /d 1 /f</Path></RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add"><Order>3</Order><Path>reg.exe add "HKLM\\SYSTEM\\Setup\\LabConfig" /v BypassRAMCheck /t REG_DWORD /d 1 /f</Path></RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add"><Order>4</Order><Path>reg.exe add "HKLM\\SYSTEM\\Setup\\MoSetup" /v AllowUpgradesWithUnsupportedTPMOrCPU /t REG_DWORD /d 1 /f</Path></RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
<settings pass="offlineServicing">
<component name="Microsoft-Windows-LUA-Settings" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"><EnableLUA>false</EnableLUA></component>
</settings>
<settings pass="generalize">
<component name="Microsoft-Windows-PnPSysprep" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"><PersistAllDeviceInstalls>true</PersistAllDeviceInstalls></component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<ComputerName>WIN11-QEMU</ComputerName>
<OEMName>Codex QEMU</OEMName>
</component>
<component name="Microsoft-Windows-Deployment" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add"><Order>1</Order><Path>reg.exe add "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OOBE" /v BypassNRO /t REG_DWORD /d 1 /f</Path></RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add"><Order>2</Order><Path>reg.exe add "HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Signatures\\FirstNetwork" /v Category /t REG_DWORD /d 1 /f</Path></RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add"><Order>3</Order><Path>C:\\Windows\\Drivers\\Balloon\\blnsvr.exe -i</Path><Description>Install VirtIO Balloon service</Description></RunSynchronousCommand>
</RunSynchronous>
</component>
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"><fDenyTSConnections>false</fDenyTSConnections></component>
<component name="Microsoft-Windows-TerminalServices-RDP-WinStationExtensions" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"><UserAuthentication>0</UserAuthentication></component>
<component name="Networking-MPSSVC-Svc" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<FirewallGroups><FirewallGroup wcm:action="add" wcm:keyValue="RemoteDesktop"><Active>true</Active><Profile>all</Profile><Group>@FirewallAPI.dll,-28752</Group></FirewallGroup></FirewallGroups>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<UserAccounts>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Name>{username}</Name><Group>Administrators</Group>
<Password><Value>{password}</Value><PlainText>true</PlainText></Password>
</LocalAccount>
</LocalAccounts>
<AdministratorPassword><Value>{password}</Value><PlainText>true</PlainText></AdministratorPassword>
</UserAccounts>
<AutoLogon>
<Username>{username}</Username><Enabled>true</Enabled><LogonCount>999</LogonCount>
<Password><Value>{password}</Value><PlainText>true</PlainText></Password>
</AutoLogon>
<Display><ColorDepth>32</ColorDepth><HorizontalResolution>1920</HorizontalResolution><VerticalResolution>1080</VerticalResolution></Display>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideLocalAccountScreen>true</HideLocalAccountScreen>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<NetworkLocation>Home</NetworkLocation>
<ProtectYourPC>3</ProtectYourPC>
<SkipUserOOBE>true</SkipUserOOBE>
<SkipMachineOOBE>true</SkipMachineOOBE>
</OOBE>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add"><Order>1</Order><CommandLine>powershell.exe -ExecutionPolicy Unrestricted -NoLogo -NoProfile -NonInteractive set-localuser -name "{username}" -passwordneverexpires 1</CommandLine></SynchronousCommand>
<SynchronousCommand wcm:action="add"><Order>2</Order><CommandLine>cmd /C POWERCFG -H OFF</CommandLine></SynchronousCommand>
<SynchronousCommand wcm:action="add"><Order>3</Order><CommandLine>cmd /C POWERCFG -X -standby-timeout-ac 0</CommandLine></SynchronousCommand>
</FirstLogonCommands>
</component>
</settings>
</unattend>
'''
Path(out).write_text(xml)
PY
}
patch_iso_tree() {
local iso_tree="$1"
local drivers="$2"
local answer="$3"
local boot_wim
boot_wim="$(find "$iso_tree/sources" -maxdepth 1 -type f \( -iname boot.wim -o -iname boot.esd \) -print -quit)"
[ -n "$boot_wim" ] || { echo "Could not find boot.wim/boot.esd" >&2; return 1; }
local index="1"
if wimlib-imagex info --xml "$boot_wim" | iconv -f UTF-16LE -t UTF-8 | grep -q '<IMAGE INDEX="2">'; then
index="2"
fi
local pedriver="$TMP_ROOT/WinPEDriver"
mkdir -p "$pedriver"
for d in qxl viofs sriov smbus qxldod viorng viostor viomem NetKVM Balloon vioscsi pvpanic vioinput viogpudo vioserial qemupciserial; do
[ -d "$drivers/$d/w11/ARM64" ] || continue
mkdir -p "$pedriver/$d"
rsync -a "$drivers/$d/w11/ARM64/" "$pedriver/$d/"
done
mkdir -p "$iso_tree/sources/\$OEM\$/\$\$/Drivers"
rsync -a "$pedriver/" "$iso_tree/sources/\$OEM\$/\$\$/Drivers/"
mkdir -p "$iso_tree/sources/\$OEM\$/\$\$/Setup/Scripts"
cat > "$iso_tree/sources/\$OEM\$/\$\$/Setup/Scripts/SetupComplete.cmd" <<'EOF'
@echo off
set LOG=C:\Windows\Setup\Scripts\virtio-rdp-setup.log
echo [%DATE% %TIME%] Installing copied VirtIO drivers > "%LOG%"
for /r C:\Windows\Drivers %%i in (*.inf) do pnputil /add-driver "%%i" /install >> "%LOG%" 2>&1
echo [%DATE% %TIME%] Enabling RDP >> "%LOG%"
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f >> "%LOG%" 2>&1
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication /t REG_DWORD /d 0 /f >> "%LOG%" 2>&1
netsh advfirewall firewall set rule group="remote desktop" new enable=Yes >> "%LOG%" 2>&1
sc config TermService start= auto >> "%LOG%" 2>&1
net start TermService >> "%LOG%" 2>&1
echo [%DATE% %TIME%] Installing and enabling OpenSSH Server >> "%LOG%"
powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0; Set-Service sshd -StartupType Automatic; Start-Service sshd; Enable-NetFirewallRule -Name OpenSSH-Server-In-TCP; Set-NetFirewallRule -Name OpenSSH-Server-In-TCP -Profile Any; New-Item -Path 'HKLM:\SOFTWARE\OpenSSH' -Force | Out-Null; New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name DefaultShell -Value 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -PropertyType String -Force" >> "%LOG%" 2>&1
exit /b 0
EOF
wimlib-imagex update "$boot_wim" "$index" --command "delete --force --recursive /\\\$WinPEDriver\\\$" >/dev/null 2>&1 || true
wimlib-imagex update "$boot_wim" "$index" --command "add $pedriver /\\\$WinPEDriver\\\$"
wimlib-imagex update "$boot_wim" "$index" --command "delete --force /autounattend.xml" >/dev/null 2>&1 || true
wimlib-imagex update "$boot_wim" "$index" --command "add $answer /autounattend.xml"
cp "$answer" "$iso_tree/autounattend.xml"
}
build_auto_iso() {
local iso_tree="$1"
local out="$2"
local etfs efisys
etfs="$(find "$iso_tree" -type f -iname etfsboot.com -print -quit)"
efisys="$(find "$iso_tree" -type f \( -iname efisys_noprompt.bin -o -iname efisys.bin \) -print -quit)"
[ -n "$etfs" ] || { echo "Could not find etfsboot.com" >&2; return 1; }
[ -n "$efisys" ] || { echo "Could not find efisys*.bin" >&2; return 1; }
local etfs_rel="${etfs#$iso_tree/}"
local efisys_rel="${efisys#$iso_tree/}"
mkisofs -o "$out" \
-b "$etfs_rel" -no-emul-boot -c BOOT.CAT \
-iso-level 4 -J -l -D -N -joliet-long -relaxed-filenames \
-V WIN11ARM64AUTO -udf -boot-info-table \
-eltorito-alt-boot -eltorito-boot "$efisys_rel" -no-emul-boot \
-quiet "$iso_tree"
}
rdp_auth_ready() {
xfreerdp \
+auth-only \
/cert:ignore \
/log-level:ERROR \
/timeout:5000 \
/u:"$USERNAME" \
/p:"$PASSWORD" \
/v:127.0.0.1:"$RDP_PORT" >/dev/null 2>&1
}
ssh_banner_ready() {
nc -G 2 -w 2 127.0.0.1 "$SSH_PORT" 2>/dev/null | head -n 1 | grep -q '^SSH-'
}
start_tpm() {
mkdir -p "$TPM_STATE"
rm -f "$TPM_SOCK"
swtpm socket --tpm2 --tpmstate dir="$TPM_STATE" --ctrl type=unixio,path="$ROOT/$TPM_SOCK" --daemon
}
screen_kind() {
local ppm="$1"
python3 - "$ppm" <<'PY'
import sys
from pathlib import Path
data = Path(sys.argv[1]).read_bytes()
if not data.startswith(b"P6"):
print("unknown")
raise SystemExit
idx = data.find(b"\n255\n")
if idx < 0:
print("unknown")
raise SystemExit
pixels = data[idx + 5:]
blue = orange = white = 0
total = len(pixels) // 3
for i in range(0, len(pixels), 3):
r, g, b = pixels[i], pixels[i + 1], pixels[i + 2]
if b > 90 and g > 60 and r < 50:
blue += 1
if r > 170 and 60 < g < 150 and b < 60:
orange += 1
if r > 210 and g > 210 and b > 210:
white += 1
if blue > total * 0.35:
print("windows-setup")
elif orange > 200:
print("firmware")
elif white > 500:
print("windows-text")
else:
print("unknown")
PY
}
current_screen_kind() {
local ppm="$TMP_ROOT/screen.ppm"
[ -S "$MONITOR" ] || { echo "unknown"; return 0; }
printf 'screendump %s\n' "$ppm" | socat - UNIX-CONNECT:"$MONITOR" >/dev/null 2>&1 || { echo "unknown"; return 0; }
screen_kind "$ppm"
}
stop_qemu() {
if [ -n "${QEMU_PID:-}" ] && kill -0 "$QEMU_PID" 2>/dev/null; then
[ -S "$MONITOR" ] && printf 'system_powerdown\n' | socat - UNIX-CONNECT:"$MONITOR" >/dev/null 2>&1 || true
for _ in $(seq 1 30); do
kill -0 "$QEMU_PID" 2>/dev/null || break
sleep 1
done
kill -0 "$QEMU_PID" 2>/dev/null && kill "$QEMU_PID" 2>/dev/null || true
fi
QEMU_PID=""
}
launch_qemu() {
local auto_iso="${1:-}"
local name="$2"
rm -f "$MONITOR" "$QEMU_LOG"
cp "$EDK2_VARS_TEMPLATE" "$VARS"
start_tpm
local args=(
-name "$name"
-machine virt,accel=hvf,highmem=on \
-cpu host \
-smp "$CPU_CORES" \
-m "$RAM_SIZE" \
-drive if=pflash,format=raw,readonly=on,file="$EDK2_CODE" \
-drive if=pflash,format=raw,file="$VARS" \
-device virtio-gpu-pci,xres=1920,yres=1080,edid=on \
-device qemu-xhci \
-device usb-kbd \
-device usb-tablet \
-chardev socket,id=chrtpm,path="$TPM_SOCK" \
-tpmdev emulator,id=tpm0,chardev=chrtpm \
-device tpm-tis-device,tpmdev=tpm0 \
-drive if=none,id=system,format=qcow2,cache=writeback,discard=unmap,file="$TARGET" \
-device nvme,drive=system,serial=WIN11ARM64,bootindex=1 \
-netdev user,id=net0,hostfwd=tcp:127.0.0.1:"$RDP_PORT"-:3389,hostfwd=tcp:127.0.0.1:"$SSH_PORT"-:22 \
-device virtio-net-pci,disable-legacy=on,disable-modern=off,netdev=net0,mac=52:54:00:12:34:59 \
-monitor unix:"$MONITOR",server,nowait \
-display cocoa,zoom-to-fit=on
)
if [ -n "$auto_iso" ]; then
args+=(
-drive if=none,id=installiso,format=raw,readonly=on,media=cdrom,file="$auto_iso"
-device usb-storage,id=installisodev,drive=installiso,bootindex=2
)
fi
qemu-system-aarch64 "${args[@]}" >"$QEMU_LOG" 2>&1 &
QEMU_PID="$!"
}
wait_for_rdp_or_firmware_stall() {
local deadline=$((SECONDS + INSTALL_TIMEOUT_MINUTES * 60))
local saw_setup=""
local firmware_since=""
echo "Waiting up to $INSTALL_TIMEOUT_MINUTES minutes for RDP authentication and SSH on 127.0.0.1..."
while (( SECONDS < deadline )); do
if rdp_auth_ready && ssh_banner_ready; then
echo "RDP authentication and the SSH banner succeeded; Windows boot, VirtIO networking, and OpenSSH passed."
stop_qemu
return 0
fi
if ! kill -0 "$QEMU_PID" 2>/dev/null; then
echo "QEMU exited before RDP became available; continuing with disk-only boot."
QEMU_PID=""
return 2
fi
local kind
kind="$(current_screen_kind)"
case "$kind" in
windows-setup|windows-text)
saw_setup=1
firmware_since=""
;;
firmware)
if [ -n "$saw_setup" ]; then
: "${firmware_since:=$SECONDS}"
if (( SECONDS - firmware_since >= FIRMWARE_STALL_SECONDS )); then
echo "Firmware splash persisted after Windows setup; switching to disk-only boot."
stop_qemu
return 2
fi
fi
;;
*)
firmware_since=""
;;
esac
sleep 15
done
echo "Timed out waiting for RDP test." >&2
return 1
}
run_disk_only_until_rdp() {
local cycle deadline
deadline=$((SECONDS + INSTALL_TIMEOUT_MINUTES * 60))
for cycle in $(seq 1 "$DISK_BOOT_CYCLES"); do
(( SECONDS < deadline )) || break
echo "Disk-only boot cycle $cycle/$DISK_BOOT_CYCLES..."
launch_qemu "" "win11-arm64-diskonly"
while (( SECONDS < deadline )); do
if rdp_auth_ready && ssh_banner_ready; then
echo "RDP authentication and the SSH banner succeeded; Windows boot, VirtIO networking, and OpenSSH passed."
stop_qemu
return 0
fi
if ! kill -0 "$QEMU_PID" 2>/dev/null; then
echo "QEMU exited during disk-only boot cycle $cycle; relaunching."
QEMU_PID=""
break
fi
sleep 15
done
stop_qemu
done
echo "Timed out waiting for disk-only RDP test." >&2
return 1
}
run_qemu_install_and_test() {
local auto_iso="$1"
launch_qemu "$auto_iso" "win11-arm64-install"
wait_for_rdp_or_firmware_stall && return 0
run_disk_only_until_rdp
}
main() {
install_deps
for cmd in qemu-system-aarch64 qemu-img wimlib-imagex mkisofs swtpm curl aria2c python3 socat xfreerdp hdiutil nc rsync; do
require_cmd "$cmd"
done
assert_clean_images
rm -f "$TARGET"
qemu-img create -f qcow2 "$TARGET" "$DISK_SIZE"
TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/win11-arm64-install.XXXXXX")"
local iso="$TMP_ROOT/win11-arm64.iso"
local virtio="$TMP_ROOT/virtio-arm.tar.xz"
local drivers="$TMP_ROOT/drivers"
local iso_mount="$TMP_ROOT/iso-mount"
local iso_tree="$TMP_ROOT/iso-tree"
local answer="$TMP_ROOT/autounattend.xml"
local auto_iso="$TMP_ROOT/win11-arm64-auto.iso"
echo "Downloading Windows 11 ARM64 ISO..."
download "$WIN_ISO_URL" "$iso"
sha256_check "$WIN_ISO_SHA256" "$iso"
echo "Downloading ARM64 VirtIO drivers..."
download "$VIRTIO_ARM_URL" "$virtio"
sha256_check "$VIRTIO_ARM_SHA256" "$virtio"
mkdir -p "$drivers"
tar -xJf "$virtio" -C "$drivers"
echo "Extracting installer ISO..."
mkdir -p "$iso_mount" "$iso_tree"
hdiutil attach -readonly -nobrowse -mountpoint "$iso_mount" "$iso" >/dev/null
rsync -a "$iso_mount/" "$iso_tree/"
hdiutil detach "$iso_mount" >/dev/null
chmod -R u+w "$iso_tree"
make_answer_file "$answer"
echo "Patching boot.wim with autounattend.xml and ARM64 VirtIO drivers..."
patch_iso_tree "$iso_tree" "$drivers" "$answer"
echo "Rebuilding temporary auto-install ISO..."
build_auto_iso "$iso_tree" "$auto_iso"
echo "Installing into $TARGET..."
run_qemu_install_and_test "$auto_iso"
echo "Final disk:"
qemu-img info "$TARGET"
echo "Checking for stale image files:"
find . -type f \( -name '*.raw' -o -name '*.img' -o -name '*.iso' -o -name '*.qcow2' \) -exec ls -lh {} +
}
main "$@"
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
QEMU_SHARE="$(brew --prefix qemu)/share/qemu"
PATCHED_QEMU="$HOME/opt/qemu-cocoa-proper/bin/qemu-system-aarch64"
if [[ -z "${QEMU_BIN:-}" && -x "$PATCHED_QEMU" ]]; then
QEMU_BIN="$PATCHED_QEMU"
else
QEMU_BIN="${QEMU_BIN:-qemu-system-aarch64}"
fi
EDK2_CODE="$QEMU_SHARE/edk2-aarch64-code.fd"
EDK2_VARS_TEMPLATE="$QEMU_SHARE/edk2-arm-vars.fd"
VARS="work/vm/edk2-arm-vars.fd"
DISK="${1:-outputs/win11-arm64-50g.qcow2}"
FORMAT="${FORMAT:-qcow2}"
RDP_PORT="${RDP_PORT:-3390}"
SSH_PORT="${SSH_PORT:-2222}"
NETWORK_MODE="${NETWORK_MODE:-user}"
BRIDGE_IF="${BRIDGE_IF:-en0}"
TPM_SOCK="work/vm/swtpm-sock"
STARTUP_DIR="work/vm/uefi-startup"
cleanup() {
pkill -f "swtpm.*$ROOT/$TPM_SOCK" >/dev/null 2>&1 || true
}
trap cleanup EXIT
mkdir -p work/vm work/vm/swtpm-state "$STARTUP_DIR"
cleanup
rm -f work/vm/qemu-monitor.sock "$TPM_SOCK"
cp "$EDK2_VARS_TEMPLATE" "$VARS"
cat > "$STARTUP_DIR/startup.nsh" <<'EOF'
FS0:\EFI\Microsoft\Boot\bootmgfw.efi
FS0:\EFI\BOOT\BOOTAA64.EFI
FS1:\EFI\Microsoft\Boot\bootmgfw.efi
FS1:\EFI\BOOT\BOOTAA64.EFI
FS2:\EFI\Microsoft\Boot\bootmgfw.efi
FS2:\EFI\BOOT\BOOTAA64.EFI
FS3:\EFI\Microsoft\Boot\bootmgfw.efi
FS3:\EFI\BOOT\BOOTAA64.EFI
FS4:\EFI\Microsoft\Boot\bootmgfw.efi
FS4:\EFI\BOOT\BOOTAA64.EFI
FS5:\EFI\Microsoft\Boot\bootmgfw.efi
FS5:\EFI\BOOT\BOOTAA64.EFI
EOF
swtpm socket \
--tpm2 \
--tpmstate dir=work/vm/swtpm-state \
--ctrl type=unixio,path="$ROOT/$TPM_SOCK" \
--daemon
if [[ "$NETWORK_MODE" == "bridged" ]]; then
QEMU_RUN=(sudo "$QEMU_BIN")
NET_ARGS=(-netdev "vmnet-bridged,id=net0,ifname=$BRIDGE_IF")
else
QEMU_RUN=("$QEMU_BIN")
NET_ARGS=(-netdev "user,id=net0,hostfwd=tcp:127.0.0.1:$RDP_PORT-:3389,hostfwd=tcp:127.0.0.1:$SSH_PORT-:22")
fi
"${QEMU_RUN[@]}" \
-name win11-arm64 \
-machine virt,accel=hvf,highmem=on \
-cpu host \
-smp 4 \
-m 8G \
-drive if=pflash,format=raw,readonly=on,file="$EDK2_CODE" \
-drive if=pflash,format=raw,file="$VARS" \
-device virtio-gpu-pci,xres=1920,yres=1080,edid=on \
-device qemu-xhci \
-device usb-kbd \
-device usb-tablet \
-chardev socket,id=chrtpm,path="$TPM_SOCK" \
-tpmdev emulator,id=tpm0,chardev=chrtpm \
-device tpm-tis-device,tpmdev=tpm0 \
-drive if=none,id=system,format="$FORMAT",cache=writeback,discard=unmap,file="$DISK" \
-device nvme,drive=system,serial=WIN11ARM64,bootindex=1 \
-drive if=none,id=startup,format=raw,readonly=on,file=fat:ro:"$STARTUP_DIR" \
-device usb-storage,drive=startup,bootindex=2 \
"${NET_ARGS[@]}" \
-device virtio-net-pci,disable-legacy=on,disable-modern=off,netdev=net0,mac=52:54:00:12:34:59 \
-monitor unix:work/vm/qemu-monitor.sock,server,nowait \
-display cocoa,zoom-to-fit=on
37437f4d2cf3eb9c8e5c4daafe0ec21fd862d19409fe9d6572172a99831b68b1 ./0001-build-recognize-the-AArch64-MSYS-target.patch
c2677b17b914ca2ec8ec6c23fa910bbf194f02c55e2a1fa926b1511d021aecab ./0002-winsup-make-shared-sources-compile-cleanly-with-Clan.patch
0917434b8d244874e8ee0279d02f8e34d9529dc3f55077b03384bd1bc5f34928 ./0003-newlib-support-the-AArch64-MSYS-PE-ABI.patch
465643d6d471e31c4e836bc23205245eeea0ceafb30420f7bdc3cec76510f88a ./0004-winsup-add-the-Windows-ARM64-runtime-implementation.patch
ce7ede7c8cbf9428f5f314db0527cbafc0ff860ee99170fbb6bb508b66a06f6b ./0005-build-regenerate-autotools-outputs.patch
98cb73d866e368375f5af28992c69ed0f65d5b43079d1009f9ef4588241ee975 ./0006-docs-record-the-ARM64-Clang-porting-procedure.patch
2061f8263a1de92f7ed1e84b255b4000ffdf73b4e0988a27fdfc63e9858edaf0 ./0007-docs-frame-the-port-as-WOA-QEMU-validation.patch
c8d59fd2358af7b71379ec0200f164ed4d91b388073c60d7be190877867e9bd7 ./GIST_README.md
aacbd7bffa1b000f1a6c68bcf9e8e87d46342cd9cdfb647b6b3e3e7fb2d623cc ./MSYS2_ARM64_README.md
5da66e6e7277458c48ec6565ad465a89704e384ab73224306277ec4bbe70f74b ./WOA_COMPARISON.md
cc617fdc630b11bbd8b6501e0cf047fdd6eba018b7d036b5b61621fb0af226b1 ./aarch64-pc-msys-clang
12959a6cd7139a56abaa5ad263227a1b4e597621b2cfbaae34703dbab716af00 ./aarch64-pc-msys-clang++
1a90f5a9165d22c12f41c1ed66e91c61abcf0960b2a37bddcdfa3a9787eed55e ./add-msys2-arm64-bootstrap-fork-copy.py
01fb4e6514a02bf5f6f769724480e3a99f21de5ba81ad8930d8d8a875b3e35bf ./arm64-fork-bootstrap-copy.S
d065a2c6f0b2f25b0560468cb58c558f4554a27f6518516129fa82fa21f63b4d ./arm64_fenv_excepts.c
70edfa8d3518ff6a7b611cf97919fc4bfdb5b5805b0edcde2b699520a0f0bc93 ./arm64_link_support.c
546d946ee3143a7f0d331b6e309ae577416ff8f5e731f8625b7bcdbda12661ec ./bash-arm64-win11-fork-status.sh
71f8c2d43b536bcffdb268d6b317fae925eebc40acb430cc7b69551da4038d70 ./bash-arm64-win11-smoke.sh
ad1deabb1b66017434684602f4d582c9645249db3c906dd09630dbd3e0f1374f ./build-arm64-support-libs.sh
1bce8b87fed704f41dddc2cbcb2d549666388e56f1a2884128531a2a8b184937 ./build-msys-loader-probe.sh
5e4b8f3c38b21bbb63a74bf98f34285f1f565df16dec17478a8ce12d64c6f764 ./catanl_only.c
6c44a5aca5001b3ed36b82763c8476c36d17b226fa3c0366e55e64848d3b8c7b ./fix-msys-arm64-crt.py
faf19e79e3cc0a38e427e82f5a9e98e934041464f1362a96f23eaba4060dec49 ./kernel32-probe.def
5dc73f3d5da93571c36bde41eb6c09e61e802ab507e8e1dc1e2b8052cbe12ba2 ./llvm-aarch64-cygwin-target.patch
145367e0a03a107e6d84bddfe6e31dea43cb712195a4129ba14b8422e025edb7 ./llvm-ms-builtins-long-long.patch
3189272fdc4cddb180bb732e78f9470e505342d627dd9f9855524c2660d07347 ./msys-fork-probe.c
d5ffe1e9354b997e75c3273503627b360c1c702d341057bafa0242f6a220e2b7 ./msys-loader-probe.c
2ec19a045ea4f5bf92c1e670fa08e105500cacb6108e819f6c6b979bbeb25f0d ./msys-pipe-fork-probe.c
358ad122cc4074ecd01b20cf4d30018393a3d7c4232ae4a47d4a55c5698e3348 ./msys-toolchain-excpt.h
d5fbeda28cb6769922d6c7924afc06b294d64724ca3e5a3d01357ec1d03115f4 ./msys-toolchain-w32api-ntstatus.h
46133fa50735c4523ce895ade23dd0a86e86e351750bf32ac6060fc00e7627d7 ./msys2-runtime-series
bffa9d50e1cabdb6d705ad88081b9a1b97da17623aaf09f600925dfcceda06ad ./prepare-msys2-arm64-dll.sh
0401dbce111bcec4ba0b2d908a87edb99c358e6098be34734aec079ad1558b25 ./qemu-11.0.1-cocoa-force-1920x1080-uiinfo.patch
e4d45084dbb68b76fd2fc701de58b03f1ac5e7f976ddad8bbe5fa974f745ed98 ./reinstall-win11-arm64-qcow2.sh
9c9e434d1be8474e16d176b84d3f562f9bba8e689a8abc0164716b51c750e754 ./run-win11.sh
3ad4860b479c51792309218d67b8dad90cfc417ac94ff81e8b756c03e048e1a7 ./sigjmp-mask-probe.c
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
static sigjmp_buf restore_env;
static sigjmp_buf preserve_env;
static int
signal_is_blocked(int signal_number)
{
sigset_t current;
if (sigprocmask(SIG_SETMASK, NULL, &current) != 0)
return -1;
return sigismember(&current, signal_number);
}
int
main(void)
{
sigset_t signal_set;
int value;
sigemptyset(&signal_set);
sigaddset(&signal_set, SIGUSR1);
if (sigprocmask(SIG_BLOCK, &signal_set, NULL) != 0)
return 10;
value = sigsetjmp(restore_env, 1);
if (value == 0)
{
if (sigprocmask(SIG_UNBLOCK, &signal_set, NULL) != 0)
return 11;
siglongjmp(restore_env, 42);
}
if (value != 42 || signal_is_blocked(SIGUSR1) != 1)
return 12;
puts("SIGJMP_MASK_RESTORED=1");
if (sigprocmask(SIG_BLOCK, &signal_set, NULL) != 0)
return 20;
value = sigsetjmp(preserve_env, 0);
if (value == 0)
{
if (sigprocmask(SIG_UNBLOCK, &signal_set, NULL) != 0)
return 21;
siglongjmp(preserve_env, 24);
}
if (value != 24 || signal_is_blocked(SIGUSR1) != 0)
return 22;
puts("SIGJMP_MASK_UNCHANGED=1");
return 0;
}

QEMU validation of Windows-on-ARM-Experiments

The Windows-on-ARM-Experiments organization provides the ARM64 runtime foundation exercised by this work. Its newlib-cygwin, GCC, binutils, package, and CI repositories form the broader GNU-toolchain port; this experiment adapts that direction to Clang/MSYS2 and tests it in a reproducible Windows ARM64 QEMU environment.

The value demonstrated here is not a separate invention of the ARM64 runtime. It is a pinned QEMU reproduction showing that the WOA-derived architecture work can load a native MSYS2 DLL and run focused Bash/fork behavior.

Status checked on 2026-07-18

Area Windows-on-ARM-Experiments This experiment
Compiler path GNU binutils and GCC for aarch64-pc-cygwin/aarch64-pc-msys Patched Clang target with GNU ARM64 PE/COFF binutils
Runtime scope Broad Cygwin AArch64 port: startup, TLS, imports, memory functions, pthreads, exceptions, signals, linker and CI Adaptation of that ARM64 foundation to MSYS2 3.6.9, sufficient to load the DLL and exercise Bash/fork probes
CI Builds on WSL and native Windows ARM64; ARM tests are currently non-gating Reproduced manually in a Windows 11 ARM64 QEMU/HVF VM
Fork/signals Fork/exec remains a draft PR; signal-stack work remains open Canonical fork, pipe-fork and Bash command substitution pass, with transient child-start retries
MSYS2 packages Cross-binutils and stage-1 GCC done; runtime WIP and Bash TODO in the published roadmap No package repository; Bash 5.3 executable and focused probes only
ABI GNU port currently carries its own Cygwin AArch64 ABI decisions, including 64-bit long double work LP64 Clang target with IEEE binary128 long double

Overlap requiring an authorship audit

The runtime patch series touches architecture areas also implemented by WOA:

  • target/configure recognition and linker scripts;
  • AArch64 newlib assembly and setjmp support;
  • startup, TLS, exception and signal context handling;
  • lazy imports, import-library generation and relocation;
  • pthread stack switching and allocator integration;
  • endian, CPU, profiling and resource helpers.

Before proposing runtime changes upstream, compare each hunk with WOA's commit history. Preserve original authorship for code or design adopted from that work, and drop local changes already solved there.

Validated contribution delta

The useful contribution from this experiment is narrower than the six-patch bundle and centers on validation:

  1. Clang recognition and ABI tests for aarch64-pc-cygwin.
  2. Clang compatibility fixes that are independently reviewable and do not change x86_64 behavior.
  3. A reproducible macOS-to-Windows-ARM64 cross-build and QEMU test path.
  4. Focused native probes demonstrating that the WOA-derived runtime can perform DLL load, fork, pipe-fork, Bash command substitution, subshell status, and external process execution.
  5. Reproduction of remaining QEMU/runtime failures with exact hashes.

The next upstream step is coordination on msys2-runtime issue #53 and with the WOA maintainers. A runtime PR should follow only after the overlap is reduced to a small, attributable delta and regression tests cover x86_64 as well as ARM64.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment