summaryrefslogtreecommitdiff
path: root/system/musl
diff options
context:
space:
mode:
Diffstat (limited to 'system/musl')
-rw-r--r--system/musl/0001-iconv-fix-erroneous-input-validation-in-EUC-KR-decod.patch38
-rw-r--r--system/musl/0002-iconv-harden-UTF-8-output-code-path-against-input-de.patch37
-rw-r--r--system/musl/APKBUILD33
-rw-r--r--system/musl/amalgamation.patch385
-rw-r--r--system/musl/handle-aux-at_base.patch4
-rw-r--r--system/musl/powerpc-wchar_t.patch26
-rw-r--r--system/musl/ppc-hwcap.patch36
-rw-r--r--system/musl/realpath.patch37
-rw-r--r--system/musl/signed-wchar_t-fixes.patch77
-rw-r--r--system/musl/strftime-add-l-support.patch25
-rw-r--r--system/musl/x87-math.patch157
11 files changed, 509 insertions, 346 deletions
diff --git a/system/musl/0001-iconv-fix-erroneous-input-validation-in-EUC-KR-decod.patch b/system/musl/0001-iconv-fix-erroneous-input-validation-in-EUC-KR-decod.patch
new file mode 100644
index 000000000..ff92d8ef9
--- /dev/null
+++ b/system/musl/0001-iconv-fix-erroneous-input-validation-in-EUC-KR-decod.patch
@@ -0,0 +1,38 @@
+From e5adcd97b5196e29991b524237381a0202a60659 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Sun, 9 Feb 2025 10:07:19 -0500
+Subject: [PATCH] iconv: fix erroneous input validation in EUC-KR decoder
+
+as a result of incorrect bounds checking on the lead byte being
+decoded, certain invalid inputs which should produce an encoding
+error, such as "\xc8\x41", instead produced out-of-bounds loads from
+the ksc table.
+
+in a worst case, the loaded value may not be a valid unicode scalar
+value, in which case, if the output encoding was UTF-8, wctomb would
+return (size_t)-1, causing an overflow in the output pointer and
+remaining buffer size which could clobber memory outside of the output
+buffer.
+
+bug report was submitted in private by Nick Wellnhofer on account of
+potential security implications.
+---
+ src/locale/iconv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/locale/iconv.c b/src/locale/iconv.c
+index 9605c8e9..008c93f0 100644
+--- a/src/locale/iconv.c
++++ b/src/locale/iconv.c
+@@ -502,7 +502,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
+ if (c >= 93 || d >= 94) {
+ c += (0xa1-0x81);
+ d += 0xa1;
+- if (c >= 93 || c>=0xc6-0x81 && d>0x52)
++ if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52)
+ goto ilseq;
+ if (d-'A'<26) d = d-'A';
+ else if (d-'a'<26) d = d-'a'+26;
+--
+2.21.0
+
diff --git a/system/musl/0002-iconv-harden-UTF-8-output-code-path-against-input-de.patch b/system/musl/0002-iconv-harden-UTF-8-output-code-path-against-input-de.patch
new file mode 100644
index 000000000..d66e66e3f
--- /dev/null
+++ b/system/musl/0002-iconv-harden-UTF-8-output-code-path-against-input-de.patch
@@ -0,0 +1,37 @@
+From c47ad25ea3b484e10326f933e927c0bc8cded3da Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Wed, 12 Feb 2025 17:06:30 -0500
+Subject: [PATCH] iconv: harden UTF-8 output code path against input decoder
+ bugs
+
+the UTF-8 output code was written assuming an invariant that iconv's
+decoders only emit valid Unicode Scalar Values which wctomb can encode
+successfully, thereby always returning a value between 1 and 4.
+
+if this invariant is not satisfied, wctomb returns (size_t)-1, and the
+subsequent adjustments to the output buffer pointer and remaining
+output byte count overflow, moving the output position backwards,
+potentially past the beginning of the buffer, without storing any
+bytes.
+---
+ src/locale/iconv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/locale/iconv.c b/src/locale/iconv.c
+index 008c93f0..52178950 100644
+--- a/src/locale/iconv.c
++++ b/src/locale/iconv.c
+@@ -545,6 +545,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
+ if (*outb < k) goto toobig;
+ memcpy(*out, tmp, k);
+ } else k = wctomb_utf8(*out, c);
++ /* This failure condition should be unreachable, but
++ * is included to prevent decoder bugs from translating
++ * into advancement outside the output buffer range. */
++ if (k>4) goto ilseq;
+ *out += k;
+ *outb -= k;
+ break;
+--
+2.21.0
+
diff --git a/system/musl/APKBUILD b/system/musl/APKBUILD
index 5c95298d1..5951328a1 100644
--- a/system/musl/APKBUILD
+++ b/system/musl/APKBUILD
@@ -1,7 +1,7 @@
# Maintainer: A. Wilcox <awilfox@adelielinux.org>
pkgname=musl
-pkgver=1.1.23
-pkgrel=2
+pkgver=1.2.3
+pkgrel=3
pkgdesc="System library (libc) implementation"
url="https://www.musl-libc.org/"
arch="all"
@@ -21,14 +21,17 @@ nolibc) ;;
triggers="$pkgname-utils.trigger=/etc/ld.so.conf.d"
;;
esac
-source="https://www.musl-libc.org/releases/musl-$pkgver.tar.gz
+source="https://musl.libc.org/releases/musl-${pkgver}.tar.gz
amalgamation.patch
3001-make-real-lastlog-h.patch
handle-aux-at_base.patch
fgetspent_r.patch
- powerpc-wchar_t.patch
- strftime-add-l-support.patch
- x87-math.patch
+ ppc-hwcap.patch
+ realpath.patch
+ signed-wchar_t-fixes.patch
+
+ 0001-iconv-fix-erroneous-input-validation-in-EUC-KR-decod.patch
+ 0002-iconv-harden-UTF-8-output-code-path-against-input-de.patch
ldconfig
getent.c
@@ -40,6 +43,10 @@ source="https://www.musl-libc.org/releases/musl-$pkgver.tar.gz
# - CVE-2016-8859
# 1.1.23-r2:
# - CVE-2019-14697
+# 1.2.0-r2:
+# - CVE-2020-28928
+# 1.2.3-r3:
+# - CVE-2025-26519
build() {
[ "$BOOTSTRAP" = "nocc" ] && return 0
@@ -119,14 +126,16 @@ utils() {
install -D -m755 "$srcdir"/ldconfig "$subpkgdir"/sbin
}
-sha512sums="a2278de9903852b08352d3e734a39d4616caa602496997ba843e8fea0e1c481761776745faf04536a149d1c4af416b68df681b6fbc9ae2de8794e18c2e853b09 musl-1.1.23.tar.gz
-ef532aebeaa89b3274f7f75f1adaa4d1eea60f4e2822a6711c748768cc3a65a77ebd218d7a8ab41157684f7855dd4c5c2cdea7461b7569264d3517deba0ef9b2 amalgamation.patch
+sha512sums="9332f713d3eb7de4369bc0327d99252275ee52abf523ee34b894b24a387f67579787f7c72a46cf652e090cffdb0bc3719a4e7b84dca66890b6a37f12e8ad089c musl-1.2.3.tar.gz
+f7b05d8c5f804ba3ad6998b3de5fa4d9dfceac4aca63dd67298c2d5f27cdd28a91eba74f6e428c258323da80635dd333bae2c47ff918894797cba92bd5700909 amalgamation.patch
88ae443dbb8e0a4368235bdc3a1c5c7b718495afa75e06deb8e01becc76cb1f0d6964589e2204fc749c9c1b3190b8b9ac1ae2c0099cab8e2ce3ec877103d4332 3001-make-real-lastlog-h.patch
-6a7ff16d95b5d1be77e0a0fbb245491817db192176496a57b22ab037637d97a185ea0b0d19da687da66c2a2f5578e4343d230f399d49fe377d8f008410974238 handle-aux-at_base.patch
+1f4e9aea5a546015c75f77aa0dec10d56fc14831ccc15cf71ff27fc15ac5230ffeadb382ebe1c87c1ea07a462620e16ed01cd36252d997d1a9c2af11cb5c9ff3 handle-aux-at_base.patch
ded41235148930f8cf781538f7d63ecb0c65ea4e8ce792565f3649ee2523592a76b2a166785f0b145fc79f5852fd1fb1729a7a09110b3b8f85cba3912e790807 fgetspent_r.patch
-fda015fad0d0a65efb192c08d201b2f5b2bfff18c43b551855b119a1d63213bd417a93a6b2965e68243884c5b17b34a585795cc4cace603788d37149e933cfb1 powerpc-wchar_t.patch
-7ed6c620a5ea5585c323936b1ff01eb7f01a1192240706a0d0470b661a7a03ea10ed17507c59678aaedce51b7a5ea839c2f528f19f12de02119bf4e47f7c3998 strftime-add-l-support.patch
-e3c98f64e901ac08a4a7dfbb7c46fb6ecc1cc7e825a8f4834b5a9dd1cafaa2e8ee1ccf6c55c7f07cc4ede9c54cd039e61dec41df6b973fac1ad42e7d3faa1932 x87-math.patch
+96d88bb9c03f6eddcfc22cbd04efa73535f4ab78409954a042a2e08294cc8df1fb2cb0475eadb92a7fa281229abaa600f034d3ef08e918c6016dbf9be1db28d9 ppc-hwcap.patch
+d5ec3f1a86f2194e0af83c2391508811b939d0f8f2fd2ac5ac7f03774f8a250ce42399110d2ae04d32b864ee292863fed683a029b64598dbbcb21d9811a825d0 realpath.patch
+3770af3bc961e5d5b8c152c428cd20dc54e026b23b31d764fbc2e71ee38140d160db2267755f23800bc8586fd4b51554b1caebb2415bef82fd0f4a6dd8bf640d signed-wchar_t-fixes.patch
+a69f77c4b4c7fefb543f5a1678f981b001c35cdb4c0bb2dfb56548eebc88e725330b9961a5435d11e6e1e3185b508f1fd5bf72e6aa67b708a8e8186c4b33392a 0001-iconv-fix-erroneous-input-validation-in-EUC-KR-decod.patch
+c4777d653007ea3e2af5e3edf7804e5b5562823e41543991b7c04843203a6e93c1e1e2c63b178c8ed2f89411040230268d8a83ebc3018ad199aad958587c0faf 0002-iconv-harden-UTF-8-output-code-path-against-input-de.patch
cb71d29a87f334c75ecbc911becde7be825ab30d8f39fa6d64cb53812a7c9abaf91d9804c72540e5be3ddd3c84cfe7fd9632274309005cb8bcdf9a9b09b4b923 ldconfig
378d70e65bcc65bb4e1415354cecfa54b0c1146dfb24474b69e418cdbf7ad730472cd09f6f103e1c99ba6c324c9560bccdf287f5889bbc3ef0bdf0e08da47413 getent.c
9d42d66fb1facce2b85dad919be5be819ee290bd26ca2db00982b2f8e055a0196290a008711cbe2b18ec9eee8d2270e3b3a4692c5a1b807013baa5c2b70a2bbf iconv.c"
diff --git a/system/musl/amalgamation.patch b/system/musl/amalgamation.patch
index e53290e21..5e273ce7f 100644
--- a/system/musl/amalgamation.patch
+++ b/system/musl/amalgamation.patch
@@ -1,12 +1,21 @@
+diff --git a/compat/time32/timespec_get_time32.c b/compat/time32/timespec_get_time32.c
+index e9ca94cb..b39b12ee 100644
+--- a/compat/time32/timespec_get_time32.c
++++ b/compat/time32/timespec_get_time32.c
+@@ -1,3 +1,4 @@
++#define _BSD_SOURCE
+ #include "time32.h"
+ #include <time.h>
+ #include <errno.h>
diff --git a/include/stdlib.h b/include/stdlib.h
-index 42ca8336..4bbaded0 100644
+index b507ca33..5e14b07c 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
-@@ -39,14 +39,18 @@ void *malloc (size_t);
+@@ -41,14 +41,18 @@ void *malloc (size_t);
void *calloc (size_t, size_t);
void *realloc (void *, size_t);
void free (void *);
-+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
++#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
void *aligned_alloc(size_t, size_t);
+#endif
@@ -14,14 +23,14 @@ index 42ca8336..4bbaded0 100644
int atexit (void (*) (void));
_Noreturn void exit (int);
_Noreturn void _Exit (int);
-+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
++#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
int at_quick_exit (void (*) (void));
_Noreturn void quick_exit (int);
+#endif
char *getenv (const char *);
-@@ -100,7 +104,6 @@ int posix_memalign (void **, size_t, size_t);
+@@ -102,7 +106,6 @@ int posix_memalign (void **, size_t, size_t);
int setenv (const char *, const char *, int);
int unsetenv (const char *);
int mkstemp (char *);
@@ -29,7 +38,7 @@ index 42ca8336..4bbaded0 100644
char *mkdtemp (char *);
int getsubopt (char **, char *const *, char **);
int rand_r (unsigned *);
-@@ -138,6 +141,7 @@ void lcong48 (unsigned short [7]);
+@@ -140,6 +143,7 @@ void lcong48 (unsigned short [7]);
#include <alloca.h>
char *mktemp (char *);
int mkstemps (char *, int);
@@ -37,18 +46,30 @@ index 42ca8336..4bbaded0 100644
int mkostemps (char *, int, int);
void *valloc (size_t);
void *memalign(size_t, size_t);
+diff --git a/include/sys/time.h b/include/sys/time.h
+index cdc67ef6..fd773896 100644
+--- a/include/sys/time.h
++++ b/include/sys/time.h
+@@ -13,6 +13,7 @@ int gettimeofday (struct timeval *__restrict, void *__restrict);
+ #define ITIMER_REAL 0
+ #define ITIMER_VIRTUAL 1
+ #define ITIMER_PROF 2
++#define __USE_TIME_BITS64 1
+
+ struct itimerval {
+ struct timeval it_interval;
diff --git a/include/time.h b/include/time.h
-index 672b3fc3..c5946dd0 100644
+index 3d948372..deb4a450 100644
--- a/include/time.h
+++ b/include/time.h
-@@ -58,11 +58,14 @@ struct tm *gmtime (const time_t *);
+@@ -60,11 +60,14 @@ struct tm *gmtime (const time_t *);
struct tm *localtime (const time_t *);
char *asctime (const struct tm *);
char *ctime (const time_t *);
-int timespec_get(struct timespec *, int);
-#define CLOCKS_PER_SEC 1000000L
-+#if __STDC_VERSION__ >= 201112L
++#if __STDC_VERSION__ >= 201112L || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+int timespec_get(struct timespec *, int);
#define TIME_UTC 1
@@ -58,11 +79,58 @@ index 672b3fc3..c5946dd0 100644
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+@@ -139,7 +142,10 @@ __REDIR(mktime, __mktime64);
+ __REDIR(gmtime, __gmtime64);
+ __REDIR(localtime, __localtime64);
+ __REDIR(ctime, __ctime64);
++# if __STDC_VERSION__ >= 201112L || defined(_BSD_SOURCE) \
++ || defined(_GNU_SOURCE)
+ __REDIR(timespec_get, __timespec_get_time64);
++# endif
+ #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
diff --git a/include/unistd.h b/include/unistd.h
-index 9485da7a..1bdd3292 100644
+index ee2dbe8a..ed75e578 100644
--- a/include/unistd.h
+++ b/include/unistd.h
-@@ -274,6 +274,7 @@ int eaccess(const char *, int);
+@@ -35,16 +35,23 @@ extern "C" {
+ #include <bits/alltypes.h>
+
+ int pipe(int [2]);
+-int pipe2(int [2], int);
+ int close(int);
+-int posix_close(int, int);
+ int dup(int);
+ int dup2(int, int);
+-int dup3(int, int, int);
+ off_t lseek(int, off_t, int);
+ int fsync(int);
+ int fdatasync(int);
+
++#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \
++ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 > 700) \
++ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 > 200809L)
++int pipe2(int [2], int);
++int dup3(int, int, int);
++int posix_close(int, int);
++
++#define POSIX_CLOSE_RESTART 0
++#endif
++
+ ssize_t read(int, void *, size_t);
+ ssize_t write(int, const void *, size_t);
+ ssize_t pread(int, void *, size_t, off_t);
+@@ -206,8 +213,6 @@ pid_t gettid(void);
+ #define off64_t off_t
+ #endif
+
+-#define POSIX_CLOSE_RESTART 0
+-
+ #define _XOPEN_VERSION 700
+ #define _XOPEN_UNIX 1
+ #define _XOPEN_ENH_I18N 1
+@@ -280,6 +285,7 @@ pid_t gettid(void);
#define _PC_ALLOC_SIZE_MIN 18
#define _PC_SYMLINK_MAX 19
#define _PC_2_SYMLINKS 20
@@ -70,7 +138,7 @@ index 9485da7a..1bdd3292 100644
#define _SC_ARG_MAX 0
#define _SC_CHILD_MAX 1
-@@ -417,6 +418,7 @@ int eaccess(const char *, int);
+@@ -423,6 +429,7 @@ pid_t gettid(void);
#define _SC_XOPEN_STREAMS 246
#define _SC_THREAD_ROBUST_PRIO_INHERIT 247
#define _SC_THREAD_ROBUST_PRIO_PROTECT 248
@@ -78,7 +146,7 @@ index 9485da7a..1bdd3292 100644
#define _CS_PATH 0
#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
-@@ -459,6 +461,8 @@ int eaccess(const char *, int);
+@@ -465,6 +472,8 @@ pid_t gettid(void);
#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147
#define _CS_V6_ENV 1148
#define _CS_V7_ENV 1149
@@ -103,18 +171,20 @@ index 02cb1aa2..8f870a69 100644
return 0;
}
diff --git a/src/conf/fpathconf.c b/src/conf/fpathconf.c
-index e6aca5cf..b6a9d63e 100644
+index e6aca5cf..83e47e87 100644
--- a/src/conf/fpathconf.c
+++ b/src/conf/fpathconf.c
-@@ -4,7 +4,7 @@
+@@ -4,8 +4,8 @@
long fpathconf(int fd, int name)
{
- static const short values[] = {
+- [_PC_LINK_MAX] = _POSIX_LINK_MAX,
+ static const long values[] = {
- [_PC_LINK_MAX] = _POSIX_LINK_MAX,
++ [_PC_LINK_MAX] = -1,
[_PC_MAX_CANON] = _POSIX_MAX_CANON,
[_PC_MAX_INPUT] = _POSIX_MAX_INPUT,
+ [_PC_NAME_MAX] = NAME_MAX,
@@ -25,7 +25,8 @@ long fpathconf(int fd, int name)
[_PC_REC_XFER_ALIGN] = 4096,
[_PC_ALLOC_SIZE_MIN] = 4096,
@@ -126,7 +196,7 @@ index e6aca5cf..b6a9d63e 100644
if (name >= sizeof(values)/sizeof(values[0])) {
errno = EINVAL;
diff --git a/src/conf/sysconf.c b/src/conf/sysconf.c
-index 45ef1c16..483e1635 100644
+index 3baaed32..04369596 100644
--- a/src/conf/sysconf.c
+++ b/src/conf/sysconf.c
@@ -165,6 +165,7 @@ long sysconf(int name)
@@ -138,18 +208,45 @@ index 45ef1c16..483e1635 100644
if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {
diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c
-index 40bc7ece..4d51cdfe 100644
+index 360c4437..76dbfc37 100644
--- a/src/locale/setlocale.c
+++ b/src/locale/setlocale.c
-@@ -11,6 +11,8 @@ char *setlocale(int cat, const char *name)
+@@ -13,6 +13,8 @@ char *setlocale(int cat, const char *name)
if ((unsigned)cat > LC_ALL) return 0;
+ if (name && (!strncmp(name, "VSX4L", 5))) return 0;
+
- LOCK(lock);
+ LOCK(__locale_lock);
/* For LC_ALL, setlocale is required to return a string which
+diff --git a/src/malloc/posix_memalign.c b/src/malloc/posix_memalign.c
+index ad4d8f47..3318f86a 100644
+--- a/src/malloc/posix_memalign.c
++++ b/src/malloc/posix_memalign.c
+@@ -1,3 +1,4 @@
++#define _BSD_SOURCE
+ #include <stdlib.h>
+ #include <errno.h>
+
+diff --git a/src/misc/forkpty.c b/src/misc/forkpty.c
+index caf13adb..43494b96 100644
+--- a/src/misc/forkpty.c
++++ b/src/misc/forkpty.c
+@@ -1,3 +1,4 @@
++#define _GNU_SOURCE
+ #include <pty.h>
+ #include <utmp.h>
+ #include <unistd.h>
+diff --git a/src/misc/wordexp.c b/src/misc/wordexp.c
+index db83a69f..be9cb6d5 100644
+--- a/src/misc/wordexp.c
++++ b/src/misc/wordexp.c
+@@ -1,3 +1,4 @@
++#define _GNU_SOURCE
+ #include <wordexp.h>
+ #include <unistd.h>
+ #include <stdio.h>
diff --git a/src/process/execlp.c b/src/process/execlp.c
index 5eed886e..f6da398b 100644
--- a/src/process/execlp.c
@@ -202,18 +299,18 @@ index 00000000..180bb2aa
+ return execv("/bin/sh", nargv);
+}
diff --git a/src/process/execvp.c b/src/process/execvp.c
-index 2dddeddb..fdd0ca48 100644
+index ef3b9dd5..5e6255f7 100644
--- a/src/process/execvp.c
+++ b/src/process/execvp.c
-@@ -6,6 +6,7 @@
- #include "libc.h"
+@@ -5,6 +5,7 @@
+ #include <limits.h>
extern char **__environ;
+extern int __execsh(const char *, char *const []);
int __execvpe(const char *file, char *const argv[], char *const envp[])
{
-@@ -56,7 +57,12 @@ int __execvpe(const char *file, char *const argv[], char *const envp[])
+@@ -54,7 +55,12 @@ int __execvpe(const char *file, char *const argv[], char *const envp[])
int execvp(const char *file, char *const argv[])
{
@@ -228,10 +325,10 @@ index 2dddeddb..fdd0ca48 100644
weak_alias(__execvpe, execvpe);
diff --git a/src/process/system.c b/src/process/system.c
-index 9135b815..aa01e13b 100644
+index 5af59b80..3f61d278 100644
--- a/src/process/system.c
+++ b/src/process/system.c
-@@ -19,7 +19,9 @@ int system(const char *cmd)
+@@ -18,7 +18,9 @@ int system(const char *cmd)
pthread_testcancel();
@@ -242,11 +339,20 @@ index 9135b815..aa01e13b 100644
sigaction(SIGINT, &sa, &oldint);
sigaction(SIGQUIT, &sa, &oldquit);
+diff --git a/src/stdio/popen.c b/src/stdio/popen.c
+index 3ec83394..58883b11 100644
+--- a/src/stdio/popen.c
++++ b/src/stdio/popen.c
+@@ -1,3 +1,4 @@
++#define _GNU_SOURCE
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <errno.h>
diff --git a/src/thread/pthread_attr_setinheritsched.c b/src/thread/pthread_attr_setinheritsched.c
-index e540e846..4115e2fe 100644
+index ca264be7..fbfff6f8 100644
--- a/src/thread/pthread_attr_setinheritsched.c
+++ b/src/thread/pthread_attr_setinheritsched.c
-@@ -23,7 +23,7 @@ void *__start_sched(void *p)
+@@ -3,7 +3,7 @@
int pthread_attr_setinheritsched(pthread_attr_t *a, int inherit)
{
@@ -267,19 +373,37 @@ index 46b520c0..933bdb38 100644
+ return ENOTSUP;
}
}
+diff --git a/src/time/strftime.c b/src/time/strftime.c
+index cc53d536..98caa1f6 100644
+--- a/src/time/strftime.c
++++ b/src/time/strftime.c
+@@ -95,6 +95,8 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *
+ case 'H':
+ val = tm->tm_hour;
+ goto number;
++ case 'l':
++ def_pad = ' ';
+ case 'I':
+ val = tm->tm_hour;
+ if (!val) val = 12;
diff --git a/src/time/timespec_get.c b/src/time/timespec_get.c
-index 03c5a77b..c423b825 100644
+index 40ea9c1c..e396da09 100644
--- a/src/time/timespec_get.c
+++ b/src/time/timespec_get.c
-@@ -6,7 +6,7 @@ int __clock_gettime(clockid_t, struct timespec *);
- * are considered erroneous. */
- int timespec_get(struct timespec * ts, int base)
- {
-- if (base != TIME_UTC) return 0;
-+ if (base != 1) return 0;
- int ret = __clock_gettime(CLOCK_REALTIME, ts);
- return ret < 0 ? 0 : base;
- }
+@@ -1,3 +1,4 @@
++#define _BSD_SOURCE
+ #include <time.h>
+
+ /* There is no other implemented value than TIME_UTC; all other values
+diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c
+index 557503eb..756a7bc4 100644
+--- a/src/unistd/faccessat.c
++++ b/src/unistd/faccessat.c
+@@ -1,3 +1,4 @@
++#define _GNU_SOURCE
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/wait.h>
diff --git a/src/unistd/getcwd.c b/src/unistd/getcwd.c
index f407ffe0..4fd3a60c 100644
--- a/src/unistd/getcwd.c
@@ -297,92 +421,105 @@ index f407ffe0..4fd3a60c 100644
if (ret == 0 || buf[0] != '/') {
errno = ENOENT;
return 0;
-diff --git a/src/conf/fpathconf.c b/src/conf/fpathconf.c
-index b6a9d63e..83e47e87 100644
---- a/src/conf/fpathconf.c
-+++ b/src/conf/fpathconf.c
-@@ -5,7 +5,7 @@
- long fpathconf(int fd, int name)
- {
- static const long values[] = {
-- [_PC_LINK_MAX] = _POSIX_LINK_MAX,
-+ [_PC_LINK_MAX] = -1,
- [_PC_MAX_CANON] = _POSIX_MAX_CANON,
- [_PC_MAX_INPUT] = _POSIX_MAX_INPUT,
- [_PC_NAME_MAX] = NAME_MAX,
-diff --git a/include/unistd.h b/include/unistd.h
-index 1bdd3292..cdb16c19 100644
---- a/include/unistd.h
-+++ b/include/unistd.h
-@@ -33,16 +33,23 @@ extern "C" {
- #include <bits/alltypes.h>
-
- int pipe(int [2]);
--int pipe2(int [2], int);
- int close(int);
--int posix_close(int, int);
- int dup(int);
- int dup2(int, int);
--int dup3(int, int, int);
- off_t lseek(int, off_t, int);
- int fsync(int);
- int fdatasync(int);
+diff --git a/src/unistd/renameat.c b/src/unistd/renameat.c
+index c3b40a25..6af5aed6 100644
+--- a/src/unistd/renameat.c
++++ b/src/unistd/renameat.c
+@@ -1,11 +1,93 @@
++#include <errno.h>
++#include <fcntl.h>
++#include <libgen.h>
++#include <limits.h>
+ #include <stdio.h>
++#include <string.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <unistd.h>
+ #include "syscall.h"
-+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \
-+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 > 700) \
-+ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 > 200809L)
-+int pipe2(int [2], int);
-+int dup3(int, int, int);
-+int posix_close(int, int);
++static inline int test_symlink_dirness(int fd, const char *pathname)
++{
++ struct stat statbuf;
++ if (fstatat(fd, pathname, &statbuf, AT_SYMLINK_NOFOLLOW) == -1) {
++ return 1;
++ }
++ if (S_ISLNK(statbuf.st_mode)) {
++ if (fstatat(fd, pathname, &statbuf, 0) == -1) return 1;
+
-+#define POSIX_CLOSE_RESTART 0
-+#endif
++ if (S_ISDIR(statbuf.st_mode)) return 0;
++ else {
++ errno = ENOTDIR;
++ return -1;
++ }
++ }
++ return 1;
++}
+
- ssize_t read(int, void *, size_t);
- ssize_t write(int, const void *, size_t);
- ssize_t pread(int, void *, size_t, off_t);
-@@ -200,8 +207,6 @@ int eaccess(const char *, int);
- #define off64_t off_t
- #endif
-
--#define POSIX_CLOSE_RESTART 0
--
- #define _XOPEN_VERSION 700
- #define _XOPEN_UNIX 1
- #define _XOPEN_ENH_I18N 1
-diff --git a/src/misc/forkpty.c b/src/misc/forkpty.c
-index caf13adb..047eb7d6 100644
---- a/src/misc/forkpty.c
-+++ b/src/misc/forkpty.c
-@@ -1,3 +1,4 @@
-+#define _GNU_SOURCE
- #include <pty.h>
- #include <utmp.h>
- #include <unistd.h>
-diff --git a/src/misc/wordexp.c b/src/misc/wordexp.c
-index db83a69f..1ae03f9f 100644
---- a/src/misc/wordexp.c
-+++ b/src/misc/wordexp.c
-@@ -1,3 +1,4 @@
-+#define _GNU_SOURCE
- #include <wordexp.h>
- #include <unistd.h>
- #include <stdio.h>
-diff --git a/src/stdio/popen.c b/src/stdio/popen.c
-index 92cb57ee..1ff9e0d9 100644
---- a/src/stdio/popen.c
-+++ b/src/stdio/popen.c
-@@ -1,3 +1,4 @@
-+#define _GNU_SOURCE
- #include <fcntl.h>
- #include <unistd.h>
- #include <errno.h>
-diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c
-index 76bbd4c7..d5e70608 100644
---- a/src/unistd/faccessat.c
-+++ b/src/unistd/faccessat.c
-@@ -1,3 +1,4 @@
-+#define _GNU_SOURCE
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/wait.h>
+ int renameat(int oldfd, const char *old, int newfd, const char *new)
+ {
+-#ifdef SYS_renameat
++ char old_copy[PATH_MAX+1], new_copy[PATH_MAX+1];
++ char *base;
++ size_t old_size, new_size;
++ struct stat oldstat, newstat;
++ int r;
++
++ if ((old_size = strlen(old)) > PATH_MAX || \
++ (new_size = strlen(new)) > PATH_MAX) {
++ errno = ENAMETOOLONG;
++ return -1;
++ }
++
++ if (old_size == 0 || new_size == 0) {
++ errno = ENOENT;
++ return -1;
++ }
++
++ /* Test equality of old and new.
++ If they both resolve to the same dentry, we do nothing. */
++ if (fstatat(oldfd, old, &oldstat, AT_SYMLINK_NOFOLLOW) == 0 && \
++ fstatat(newfd, new, &newstat, AT_SYMLINK_NOFOLLOW) == 0 && \
++ oldstat.st_dev == newstat.st_dev && \
++ oldstat.st_ino == newstat.st_ino) return 0;
++
++ strcpy(old_copy, old);
++ strcpy(new_copy, new);
++
++ base = basename(old_copy);
++ strncpy(old_copy, base, sizeof(old_copy));
++ base = basename(new_copy);
++ strncpy(new_copy, base, sizeof(new_copy));
++
++ if (strcmp(old_copy, ".") == 0 || strcmp(old_copy, "..") == 0 ||
++ strcmp(new_copy, ".") == 0 || strcmp(new_copy, "..") == 0) {
++ errno = EINVAL;
++ return -1;
++ }
++
++ /* The Linux kernel will fail when attempting to rename a symlink of a
++ directory with a trailing slash. We therefore have to handle this
++ case ourselves. */
++ if (old[old_size - 1] == '/') {
++ /* Calling stat(2) on a symlink to a dir with the trailing
++ slash causes stat(2) to return the actual directory instead
++ of the symlink itself. */
++ strcpy(old_copy, old);
++ old_copy[old_size - 1] = '\0';
++ r = test_symlink_dirness(oldfd, old_copy);
++ if (r == 0) old = old_copy;
++ else if (r == -1) return -1;
++ }
++
++ if (new[new_size - 1] == '/') {
++ strcpy(new_copy, new);
++ new_copy[new_size - 1] = '\0';
++ r = test_symlink_dirness(newfd, new_copy);
++ if (r == 0) new = new_copy;
++ else if (r == -1) return -1;
++ }
++
+ return syscall(SYS_renameat, oldfd, old, newfd, new);
+-#else
+- return syscall(SYS_renameat2, oldfd, old, newfd, new, 0);
+-#endif
+ }
diff --git a/system/musl/handle-aux-at_base.patch b/system/musl/handle-aux-at_base.patch
index c16463824..697c82bbb 100644
--- a/system/musl/handle-aux-at_base.patch
+++ b/system/musl/handle-aux-at_base.patch
@@ -2,7 +2,7 @@ diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
index b125eb1..616c6a6 100644
--- a/src/env/__init_tls.c
+++ b/src/env/__init_tls.c
-@@ -66,8 +66,10 @@ void *__copy_tls(unsigned char *mem)
+@@ -72,8 +72,10 @@ void *__copy_tls(unsigned char *mem)
}
#if ULONG_MAX == 0xffffffff
@@ -13,7 +13,7 @@ index b125eb1..616c6a6 100644
typedef Elf64_Phdr Phdr;
#endif
-@@ -77,15 +79,23 @@ extern const size_t _DYNAMIC[];
+@@ -82,15 +84,23 @@ extern const size_t _DYNAMIC[];
static void static_init_tls(size_t *aux)
{
unsigned char *p;
diff --git a/system/musl/powerpc-wchar_t.patch b/system/musl/powerpc-wchar_t.patch
deleted file mode 100644
index 62b24a5f1..000000000
--- a/system/musl/powerpc-wchar_t.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 0da9cc40f861293db7baba3854b44d73658b168d Mon Sep 17 00:00:00 2001
-From: q66 <daniel@octaforge.org>
-Date: Wed, 22 May 2019 13:18:53 +0200
-Subject: [PATCH] properly deal with wchar_t definition on 32-bit powerpc
-
-Clang defines it to be int, gcc defines it to be long. The old
-code results in conflicts when building things with clang. This
-same change is already incorporated for i386 in musl upstream,
-so apply it to powerpc as well.
-
-diff --git a/arch/powerpc/bits/alltypes.h.in b/arch/powerpc/bits/alltypes.h.in
---- a/arch/powerpc/bits/alltypes.h.in
-+++ b/arch/powerpc/bits/alltypes.h.in
-@@ -6,8 +6,12 @@ TYPEDEF __builtin_va_list va_list;
- TYPEDEF __builtin_va_list __isoc_va_list;
-
- #ifndef __cplusplus
-+#ifdef __WCHAR_TYPE__
-+TYPEDEF __WCHAR_TYPE__ wchar_t;
-+#else
- TYPEDEF long wchar_t;
- #endif
-+#endif
-
- TYPEDEF float float_t;
- TYPEDEF double double_t;
diff --git a/system/musl/ppc-hwcap.patch b/system/musl/ppc-hwcap.patch
new file mode 100644
index 000000000..3ebd5c42b
--- /dev/null
+++ b/system/musl/ppc-hwcap.patch
@@ -0,0 +1,36 @@
+From 2c788798c1f625c42e844311f5a5d2e19707d581 Mon Sep 17 00:00:00 2001
+From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
+Date: Fri, 3 Jan 2025 13:36:33 -0600
+Subject: [PATCH] powerpc: Update HWCAP bits for Power10
+
+Linux kernel commit ee988c11acf6f9464b7b44e9a091bf6afb3b3a49 added two
+new HWCAP bits: one for ARCH_3_1, which is the Power10 ISA revision, and
+one for MMA, which is the optional Matrix Multiply Assist extension.
+---
+ arch/powerpc/bits/hwcap.h | 2 ++
+ arch/powerpc64/bits/hwcap.h | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/arch/powerpc/bits/hwcap.h b/arch/powerpc/bits/hwcap.h
+index 803de9b5..12981623 100644
+--- a/arch/powerpc/bits/hwcap.h
++++ b/arch/powerpc/bits/hwcap.h
+@@ -41,3 +41,5 @@
+ #define PPC_FEATURE2_DARN 0x00200000
+ #define PPC_FEATURE2_SCV 0x00100000
+ #define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000
++#define PPC_FEATURE2_ARCH_3_1 0x00040000
++#define PPC_FEATURE2_MMA 0x00020000
+diff --git a/arch/powerpc64/bits/hwcap.h b/arch/powerpc64/bits/hwcap.h
+index 803de9b5..12981623 100644
+--- a/arch/powerpc64/bits/hwcap.h
++++ b/arch/powerpc64/bits/hwcap.h
+@@ -41,3 +41,5 @@
+ #define PPC_FEATURE2_DARN 0x00200000
+ #define PPC_FEATURE2_SCV 0x00100000
+ #define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000
++#define PPC_FEATURE2_ARCH_3_1 0x00040000
++#define PPC_FEATURE2_MMA 0x00020000
+--
+2.40.0
+
diff --git a/system/musl/realpath.patch b/system/musl/realpath.patch
new file mode 100644
index 000000000..25d685918
--- /dev/null
+++ b/system/musl/realpath.patch
@@ -0,0 +1,37 @@
+From 99b84a793669c69acc705a61d339441b50bd09a8 Mon Sep 17 00:00:00 2001
+From: Natanael Copa <ncopa@alpinelinux.org>
+Date: Wed, 13 Jan 2021 14:28:35 +0100
+Subject: [PATCH] realpath: replace leading // with a single /
+
+On some systems a leading double slash may have special meaning, so
+POSIX[1] says that "If a pathname begins with two successive <slash>
+characters, the first component following the leading <slash> characters
+may be interpreted in an implementation-defined manner"
+
+While current musl implementation is technically correct, most other
+systems' (at least GNU libc, freebsd, openbsd, netbsd macOS)
+implementations will replace a leading // with a single /. Make musl
+do the same to avoid surprises.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
+---
+ src/misc/realpath.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/src/misc/realpath.c b/src/misc/realpath.c
+index db8b74dc..414b4741 100644
+--- a/src/misc/realpath.c
++++ b/src/misc/realpath.c
+@@ -46,9 +46,6 @@ restart:
+ q=0;
+ output[q++] = '/';
+ p++;
+- /* Initial // is special. */
+- if (stack[p] == '/' && stack[p+1] != '/')
+- output[q++] = '/';
+ continue;
+ }
+
+--
+2.29.2
+
diff --git a/system/musl/signed-wchar_t-fixes.patch b/system/musl/signed-wchar_t-fixes.patch
new file mode 100644
index 000000000..0d5309315
--- /dev/null
+++ b/system/musl/signed-wchar_t-fixes.patch
@@ -0,0 +1,77 @@
+From 99b84a793669c69acc705a61d339441b50bd09a8 Mon Sep 17 00:00:00 2001
+From: Gabriel Ravier <gabravier@gmail.com>
+Date: Wed, 4 Jan 2023 16:07:19 +0100
+Subject: [PATCH] fix return value of wcs{,n}cmp for near-limits signed wchar_t values
+
+The standard states that:
+
+ > Unless explicitly stated otherwise, the functions described in
+ this subclause order two wide characters the same way as two
+ integers of the underlying integer type designated by `wchar_t`.
+ > [...]
+ > The `wcscmp` function returns an integer greater than, equal to,
+ or less than zero, accordingly as the wide string pointed to by s1
+ is greater than, equal to, or less than the wide string pointed to
+ by s2.
+ > The `wcsncmp` function returns an integer greater than, equal to,
+ or less than zero, accordingly as the possibly null-terminated
+ array pointed to by s1 is greater than, equal to, or less than the
+ possibly null-terminated array pointed to by s2
+ - N3047 (latest C draft as of the time of writing)
+
+Yet a simple test program such as this:
+
+ #include <wchar.h>
+ #include <stdio.h>
+
+ int main()
+ {
+ wchar_t str1[2] = { WCHAR_MAX, L'\0' };
+ wchar_t str2[2] = { WCHAR_MIN, L'\0' };
+
+ printf("%d\n", wcscmp(str1, str2));
+ printf("%d\n", wcsncmp(str1, str2, 1));
+ }
+
+Will fail to run correctly according to this specification on musl (on
+targets that have signed wchar_t), as it will print -1 instead of
+1 (it should print 1, since WCHAR_MAX > WCHAR_MIN).
+
+This appears to be due to the fact that musl uses a simple subtraction
+to implement wcscmp and wcsncmp, which may result in an overflow.
+
+This patch fixes this by replacing the subtraction with a little bit
+of code that orders the characters correctly, returning -1 if the
+character from the first string is smaller than the one from the
+second, 0 if they are equal and 1 if the character from the first
+string is larger than the one from the second
+---
+ src/string/wcscmp.c | 2 +-
+ src/string/wcsncmp.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/string/wcscmp.c b/src/string/wcscmp.c
+index 26eeee70..286ec3ea 100644
+--- a/src/string/wcscmp.c
++++ b/src/string/wcscmp.c
+@@ -3,5 +3,5 @@
+ int wcscmp(const wchar_t *l, const wchar_t *r)
+ {
+ for (; *l==*r && *l && *r; l++, r++);
+- return *l - *r;
++ return *l < *r ? -1 : *l > *r;
+ }
+diff --git a/src/string/wcsncmp.c b/src/string/wcsncmp.c
+index 4ab32a92..2b3558bf 100644
+--- a/src/string/wcsncmp.c
++++ b/src/string/wcsncmp.c
+@@ -3,5 +3,5 @@
+ int wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)
+ {
+ for (; n && *l==*r && *l && *r; n--, l++, r++);
+- return n ? *l - *r : 0;
++ return n ? (*l < *r ? -1 : *l > *r) : 0;
+ }
+--
+2.38.1
+
diff --git a/system/musl/strftime-add-l-support.patch b/system/musl/strftime-add-l-support.patch
deleted file mode 100644
index 8305a9910..000000000
--- a/system/musl/strftime-add-l-support.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 481def0e92ebfe81f40f416ddf345de15647e46b Mon Sep 17 00:00:00 2001
-From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
-Date: Fri, 31 May 2019 19:03:20 -0500
-Subject: [PATCH] strftime: add %l support
-
----
- src/time/strftime.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/src/time/strftime.c b/src/time/strftime.c
-index cc53d536..98caa1f6 100644
---- a/src/time/strftime.c
-+++ b/src/time/strftime.c
-@@ -95,6 +95,8 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *
- case 'H':
- val = tm->tm_hour;
- goto number;
-+ case 'l':
-+ def_pad = ' ';
- case 'I':
- val = tm->tm_hour;
- if (!val) val = 12;
---
-2.21.0
-
diff --git a/system/musl/x87-math.patch b/system/musl/x87-math.patch
deleted file mode 100644
index d21be43b3..000000000
--- a/system/musl/x87-math.patch
+++ /dev/null
@@ -1,157 +0,0 @@
-diff --git a/src/math/i386/asin.s b/src/math/i386/asin.s
-index a9f691bf..920d967a 100644
---- a/src/math/i386/asin.s
-+++ b/src/math/i386/asin.s
-@@ -7,13 +7,10 @@ asinf:
- cmp $0x01000000,%eax
- jae 1f
- # subnormal x, return x with underflow
-- fnstsw %ax
-- and $16,%ax
-- jnz 2f
- fld %st(0)
- fmul %st(1)
- fstps 4(%esp)
--2: ret
-+ ret
-
- .global asinl
- .type asinl,@function
-@@ -30,11 +27,8 @@ asin:
- cmp $0x00200000,%eax
- jae 1f
- # subnormal x, return x with underflow
-- fnstsw %ax
-- and $16,%ax
-- jnz 2f
- fsts 4(%esp)
--2: ret
-+ ret
- 1: fld %st(0)
- fld1
- fsub %st(0),%st(1)
-diff --git a/src/math/i386/atan.s b/src/math/i386/atan.s
-index d73137b2..a26feae1 100644
---- a/src/math/i386/atan.s
-+++ b/src/math/i386/atan.s
-@@ -10,8 +10,5 @@ atan:
- fpatan
- ret
- # subnormal x, return x with underflow
--1: fnstsw %ax
-- and $16,%ax
-- jnz 2f
-- fsts 4(%esp)
--2: ret
-+1: fsts 4(%esp)
-+ ret
-diff --git a/src/math/i386/atan2.s b/src/math/i386/atan2.s
-index a7d2979b..76b95f31 100644
---- a/src/math/i386/atan2.s
-+++ b/src/math/i386/atan2.s
-@@ -10,8 +10,5 @@ atan2:
- cmp $0x00200000,%eax
- jae 1f
- # subnormal x, return x with underflow
-- fnstsw %ax
-- and $16,%ax
-- jnz 1f
- fsts 4(%esp)
- 1: ret
-diff --git a/src/math/i386/atan2f.s b/src/math/i386/atan2f.s
-index 14b88ce5..c9408a90 100644
---- a/src/math/i386/atan2f.s
-+++ b/src/math/i386/atan2f.s
-@@ -10,9 +10,6 @@ atan2f:
- cmp $0x01000000,%eax
- jae 1f
- # subnormal x, return x with underflow
-- fnstsw %ax
-- and $16,%ax
-- jnz 1f
- fld %st(0)
- fmul %st(1)
- fstps 4(%esp)
-diff --git a/src/math/i386/atanf.s b/src/math/i386/atanf.s
-index 8caddefa..893beac5 100644
---- a/src/math/i386/atanf.s
-+++ b/src/math/i386/atanf.s
-@@ -10,10 +10,7 @@ atanf:
- fpatan
- ret
- # subnormal x, return x with underflow
--1: fnstsw %ax
-- and $16,%ax
-- jnz 2f
-- fld %st(0)
-+1: fld %st(0)
- fmul %st(1)
- fstps 4(%esp)
--2: ret
-+ ret
-diff --git a/src/math/i386/exp.s b/src/math/i386/exp.s
-index c7aa5b6e..df87c497 100644
---- a/src/math/i386/exp.s
-+++ b/src/math/i386/exp.s
-@@ -7,13 +7,10 @@ expm1f:
- cmp $0x01000000,%eax
- jae 1f
- # subnormal x, return x with underflow
-- fnstsw %ax
-- and $16,%ax
-- jnz 2f
- fld %st(0)
- fmul %st(1)
- fstps 4(%esp)
--2: ret
-+ ret
-
- .global expm1l
- .type expm1l,@function
-@@ -30,11 +27,8 @@ expm1:
- cmp $0x00200000,%eax
- jae 1f
- # subnormal x, return x with underflow
-- fnstsw %ax
-- and $16,%ax
-- jnz 2f
- fsts 4(%esp)
--2: ret
-+ ret
- 1: fldl2e
- fmulp
- mov $0xc2820000,%eax
-diff --git a/src/math/i386/log1p.s b/src/math/i386/log1p.s
-index 6b6929c7..354f391a 100644
---- a/src/math/i386/log1p.s
-+++ b/src/math/i386/log1p.s
-@@ -16,9 +16,6 @@ log1p:
- fyl2x
- ret
- # subnormal x, return x with underflow
--2: fnstsw %ax
-- and $16,%ax
-- jnz 1f
-- fsts 4(%esp)
-+2: fsts 4(%esp)
- fstp %st(1)
--1: ret
-+ ret
-diff --git a/src/math/i386/log1pf.s b/src/math/i386/log1pf.s
-index c0bcd30f..4d3484cd 100644
---- a/src/math/i386/log1pf.s
-+++ b/src/math/i386/log1pf.s
-@@ -16,10 +16,7 @@ log1pf:
- fyl2x
- ret
- # subnormal x, return x with underflow
--2: fnstsw %ax
-- and $16,%ax
-- jnz 1f
-- fxch
-+2: fxch
- fmul %st(1)
- fstps 4(%esp)
--1: ret
-+ ret
-