From ca6f46aff1fc89c3d06ff9e85ab8c7871a695924 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 1 Mar 2024 15:49:58 -0500 Subject: [PATCH 001/115] iconv: add euro symbol to GBK as single byte 0x80 this is how it's defined in the cp936 document referenced by the IANA charset registry as defining GBK, and of the mappings defined there, was the only one missing. it is not accepted for GB18030, as GB18030 is a UTF and has its own unique mapping for the euro symbol. --- src/locale/iconv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/locale/iconv.c b/src/locale/iconv.c index 175def1c..0b2d0016 100644 --- a/src/locale/iconv.c +++ b/src/locale/iconv.c @@ -403,6 +403,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri if (c < 128) break; if (c < 0xa1) goto ilseq; case GBK: + if (c == 128) { + c = 0x20ac; + break; + } case GB18030: if (c < 128) break; c -= 0x81; From b5121e2ed88504c7186569f1fd6f96a63b7151ca Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 1 Mar 2024 16:04:48 -0500 Subject: [PATCH 002/115] iconv: add aliases for GBK these are taken from the IANA registry, restricted to those that match the forms already used for other supported character encodings. --- 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 0b2d0016..4b7967a7 100644 --- a/src/locale/iconv.c +++ b/src/locale/iconv.c @@ -52,7 +52,7 @@ static const unsigned char charmaps[] = "shiftjis\0sjis\0cp932\0\0\321" "iso2022jp\0\0\322" "gb18030\0\0\330" -"gbk\0\0\331" +"gbk\0cp936\0windows936\0\0\331" "gb2312\0\0\332" "big5\0bigfive\0cp950\0big5hkscs\0\0\340" "euckr\0ksc5601\0ksx1001\0cp949\0\0\350" From fd7d018521115f2674bf85cbccaf745852b9ed3a Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 2 Mar 2024 12:34:05 -0500 Subject: [PATCH 003/115] add missing inline keyword on default a_barrier definition this is not needed, but may act as a hint to the compiler, and also serves to suppress unused function warnings if enabled (on by default since commit 86ac0f794731f03dfff40ee843ff9e2752945d5e). --- src/internal/atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/atomic.h b/src/internal/atomic.h index 96c1552d..8f71c8cd 100644 --- a/src/internal/atomic.h +++ b/src/internal/atomic.h @@ -194,7 +194,7 @@ static inline void a_store(volatile int *p, int v) #ifndef a_barrier #define a_barrier a_barrier -static void a_barrier() +static inline void a_barrier() { volatile int tmp = 0; a_cas(&tmp, 0, 0); From 7ada6dde6f9dc6a2836c3d92c2f762d35fd229e0 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 2 Mar 2024 15:01:18 -0500 Subject: [PATCH 004/115] iconv: fix missing bounds checking for shift_jis decoding the jis0208 table we use is only 84x94 in size, but the shift_jis encoding supports a 94x94 grid. attempts to convert sequences outside of the supported zone resulted in out-of-bounds table reads, misinterpreting adjacent rodata as part of the character table and thereby converting these sequences to unexpected characters. --- src/locale/iconv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/locale/iconv.c b/src/locale/iconv.c index 4b7967a7..7fb2e1ef 100644 --- a/src/locale/iconv.c +++ b/src/locale/iconv.c @@ -340,6 +340,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri c++; d -= 159; } + if (c>=84) goto ilseq; c = jis0208[c][d]; if (!c) goto ilseq; break; From bdc9a9ff6f95e5d527e1660e44ebd059e6ca8acf Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 13 Mar 2024 10:39:37 -0400 Subject: [PATCH 005/115] uio.h: add RWF_NOAPPEND flag for pwritev2 added in linux kernel commit 73fa7547c70b32cc69685f79be31135797734eb6. this is added now as a prerequisite for fixing pwrite/pwritev behavior for O_APPEND files. --- include/sys/uio.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/sys/uio.h b/include/sys/uio.h index 8b5e3de7..5e99c7fa 100644 --- a/include/sys/uio.h +++ b/include/sys/uio.h @@ -46,6 +46,7 @@ ssize_t pwritev2 (int, const struct iovec *, int, off_t, int); #define RWF_SYNC 0x00000004 #define RWF_NOWAIT 0x00000008 #define RWF_APPEND 0x00000010 +#define RWF_NOAPPEND 0x00000020 #endif #ifdef __cplusplus From 5370070fded61b569196764673a4fc8440aac79e Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 13 Mar 2024 10:47:42 -0400 Subject: [PATCH 006/115] fix pwrite/pwritev handling of O_APPEND files POSIX requires pwrite to honor the explicit file offset where the write should take place even if the file was opened as O_APPEND. however, linux historically defined the pwrite syscall family as honoring O_APPEND. this cannot be changed on the kernel side due to stability policy, but the addition of the pwritev2 syscall with a flags argument opened the door to fixing it, and linux commit 73fa7547c70b32cc69685f79be31135797734eb6 adds the RWF_NOAPPEND flag that lets us request a write honoring the file offset argument. this patch changes the pwrite function to first attempt using the pwritev2 syscall with RWF_NOAPPEND, falling back to using the old pwrite syscall only after checking that O_APPEND is not set for the open file. if O_APPEND is set, the operation fails with EOPNOTSUPP, reflecting that the kernel does not support the correct behavior. this is an extended error case needed to avoid the wrong behavior that happened before (writing the data at the wrong location), and is aligned with the spirit of the POSIX requirement that "An attempt to perform a pwrite() on a file that is incapable of seeking shall result in an error." since the pwritev2 syscall interprets the offset of -1 as a request to write at the current file offset, it is mapped to a different negative value that will produce the expected error. pwritev, though not governed by POSIX at this time, is adjusted to match pwrite in honoring the offset. --- src/unistd/pwrite.c | 11 +++++++++++ src/unistd/pwritev.c | 10 +++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/unistd/pwrite.c b/src/unistd/pwrite.c index 869b69f0..a008b3ec 100644 --- a/src/unistd/pwrite.c +++ b/src/unistd/pwrite.c @@ -1,7 +1,18 @@ +#define _GNU_SOURCE #include +#include +#include #include "syscall.h" ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) { + if (ofs == -1) ofs--; + int r = __syscall_cp(SYS_pwritev2, fd, + (&(struct iovec){ .iov_base = (void *)buf, .iov_len = size }), + 1, (long)(ofs), (long)(ofs>>32), RWF_NOAPPEND); + if (r != -EOPNOTSUPP && r != -ENOSYS) + return __syscall_ret(r); + if (fcntl(fd, F_GETFL) & O_APPEND) + return __syscall_ret(-EOPNOTSUPP); return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs)); } diff --git a/src/unistd/pwritev.c b/src/unistd/pwritev.c index becf9deb..44a53d85 100644 --- a/src/unistd/pwritev.c +++ b/src/unistd/pwritev.c @@ -1,10 +1,18 @@ -#define _BSD_SOURCE +#define _GNU_SOURCE #include #include +#include #include "syscall.h" ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs) { + if (ofs == -1) ofs--; + int r = __syscall_cp(SYS_pwritev2, fd, iov, count, + (long)(ofs), (long)(ofs>>32), RWF_NOAPPEND); + if (r != -EOPNOTSUPP && r != -ENOSYS) + return __syscall_ret(r); + if (fcntl(fd, F_GETFL) & O_APPEND) + return __syscall_ret(-EOPNOTSUPP); return syscall_cp(SYS_pwritev, fd, iov, count, (long)(ofs), (long)(ofs>>32)); } From 9683bd62414604d3bd56cf6bd7be8f54aa31e7d3 Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Thu, 14 Mar 2024 00:57:15 +0100 Subject: [PATCH 007/115] math: fix fma(x,y,0) when x*y rounds to -0 if x!=0, y!=0, z==0 then fma(x,y,z) == x*y in all rounding modes, while adding z can ruin the sign of 0 if x*y rounds to -0. --- src/math/fma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/math/fma.c b/src/math/fma.c index 0c6f90c9..adfadca8 100644 --- a/src/math/fma.c +++ b/src/math/fma.c @@ -53,7 +53,7 @@ double fma(double x, double y, double z) return x*y + z; if (nz.e >= ZEROINFNAN) { if (nz.e > ZEROINFNAN) /* z==0 */ - return x*y + z; + return x*y; return z; } From e3b0ace505155b6b8e301d69924b0773fd82cb6e Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Sun, 10 Mar 2024 21:00:40 +0100 Subject: [PATCH 008/115] complex: fix comment in cacosh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The principal expressions defining acosh and acos are such that acosh(z) = ±i acos(z) where the + is only true on the Im(z)>0 half of the complex plane (and partly on Im(z)==0 depending on number representation). fix the comment without expanding on the details. --- src/complex/cacosh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/complex/cacosh.c b/src/complex/cacosh.c index 76127f75..55b857ce 100644 --- a/src/complex/cacosh.c +++ b/src/complex/cacosh.c @@ -1,6 +1,6 @@ #include "complex_impl.h" -/* acosh(z) = i acos(z) */ +/* acosh(z) = ±i acos(z) */ double complex cacosh(double complex z) { From 24ebbbdedcf626808a902d8797df239f94af9620 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 12 Apr 2024 19:57:59 -0400 Subject: [PATCH 009/115] printf: fix edge case where hex float precision was not honored commit cfa0a54c082d41db6446638eed1d57f163434092 attempted to fix rounding on archs where long double is not 80-bit (where LDBL_MANT_DIG is not zero mod four), but failed to address the edge case where rounding was skipped because LDBL_MANT_DIG/4 rounded down in the comparison against the requested precision. the rounding logic based on hex digit count is difficult to understand and not well-motivated, so rather than try to fix it, replace it with an explicit calculation in terms of number of bits to be kept, without any truncating division operations. based on patch by Peter Ammon, but with scalbn to apply the rounding exponent since the value will not generally fit in any integer type. scalbn is used instead of scalbnl to avoid pulling in the latter unnecessarily, since the value is an exact power of two whose exponent range is bounded by LDBL_MANT_DIG, a small integer. --- src/stdio/vfprintf.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index 497c5e19..dc648e7e 100644 --- a/src/stdio/vfprintf.c +++ b/src/stdio/vfprintf.c @@ -211,18 +211,11 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) if (y) e2--; if ((t|32)=='a') { - long double round = 8.0; - int re; - if (t&32) prefix += 9; pl += 2; - if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0; - else re=LDBL_MANT_DIG/4-1-p; - - if (re) { - round *= 1<<(LDBL_MANT_DIG%4); - while (re--) round*=16; + if (p>=0 && p<(LDBL_MANT_DIG-1+3)/4) { + double round = scalbn(1, LDBL_MANT_DIG-1-(p*4)); if (*prefix=='-') { y=-y; y-=round; From 3f49203c55ccd5d4217abf13addb18844136455f Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 13 Apr 2024 12:15:37 -0400 Subject: [PATCH 010/115] initgroups: do not artificially limit number of supplementary groups historically linux limited the number of supplementary groups a process could be in to 32, but this limit was raised to 65536 in linux 2.6.4. proposals to support the new limit, change NGROUPS_MAX, or make it dynamic have been stalled due to the impact it would have on initgroups where the groups array exists in automatic storage. the changes here decouple initgroups from the value of NGROUPS_MAX and allow it to fall back to allocating a buffer in the case where getgrouplist indicates the user has more supplementary groups than could be reported in the buffer. getgrouplist already involves allocation, so this does not pull in any new link dependency. likewise, getgrouplist is already using the public malloc (vs internal libc one), so initgroups does the same. if this turns out not to be the best choice, both can be changed together later. the initial buffer size is left at 32, but now as the literal value, so that any potential future change to NGROUPS_MAX will not affect initgroups. --- src/misc/initgroups.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/misc/initgroups.c b/src/misc/initgroups.c index 922a9581..101f5c7b 100644 --- a/src/misc/initgroups.c +++ b/src/misc/initgroups.c @@ -1,11 +1,29 @@ #define _GNU_SOURCE #include #include +#include int initgroups(const char *user, gid_t gid) { - gid_t groups[NGROUPS_MAX]; - int count = NGROUPS_MAX; - if (getgrouplist(user, gid, groups, &count) < 0) return -1; - return setgroups(count, groups); + gid_t buf[32], *groups = buf; + int count = sizeof buf / sizeof *buf, prev_count = count; + while (getgrouplist(user, gid, groups, &count) < 0) { + if (groups != buf) free(groups); + + /* Return if failure isn't buffer size */ + if (count <= prev_count) + return -1; + + /* Always increase by at least 50% to limit to + * logarithmically many retries on TOCTOU races. */ + if (count < prev_count + (prev_count>>1)) + count = prev_count + (prev_count>>1); + + groups = calloc(count, sizeof *groups); + if (!groups) return -1; + prev_count = count; + } + int ret = setgroups(count, groups); + if (groups != buf) free(groups); + return ret; } From cbf1c7b605d979bb7fdde8b8e6a66acdba18c6b0 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 24 Apr 2024 13:26:03 -0400 Subject: [PATCH 011/115] add missing STATX_ATTR_* macros omitted when statx was added commit b817541f1cfd38e4b81257b3215e276ea9d0fc61 added statx and the mask constant macros, but not the stx_attributes[_mask] ones. --- include/sys/stat.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/sys/stat.h b/include/sys/stat.h index 6690192d..57d640d7 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -121,6 +121,16 @@ int lchmod(const char *, mode_t); #define STATX_BTIME 0x800U #define STATX_ALL 0xfffU +#define STATX_ATTR_COMPRESSED 0x4 +#define STATX_ATTR_IMMUTABLE 0x10 +#define STATX_ATTR_APPEND 0x20 +#define STATX_ATTR_NODUMP 0x40 +#define STATX_ATTR_ENCRYPTED 0x800 +#define STATX_ATTR_AUTOMOUNT 0x1000 +#define STATX_ATTR_MOUNT_ROOT 0x2000 +#define STATX_ATTR_VERITY 0x100000 +#define STATX_ATTR_DAX 0x200000 + struct statx_timestamp { int64_t tv_sec; uint32_t tv_nsec, __pad; From a23cf8f9c5ab8ff1e1742a68b352e58b9febbe4a Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Sat, 20 Apr 2024 20:29:07 -0700 Subject: [PATCH 012/115] riscv mcontext_t/sigcontext: use __aligned__ instead of aligned aligned may be defined by the application for its own use before bits/signal.h is included. --- arch/riscv32/bits/signal.h | 2 +- arch/riscv64/bits/signal.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv32/bits/signal.h b/arch/riscv32/bits/signal.h index 271e7da6..50b66ec9 100644 --- a/arch/riscv32/bits/signal.h +++ b/arch/riscv32/bits/signal.h @@ -19,7 +19,7 @@ struct __riscv_mc_d_ext_state { }; struct __riscv_mc_q_ext_state { - unsigned long long __f[64] __attribute__((aligned(16))); + unsigned long long __f[64] __attribute__((__aligned__(16))); unsigned int __fcsr; unsigned int __reserved[3]; }; diff --git a/arch/riscv64/bits/signal.h b/arch/riscv64/bits/signal.h index 6a53feb7..56f8fe17 100644 --- a/arch/riscv64/bits/signal.h +++ b/arch/riscv64/bits/signal.h @@ -19,7 +19,7 @@ struct __riscv_mc_d_ext_state { }; struct __riscv_mc_q_ext_state { - unsigned long long __f[64] __attribute__((aligned(16))); + unsigned long long __f[64] __attribute__((__aligned__(16))); unsigned int __fcsr; unsigned int __reserved[3]; }; From 3f9d4224d8db7868b6c2f526746d597785d30c61 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 6 May 2024 17:13:23 -0400 Subject: [PATCH 013/115] printf decimal integer formatting: shave off one division once the remaining value is less than 10, the modulo operation to produce the final digit and division to prepare for next loop iteration can be dropped. this may be a meaningful performance distinction when formatting low-magnitude numbers in bulk, and should never hurt. based on patch by Viktor Reznov. --- src/stdio/vfprintf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index dc648e7e..360d723a 100644 --- a/src/stdio/vfprintf.c +++ b/src/stdio/vfprintf.c @@ -166,7 +166,8 @@ static char *fmt_u(uintmax_t x, char *s) { unsigned long y; for ( ; x>ULONG_MAX; x/=10) *--s = '0' + x%10; - for (y=x; y; y/=10) *--s = '0' + y%10; + for (y=x; y>=10; y/=10) *--s = '0' + y%10; + if (y) *--s = '0' + y; return s; } From fced99e93daeefb0192fd16304f978d4401d1d77 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 6 May 2024 18:40:23 -0400 Subject: [PATCH 014/115] strptime: implement conversion specifiers adopted for next POSIX issue the %s conversion is added as the outcome of Austin Group tracker issue 169 and its unspecified behavior is clarified as the outcome of issue 1727. the %F, %g, %G, %u, %V, %z, and %Z conversions are added as the outcome of Austin Group tracker issue 879 for alignment with strftime and the behaviors of %u, %z, and %Z are defined as the outcome of issue 1727. at this time, the conversions with unspecified effects on struct tm are all left as parse-only no-ops. this may be changed at a later time, particularly for %s, if there is reasonable cross-implementation consensus outside the standards process on what the behavior should be. --- src/time/strptime.c | 66 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/time/strptime.c b/src/time/strptime.c index c54a0d8c..b1147242 100644 --- a/src/time/strptime.c +++ b/src/time/strptime.c @@ -59,6 +59,22 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri s = strptime(s, "%m/%d/%y", tm); if (!s) return 0; break; + case 'F': + /* Use temp buffer to implement the odd requirement + * that entire field be width-limited but the year + * subfield not itself be limited. */ + i = 0; + char tmp[20]; + if (*s == '-' || *s == '+') tmp[i++] = *s++; + while (*s=='0' && isdigit(s[1])) s++; + for (; *s && i<(size_t)w && i+1tm_hour; min = 0; @@ -114,6 +130,13 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri s = strptime(s, "%H:%M", tm); if (!s) return 0; break; + case 's': + /* Parse only. Effect on tm is unspecified + * and presently no effect is implemented.. */ + if (*s == '-') s++; + if (!isdigit(*s)) return 0; + while (isdigit(*s)) s++; + break; case 'S': dest = &tm->tm_sec; min = 0; @@ -125,11 +148,30 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri break; case 'U': case 'W': - /* Throw away result, for now. (FIXME?) */ + /* Throw away result of %U, %V, %W, %g, and %G. Effect + * is unspecified and there is no clear right choice. */ dest = &dummy; min = 0; range = 54; goto numeric_range; + case 'V': + dest = &dummy; + min = 1; + range = 53; + goto numeric_range; + case 'g': + dest = &dummy; + w = 2; + goto numeric_digits; + case 'G': + dest = &dummy; + if (w<0) w=4; + goto numeric_digits; + case 'u': + dest = &tm->tm_wday; + min = 1; + range = 7; + goto numeric_range; case 'w': dest = &tm->tm_wday; min = 0; @@ -154,6 +196,28 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri adj = 1900; want_century = 0; goto numeric_digits; + case 'z': + if (*s == '+') neg = 0; + else if (*s == '-') neg = 1; + else return 0; + for (i=0; i<4; i++) if (!isdigit(s[1+i])) return 0; + tm->__tm_gmtoff = (s[1]-'0')*36000+(s[2]-'0')*3600 + + (s[3]-'0')*600 + (s[4]-'0')*60; + if (neg) tm->__tm_gmtoff = -tm->__tm_gmtoff; + s += 5; + break; + case 'Z': + if (!strncmp(s, tzname[0], len = strlen(tzname[0]))) { + tm->tm_isdst = 0; + s += len; + } else if (!strncmp(s, tzname[1], len=strlen(tzname[1]))) { + tm->tm_isdst = 1; + s += len; + } else { + /* FIXME: is this supposed to be an error? */ + while ((*s|32)-'a' <= 'z'-'a') s++; + } + break; case '%': if (*s++ != '%') return 0; break; From 6f666231bf51703fadbef10460d462fb573548a1 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 7 May 2024 08:18:49 -0400 Subject: [PATCH 015/115] ldso: fix non-functional fix to early dynamic PAGE_SIZE access commit f47a8cdd250d9163fcfb39bf4e9d813957c0b187 introduced an alternate mechanism for access to runtime page size for compatibility with early stages of dynamic linking, but because pthread_impl.h indirectly includes libc.h, the condition #ifndef PAGE_SIZE was never satisfied. rather than depend on order of inclusion, use the (baseline POSIX) macro PAGESIZE, not the (XSI) macro PAGE_SIZE, to determine whether page size is dynamic. our internal libc.h only provides a dynamic definition for PAGE_SIZE, not for PAGESIZE. --- ldso/dynlink.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 324aa859..42687da2 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -21,15 +21,17 @@ #include #include "pthread_impl.h" #include "fork_impl.h" +#include "libc.h" #include "dynlink.h" static size_t ldso_page_size; -#ifndef PAGE_SIZE +/* libc.h may have defined a macro for dynamic PAGE_SIZE already, but + * PAGESIZE is only defined if it's constant for the arch. */ +#ifndef PAGESIZE +#undef PAGE_SIZE #define PAGE_SIZE ldso_page_size #endif -#include "libc.h" - #define malloc __libc_malloc #define calloc __libc_calloc #define realloc __libc_realloc From ef600888d2916a2c7b7f2ec3bfa1e18997121b12 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 7 May 2024 08:55:55 -0400 Subject: [PATCH 016/115] align aarch64, riscv64, loongarch64 stat structure padding type this change is purely to document that they are the same in preparation to remove the arch-specific headers for these archs and replace them with a generic version that matches riscv32 and can be shared by these and all future archs. --- arch/aarch64/bits/stat.h | 2 +- arch/loongarch64/bits/stat.h | 2 +- arch/riscv64/bits/stat.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/aarch64/bits/stat.h b/arch/aarch64/bits/stat.h index b7f4221b..f6d9e864 100644 --- a/arch/aarch64/bits/stat.h +++ b/arch/aarch64/bits/stat.h @@ -6,7 +6,7 @@ struct stat { uid_t st_uid; gid_t st_gid; dev_t st_rdev; - unsigned long __pad; + unsigned long long __pad; off_t st_size; blksize_t st_blksize; int __pad2; diff --git a/arch/loongarch64/bits/stat.h b/arch/loongarch64/bits/stat.h index b7f4221b..f6d9e864 100644 --- a/arch/loongarch64/bits/stat.h +++ b/arch/loongarch64/bits/stat.h @@ -6,7 +6,7 @@ struct stat { uid_t st_uid; gid_t st_gid; dev_t st_rdev; - unsigned long __pad; + unsigned long long __pad; off_t st_size; blksize_t st_blksize; int __pad2; diff --git a/arch/riscv64/bits/stat.h b/arch/riscv64/bits/stat.h index b7f4221b..f6d9e864 100644 --- a/arch/riscv64/bits/stat.h +++ b/arch/riscv64/bits/stat.h @@ -6,7 +6,7 @@ struct stat { uid_t st_uid; gid_t st_gid; dev_t st_rdev; - unsigned long __pad; + unsigned long long __pad; off_t st_size; blksize_t st_blksize; int __pad2; From 0dfa1d8caadb7b308740d7695b592c207bfad543 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 7 May 2024 08:58:45 -0400 Subject: [PATCH 017/115] unify bits/stat.h for all archs sharing a common definition future archs should not define their own bits/stat.h but use this generic one. --- arch/{aarch64 => generic}/bits/stat.h | 0 arch/loongarch64/bits/stat.h | 18 ------------------ arch/riscv32/bits/stat.h | 18 ------------------ arch/riscv64/bits/stat.h | 18 ------------------ 4 files changed, 54 deletions(-) rename arch/{aarch64 => generic}/bits/stat.h (100%) delete mode 100644 arch/loongarch64/bits/stat.h delete mode 100644 arch/riscv32/bits/stat.h delete mode 100644 arch/riscv64/bits/stat.h diff --git a/arch/aarch64/bits/stat.h b/arch/generic/bits/stat.h similarity index 100% rename from arch/aarch64/bits/stat.h rename to arch/generic/bits/stat.h diff --git a/arch/loongarch64/bits/stat.h b/arch/loongarch64/bits/stat.h deleted file mode 100644 index f6d9e864..00000000 --- a/arch/loongarch64/bits/stat.h +++ /dev/null @@ -1,18 +0,0 @@ -struct stat { - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - unsigned long long __pad; - off_t st_size; - blksize_t st_blksize; - int __pad2; - blkcnt_t st_blocks; - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - unsigned __unused[2]; -}; diff --git a/arch/riscv32/bits/stat.h b/arch/riscv32/bits/stat.h deleted file mode 100644 index f6d9e864..00000000 --- a/arch/riscv32/bits/stat.h +++ /dev/null @@ -1,18 +0,0 @@ -struct stat { - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - unsigned long long __pad; - off_t st_size; - blksize_t st_blksize; - int __pad2; - blkcnt_t st_blocks; - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - unsigned __unused[2]; -}; diff --git a/arch/riscv64/bits/stat.h b/arch/riscv64/bits/stat.h deleted file mode 100644 index f6d9e864..00000000 --- a/arch/riscv64/bits/stat.h +++ /dev/null @@ -1,18 +0,0 @@ -struct stat { - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - unsigned long long __pad; - off_t st_size; - blksize_t st_blksize; - int __pad2; - blkcnt_t st_blocks; - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - unsigned __unused[2]; -}; From 29b216b2f22d3341c4c00608d7ad554a6aed26f7 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 7 May 2024 09:01:47 -0400 Subject: [PATCH 018/115] unistd.h: derive ILP32/LP64 macros from __LONG_MAX instead of arch bits --- arch/aarch64/bits/posix.h | 2 -- arch/arm/bits/posix.h | 2 -- arch/i386/bits/posix.h | 2 -- arch/loongarch64/bits/posix.h | 2 -- arch/m68k/bits/posix.h | 2 -- arch/microblaze/bits/posix.h | 2 -- arch/mips/bits/posix.h | 2 -- arch/mips64/bits/posix.h | 2 -- arch/mipsn32/bits/posix.h | 2 -- arch/or1k/bits/posix.h | 2 -- arch/powerpc/bits/posix.h | 2 -- arch/powerpc64/bits/posix.h | 2 -- arch/riscv32/bits/posix.h | 2 -- arch/riscv64/bits/posix.h | 2 -- arch/s390x/bits/posix.h | 2 -- arch/sh/bits/posix.h | 2 -- arch/x32/bits/posix.h | 2 -- arch/x86_64/bits/posix.h | 2 -- include/unistd.h | 8 +++++++- 19 files changed, 7 insertions(+), 37 deletions(-) delete mode 100644 arch/aarch64/bits/posix.h delete mode 100644 arch/arm/bits/posix.h delete mode 100644 arch/i386/bits/posix.h delete mode 100644 arch/loongarch64/bits/posix.h delete mode 100644 arch/m68k/bits/posix.h delete mode 100644 arch/microblaze/bits/posix.h delete mode 100644 arch/mips/bits/posix.h delete mode 100644 arch/mips64/bits/posix.h delete mode 100644 arch/mipsn32/bits/posix.h delete mode 100644 arch/or1k/bits/posix.h delete mode 100644 arch/powerpc/bits/posix.h delete mode 100644 arch/powerpc64/bits/posix.h delete mode 100644 arch/riscv32/bits/posix.h delete mode 100644 arch/riscv64/bits/posix.h delete mode 100644 arch/s390x/bits/posix.h delete mode 100644 arch/sh/bits/posix.h delete mode 100644 arch/x32/bits/posix.h delete mode 100644 arch/x86_64/bits/posix.h diff --git a/arch/aarch64/bits/posix.h b/arch/aarch64/bits/posix.h deleted file mode 100644 index c37b94c1..00000000 --- a/arch/aarch64/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_LP64_OFF64 1 -#define _POSIX_V7_LP64_OFF64 1 diff --git a/arch/arm/bits/posix.h b/arch/arm/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/arm/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/i386/bits/posix.h b/arch/i386/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/i386/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/loongarch64/bits/posix.h b/arch/loongarch64/bits/posix.h deleted file mode 100644 index 8068ce98..00000000 --- a/arch/loongarch64/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_LP64_OFF64 1 -#define _POSIX_V7_LP64_OFF64 1 diff --git a/arch/m68k/bits/posix.h b/arch/m68k/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/m68k/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/microblaze/bits/posix.h b/arch/microblaze/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/microblaze/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/mips/bits/posix.h b/arch/mips/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/mips/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/mips64/bits/posix.h b/arch/mips64/bits/posix.h deleted file mode 100644 index acf42944..00000000 --- a/arch/mips64/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_LP64_OFFBIG 1 -#define _POSIX_V7_LP64_OFFBIG 1 diff --git a/arch/mipsn32/bits/posix.h b/arch/mipsn32/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/mipsn32/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/or1k/bits/posix.h b/arch/or1k/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/or1k/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/powerpc/bits/posix.h b/arch/powerpc/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/powerpc/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/powerpc64/bits/posix.h b/arch/powerpc64/bits/posix.h deleted file mode 100644 index c37b94c1..00000000 --- a/arch/powerpc64/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_LP64_OFF64 1 -#define _POSIX_V7_LP64_OFF64 1 diff --git a/arch/riscv32/bits/posix.h b/arch/riscv32/bits/posix.h deleted file mode 100644 index 8897d37d..00000000 --- a/arch/riscv32/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/riscv64/bits/posix.h b/arch/riscv64/bits/posix.h deleted file mode 100644 index 8068ce98..00000000 --- a/arch/riscv64/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_LP64_OFF64 1 -#define _POSIX_V7_LP64_OFF64 1 diff --git a/arch/s390x/bits/posix.h b/arch/s390x/bits/posix.h deleted file mode 100644 index c37b94c1..00000000 --- a/arch/s390x/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_LP64_OFF64 1 -#define _POSIX_V7_LP64_OFF64 1 diff --git a/arch/sh/bits/posix.h b/arch/sh/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/sh/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/x32/bits/posix.h b/arch/x32/bits/posix.h deleted file mode 100644 index 30a38714..00000000 --- a/arch/x32/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/arch/x86_64/bits/posix.h b/arch/x86_64/bits/posix.h deleted file mode 100644 index c37b94c1..00000000 --- a/arch/x86_64/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_LP64_OFF64 1 -#define _POSIX_V7_LP64_OFF64 1 diff --git a/include/unistd.h b/include/unistd.h index 5bc7f798..42b0e82b 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -257,7 +257,13 @@ pid_t gettid(void); #define _POSIX2_C_BIND _POSIX_VERSION -#include +#if __LONG_MAX == 0x7fffffffL +#define _POSIX_V6_ILP32_OFFBIG 1 +#define _POSIX_V7_ILP32_OFFBIG 1 +#else +#define _POSIX_V6_LP64_OFF64 1 +#define _POSIX_V7_LP64_OFF64 1 +#endif From e709a6f07ade208ba513f9225222336f30c304b0 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 7 May 2024 09:07:41 -0400 Subject: [PATCH 019/115] sys/reg.h: derive __WORDSIZE from __LONG_MAX this removes an otherwise-unnecessary bits header from most archs, replacing it with an empty generic version. --- arch/aarch64/bits/reg.h | 2 -- arch/arm/bits/reg.h | 3 --- arch/generic/bits/reg.h | 0 arch/i386/bits/reg.h | 2 -- arch/loongarch64/bits/reg.h | 2 -- arch/m68k/bits/reg.h | 2 -- arch/microblaze/bits/reg.h | 3 --- arch/mips/bits/reg.h | 3 --- arch/mips64/bits/reg.h | 3 --- arch/mipsn32/bits/reg.h | 3 --- arch/or1k/bits/reg.h | 3 --- arch/powerpc/bits/reg.h | 3 --- arch/powerpc64/bits/reg.h | 3 --- arch/riscv32/bits/reg.h | 2 -- arch/riscv64/bits/reg.h | 2 -- arch/s390x/bits/reg.h | 2 -- arch/x32/bits/reg.h | 2 -- arch/x86_64/bits/reg.h | 2 -- include/sys/reg.h | 9 +++++++++ 19 files changed, 9 insertions(+), 42 deletions(-) delete mode 100644 arch/aarch64/bits/reg.h delete mode 100644 arch/arm/bits/reg.h create mode 100644 arch/generic/bits/reg.h delete mode 100644 arch/loongarch64/bits/reg.h delete mode 100644 arch/microblaze/bits/reg.h delete mode 100644 arch/or1k/bits/reg.h delete mode 100644 arch/powerpc/bits/reg.h delete mode 100644 arch/powerpc64/bits/reg.h delete mode 100644 arch/riscv32/bits/reg.h delete mode 100644 arch/riscv64/bits/reg.h delete mode 100644 arch/s390x/bits/reg.h diff --git a/arch/aarch64/bits/reg.h b/arch/aarch64/bits/reg.h deleted file mode 100644 index 2633f39d..00000000 --- a/arch/aarch64/bits/reg.h +++ /dev/null @@ -1,2 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 diff --git a/arch/arm/bits/reg.h b/arch/arm/bits/reg.h deleted file mode 100644 index 0c7bffca..00000000 --- a/arch/arm/bits/reg.h +++ /dev/null @@ -1,3 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 -/* FIXME */ diff --git a/arch/generic/bits/reg.h b/arch/generic/bits/reg.h new file mode 100644 index 00000000..e69de29b diff --git a/arch/i386/bits/reg.h b/arch/i386/bits/reg.h index 8bc2582d..7dfe8250 100644 --- a/arch/i386/bits/reg.h +++ b/arch/i386/bits/reg.h @@ -1,5 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 #define EBX 0 #define ECX 1 #define EDX 2 diff --git a/arch/loongarch64/bits/reg.h b/arch/loongarch64/bits/reg.h deleted file mode 100644 index 2633f39d..00000000 --- a/arch/loongarch64/bits/reg.h +++ /dev/null @@ -1,2 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 diff --git a/arch/m68k/bits/reg.h b/arch/m68k/bits/reg.h index 99201f70..fedc4f9f 100644 --- a/arch/m68k/bits/reg.h +++ b/arch/m68k/bits/reg.h @@ -1,5 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 #define PT_D1 0 #define PT_D2 1 #define PT_D3 2 diff --git a/arch/microblaze/bits/reg.h b/arch/microblaze/bits/reg.h deleted file mode 100644 index 0c7bffca..00000000 --- a/arch/microblaze/bits/reg.h +++ /dev/null @@ -1,3 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 -/* FIXME */ diff --git a/arch/mips/bits/reg.h b/arch/mips/bits/reg.h index 0c370987..2611b632 100644 --- a/arch/mips/bits/reg.h +++ b/arch/mips/bits/reg.h @@ -1,6 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 - #define EF_R0 6 #define EF_R1 7 #define EF_R2 8 diff --git a/arch/mips64/bits/reg.h b/arch/mips64/bits/reg.h index a3f63acc..16178dd3 100644 --- a/arch/mips64/bits/reg.h +++ b/arch/mips64/bits/reg.h @@ -1,6 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 - #define EF_R0 0 #define EF_R1 1 #define EF_R2 2 diff --git a/arch/mipsn32/bits/reg.h b/arch/mipsn32/bits/reg.h index a3f63acc..16178dd3 100644 --- a/arch/mipsn32/bits/reg.h +++ b/arch/mipsn32/bits/reg.h @@ -1,6 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 - #define EF_R0 0 #define EF_R1 1 #define EF_R2 2 diff --git a/arch/or1k/bits/reg.h b/arch/or1k/bits/reg.h deleted file mode 100644 index 0c7bffca..00000000 --- a/arch/or1k/bits/reg.h +++ /dev/null @@ -1,3 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 -/* FIXME */ diff --git a/arch/powerpc/bits/reg.h b/arch/powerpc/bits/reg.h deleted file mode 100644 index 0c7bffca..00000000 --- a/arch/powerpc/bits/reg.h +++ /dev/null @@ -1,3 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 -/* FIXME */ diff --git a/arch/powerpc64/bits/reg.h b/arch/powerpc64/bits/reg.h deleted file mode 100644 index 49382c8f..00000000 --- a/arch/powerpc64/bits/reg.h +++ /dev/null @@ -1,3 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 -/* FIXME */ diff --git a/arch/riscv32/bits/reg.h b/arch/riscv32/bits/reg.h deleted file mode 100644 index 0192a293..00000000 --- a/arch/riscv32/bits/reg.h +++ /dev/null @@ -1,2 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 diff --git a/arch/riscv64/bits/reg.h b/arch/riscv64/bits/reg.h deleted file mode 100644 index 2633f39d..00000000 --- a/arch/riscv64/bits/reg.h +++ /dev/null @@ -1,2 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 diff --git a/arch/s390x/bits/reg.h b/arch/s390x/bits/reg.h deleted file mode 100644 index 2633f39d..00000000 --- a/arch/s390x/bits/reg.h +++ /dev/null @@ -1,2 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 diff --git a/arch/x32/bits/reg.h b/arch/x32/bits/reg.h index 5faaef1a..6e54abcf 100644 --- a/arch/x32/bits/reg.h +++ b/arch/x32/bits/reg.h @@ -1,5 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 #define R15 0 #define R14 1 #define R13 2 diff --git a/arch/x86_64/bits/reg.h b/arch/x86_64/bits/reg.h index a4df04ce..6e54abcf 100644 --- a/arch/x86_64/bits/reg.h +++ b/arch/x86_64/bits/reg.h @@ -1,5 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 #define R15 0 #define R14 1 #define R13 2 diff --git a/include/sys/reg.h b/include/sys/reg.h index b47452d0..4e6ce222 100644 --- a/include/sys/reg.h +++ b/include/sys/reg.h @@ -4,6 +4,15 @@ #include #include +#include + +#undef __WORDSIZE +#if __LONG_MAX == 0x7fffffffL +#define __WORDSIZE 32 +#else +#define __WORDSIZE 64 +#endif + #include #endif From 7019fbe103165b9b26a9391d5ecd4c7fcb6f3ec9 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 7 May 2024 09:11:10 -0400 Subject: [PATCH 020/115] sys/user.h: derive __WORDSIZE from __LONG_MAX previously, only a few archs defined it here. this change makes the presence consistent across all archs, and reduces the amount of header duplication (and potential for future inconsistency) between archs. --- arch/s390x/bits/user.h | 3 --- arch/sh/bits/user.h | 3 --- arch/x32/bits/user.h | 3 --- arch/x86_64/bits/user.h | 3 --- include/sys/user.h | 9 +++++++++ 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/arch/s390x/bits/user.h b/arch/s390x/bits/user.h index ff3f0483..47f94f20 100644 --- a/arch/s390x/bits/user.h +++ b/arch/s390x/bits/user.h @@ -1,6 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 - typedef union { double d; float f; diff --git a/arch/sh/bits/user.h b/arch/sh/bits/user.h index 07fe843b..b6ba16ed 100644 --- a/arch/sh/bits/user.h +++ b/arch/sh/bits/user.h @@ -1,6 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 - #define REG_REG0 0 #define REG_REG15 15 #define REG_PC 16 diff --git a/arch/x32/bits/user.h b/arch/x32/bits/user.h index eac82a14..b328edf9 100644 --- a/arch/x32/bits/user.h +++ b/arch/x32/bits/user.h @@ -1,6 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 - typedef struct user_fpregs_struct { uint16_t cwd, swd, ftw, fop; uint64_t rip, rdp; diff --git a/arch/x86_64/bits/user.h b/arch/x86_64/bits/user.h index 4073cc06..b328edf9 100644 --- a/arch/x86_64/bits/user.h +++ b/arch/x86_64/bits/user.h @@ -1,6 +1,3 @@ -#undef __WORDSIZE -#define __WORDSIZE 64 - typedef struct user_fpregs_struct { uint16_t cwd, swd, ftw, fop; uint64_t rip, rdp; diff --git a/include/sys/user.h b/include/sys/user.h index 96a03400..78036da3 100644 --- a/include/sys/user.h +++ b/include/sys/user.h @@ -8,6 +8,15 @@ extern "C" { #include #include +#include + +#undef __WORDSIZE +#if __LONG_MAX == 0x7fffffffL +#define __WORDSIZE 32 +#else +#define __WORDSIZE 64 +#endif + #include #ifdef __cplusplus From 2c124e13bd7941fe0b885eecdc5de6f09aacf06a Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 7 May 2024 09:17:51 -0400 Subject: [PATCH 021/115] stdint.h: derive limits from __LONG_MAX, use common fast16 types the bits file is retained, but as a single generic version, to allow for the unlikely future possibility of letting a new arch define something differently. --- arch/arm/bits/stdint.h | 20 -------------------- arch/{aarch64 => generic}/bits/stdint.h | 9 +++++++++ arch/i386/bits/stdint.h | 20 -------------------- arch/loongarch64/bits/stdint.h | 20 -------------------- arch/m68k/bits/stdint.h | 20 -------------------- arch/microblaze/bits/stdint.h | 20 -------------------- arch/mips/bits/stdint.h | 20 -------------------- arch/mips64/bits/stdint.h | 20 -------------------- arch/mipsn32/bits/stdint.h | 20 -------------------- arch/or1k/bits/stdint.h | 20 -------------------- arch/powerpc/bits/stdint.h | 20 -------------------- arch/powerpc64/bits/stdint.h | 20 -------------------- arch/riscv32/bits/stdint.h | 20 -------------------- arch/riscv64/bits/stdint.h | 20 -------------------- arch/s390x/bits/stdint.h | 20 -------------------- arch/sh/bits/stdint.h | 20 -------------------- arch/x32/bits/stdint.h | 20 -------------------- arch/x86_64/bits/stdint.h | 20 -------------------- 18 files changed, 9 insertions(+), 340 deletions(-) delete mode 100644 arch/arm/bits/stdint.h rename arch/{aarch64 => generic}/bits/stdint.h (68%) delete mode 100644 arch/i386/bits/stdint.h delete mode 100644 arch/loongarch64/bits/stdint.h delete mode 100644 arch/m68k/bits/stdint.h delete mode 100644 arch/microblaze/bits/stdint.h delete mode 100644 arch/mips/bits/stdint.h delete mode 100644 arch/mips64/bits/stdint.h delete mode 100644 arch/mipsn32/bits/stdint.h delete mode 100644 arch/or1k/bits/stdint.h delete mode 100644 arch/powerpc/bits/stdint.h delete mode 100644 arch/powerpc64/bits/stdint.h delete mode 100644 arch/riscv32/bits/stdint.h delete mode 100644 arch/riscv64/bits/stdint.h delete mode 100644 arch/s390x/bits/stdint.h delete mode 100644 arch/sh/bits/stdint.h delete mode 100644 arch/x32/bits/stdint.h delete mode 100644 arch/x86_64/bits/stdint.h diff --git a/arch/arm/bits/stdint.h b/arch/arm/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/arm/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/aarch64/bits/stdint.h b/arch/generic/bits/stdint.h similarity index 68% rename from arch/aarch64/bits/stdint.h rename to arch/generic/bits/stdint.h index 1bb147f2..86489187 100644 --- a/arch/aarch64/bits/stdint.h +++ b/arch/generic/bits/stdint.h @@ -12,9 +12,18 @@ typedef uint32_t uint_fast32_t; #define UINT_FAST16_MAX UINT32_MAX #define UINT_FAST32_MAX UINT32_MAX +#if __LONG_MAX == 0x7fffffffL +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX +#define SIZE_MAX UINT32_MAX +#else #define INTPTR_MIN INT64_MIN #define INTPTR_MAX INT64_MAX #define UINTPTR_MAX UINT64_MAX #define PTRDIFF_MIN INT64_MIN #define PTRDIFF_MAX INT64_MAX #define SIZE_MAX UINT64_MAX +#endif diff --git a/arch/i386/bits/stdint.h b/arch/i386/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/i386/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/loongarch64/bits/stdint.h b/arch/loongarch64/bits/stdint.h deleted file mode 100644 index 1bb147f2..00000000 --- a/arch/loongarch64/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT64_MIN -#define INTPTR_MAX INT64_MAX -#define UINTPTR_MAX UINT64_MAX -#define PTRDIFF_MIN INT64_MIN -#define PTRDIFF_MAX INT64_MAX -#define SIZE_MAX UINT64_MAX diff --git a/arch/m68k/bits/stdint.h b/arch/m68k/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/m68k/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/microblaze/bits/stdint.h b/arch/microblaze/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/microblaze/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/mips/bits/stdint.h b/arch/mips/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/mips/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/mips64/bits/stdint.h b/arch/mips64/bits/stdint.h deleted file mode 100644 index 1bb147f2..00000000 --- a/arch/mips64/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT64_MIN -#define INTPTR_MAX INT64_MAX -#define UINTPTR_MAX UINT64_MAX -#define PTRDIFF_MIN INT64_MIN -#define PTRDIFF_MAX INT64_MAX -#define SIZE_MAX UINT64_MAX diff --git a/arch/mipsn32/bits/stdint.h b/arch/mipsn32/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/mipsn32/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/or1k/bits/stdint.h b/arch/or1k/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/or1k/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/powerpc/bits/stdint.h b/arch/powerpc/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/powerpc/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/powerpc64/bits/stdint.h b/arch/powerpc64/bits/stdint.h deleted file mode 100644 index 1bb147f2..00000000 --- a/arch/powerpc64/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT64_MIN -#define INTPTR_MAX INT64_MAX -#define UINTPTR_MAX UINT64_MAX -#define PTRDIFF_MIN INT64_MIN -#define PTRDIFF_MAX INT64_MAX -#define SIZE_MAX UINT64_MAX diff --git a/arch/riscv32/bits/stdint.h b/arch/riscv32/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/riscv32/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/riscv64/bits/stdint.h b/arch/riscv64/bits/stdint.h deleted file mode 100644 index 1bb147f2..00000000 --- a/arch/riscv64/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT64_MIN -#define INTPTR_MAX INT64_MAX -#define UINTPTR_MAX UINT64_MAX -#define PTRDIFF_MIN INT64_MIN -#define PTRDIFF_MAX INT64_MAX -#define SIZE_MAX UINT64_MAX diff --git a/arch/s390x/bits/stdint.h b/arch/s390x/bits/stdint.h deleted file mode 100644 index 1bb147f2..00000000 --- a/arch/s390x/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT64_MIN -#define INTPTR_MAX INT64_MAX -#define UINTPTR_MAX UINT64_MAX -#define PTRDIFF_MIN INT64_MIN -#define PTRDIFF_MAX INT64_MAX -#define SIZE_MAX UINT64_MAX diff --git a/arch/sh/bits/stdint.h b/arch/sh/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/sh/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/x32/bits/stdint.h b/arch/x32/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/x32/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX -#define SIZE_MAX UINT32_MAX diff --git a/arch/x86_64/bits/stdint.h b/arch/x86_64/bits/stdint.h deleted file mode 100644 index 1bb147f2..00000000 --- a/arch/x86_64/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN - -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT64_MIN -#define INTPTR_MAX INT64_MAX -#define UINTPTR_MAX UINT64_MAX -#define PTRDIFF_MIN INT64_MIN -#define PTRDIFF_MAX INT64_MAX -#define SIZE_MAX UINT64_MAX From 1b0d48517f816e98f19111df82f32bfc1608ecec Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 8 May 2024 08:50:03 -0400 Subject: [PATCH 022/115] implement posix_getdents adopted for next issue of POSIX this interface was added as the outcome of Austin Group tracker issue 697. no error is specified for unsupported flags, which is probably an oversight. for now, EOPNOTSUPP is used so as not to overload EINVAL. --- include/dirent.h | 18 +++++++++++++++--- src/dirent/posix_getdents.c | 11 +++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/dirent/posix_getdents.c diff --git a/include/dirent.h b/include/dirent.h index 2d8fffb2..7fa60e06 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -9,14 +9,23 @@ extern "C" { #define __NEED_ino_t #define __NEED_off_t -#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) #define __NEED_size_t -#endif +#define __NEED_ssize_t #include #include +typedef unsigned short reclen_t; + +struct posix_dent { + ino_t d_ino; + off_t d_off; + reclen_t d_reclen; + unsigned char d_type; + char d_name[]; +}; + typedef struct __dirstream DIR; #define d_fileno d_ino @@ -29,6 +38,8 @@ int readdir_r(DIR *__restrict, struct dirent *__restrict, struct dire void rewinddir(DIR *); int dirfd(DIR *); +ssize_t posix_getdents(int, void *, size_t, int); + int alphasort(const struct dirent **, const struct dirent **); int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **)); @@ -37,7 +48,6 @@ void seekdir(DIR *, long); long telldir(DIR *); #endif -#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) #define DT_UNKNOWN 0 #define DT_FIFO 1 #define DT_CHR 2 @@ -47,6 +57,8 @@ long telldir(DIR *); #define DT_LNK 10 #define DT_SOCK 12 #define DT_WHT 14 + +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) #define IFTODT(x) ((x)>>12 & 017) #define DTTOIF(x) ((x)<<12) int getdents(int, struct dirent *, size_t); diff --git a/src/dirent/posix_getdents.c b/src/dirent/posix_getdents.c new file mode 100644 index 00000000..b19e8127 --- /dev/null +++ b/src/dirent/posix_getdents.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include "syscall.h" + +int posix_getdents(int fd, void *buf, size_t len, int flags) +{ + if (flags) return __syscall_ret(-EOPNOTSUPP); + if (len>INT_MAX) len = INT_MAX; + return syscall(SYS_getdents, fd, buf, len); +} From 84015cee177e835db5e65bd34b60635f2a5a5056 Mon Sep 17 00:00:00 2001 From: Gonzalo Alvarez Date: Sat, 11 May 2024 17:52:04 -0400 Subject: [PATCH 023/115] fix typo that broke sys/reg.h and sys/user.h commit 7019fbe103165b9b26a9391d5ecd4c7fcb6f3ec9 and commit e709a6f07ade208ba513f9225222336f30c304b0 misspelled bits/alltypes.h. --- include/sys/reg.h | 2 +- include/sys/user.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/sys/reg.h b/include/sys/reg.h index 4e6ce222..0272e137 100644 --- a/include/sys/reg.h +++ b/include/sys/reg.h @@ -4,7 +4,7 @@ #include #include -#include +#include #undef __WORDSIZE #if __LONG_MAX == 0x7fffffffL diff --git a/include/sys/user.h b/include/sys/user.h index 78036da3..511caba3 100644 --- a/include/sys/user.h +++ b/include/sys/user.h @@ -8,7 +8,7 @@ extern "C" { #include #include -#include +#include #undef __WORDSIZE #if __LONG_MAX == 0x7fffffffL From cbf59dd662cea8786c2f3a5ea21f8da64f002b30 Mon Sep 17 00:00:00 2001 From: mojyack Date: Sun, 12 May 2024 12:13:06 -0400 Subject: [PATCH 024/115] aarch64 crti.o: fix alignment of _init/_fini without explicit alignment directives, whether they end up at the necessary alignment depends on linker/linking conditions. initially reported as mold issue 1255. --- crt/aarch64/crti.s | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crt/aarch64/crti.s b/crt/aarch64/crti.s index 775df0ac..3776fa64 100644 --- a/crt/aarch64/crti.s +++ b/crt/aarch64/crti.s @@ -1,6 +1,7 @@ .section .init .global _init .type _init,%function +.align 2 _init: stp x29,x30,[sp,-16]! mov x29,sp @@ -8,6 +9,7 @@ _init: .section .fini .global _fini .type _fini,%function +.align 2 _fini: stp x29,x30,[sp,-16]! mov x29,sp From 007997299248b8682dcbb73595c53dfe86071c83 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 12 May 2024 15:33:15 -0400 Subject: [PATCH 025/115] fix mismatched type in posix_getdents definition commit 1b0d48517f816e98f19111df82f32bfc1608ecec wrongly copied the getdents return type of int rather than matching the ssize_t used by posix_getdents. this was overlooked in testing on 32-bit archs but obviously broke 64-bit archs. --- src/dirent/posix_getdents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dirent/posix_getdents.c b/src/dirent/posix_getdents.c index b19e8127..26c16ac6 100644 --- a/src/dirent/posix_getdents.c +++ b/src/dirent/posix_getdents.c @@ -3,7 +3,7 @@ #include #include "syscall.h" -int posix_getdents(int fd, void *buf, size_t len, int flags) +ssize_t posix_getdents(int fd, void *buf, size_t len, int flags) { if (flags) return __syscall_ret(-EOPNOTSUPP); if (len>INT_MAX) len = INT_MAX; From 05ce67fea99ca09cd4b6625cff7aec9cc222dd5a Mon Sep 17 00:00:00 2001 From: Tony Ambardar Date: Mon, 6 May 2024 20:28:32 -0700 Subject: [PATCH 026/115] add renameat2 linux syscall wrapper This syscall is available since Linux 3.15 and also implemented in glibc from version 2.28. It is commonly used in filesystem or security contexts. Constants RENAME_NOREPLACE, RENAME_EXCHANGE, RENAME_WHITEOUT are guarded by _GNU_SOURCE as with glibc. --- include/stdio.h | 7 +++++++ src/linux/renameat2.c | 11 +++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/linux/renameat2.c diff --git a/include/stdio.h b/include/stdio.h index cb858618..4ea4c170 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -158,6 +158,13 @@ char *ctermid(char *); #define L_ctermid 20 #endif +#if defined(_GNU_SOURCE) +#define RENAME_NOREPLACE (1 << 0) +#define RENAME_EXCHANGE (1 << 1) +#define RENAME_WHITEOUT (1 << 2) + +int renameat2(int, const char *, int, const char *, unsigned); +#endif #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ || defined(_BSD_SOURCE) diff --git a/src/linux/renameat2.c b/src/linux/renameat2.c new file mode 100644 index 00000000..b8060388 --- /dev/null +++ b/src/linux/renameat2.c @@ -0,0 +1,11 @@ +#define _GNU_SOURCE +#include +#include "syscall.h" + +int renameat2(int oldfd, const char *old, int newfd, const char *new, unsigned flags) +{ +#ifdef SYS_renameat + if (!flags) return syscall(SYS_renameat, oldfd, old, newfd, new); +#endif + return syscall(SYS_renameat2, oldfd, old, newfd, new, flags); +} From 895736d49bd2bb318c69de99a05ea70c035c2da9 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Thu, 13 Jun 2024 11:48:40 -0400 Subject: [PATCH 027/115] syslog: fix incorrect LOG_MAKEPRI and LOG_FAC[MASK] macros these are nonstandard and unnecessary for using the associated functionality, but resulted in applications that used them malfunctioning. patch based on proposed fix by erny hombre. --- include/syslog.h | 6 +++--- src/misc/syslog.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/syslog.h b/include/syslog.h index 5b4d2964..976fee09 100644 --- a/include/syslog.h +++ b/include/syslog.h @@ -18,7 +18,7 @@ extern "C" { #define LOG_PRIMASK 7 #define LOG_PRI(p) ((p)&LOG_PRIMASK) -#define LOG_MAKEPRI(f, p) (((f)<<3)|(p)) +#define LOG_MAKEPRI(f, p) ((f)|(p)) #define LOG_MASK(p) (1<<(p)) #define LOG_UPTO(p) ((1<<((p)+1))-1) @@ -46,8 +46,8 @@ extern "C" { #define LOG_LOCAL7 (23<<3) #define LOG_NFACILITIES 24 -#define LOG_FACMASK 0x3f8 -#define LOG_FAC(p) (((p)&LOG_FACMASK)>>3) +#define LOG_FACMASK 0xf8 +#define LOG_FAC(p) ((p)&LOG_FACMASK) #define LOG_PID 0x01 #define LOG_CONS 0x02 diff --git a/src/misc/syslog.c b/src/misc/syslog.c index 710202f9..3131c782 100644 --- a/src/misc/syslog.c +++ b/src/misc/syslog.c @@ -128,7 +128,7 @@ static void _vsyslog(int priority, const char *message, va_list ap) static void __vsyslog(int priority, const char *message, va_list ap) { int cs; - if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return; + if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0xff)) return; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); LOCK(lock); _vsyslog(priority, message, ap); From 53ac44ff4c0e91536e1e34e8e59e19d2a1196a67 Mon Sep 17 00:00:00 2001 From: Florian Ziesche Date: Thu, 20 Jun 2024 22:44:35 -0400 Subject: [PATCH 028/115] dynlink: fix get_lfs64() with posix_fallocate64 "posix_fallocate64" is 17 characters long, so 16 is one too short. --- ldso/dynlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 42687da2..8707ae1c 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -363,7 +363,7 @@ static struct symdef get_lfs64(const char *name) "stat\0statfs\0statvfs\0tmpfile\0truncate\0versionsort\0" "__fxstat\0__fxstatat\0__lxstat\0__xstat\0"; size_t l; - char buf[16]; + char buf[17]; for (l=0; name[l]; l++) { if (l >= sizeof buf) goto nomatch; buf[l] = name[l]; From ab31e9d6a0fa7c5c408856c89df2dfb12c344039 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 21 Jun 2024 20:54:30 -0400 Subject: [PATCH 029/115] getusershell: skip blank lines and comments this interface does not have a lot of historical consensus on how it handles the contents of the /etc/shells file in regard to whitespace and comments, but the commonality between all checked is that they ignore lines that are blank or that begin with '#', so that is the behavior we adopt. --- src/legacy/getusershell.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/legacy/getusershell.c b/src/legacy/getusershell.c index 5fecdec2..1c5d98ec 100644 --- a/src/legacy/getusershell.c +++ b/src/legacy/getusershell.c @@ -25,8 +25,10 @@ char *getusershell(void) ssize_t l; if (!f) setusershell(); if (!f) return 0; - l = getline(&line, &linesize, f); - if (l <= 0) return 0; + do { + l = getline(&line, &linesize, f); + if (l <= 0) return 0; + } while (line[0] == '#' || line[0] == '\n'); if (line[l-1]=='\n') line[l-1]=0; return line; } From 1b97d0060ba585df41f0a55a1f8c33c704d0dfbe Mon Sep 17 00:00:00 2001 From: Joe Damato Date: Wed, 29 May 2024 06:49:59 +0000 Subject: [PATCH 030/115] sys/epoll.h: add epoll ioctls add two ioctls to get and set struct epoll_params to allow users to control epoll based busy polling of network sockets. added to uapi in commit 18e2bf0edf4dd88d9656ec92395aa47392e85b61 (Linux kernel 6.9 and newer). --- include/sys/epoll.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/sys/epoll.h b/include/sys/epoll.h index ac81a841..5f975c4a 100644 --- a/include/sys/epoll.h +++ b/include/sys/epoll.h @@ -7,6 +7,7 @@ extern "C" { #include #include +#include #include #define __NEED_sigset_t @@ -54,6 +55,17 @@ __attribute__ ((__packed__)) #endif ; +struct epoll_params { + uint32_t busy_poll_usecs; + uint16_t busy_poll_budget; + uint8_t prefer_busy_poll; + + uint8_t __pad; +}; + +#define EPOLL_IOC_TYPE 0x8A +#define EPIOCSPARAMS _IOW(EPOLL_IOC_TYPE, 0x01, struct epoll_params) +#define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params) int epoll_create(int); int epoll_create1(int); From 50ab830633134dac99011219f0210ee2759ffbde Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 22 Jun 2024 16:54:11 -0400 Subject: [PATCH 031/115] dynlink: avoid copying to temp buffer in get_lfs64 while commit 53ac44ff4c0e91536e1e34e8e59e19d2a1196a67 fixed the temp buffer being undersized, the use of a temp buffer to begin with was a mistake. instead, compare the requested symbol name in-place and use the already-null-terminated copy of the name without "64" present in lfs64_list[] to look up the real symbol. --- ldso/dynlink.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 8707ae1c..3b57c07f 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -362,19 +362,14 @@ static struct symdef get_lfs64(const char *name) "pwritev\0readdir\0scandir\0sendfile\0setrlimit\0" "stat\0statfs\0statvfs\0tmpfile\0truncate\0versionsort\0" "__fxstat\0__fxstatat\0__lxstat\0__xstat\0"; - size_t l; - char buf[17]; - for (l=0; name[l]; l++) { - if (l >= sizeof buf) goto nomatch; - buf[l] = name[l]; - } if (!strcmp(name, "readdir64_r")) return find_sym(&ldso, "readdir_r", 1); - if (l<2 || name[l-2]!='6' || name[l-1]!='4') + size_t l = strnlen(name, 18); + if (l<2 || name[l-2]!='6' || name[l-1]!='4' || name[l]) goto nomatch; - buf[l-=2] = 0; for (p=lfs64_list; *p; p++) { - if (!strcmp(buf, p)) return find_sym(&ldso, buf, 1); + if (!strncmp(name, p, l-2) && !p[l-2]) + return find_sym(&ldso, p, 1); while (*p) p++; } nomatch: From 947b4574fa7998f027d3906e1f53acb9a7553c61 Mon Sep 17 00:00:00 2001 From: Jakub Stasiak Date: Fri, 14 Jun 2024 00:59:41 +0200 Subject: [PATCH 032/115] inet_ntop: fix the IPv6 leading zero sequence compression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per RFC 5952, ties for longest sequence of zero fields must be broken by choosing the earliest, but the implementation put the leading sequence of zeros at a disadvantage. That's because for example when compressing "0:0:0:10:0:0:0:10" the strspn(buf+i, ":0") call returns 6 for the first sequence and 7 for the second one – the second sequence has the benefit of a leading colon. Changing the condition to require beating the leading sequence by not one but two characters resolves the issue. --- src/network/inet_ntop.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/inet_ntop.c b/src/network/inet_ntop.c index 4bfef2c5..f442f47d 100644 --- a/src/network/inet_ntop.c +++ b/src/network/inet_ntop.c @@ -34,7 +34,12 @@ const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen for (i=best=0, max=2; buf[i]; i++) { if (i && buf[i] != ':') continue; j = strspn(buf+i, ":0"); - if (j>max) best=i, max=j; + /* The leading sequence of zeros (best==0) is + * disadvantaged compared to sequences elsewhere + * as it doesn't have a leading colon. One extra + * character is required for another sequence to + * beat it fairly. */ + if (j>max+(best==0)) best=i, max=j; } if (max>3) { buf[best] = buf[best+1] = ':'; From 008f737ddf5de815ef7e26d195767d927c8c8e76 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 23 Jun 2024 20:52:53 -0400 Subject: [PATCH 033/115] siglongjmp: document why this function just calls longjmp --- src/signal/siglongjmp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/signal/siglongjmp.c b/src/signal/siglongjmp.c index bc317acc..53789b23 100644 --- a/src/signal/siglongjmp.c +++ b/src/signal/siglongjmp.c @@ -5,5 +5,10 @@ _Noreturn void siglongjmp(sigjmp_buf buf, int ret) { + /* If sigsetjmp was called with nonzero savemask flag, the address + * longjmp will return to is inside of sigsetjmp. The signal mask + * will then be restored in the returned-to context instead of here, + * which matters if the context we are returning from may not have + * sufficient stack space for signal delivery. */ longjmp(buf, ret); } From dd1e63c3638d5f9afb857fccf6ce1415ca5f1b8b Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 5 Jul 2024 13:22:25 -0400 Subject: [PATCH 034/115] syslog: revert LOG_FAC/LOG_FACMASK changes commit 895736d49bd2bb318c69de99a05ea70c035c2da9 made these changes along with fixing a real bug in LOG_MAKEPRI. based on further information, they do not seem to be well-motivated or in line with policy. the result of LOG_FAC is not a meaningful facility value if we shift it down like before, but apparently the way it is used by applications is as an index into an array of facility names. moreover, all historical systems which define it do so with the shift. as it is a nonstandard interface, there is no justification for providing a macro by the same name that is incompatible with historical practice. the value of LOG_FACMASK likewise is 0x3f8 on all historical systems checked. while only 5 bits are used for existing facility codes, the convention seems to be that all 7 bits belong to the facility field and theoretically could be used to expand to having more facilities. that seems unlikely to happen, but there is no reason to make a gratuitously incompatible change here. --- include/syslog.h | 4 ++-- src/misc/syslog.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/syslog.h b/include/syslog.h index 976fee09..57599e07 100644 --- a/include/syslog.h +++ b/include/syslog.h @@ -46,8 +46,8 @@ extern "C" { #define LOG_LOCAL7 (23<<3) #define LOG_NFACILITIES 24 -#define LOG_FACMASK 0xf8 -#define LOG_FAC(p) ((p)&LOG_FACMASK) +#define LOG_FACMASK 0x3f8 +#define LOG_FAC(p) (((p)&LOG_FACMASK)>>3) #define LOG_PID 0x01 #define LOG_CONS 0x02 diff --git a/src/misc/syslog.c b/src/misc/syslog.c index 3131c782..710202f9 100644 --- a/src/misc/syslog.c +++ b/src/misc/syslog.c @@ -128,7 +128,7 @@ static void _vsyslog(int priority, const char *message, va_list ap) static void __vsyslog(int priority, const char *message, va_list ap) { int cs; - if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0xff)) return; + if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); LOCK(lock); _vsyslog(priority, message, ap); From ef7d0ae21240eac9fc1e8088112bfb0fac507578 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 23 Jul 2024 12:01:41 -0400 Subject: [PATCH 035/115] move __utc string object to its own translation unit having it in __tz.c caused gmtime[_r] and timegm to pull in all of the time zone code despite having no need for it. --- src/time/__tz.c | 1 - src/time/__utc.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 src/time/__utc.c diff --git a/src/time/__tz.c b/src/time/__tz.c index c34b3eb7..54ed4cf6 100644 --- a/src/time/__tz.c +++ b/src/time/__tz.c @@ -24,7 +24,6 @@ weak_alias(__tzname, tzname); static char std_name[TZNAME_MAX+1]; static char dst_name[TZNAME_MAX+1]; -const char __utc[] = "UTC"; static int dst_off; static int r0[5], r1[5]; diff --git a/src/time/__utc.c b/src/time/__utc.c new file mode 100644 index 00000000..9e8bfc58 --- /dev/null +++ b/src/time/__utc.c @@ -0,0 +1,3 @@ +#include "time_impl.h" + +const char __utc[] = "UTC"; From 8cca79a72cccbdb54726125d690d7d0095fc2409 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 23 Jul 2024 20:36:58 -0400 Subject: [PATCH 036/115] exit: add back lock to make concurrent calls to exit safe per the C and POSIX standards, calling exit "more than once", including via return from main, produces undefined behavior. this language predates threads, and at the time it was written, could only have applied to recursive calls to exit via atexit handlers. C++ likewise makes calls to exit from global dtors undefined. nonetheless, by the present specification as written, concurrent calls to exit by multiple threads also have undefined behavior. originally, our implementation of exit did have locking to handle concurrent calls safely, but that was changed in commit 2e55da911896a91e95b24ab5dc8a9d9b0718f4de based on it being undefined. from a standpoint of both hardening and quality of implementation, that change seems to have been a mistake. this change adds back locking, but with awareness of the lock owner so that recursive calls to exit can be trapped rather than deadlocking. this also opens up the possibility of allowing recursive calls to succeed, if future consensus ends up being in favor of that. prior to this change, exit already behaved partly as if protected by a lock as long as atexit was linked, but multiple threads calling exit could concurrently "pop off" atexit handlers and execute them in parallel with one another rather than serialized in the reverse order of registration. this was a likely unnoticed but potentially very dangerous manifestation of the undefined behavior. if on the other hand atexit was not linked, multiple threads calling exit concurrently could each run their own instance of global dtors, if any, likely producing double-free situations. now, if multiple threads call exit concurrently, all but the first will permanently block (in SYS_pause) until the process terminates, and all atexit handlers, global dtors, and stdio flushing/position consistency will be handled in the thread that arrived first. this is really the only reasonable way to define concurrent calls to exit. it is not recommended usage, but may become so in the future if there is consensus/standardization, as there is a push from the rust language community (and potentially other languages interoperating with the C runtime) to make concurrent calls to the language's exit interfaces safe even when multiple languages are involved in a program, and this is only possible by having the locking in the underlying C exit. --- src/exit/exit.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/exit/exit.c b/src/exit/exit.c index a6869b37..ca11b9ad 100644 --- a/src/exit/exit.c +++ b/src/exit/exit.c @@ -1,6 +1,9 @@ #include #include #include "libc.h" +#include "pthread_impl.h" +#include "atomic.h" +#include "syscall.h" static void dummy() { @@ -26,6 +29,17 @@ weak_alias(libc_exit_fini, __libc_exit_fini); _Noreturn void exit(int code) { + /* Handle potentially concurrent or recursive calls to exit, + * whose behaviors have traditionally been undefined by the + * standards. Using a custom lock here avoids pulling in lock + * machinery and lets us trap recursive calls while supporting + * multiple threads contending to be the one to exit(). */ + static volatile int exit_lock[1]; + int tid = __pthread_self()->tid; + int prev = a_cas(exit_lock, 0, tid); + if (prev == tid) a_crash(); + else if (prev) for (;;) __syscall(SYS_pause); + __funcs_on_exit(); __libc_exit_fini(); __stdio_exit(); From 9ee6f104075fa6c37bb57a4ef406f3ff290b586c Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 24 Jul 2024 12:33:46 -0400 Subject: [PATCH 037/115] atexit: fail rather than deadlocking after last handler is called previously, global dtors, which are executed after all atexit handlers have been called rather than being implemented as an atexit handler themselves, would deadlock if they called atexit. it was intentional to disallow adding more atexit handlers past the last point where they would be executed, since a successful return from atexit imposes a contract that the handler will be executed, but this was only considered in the context of calls to atexit from other threads, not calls from the dtors. to fix this, release the lock after the exit handlers loop completes, but but set a flag first so that we can make all future calls to atexit return a failure code. --- src/exit/atexit.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/exit/atexit.c b/src/exit/atexit.c index 854e9fdd..92c91c9d 100644 --- a/src/exit/atexit.c +++ b/src/exit/atexit.c @@ -19,6 +19,7 @@ static struct fl void *a[COUNT]; } builtin, *head; +static int finished_atexit; static int slot; static volatile int lock[1]; volatile int *const __atexit_lockptr = lock; @@ -34,6 +35,10 @@ void __funcs_on_exit() func(arg); LOCK(lock); } + /* Unlock to prevent deadlock if a global dtor + * attempts to call atexit. */ + finished_atexit = 1; + UNLOCK(lock); } void __cxa_finalize(void *dso) @@ -44,6 +49,13 @@ int __cxa_atexit(void (*func)(void *), void *arg, void *dso) { LOCK(lock); + /* Prevent dtors from registering further atexit + * handlers that would never be run. */ + if (finished_atexit) { + UNLOCK(lock); + return -1; + } + /* Defer initialization of head so it can be in BSS */ if (!head) head = &builtin; From cde213f9c3ac1aa168581222edee6a6642113323 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 24 Jul 2024 12:41:04 -0400 Subject: [PATCH 038/115] timer_create: replace pthread barrier with semaphores for thread start our pthread barrier implementation reportedly has bugs that are could lead to malfunction or crash in timer_create. while this has not been reviewed to confirm, there have been past reports of pthread barrier bugs, and it seems likely that something is actually wrong. pthread barriers are an obscure primitive, and timer_create is the only place we are using them internally at present. even if they were working correctly, this means we are imposing linking of otherwise likely-dead code whenever timer_create is used. a pair of semaphores functions identically to a 2-waiter barrier except for destruction order properties. since the parent is responsible for the argument structure (including semaphores) lifetimes, the last operation on them in the timer thread must be posting to the parent. --- src/time/timer_create.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/time/timer_create.c b/src/time/timer_create.c index 9216b3ab..424c70b7 100644 --- a/src/time/timer_create.c +++ b/src/time/timer_create.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "pthread_impl.h" #include "atomic.h" @@ -12,7 +13,7 @@ struct ksigevent { }; struct start_args { - pthread_barrier_t b; + sem_t sem1, sem2; struct sigevent *sev; }; @@ -42,7 +43,14 @@ static void *start(void *arg) void (*notify)(union sigval) = args->sev->sigev_notify_function; union sigval val = args->sev->sigev_value; - pthread_barrier_wait(&args->b); + /* The two-way semaphore synchronization ensures that we see + * self->cancel set by the parent if timer creation failed or + * self->timer_id if it succeeded, and informs the parent that + * we are done accessing the arguments so that the parent can + * proceed past their block lifetime. */ + while (sem_wait(&args->sem1)); + sem_post(&args->sem2); + if (self->cancel) return 0; for (;;) { @@ -99,7 +107,8 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict else pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_barrier_init(&args.b, 0, 2); + sem_init(&args.sem1, 0, 0); + sem_init(&args.sem2, 0, 0); args.sev = evp; __block_app_sigs(&set); @@ -120,7 +129,8 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict td->cancel = 1; } td->timer_id = timerid; - pthread_barrier_wait(&args.b); + sem_post(&args.sem1); + while (sem_wait(&args.sem2)); if (timerid < 0) return -1; *res = (void *)(INTPTR_MIN | (uintptr_t)td>>1); break; From 2de6b42605661d9444dfd464a9d5c1949cbb8944 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 9 Aug 2024 23:03:52 -0400 Subject: [PATCH 039/115] fix missing make dependency for Scrt1.o due to typo commit 2f853dd6b9a95d5b13ee8f9df762125e0588df5d inadvertently changed Scrt1.o to scrt1.o in the Makefile rule for dependency on crt_arch.h. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e8cc4436..3ad88b35 100644 --- a/Makefile +++ b/Makefile @@ -109,7 +109,7 @@ obj/src/internal/version.o obj/src/internal/version.lo: obj/src/internal/version obj/crt/rcrt1.o obj/ldso/dlstart.lo obj/ldso/dynlink.lo: $(srcdir)/src/internal/dynlink.h $(srcdir)/arch/$(ARCH)/reloc.h -obj/crt/crt1.o obj/crt/scrt1.o obj/crt/rcrt1.o obj/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h +obj/crt/crt1.o obj/crt/Scrt1.o obj/crt/rcrt1.o obj/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h obj/crt/rcrt1.o: $(srcdir)/ldso/dlstart.c From b09e3174a695d1db60b2abc442d29ed3f87f0358 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 7 Aug 2024 08:51:03 +0300 Subject: [PATCH 040/115] m68k: fix POLLWRNORM and POLLWRBAND As noted in commit f5011c62c3 ("fix POLLWRNORM and POLLWRBAND on mips") m68k uses a different definition. --- arch/m68k/bits/poll.h | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 arch/m68k/bits/poll.h diff --git a/arch/m68k/bits/poll.h b/arch/m68k/bits/poll.h new file mode 100644 index 00000000..00063f41 --- /dev/null +++ b/arch/m68k/bits/poll.h @@ -0,0 +1,2 @@ +#define POLLWRNORM POLLOUT +#define POLLWRBAND 256 From 882aedf6a13891f887d20f6a4184a13e94793b84 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 10 Aug 2024 16:30:28 -0400 Subject: [PATCH 041/115] fix lost or delayed wakes in sem_post under certain race conditions if sem_post is interrupted between clearing the waiters bit from the semaphore value and performing the futex wait operation, subsequent calls to sem_post will not perform a wake operation unless a new waiter has arrived. usually, this is at most a minor nuisance, since the original wake operation will eventually happen. however, it's possible that the wake is delayed indefinitely if interrupted by a signal handler, or that the address the wake needs to be performed on is no longer mapped if the semaphore was a process-shared one that has since been unmapped but has a waiter on a different mapping of the same semaphore. this can happen when another thread using the same mapping "steals the post" atomically before actually becoming a second waiter, deduces from success that it was the last user of the semaphore mapping, then re-posts and unmaps the semaphore mapping. this scenario was described in a report by Markus Wichmann. instead of checking only the waiters bit, also check the waiter count that was sampled before the atomic post operation, and perform the wake if it's nonzero. this will not produce any additional wakes under non-race conditions, since the waiters bit only becomes zero when targeting a single waiter for wake. checking both was already the behavior prior to commit 159d1f6c02569091c7a48bdb2e2e824b844a1902. --- src/thread/sem_post.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread/sem_post.c b/src/thread/sem_post.c index 5c2517f2..1c8f763c 100644 --- a/src/thread/sem_post.c +++ b/src/thread/sem_post.c @@ -16,6 +16,6 @@ int sem_post(sem_t *sem) if (waiters <= 1) new &= ~0x80000000; } while (a_cas(sem->__val, val, new) != val); - if (val<0) __wake(sem->__val, waiters>1 ? 1 : -1, priv); + if (val<0 || waiters) __wake(sem->__val, waiters>1 ? 1 : -1, priv); return 0; } From 9c78557af0a5e521cdb46a4ca7630f2987d2523e Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 10 Aug 2024 19:49:24 -0400 Subject: [PATCH 042/115] use hidden visibility for C entry point function _start_c the file-level crt_arch.h asm fragments generally make direct (non-PLT) calls from _start to _start_c, which is only valid when there is a local, non-interposable definition for _start_c. generally, the linker is expected to know that local definitions in a main executable (as opposed to shared library) output are non-interposable, making this work, but historically there have been linker bugs in this area, and microblaze is reportedly still broken, flagging the relocation for the call as a textrel. the equivalent _dlstart_c, called from the same crt_arch.h asm fragments, has always used hidden visibility without problem, and semantically it should be hidden, so make it hidden. this ensures the direct call is always valid regardless of whether the linker properly special-cases main executable output. --- crt/crt1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crt/crt1.c b/crt/crt1.c index 8fe8ab5d..10601215 100644 --- a/crt/crt1.c +++ b/crt/crt1.c @@ -11,7 +11,7 @@ weak void _fini(); int __libc_start_main(int (*)(), int, char **, void (*)(), void(*)(), void(*)()); -void _start_c(long *p) +hidden void _start_c(long *p) { int argc = p[0]; char **argv = (void *)(p+1); From c851b268bd9b9021599ecfdf0b8a43a3ab60d661 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 10 Aug 2024 22:08:56 -0400 Subject: [PATCH 043/115] strerror: add error strings for EUCLEAN and ENAVAIL while not the only error codes presently omitted, these two are particularly likely to be encountered in the wild. EUCLEAN is used by linux filesystem and device drivers to report filesystem structure corruption or data corruption. ENAVAIL is used by some linux drivers to indicate non-availability of a resource. both names are new inventions to correspond to how they are actually used, as the original kernel strings ("Structure needs cleaning" and "No XENIX semaphores available") are not remotely meaningful or reasonable. --- src/errno/__strerror.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/errno/__strerror.h b/src/errno/__strerror.h index 14925907..0398b5b6 100644 --- a/src/errno/__strerror.h +++ b/src/errno/__strerror.h @@ -97,6 +97,8 @@ E(ESHUTDOWN, "Cannot send after socket shutdown") E(EALREADY, "Operation already in progress") E(EINPROGRESS, "Operation in progress") E(ESTALE, "Stale file handle") +E(EUCLEAN, "Data consistency error") +E(ENAVAIL, "Resource not available") E(EREMOTEIO, "Remote I/O error") E(EDQUOT, "Quota exceeded") E(ENOMEDIUM, "No medium found") From ca4e632df42a41aaaf9445a0cfaa939d50a565b8 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 14 Aug 2024 20:43:27 -0400 Subject: [PATCH 044/115] remove incorrect comment regarding powl exceptional cases the comment does not match the required or actual behavior when x<0 and y is not an integer. while it could be corrected, the role of comments here is to tell about characteristics unique to the implementation, not to restate the requirements of the standard, so just removing it seems best. --- src/math/powl.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/math/powl.c b/src/math/powl.c index 6f64ea71..9eb22162 100644 --- a/src/math/powl.c +++ b/src/math/powl.c @@ -57,14 +57,6 @@ * IEEE 0,8700 60000 6.5e-18 1.0e-18 * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. * - * - * ERROR MESSAGES: - * - * message condition value returned - * pow overflow x**y > MAXNUM INFINITY - * pow underflow x**y < 1/MAXNUM 0.0 - * pow domain x<0 and y noninteger 0.0 - * */ #include "libm.h" From e1b57ede3ecad17e8f3c4e59f7fb0df1d5a6b2f4 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Thu, 15 Aug 2024 10:07:36 -0400 Subject: [PATCH 045/115] catan: remove no-op reduction mod pi and unused code the output of atan2 is already in the correct range and does not need further reduction. the MAXNUM macros were both unused and incorrect. --- src/complex/catan.c | 25 +------------------------ src/complex/catanf.c | 28 +--------------------------- src/complex/catanl.c | 24 +----------------------- 3 files changed, 3 insertions(+), 74 deletions(-) diff --git a/src/complex/catan.c b/src/complex/catan.c index ccc2fb53..b4fe552a 100644 --- a/src/complex/catan.c +++ b/src/complex/catan.c @@ -60,29 +60,6 @@ #include "complex_impl.h" -#define MAXNUM 1.0e308 - -static const double DP1 = 3.14159265160560607910E0; -static const double DP2 = 1.98418714791870343106E-9; -static const double DP3 = 1.14423774522196636802E-17; - -static double _redupi(double x) -{ - double t; - long i; - - t = x/M_PI; - if (t >= 0.0) - t += 0.5; - else - t -= 0.5; - - i = t; /* the multiple */ - t = i; - t = ((x - t * DP1) - t * DP2) - t * DP3; - return t; -} - double complex catan(double complex z) { double complex w; @@ -95,7 +72,7 @@ double complex catan(double complex z) a = 1.0 - x2 - (y * y); t = 0.5 * atan2(2.0 * x, a); - w = _redupi(t); + w = t; t = y - 1.0; a = x2 + (t * t); diff --git a/src/complex/catanf.c b/src/complex/catanf.c index 1d569f2d..faaa907a 100644 --- a/src/complex/catanf.c +++ b/src/complex/catanf.c @@ -55,32 +55,6 @@ #include "complex_impl.h" -#define MAXNUMF 1.0e38F - -static const double DP1 = 3.140625; -static const double DP2 = 9.67502593994140625E-4; -static const double DP3 = 1.509957990978376432E-7; - -static const float float_pi = M_PI; - -static float _redupif(float xx) -{ - float x, t; - long i; - - x = xx; - t = x/float_pi; - if (t >= 0.0f) - t += 0.5f; - else - t -= 0.5f; - - i = t; /* the multiple */ - t = i; - t = ((x - t * DP1) - t * DP2) - t * DP3; - return t; -} - float complex catanf(float complex z) { float complex w; @@ -93,7 +67,7 @@ float complex catanf(float complex z) a = 1.0f - x2 - (y * y); t = 0.5f * atan2f(2.0f * x, a); - w = _redupif(t); + w = t; t = y - 1.0f; a = x2 + (t * t); diff --git a/src/complex/catanl.c b/src/complex/catanl.c index e62526c0..cd2d2b00 100644 --- a/src/complex/catanl.c +++ b/src/complex/catanl.c @@ -67,28 +67,6 @@ long double complex catanl(long double complex z) return catan(z); } #else -static const long double PIL = 3.141592653589793238462643383279502884197169L; -static const long double DP1 = 3.14159265358979323829596852490908531763125L; -static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L; -static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L; - -static long double redupil(long double x) -{ - long double t; - long i; - - t = x / PIL; - if (t >= 0.0L) - t += 0.5L; - else - t -= 0.5L; - - i = t; /* the multiple */ - t = i; - t = ((x - t * DP1) - t * DP2) - t * DP3; - return t; -} - long double complex catanl(long double complex z) { long double complex w; @@ -101,7 +79,7 @@ long double complex catanl(long double complex z) a = 1.0L - x2 - (y * y); t = atan2l(2.0L * x, a) * 0.5L; - w = redupil(t); + w = t; t = y - 1.0L; a = x2 + (t * t); From 06a964709373d4f7a4308453651b4ead66af132d Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 18 Aug 2024 13:00:10 -0400 Subject: [PATCH 046/115] iconv: add cp858 this is the same as cp850, but with the euro symbol replacing the lowercase dotless i at 0xd5. it is significant because it's used by thermal receipt printers. --- src/locale/codepages.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/locale/codepages.h b/src/locale/codepages.h index 4e236ef3..a254f0f5 100644 --- a/src/locale/codepages.h +++ b/src/locale/codepages.h @@ -286,6 +286,17 @@ "\323\174\103\215\64\365\124\123\213\77\336\150\263\115\66\375\164\363\12\55" "\255\304\42\261\57\266\234\162\17\56\260\240\162\113\56\263\310\62\66\50" +"cp858\0" +"\0\40" +"\307\360\223\216\70\344\200\123\316\71\352\254\203\316\73\356\260\103\114\61" +"\311\230\143\14\75\366\310\263\117\76\377\130\303\15\76\243\140\163\15\135" +"\341\264\63\217\76\361\104\243\212\56\277\270\302\112\57\274\204\262\312\56" +"\140\207\55\66\315\72\7\43\14\60\251\104\375\163\321\113\213\122\212\315" +"\67\363\274\163\316\63\367\74\316\60\110\13\175\65\325\116\373\254\65\51" +"\360\100\243\314\62\310\220\334\214\63\317\340\134\163\327\134\233\302\314\326" +"\323\174\103\215\64\365\124\123\213\77\336\150\263\115\66\375\164\363\12\55" +"\255\304\42\261\57\266\234\162\17\56\260\240\162\113\56\263\310\62\66\50" + "cp866\0" "\0\40" "\337\201\27\236\170\343\221\127\236\171\347\241\227\236\172" From ee18e584bfe2c694fdd27bd1251ac5b247f864d5 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 18 Aug 2024 13:53:39 -0400 Subject: [PATCH 047/115] printf core: replace if(0) blocks around switch cases with explicit gotos this is purely a readability change, not a functional one. all of the integer format cases use a common tail for handling precision logic after the string representation of the number has been generated. the code as I originally wrote it was overly clever in the aim of making a point that the flow could be done without goto, and jumped over intervening cases by wrapping them in if (0) { }, with the case labels for each inside the conditional block scope. this has been a perpetual source of complaints about the readability and comprehensibility of the file, so I am now changing it to explicitly jump to the tail logic with goto statements. --- src/stdio/vfprintf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index 360d723a..3c450c3a 100644 --- a/src/stdio/vfprintf.c +++ b/src/stdio/vfprintf.c @@ -557,11 +557,11 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, case 'x': case 'X': a = fmt_x(arg.i, z, t&32); if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2; - if (0) { + goto ifmt_tail; case 'o': a = fmt_o(arg.i, z); if ((fl&ALT_FORM) && pINTMAX_MAX) { @@ -573,7 +573,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, } else pl=0; case 'u': a = fmt_u(arg.i, z); - } + ifmt_tail: if (xp && p<0) goto overflow; if (xp) fl &= ~ZERO_PAD; if (!arg.i && !p) { From c94a0c16f08894ce3be6dafb0fe80baa77a6ff2a Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 20 Aug 2024 12:34:50 -0400 Subject: [PATCH 048/115] isatty: don't collapse all non-EBADF errors to ENOTTY linux puts hung-up ttys in a state where ioctls produce EIO, and may do the same for other types of devices in error or shutdown states. such an error clearly does not mean the device is not a tty, but it also can't reliably establish that the device is a tty, so the only safe thing to do seems to be reporting the error. programs that don't check errno will conclude that the device is not a tty, which is no different from what happens now, but at least they gain the option to differentiate between the cases. commit c84971995b3a6d5118f9357c040572f4c78bcd55 introduced the errno collapsing behavior, but prior to that, errno was not set at all by isatty. --- src/unistd/isatty.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/unistd/isatty.c b/src/unistd/isatty.c index 75a9c186..21222eda 100644 --- a/src/unistd/isatty.c +++ b/src/unistd/isatty.c @@ -6,8 +6,6 @@ int isatty(int fd) { struct winsize wsz; - unsigned long r = syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz); - if (r == 0) return 1; - if (errno != EBADF) errno = ENOTTY; - return 0; + /* +1 converts from error status (0/-1) to boolean (1/0) */ + return syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz) + 1; } From 572a2e2eb91f00f2f25d301cfb50f435e7ae16b3 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 26 Aug 2024 16:01:11 -0400 Subject: [PATCH 049/115] printf: drastically reduce stack usage without [long] double args internally, printf always works with the maximal-size supported integer and floating point formats. however, the space needed to format a floating point number is proportional to the mantissa and exponent ranges. on archs where long double is larger than double, knowing that the actual value fit in double allows us to use a much smaller buffer, roughly 1/16 the size. as a bonus, making the working buffer a VLA whose dimension depends on the format specifier prevents the compiler from lifting the stack adjustment to the top of printf_core. this makes it so printf calls without floating point arguments do not waste even the smaller amount of stack space needed for double, making it much more practical to use printf in tightly stack-constrained environments. --- src/stdio/vfprintf.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index 3c450c3a..76733997 100644 --- a/src/stdio/vfprintf.c +++ b/src/stdio/vfprintf.c @@ -178,10 +178,14 @@ static char *fmt_u(uintmax_t x, char *s) typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; #endif -static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) +static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps) { - uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion - + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion + int bufsize = (ps==BIGLPRE) + ? (LDBL_MANT_DIG+28)/29 + 1 + // mantissa expansion + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9 // exponent expansion + : (DBL_MANT_DIG+28)/29 + 1 + + (DBL_MAX_EXP+DBL_MANT_DIG+28+8)/9; + uint32_t big[bufsize]; uint32_t *a, *d, *r, *z; int e2=0, e, i, j, l; char buf[9+LDBL_MANT_DIG/4], *s; @@ -618,7 +622,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, case 'e': case 'f': case 'g': case 'a': case 'E': case 'F': case 'G': case 'A': if (xp && p<0) goto overflow; - l = fmt_fp(f, arg.f, w, p, fl, t); + l = fmt_fp(f, arg.f, w, p, fl, t, ps); if (l<0) goto overflow; continue; } From 300a1f53907a4acaadd9a696d0c67eee6fc10430 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 31 Aug 2024 12:25:44 -0400 Subject: [PATCH 050/115] sigaltstack: enforce dynamic MINSIGSTKSZ limit commit 996b6154b20184c3b08cce28eb01edb7f47e9413 added support for querying the dynamic limit but did not enforce it in sigaltstack. the kernel also does not seem to reliably enforce it, or at least does not necessarily enforce the same limit exposed to userspace, so it needs to be enforced here. --- src/signal/sigaltstack.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/signal/sigaltstack.c b/src/signal/sigaltstack.c index d3a6e821..616625c5 100644 --- a/src/signal/sigaltstack.c +++ b/src/signal/sigaltstack.c @@ -1,11 +1,13 @@ #include #include +#include #include "syscall.h" int sigaltstack(const stack_t *restrict ss, stack_t *restrict old) { if (ss) { - if (!(ss->ss_flags & SS_DISABLE) && ss->ss_size < MINSIGSTKSZ) { + size_t min = sysconf(_SC_MINSIGSTKSZ); + if (!(ss->ss_flags & SS_DISABLE) && ss->ss_size < min) { errno = ENOMEM; return -1; } From 8c43c562694fd0436494dc9d3faabb3eea86f9d8 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 31 Aug 2024 12:34:13 -0400 Subject: [PATCH 051/115] sysconf: fix _SC_MINSIGSTKSZ computation to match kernel interpretation the value placed in the aux vector AT_MINSIGSTKSZ by the kernel is purely the signal frame size, and does not include any execution space for the signal handler. this is contrary to the POSIX definition of MINSIGSTKSZ to be a value that can actually execute at least some minimal signal handler, and contrary to the historical definitions of MINSIGSTKSZ which had at least 1k of headroom. --- src/conf/sysconf.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/conf/sysconf.c b/src/conf/sysconf.c index 60d3e745..8dd5c725 100644 --- a/src/conf/sysconf.c +++ b/src/conf/sysconf.c @@ -220,8 +220,13 @@ long sysconf(int name) return (mem > LONG_MAX) ? LONG_MAX : mem; case JT_MINSIGSTKSZ & 255: case JT_SIGSTKSZ & 255: ; - long val = __getauxval(AT_MINSIGSTKSZ); - if (val < MINSIGSTKSZ) val = MINSIGSTKSZ; + /* Value from auxv/kernel is only sigfame size. Clamp it + * to at least 1k below arch's traditional MINSIGSTKSZ, + * then add 1k of working space for signal handler. */ + unsigned long sigframe_sz = __getauxval(AT_MINSIGSTKSZ); + if (sigframe_sz < MINSIGSTKSZ - 1024) + sigframe_sz = MINSIGSTKSZ - 1024; + unsigned val = sigframe_sz + 1024; if (values[name] == JT_SIGSTKSZ) val += SIGSTKSZ - MINSIGSTKSZ; return val; From 251cbb6366403a056b39638264932c82d18ec610 Mon Sep 17 00:00:00 2001 From: Gabriel Ravier Date: Fri, 13 Sep 2024 22:00:15 +0200 Subject: [PATCH 052/115] statx: fix ENOSYS emulation not setting stx_rdev_* The current implementation of the statx function fails to set the values of stx->stx_rdev_major and stx->stx_rdev_minor if the statx syscall fails with ENOSYS and thus the statx function has to fall back on fstatat-based emulation. --- src/linux/statx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/linux/statx.c b/src/linux/statx.c index 4616bff4..5f6dde92 100644 --- a/src/linux/statx.c +++ b/src/linux/statx.c @@ -21,6 +21,8 @@ int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct stx->stx_dev_major = major(st.st_dev); stx->stx_dev_minor = minor(st.st_dev); + stx->stx_rdev_major = major(st.st_rdev); + stx->stx_rdev_minor = minor(st.st_rdev); stx->stx_ino = st.st_ino; stx->stx_mode = st.st_mode; stx->stx_nlink = st.st_nlink; From 4ca8c267768e371930ef7ec9593a5f8b44a7f810 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 13 Sep 2024 17:08:11 -0400 Subject: [PATCH 053/115] statx: fix uninitialized attributes/mask in fallback path commit b817541f1cfd38e4b81257b3215e276ea9d0fc61 introduced statx with a fallback using fstatat, but failed to fill in stx_rdev_major/minor and stx_attributes[_mask]. the rdev omission has been addressed separately. rather than explicitly zeroing the attributes and their mask, pre-fill the entire structure with zeros. this will also cover the padding adjacent to stx_mode, in case it's ever used in the future. explicit zeroing of stx_btime is removed since, with this change, it will already be pre-zeroed. as an aside, zeroing it was not strictly necessary, since STATX_BASIC_STATS does not include STATX_BTIME and thus does not indicate any validity for it. --- src/linux/statx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linux/statx.c b/src/linux/statx.c index 5f6dde92..4fb96e4b 100644 --- a/src/linux/statx.c +++ b/src/linux/statx.c @@ -19,6 +19,7 @@ int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct ret = fstatat(dirfd, path, &st, flags); if (ret) return ret; + *stx = (struct statx){0}; stx->stx_dev_major = major(st.st_dev); stx->stx_dev_minor = minor(st.st_dev); stx->stx_rdev_major = major(st.st_rdev); @@ -37,7 +38,6 @@ int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct stx->stx_mtime.tv_nsec = st.st_mtim.tv_nsec; stx->stx_ctime.tv_sec = st.st_ctim.tv_sec; stx->stx_ctime.tv_nsec = st.st_ctim.tv_nsec; - stx->stx_btime = (struct statx_timestamp){.tv_sec=0, .tv_nsec=0}; stx->stx_mask = STATX_BASIC_STATS; return 0; From 23ab04a8630225371455d5f4538fd078665bb646 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 13 Sep 2024 17:21:17 -0400 Subject: [PATCH 054/115] statx: add new struct statx fields and corresponding mask macros --- include/sys/stat.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/sys/stat.h b/include/sys/stat.h index 57d640d7..0c10dc21 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -120,6 +120,9 @@ int lchmod(const char *, mode_t); #define STATX_BASIC_STATS 0x7ffU #define STATX_BTIME 0x800U #define STATX_ALL 0xfffU +#define STATX_MNT_ID 0x1000U +#define STATX_DIOALIGN 0x2000U +#define STATX_MNT_ID_UNIQUE 0x4000U #define STATX_ATTR_COMPRESSED 0x4 #define STATX_ATTR_IMMUTABLE 0x10 @@ -157,7 +160,11 @@ struct statx { uint32_t stx_rdev_minor; uint32_t stx_dev_major; uint32_t stx_dev_minor; - uint64_t __pad1[14]; + uint64_t stx_mnt_id; + uint32_t stx_dio_mem_align; + uint32_t stx_dio_offet_align; + uint64_t stx_subvol; + uint64_t __pad1[11]; }; int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict); From 6d8000d3c6e1026415f8398f540f5f3783622538 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Thu, 10 Oct 2024 17:09:24 -0400 Subject: [PATCH 055/115] abstract missing SYS_pause syscall with macros newer archs lack the syscall. the pause() function accounted for this with its own #ifdef, but that didn't allow use of the syscall directly elsewhere, so move the logic to macros in src/internal/syscall.h where it can be shared. --- src/internal/syscall.h | 11 +++++++++++ src/unistd/pause.c | 6 +----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/internal/syscall.h b/src/internal/syscall.h index 33d981f9..2d8a5c13 100644 --- a/src/internal/syscall.h +++ b/src/internal/syscall.h @@ -391,6 +391,17 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, #define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__) #define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__)) +#ifdef SYS_pause +#define __sys_pause() __syscall(SYS_pause) +#define __sys_pause_cp() __syscall_cp(SYS_pause) +#else +#define __sys_pause() __syscall(SYS_ppoll, 0, 0, 0, 0) +#define __sys_pause_cp() __syscall_cp(SYS_ppoll, 0, 0, 0, 0) +#endif + +#define sys_pause() __syscall_ret(__sys_pause()) +#define sys_pause_cp() __syscall_ret(__sys_pause_cp()) + #ifdef SYS_wait4 #define __sys_wait4(a,b,c,d) __syscall(SYS_wait4,a,b,c,d) #define __sys_wait4_cp(a,b,c,d) __syscall_cp(SYS_wait4,a,b,c,d) diff --git a/src/unistd/pause.c b/src/unistd/pause.c index 90bbf4ca..90cc8db5 100644 --- a/src/unistd/pause.c +++ b/src/unistd/pause.c @@ -3,9 +3,5 @@ int pause(void) { -#ifdef SYS_pause - return syscall_cp(SYS_pause); -#else - return syscall_cp(SYS_ppoll, 0, 0, 0, 0); -#endif + return sys_pause_cp(); } From 43664364c81a2f5fc0380ace433addbb0e38dea3 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Thu, 10 Oct 2024 17:11:48 -0400 Subject: [PATCH 056/115] fix compile regression in exit on archs without SYS_pause commit 8cca79a72cccbdb54726125d690d7d0095fc2409 added use of SYS_pause to exit() without accounting for newer archs omitting the syscall. use the newly-added __sys_pause abstraction instead, which uses SYS_ppoll when SYS_pause is missing. --- src/exit/exit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exit/exit.c b/src/exit/exit.c index ca11b9ad..17b33cc6 100644 --- a/src/exit/exit.c +++ b/src/exit/exit.c @@ -38,7 +38,7 @@ _Noreturn void exit(int code) int tid = __pthread_self()->tid; int prev = a_cas(exit_lock, 0, tid); if (prev == tid) a_crash(); - else if (prev) for (;;) __syscall(SYS_pause); + else if (prev) for (;;) __sys_pause(); __funcs_on_exit(); __libc_exit_fini(); From 2fc56aaa9f660ebd735d1595c3501b792af42eb8 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Thu, 10 Oct 2024 19:44:58 -0400 Subject: [PATCH 057/115] update contributor name in authorship notices --- COPYRIGHT | 4 ++-- src/stdlib/qsort.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index c1628e9a..2f15edc7 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -74,6 +74,7 @@ Kylie McClain Leah Neukirchen Luca Barbato Luka Perkov +Lynn Ochs M Farkas-Dyck (Strake) Mahesh Bodapati Markus Wichmann @@ -103,7 +104,6 @@ Stefan O'Rear Szabolcs Nagy Timo Teräs Trutz Behn -Valentin Ochs Will Dietz William Haddon William Pitcock @@ -143,7 +143,7 @@ domain. The code also comes with a fallback permissive license for use in jurisdictions that may not recognize the public domain. The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011 -Valentin Ochs and is licensed under an MIT-style license. +Lynn Ochs and is licensed under an MIT-style license. The x86_64 port was written by Nicholas J. Kain and is licensed under the standard MIT terms. diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c index 314ddc29..ab79dc6f 100644 --- a/src/stdlib/qsort.c +++ b/src/stdlib/qsort.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 by Valentin Ochs +/* Copyright (C) 2011 by Lynn Ochs * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to From 5be920e9103fb7c7e492af7cd8bf56a71ae0b2c6 Mon Sep 17 00:00:00 2001 From: Stefan Liebler Date: Thu, 10 Oct 2024 15:02:44 +0200 Subject: [PATCH 058/115] s390x: don't allow br r0 in CRTJMP asm The instruction encoding that would be "br %r0" is not actually a branch to r0, but instead a nop/memory-barrier. gcc 14 has been found to choose r0 for the "r"(pc) constraint, breaking CRTJMP. This patch adjusts the inline assembly constraints and marks "pc" as address ("a"), which disallows usage of r0. --- arch/s390x/reloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390x/reloc.h b/arch/s390x/reloc.h index 6e5c1fb8..38de9d9b 100644 --- a/arch/s390x/reloc.h +++ b/arch/s390x/reloc.h @@ -10,4 +10,4 @@ #define REL_TPOFF R_390_TLS_TPOFF #define CRTJMP(pc,sp) __asm__ __volatile__( \ - "lgr %%r15,%1; br %0" : : "r"(pc), "r"(sp) : "memory" ) + "lgr %%r15,%1; br %0" : : "a"(pc), "r"(sp) : "memory" ) From 047a16398b29d2702a41a0d6d15370d54b9d723c Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sat, 12 Oct 2024 16:51:51 -0700 Subject: [PATCH 059/115] sys/stat.h: fix typo in statx member name stx_dio_offset_align This was added in 23ab04a8630225371455d5f4538fd078665bb646 --- include/sys/stat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sys/stat.h b/include/sys/stat.h index 0c10dc21..c924ce2f 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -162,7 +162,7 @@ struct statx { uint32_t stx_dev_minor; uint64_t stx_mnt_id; uint32_t stx_dio_mem_align; - uint32_t stx_dio_offet_align; + uint32_t stx_dio_offset_align; uint64_t stx_subvol; uint64_t __pad1[11]; }; From 9929a571b5b662c2ce106f1c08a9faf02af58d8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 10 Oct 2024 22:50:46 +0200 Subject: [PATCH 060/115] arm: fix _init/_fini alignment in crti.o This is just cbf59dd6 applied to arm. --- crt/arm/crti.s | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crt/arm/crti.s b/crt/arm/crti.s index 18dc1e41..cccda3ea 100644 --- a/crt/arm/crti.s +++ b/crt/arm/crti.s @@ -3,11 +3,13 @@ .section .init .global _init .type _init,%function +.align 2 _init: push {r0,lr} .section .fini .global _fini .type _fini,%function +.align 2 _fini: push {r0,lr} From 4e6c827cf48aa4277033d3444e419cb435b0a68c Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sat, 19 Oct 2024 20:13:21 +0200 Subject: [PATCH 061/115] mntent: exclude trailing newline from parsed field When the pattern was changed from matching any whitespace to just matching spaces and tabs, a newline started being appended to the value of the matched field, if that field was a string. For example, in a 4-field line, the mnt_opts field would have a newline on the end. This happened because a newline is not a space or a tab, and so was matched as part of the value before the end of the string was reached. \n should therefore be added as a character that terminates a value. This shouldn't interfere with the intention of the change to space and tab only, as it was trying to make sure that other whitespace like carriage returns, that should have been part of parsed values, were. Fixes: f314e133 --- src/misc/mntent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/mntent.c b/src/misc/mntent.c index 78bf0cd0..ee17a69f 100644 --- a/src/misc/mntent.c +++ b/src/misc/mntent.c @@ -81,7 +81,7 @@ struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int bufle len = strlen(linebuf); if (len > INT_MAX) continue; for (i = 0; i < sizeof n / sizeof *n; i++) n[i] = len; - sscanf(linebuf, " %n%*[^ \t]%n %n%*[^ \t]%n %n%*[^ \t]%n %n%*[^ \t]%n %d %d", + sscanf(linebuf, " %n%*[^ \t\n]%n %n%*[^ \t\n]%n %n%*[^ \t\n]%n %n%*[^ \t\n]%n %d %d", n, n+1, n+2, n+3, n+4, n+5, n+6, n+7, &mnt->mnt_freq, &mnt->mnt_passno); } while (linebuf[n[0]] == '#' || n[1]==len); From bc5f816a7a4038255ac55e47ae6c5ef13acb8a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 18 Sep 2024 03:18:42 +0200 Subject: [PATCH 062/115] mips: use preferred asm mnemomic jr for better assembler compatibility The LLVM assembler reportedly assembles the form using the j mnemonic incorrectly (see issue 107460). The jr form is canonical and avoids this problem, so use it instead. --- crt/mips/crtn.s | 4 ++-- crt/mips64/crtn.s | 4 ++-- crt/mipsn32/crtn.s | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crt/mips/crtn.s b/crt/mips/crtn.s index 506a04b7..92eb3d0e 100644 --- a/crt/mips/crtn.s +++ b/crt/mips/crtn.s @@ -3,11 +3,11 @@ .section .init lw $gp,24($sp) lw $ra,28($sp) - j $ra + jr $ra addu $sp,$sp,32 .section .fini lw $gp,24($sp) lw $ra,28($sp) - j $ra + jr $ra addu $sp,$sp,32 diff --git a/crt/mips64/crtn.s b/crt/mips64/crtn.s index f3930b24..8f090ed3 100644 --- a/crt/mips64/crtn.s +++ b/crt/mips64/crtn.s @@ -3,11 +3,11 @@ .section .init ld $gp,16($sp) ld $ra,24($sp) - j $ra + jr $ra daddu $sp,$sp,32 .section .fini ld $gp,16($sp) ld $ra,24($sp) - j $ra + jr $ra daddu $sp,$sp,32 diff --git a/crt/mipsn32/crtn.s b/crt/mipsn32/crtn.s index dccd7e89..0679eac3 100644 --- a/crt/mipsn32/crtn.s +++ b/crt/mipsn32/crtn.s @@ -2,11 +2,11 @@ .section .init ld $gp, 16($sp) ld $ra, 24($sp) - j $ra + jr $ra addu $sp, $sp, 32 .section .fini ld $gp, 16($sp) ld $ra, 24($sp) - j $ra + jr $ra addu $sp, $sp, 32 From f2375aacac13848cb407dfa39bd06eef576d5f2a Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 22 Oct 2024 19:11:24 -0400 Subject: [PATCH 063/115] wire up vdso clock_gettime for powerpc, powerpc64, and s390x symbol names and versions obtained from vdso(7) man page. --- arch/powerpc/syscall_arch.h | 6 ++++++ arch/powerpc64/syscall_arch.h | 4 ++++ arch/s390x/syscall_arch.h | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/arch/powerpc/syscall_arch.h b/arch/powerpc/syscall_arch.h index ede97c1c..54c885cb 100644 --- a/arch/powerpc/syscall_arch.h +++ b/arch/powerpc/syscall_arch.h @@ -92,3 +92,9 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo #define SO_RCVTIMEO_OLD 18 #define SO_SNDTIMEO_OLD 19 + +#define VDSO_USEFUL +#define VDSO_CGT32_SYM "__kernel_clock_gettime" +#define VDSO_CGT32_VER "LINUX_2.6.15" +#define VDSO_CGT_SYM "__kernel_clock_gettime64" +#define VDSO_CGT_VER "LINUX_5.11" diff --git a/arch/powerpc64/syscall_arch.h b/arch/powerpc64/syscall_arch.h index 76b4e335..7d34fbe4 100644 --- a/arch/powerpc64/syscall_arch.h +++ b/arch/powerpc64/syscall_arch.h @@ -88,3 +88,7 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo #define SO_RCVTIMEO_OLD 18 #define SO_SNDTIMEO_OLD 19 + +#define VDSO_USEFUL +#define VDSO_CGT_SYM "__kernel_clock_gettime" +#define VDSO_CGT_VER "LINUX_2.6.15" diff --git a/arch/s390x/syscall_arch.h b/arch/s390x/syscall_arch.h index 83cc9a27..d1cfd2e8 100644 --- a/arch/s390x/syscall_arch.h +++ b/arch/s390x/syscall_arch.h @@ -72,3 +72,7 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo register long r7 __asm__("r7") = f; __asm_syscall("+r"(r2), "r"(r1), "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7)); } + +#define VDSO_USEFUL +#define VDSO_CGT_SYM "__kernel_clock_gettime" +#define VDSO_CGT_VER "LINUX_2.6.29" From 9b6a24f9c56caf70289c1fa3470f4841808ef3b7 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 22 Oct 2024 19:16:42 -0400 Subject: [PATCH 064/115] wire up vdso clock_gettime for riscv32 and riscv64 --- arch/riscv32/syscall_arch.h | 3 +-- arch/riscv64/syscall_arch.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/riscv32/syscall_arch.h b/arch/riscv32/syscall_arch.h index c507f15f..70d2773f 100644 --- a/arch/riscv32/syscall_arch.h +++ b/arch/riscv32/syscall_arch.h @@ -73,8 +73,7 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo } #define VDSO_USEFUL -/* We don't have a clock_gettime function. #define VDSO_CGT_SYM "__vdso_clock_gettime" -#define VDSO_CGT_VER "LINUX_2.6" */ +#define VDSO_CGT_VER "LINUX_4.15" #define IPC_64 0 diff --git a/arch/riscv64/syscall_arch.h b/arch/riscv64/syscall_arch.h index 7fd042cd..81993fc8 100644 --- a/arch/riscv64/syscall_arch.h +++ b/arch/riscv64/syscall_arch.h @@ -71,8 +71,7 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo } #define VDSO_USEFUL -/* We don't have a clock_gettime function. #define VDSO_CGT_SYM "__vdso_clock_gettime" -#define VDSO_CGT_VER "LINUX_2.6" */ +#define VDSO_CGT_VER "LINUX_4.15" #define IPC_64 0 From 61399d4bd02ae1ec03068445aa7ffe9174466bfd Mon Sep 17 00:00:00 2001 From: Xing Li Date: Tue, 10 Sep 2024 09:15:33 +0800 Subject: [PATCH 065/115] loongarch64: add TLSDESC support --- arch/loongarch64/reloc.h | 1 + include/elf.h | 1 + src/ldso/loongarch64/tlsdesc.s | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 src/ldso/loongarch64/tlsdesc.s diff --git a/arch/loongarch64/reloc.h b/arch/loongarch64/reloc.h index 61eaca9e..a4db6a9c 100644 --- a/arch/loongarch64/reloc.h +++ b/arch/loongarch64/reloc.h @@ -17,6 +17,7 @@ #define REL_TPOFF R_LARCH_TLS_TPREL64 #define REL_RELATIVE R_LARCH_RELATIVE #define REL_SYMBOLIC R_LARCH_64 +#define REL_TLSDESC R_LARCH_TLS_DESC64 #define CRTJMP(pc,sp) __asm__ __volatile__( \ "move $sp, %1 ; jr %0" : : "r"(pc), "r"(sp) : "memory" ) diff --git a/include/elf.h b/include/elf.h index 3d5e13e4..8b622f63 100644 --- a/include/elf.h +++ b/include/elf.h @@ -3329,6 +3329,7 @@ enum #define R_LARCH_TLS_TPREL32 10 #define R_LARCH_TLS_TPREL64 11 #define R_LARCH_IRELATIVE 12 +#define R_LARCH_TLS_DESC64 14 #define R_LARCH_MARK_LA 20 #define R_LARCH_MARK_PCREL 21 #define R_LARCH_SOP_PUSH_PCREL 22 diff --git a/src/ldso/loongarch64/tlsdesc.s b/src/ldso/loongarch64/tlsdesc.s new file mode 100644 index 00000000..4b6ea0e5 --- /dev/null +++ b/src/ldso/loongarch64/tlsdesc.s @@ -0,0 +1,37 @@ +.text +.global __tlsdesc_static +.hidden __tlsdesc_static +.type __tlsdesc_static,%function +__tlsdesc_static: + ld.d $a0, $a0, 8 + jr $ra +# size_t __tlsdesc_dynamic(size_t *a) +# { +# struct {size_t modidx,off;} *p = (void*)a[1]; +# size_t *dtv = *(size_t**)(tp - 8); +# return dtv[p->modidx] + p->off - tp; +# } +.global __tlsdesc_dynamic +.hidden __tlsdesc_dynamic +.type __tlsdesc_dynamic,%function +__tlsdesc_dynamic: + addi.d $sp, $sp, -16 + st.d $t1, $sp, 0 + st.d $t2, $sp, 8 + + ld.d $t2, $tp, -8 # t2=dtv + + ld.d $a0, $a0, 8 # a0=&{modidx,off} + ld.d $t1, $a0, 8 # t1=off + ld.d $a0, $a0, 0 # a0=modidx + slli.d $a0, $a0, 3 # a0=8*modidx + + add.d $a0, $a0, $t2 # a0=dtv+8*modidx + ld.d $a0, $a0, 0 # a0=dtv[modidx] + add.d $a0, $a0, $t1 # a0=dtv[modidx]+off + sub.d $a0, $a0, $tp # a0=dtv[modidx]+off-tp + + ld.d $t1, $sp, 0 + ld.d $t2, $sp, 8 + addi.d $sp, $sp, 16 + jr $ra From 47fa6e4fcc5f61c365c91a9bc90e7ed8b3a178ef Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 13 Dec 2024 11:31:40 +0000 Subject: [PATCH 066/115] SIGEV_THREAD timers: fix fatal signal if internal SIGTIMER becomes unblocked commit 6ae2568bc2367b4d47e0ea1cb043fd56e697912f introduced a fatal signal condition if the internal timer signal used for SIGEV_THREAD timers is unblocked. this can happen whenever the application alters the signal mask with SIG_SETMASK, since sigset_t objects never include the bits used for implementation-internal signals. this patch effectively reverts the breakage by adding back a no-op signal handler. overruns will not be accounted if the timer signal becomes unblocked, but POSIX does not specify them except for SIGEV_SIGNAL timers anyway. --- src/time/timer_create.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/time/timer_create.c b/src/time/timer_create.c index 424c70b7..2d8a62bd 100644 --- a/src/time/timer_create.c +++ b/src/time/timer_create.c @@ -22,6 +22,10 @@ static void dummy_0() } weak_alias(dummy_0, __pthread_tsd_run_dtors); +static void timer_handler(int sig, siginfo_t *si, void *ctx) +{ +} + static void cleanup_fromsig(void *p) { pthread_t self = __pthread_self(); @@ -98,7 +102,10 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict break; case SIGEV_THREAD: if (!init) { - struct sigaction sa = { .sa_handler = SIG_DFL }; + struct sigaction sa = { + .sa_sigaction = timer_handler, + .sa_flags = SA_SIGINFO | SA_RESTART + }; __libc_sigaction(SIGTIMER, &sa, 0); a_store(&init, 1); } From 561cd07dff8003251729569e5539b00698941697 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 13 Dec 2024 11:41:54 +0000 Subject: [PATCH 067/115] SIGEV_THREAD timers: re-block signals when reusing kernel thread previously, we left any changes made by the application to the timer thread's signal mask active when resetting the thread state for reuse. not only did this violate the intended invariant that timer threads start with all signals blocked; it also allowed application code to execute in a thread that, formally, did not exist. and further, if the internal SIGTIMER signal became unblocked, it could also lead to missed timer expiration events. --- src/time/timer_create.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/time/timer_create.c b/src/time/timer_create.c index 2d8a62bd..cc6c2236 100644 --- a/src/time/timer_create.c +++ b/src/time/timer_create.c @@ -30,6 +30,8 @@ static void cleanup_fromsig(void *p) { pthread_t self = __pthread_self(); __pthread_tsd_run_dtors(); + __block_app_sigs(0); + __syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGTIMER_SET, 0, _NSIG/8); self->cancel = 0; self->cancelbuf = 0; self->canceldisable = 0; From d36e5bf83b601da15b2b4ab0cc225d3fb93ef489 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 23 Dec 2024 07:05:06 +0000 Subject: [PATCH 068/115] mq: add x32-specific implementations to work around mismatched kernel ABI the kernel mq_attr structure has 8 64-bit longs instead of 8 32-bit longs. it's not clear that this is the nicest way to implement the fix, but the concept (translation) is right, and the details can be changed later if desired. --- src/mq/x32/mq_open.c | 22 ++++++++++++++++++++++ src/mq/x32/mq_setattr.c | 14 ++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/mq/x32/mq_open.c create mode 100644 src/mq/x32/mq_setattr.c diff --git a/src/mq/x32/mq_open.c b/src/mq/x32/mq_open.c new file mode 100644 index 00000000..23481959 --- /dev/null +++ b/src/mq/x32/mq_open.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include "syscall.h" + +mqd_t mq_open(const char *name, int flags, ...) +{ + mode_t mode = 0; + struct mq_attr *attr = 0; + long long attrbuf[8]; + if (*name == '/') name++; + if (flags & O_CREAT) { + va_list ap; + va_start(ap, flags); + mode = va_arg(ap, mode_t); + attr = va_arg(ap, struct mq_attr *); + if (attr) for (int i=0; i<8; i++) + attrbuf[i] = *(long *)((char *)attr + i*sizeof(long)); + va_end(ap); + } + return syscall(SYS_mq_open, name, flags, mode, attr?attrbuf:0); +} diff --git a/src/mq/x32/mq_setattr.c b/src/mq/x32/mq_setattr.c new file mode 100644 index 00000000..0c631175 --- /dev/null +++ b/src/mq/x32/mq_setattr.c @@ -0,0 +1,14 @@ +#include +#include "syscall.h" + +int mq_setattr(mqd_t mqd, const struct mq_attr *restrict new, struct mq_attr *restrict old) +{ + long long attr[8]; + if (new) for (int i=0; i<8; i++) + attr[i] = *(long *)((char *)new + i*sizeof(long)); + int ret = __syscall(SYS_mq_getsetattr, mqd, new?attr:0, old?attr:0); + if (ret < 0) return __syscall_ret(ret); + if (old) for (int i=0; i<8; i++) + *(long *)((char *)old + i*sizeof(long)) = attr[i]; + return 0; +} From 1a98576401ff604ff06a030a3644e2780b2a837d Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 13 Jan 2025 08:31:02 -0500 Subject: [PATCH 069/115] sched.h: reduce namespace conflicts in _GNU_SOURCE profile we have the cpuset macros call calloc/free/memset/memcmp directly so that they don't depend on any further ABI surface. this is not namespace-clean, but only affects the _GNU_SOURCE feature profile, which is not intended to be namespace-clean. nonetheless, reports come up now and then of things which are gratuitously broken, usually when an application has wrapped malloc with macros. this patch parenthesizes the function names so that function-like macros will not be expanded, and removes the unused declaration of memcpy. this is not a complete solution, but it should improve things for affected applications, particularly ones which are not even trying to use the cpuset interfaces which got them just because g++ always defines _GNU_SOURCE. --- include/sched.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/include/sched.h b/include/sched.h index 204c34f5..8c3b53f0 100644 --- a/include/sched.h +++ b/include/sched.h @@ -78,11 +78,10 @@ int clone (int (*)(void *), void *, int, void *, ...); int unshare(int); int setns(int, int); -void *memcpy(void *__restrict, const void *__restrict, size_t); -int memcmp(const void *, const void *, size_t); -void *memset (void *, int, size_t); -void *calloc(size_t, size_t); -void free(void *); +int (memcmp)(const void *, const void *, size_t); +void *(memset)(void *, int, size_t); +void *(calloc)(size_t, size_t); +void (free)(void *); typedef struct cpu_set_t { unsigned long __bits[128/sizeof(long)]; } cpu_set_t; int __sched_cpucount(size_t, const cpu_set_t *); @@ -116,13 +115,13 @@ __CPU_op_func_S(XOR, ^) #define CPU_XOR_S(a,b,c,d) __CPU_XOR_S(a,b,c,d) #define CPU_COUNT_S(size,set) __sched_cpucount(size,set) -#define CPU_ZERO_S(size,set) memset(set,0,size) -#define CPU_EQUAL_S(size,set1,set2) (!memcmp(set1,set2,size)) +#define CPU_ZERO_S(size,set) (memset)(set,0,size) +#define CPU_EQUAL_S(size,set1,set2) (!(memcmp)(set1,set2,size)) #define CPU_ALLOC_SIZE(n) (sizeof(long) * ( (n)/(8*sizeof(long)) \ + ((n)%(8*sizeof(long)) + 8*sizeof(long)-1)/(8*sizeof(long)) ) ) -#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n))) -#define CPU_FREE(set) free(set) +#define CPU_ALLOC(n) ((cpu_set_t *)(calloc)(1,CPU_ALLOC_SIZE(n))) +#define CPU_FREE(set) (free)(set) #define CPU_SETSIZE 1024 From 5ccf05d86dacba0e6542ae1a6b6508a41cfe326e Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Mon, 18 Nov 2024 03:44:47 +0000 Subject: [PATCH 070/115] ldso: don't reclaim zero-memory-sized segments Some weird linkers may emit PT_LOAD segments with memsz = 0. ELF specification does not forbid this, but such a segment with non-zero p_vaddr will result in reclaiming of invalid memory address. This patch skips such segments during reclaiming for better compatibility. --- ldso/dynlink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 3b57c07f..715948f4 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -616,6 +616,7 @@ static void reclaim_gaps(struct dso *dso) for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) { if (ph->p_type!=PT_LOAD) continue; if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue; + if (ph->p_memsz == 0) continue; reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr); reclaim(dso, ph->p_vaddr+ph->p_memsz, ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE); From 6af4f25b899e89e4b91f8c197ae5a6ce04bcce7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 24 Jan 2025 06:12:13 +0100 Subject: [PATCH 071/115] s390x: manually inline __tls_get_addr in __tls_get_offset Calling __tls_get_addr with brasl is not valid since it's a global symbol; doing so results in an R_390_PC32DBL relocation error from lld. We could fix this by marking __tls_get_addr hidden since it is not part of the s390x ABI, or by using a different instruction. However, given its simplicity, it makes more sense to just manually inline it into __tls_get_offset for performance. The patch has been tested by applying to Zig's bundled musl copy and running the full Zig test suite under qemu-s390x. --- src/thread/s390x/__tls_get_offset.s | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/thread/s390x/__tls_get_offset.s b/src/thread/s390x/__tls_get_offset.s index 8ee92de8..405f118b 100644 --- a/src/thread/s390x/__tls_get_offset.s +++ b/src/thread/s390x/__tls_get_offset.s @@ -1,17 +1,17 @@ .global __tls_get_offset .type __tls_get_offset,%function __tls_get_offset: - stmg %r14, %r15, 112(%r15) - aghi %r15, -160 + ear %r0, %a0 + sllg %r0, %r0, 32 + ear %r0, %a1 - la %r2, 0(%r2, %r12) - brasl %r14, __tls_get_addr + la %r1, 0(%r2, %r12) - ear %r1, %a0 - sllg %r1, %r1, 32 - ear %r1, %a1 + lg %r3, 0(%r1) + sllg %r4, %r3, 3 + lg %r5, 8(%r0) + lg %r2, 0(%r4, %r5) + ag %r2, 8(%r1) + sgr %r2, %r0 - sgr %r2, %r1 - - lmg %r14, %r15, 272(%r15) br %r14 From 5e594aeabf331ae0abb380c5fa58e5348b2b0148 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 9 Feb 2025 10:02:10 -0500 Subject: [PATCH 072/115] iconv: fix erroneous decoding of some invalid ShiftJIS sequences out-of-range second bytes were not handled, leading to wrong character output rather than a reported encoding error. fix based on bug report by Nick Wellnhofer, submitted in private in case the issue turned out to have security implications. --- src/locale/iconv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/locale/iconv.c b/src/locale/iconv.c index 7fb2e1ef..9605c8e9 100644 --- a/src/locale/iconv.c +++ b/src/locale/iconv.c @@ -339,6 +339,8 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri } else if (d-159 <= 252-159) { c++; d -= 159; + } else { + goto ilseq; } if (c>=84) goto ilseq; c = jis0208[c][d]; From e5adcd97b5196e29991b524237381a0202a60659 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 9 Feb 2025 10:07:19 -0500 Subject: [PATCH 073/115] 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; From 4c4f15dae57125e5b65b9690901384ae501d38e2 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 9 Feb 2025 13:36:44 -0500 Subject: [PATCH 074/115] hasmntopt: match only whole options not arbitrary substrings the man page for this nonstandardized function has historically documented it as scanning for a substring; however, this is functionally incorrect (matches the substring "atime" in the "noatime" option, for example) and differs from other existing implementations. with the change made here, it should match glibc and other implementations, only matching whole options delimited by commas or separated from a value by an equals sign. --- src/misc/mntent.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/misc/mntent.c b/src/misc/mntent.c index ee17a69f..76f9c162 100644 --- a/src/misc/mntent.c +++ b/src/misc/mntent.c @@ -115,5 +115,13 @@ int addmntent(FILE *f, const struct mntent *mnt) char *hasmntopt(const struct mntent *mnt, const char *opt) { - return strstr(mnt->mnt_opts, opt); + size_t l = strlen(opt); + char *p = mnt->mnt_opts; + for (;;) { + if (!strncmp(p, opt, l) && (!p[l] || p[l]==',' || p[l]=='=')) + return p; + p = strchr(p, ','); + if (!p) return 0; + p++; + } } From c47ad25ea3b484e10326f933e927c0bc8cded3da Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 12 Feb 2025 17:06:30 -0500 Subject: [PATCH 075/115] 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; From f1cda422cd3917130da4df423c1fcb6927f0f8eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 23 Nov 2024 01:19:51 +0100 Subject: [PATCH 076/115] i386, x86_64, x32: set the symbol type for the crt1 START function --- arch/i386/crt_arch.h | 1 + arch/x32/crt_arch.h | 1 + arch/x86_64/crt_arch.h | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/i386/crt_arch.h b/arch/i386/crt_arch.h index 43c8477a..1a80fce3 100644 --- a/arch/i386/crt_arch.h +++ b/arch/i386/crt_arch.h @@ -3,6 +3,7 @@ __asm__( ".weak _DYNAMIC \n" ".hidden _DYNAMIC \n" ".global " START "\n" +".type " START ",%function \n" START ":\n" " xor %ebp,%ebp \n" " mov %esp,%eax \n" diff --git a/arch/x32/crt_arch.h b/arch/x32/crt_arch.h index 3eec61bd..b1c9c476 100644 --- a/arch/x32/crt_arch.h +++ b/arch/x32/crt_arch.h @@ -1,6 +1,7 @@ __asm__( ".text \n" ".global " START " \n" +".type " START ",%function \n" START ": \n" " xor %rbp,%rbp \n" " mov %rsp,%rdi \n" diff --git a/arch/x86_64/crt_arch.h b/arch/x86_64/crt_arch.h index 3eec61bd..b1c9c476 100644 --- a/arch/x86_64/crt_arch.h +++ b/arch/x86_64/crt_arch.h @@ -1,6 +1,7 @@ __asm__( ".text \n" ".global " START " \n" +".type " START ",%function \n" START ": \n" " xor %rbp,%rbp \n" " mov %rsp,%rdi \n" From 362fc54572553254049b8e9d850725b232ed147d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 23 Nov 2024 01:20:08 +0100 Subject: [PATCH 077/115] riscv: mark __restore and __restore_rt hidden --- src/signal/riscv32/restore.s | 2 ++ src/signal/riscv64/restore.s | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/signal/riscv32/restore.s b/src/signal/riscv32/restore.s index 40012c75..5a0af695 100644 --- a/src/signal/riscv32/restore.s +++ b/src/signal/riscv32/restore.s @@ -1,7 +1,9 @@ .global __restore +.hidden __restore .type __restore, %function __restore: .global __restore_rt +.hidden __restore_rt .type __restore_rt, %function __restore_rt: li a7, 139 # SYS_rt_sigreturn diff --git a/src/signal/riscv64/restore.s b/src/signal/riscv64/restore.s index 40012c75..5a0af695 100644 --- a/src/signal/riscv64/restore.s +++ b/src/signal/riscv64/restore.s @@ -1,7 +1,9 @@ .global __restore +.hidden __restore .type __restore, %function __restore: .global __restore_rt +.hidden __restore_rt .type __restore_rt, %function __restore_rt: li a7, 139 # SYS_rt_sigreturn From 00fb7107cafc9cd7316f85ae2d8b61e478caaa7f Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 21 Feb 2025 19:32:27 -0500 Subject: [PATCH 078/115] shadow.h: remove declaration of function not implemented --- include/shadow.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/shadow.h b/include/shadow.h index 2b1be413..a9d6940f 100644 --- a/include/shadow.h +++ b/include/shadow.h @@ -28,7 +28,6 @@ void setspent(void); void endspent(void); struct spwd *getspent(void); struct spwd *fgetspent(FILE *); -struct spwd *sgetspent(const char *); int putspent(const struct spwd *, FILE *); struct spwd *getspnam(const char *); From cabbd8697d39c09ca37fb3d63b86b42526b81fda Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 21 Feb 2025 19:42:38 -0500 Subject: [PATCH 079/115] bind_textdomain_codeset: fix return value this function is documented as returning a null pointer on failure and the current textdomain encoding, which is always UTF-8 in our implementation, on success. there was some confusion over whether it's expected to also return a null pointer in the case where it's using the locale's encoding by default, rather than an explicitly bound one, but it does not seem like that behavior would match applications' expectations, and it would require gratuitously storing a meaningless 1-bit state for the textdomain. --- src/locale/bind_textdomain_codeset.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/locale/bind_textdomain_codeset.c b/src/locale/bind_textdomain_codeset.c index 5ebfd5e8..240e83ed 100644 --- a/src/locale/bind_textdomain_codeset.c +++ b/src/locale/bind_textdomain_codeset.c @@ -5,7 +5,9 @@ char *bind_textdomain_codeset(const char *domainname, const char *codeset) { - if (codeset && strcasecmp(codeset, "UTF-8")) + if (codeset && strcasecmp(codeset, "UTF-8")) { errno = EINVAL; - return NULL; + return 0; + } + return "UTF-8"; } From b0dc340b3865a9b980e3b9a6938fdec6fe10fba2 Mon Sep 17 00:00:00 2001 From: Xing Li Date: Fri, 15 Nov 2024 15:26:42 +0800 Subject: [PATCH 080/115] loongarch64: add bits/hwcap.h for cpu feature bits in AT_HWCAP auxv entry --- arch/loongarch64/bits/hwcap.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 arch/loongarch64/bits/hwcap.h diff --git a/arch/loongarch64/bits/hwcap.h b/arch/loongarch64/bits/hwcap.h new file mode 100644 index 00000000..b8184f69 --- /dev/null +++ b/arch/loongarch64/bits/hwcap.h @@ -0,0 +1,14 @@ +#define HWCAP_LOONGARCH_CPUCFG (1 << 0) +#define HWCAP_LOONGARCH_LAM (1 << 1) +#define HWCAP_LOONGARCH_UAL (1 << 2) +#define HWCAP_LOONGARCH_FPU (1 << 3) +#define HWCAP_LOONGARCH_LSX (1 << 4) +#define HWCAP_LOONGARCH_LASX (1 << 5) +#define HWCAP_LOONGARCH_CRC32 (1 << 6) +#define HWCAP_LOONGARCH_COMPLEX (1 << 7) +#define HWCAP_LOONGARCH_CRYPTO (1 << 8) +#define HWCAP_LOONGARCH_LVZ (1 << 9) +#define HWCAP_LOONGARCH_LBT_X86 (1 << 10) +#define HWCAP_LOONGARCH_LBT_ARM (1 << 11) +#define HWCAP_LOONGARCH_LBT_MIPS (1 << 12) +#define HWCAP_LOONGARCH_PTW (1 << 13) From 06c5e4e832f4796be02c743270fb554f978de02c Mon Sep 17 00:00:00 2001 From: Lihua Zhao Date: Wed, 18 Dec 2024 17:12:22 +0800 Subject: [PATCH 081/115] signal: check sigpause() input parameter --- src/signal/sigpause.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/signal/sigpause.c b/src/signal/sigpause.c index 363d2fec..1587c391 100644 --- a/src/signal/sigpause.c +++ b/src/signal/sigpause.c @@ -4,6 +4,6 @@ int sigpause(int sig) { sigset_t mask; sigprocmask(0, 0, &mask); - sigdelset(&mask, sig); + if (sigdelset(&mask, sig)) return -1; return sigsuspend(&mask); } From 5e03c03fcde3534b37a0b995a438cd176d6882d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 8 Feb 2025 05:39:59 +0100 Subject: [PATCH 082/115] clone: align the given stack pointer on or1k and riscv This was an oversight specific to these archs; others have always aligned the new stack pointer correctly. --- src/thread/or1k/clone.s | 2 ++ src/thread/riscv32/clone.s | 1 + src/thread/riscv64/clone.s | 1 + 3 files changed, 4 insertions(+) diff --git a/src/thread/or1k/clone.s b/src/thread/or1k/clone.s index 2473ac20..9a84aeba 100644 --- a/src/thread/or1k/clone.s +++ b/src/thread/or1k/clone.s @@ -6,6 +6,8 @@ .hidden __clone .type __clone,@function __clone: + l.xori r11, r0, -4 + l.and r4, r4, r11 l.addi r4, r4, -8 l.sw 0(r4), r3 l.sw 4(r4), r6 diff --git a/src/thread/riscv32/clone.s b/src/thread/riscv32/clone.s index 3102239d..e2116e33 100644 --- a/src/thread/riscv32/clone.s +++ b/src/thread/riscv32/clone.s @@ -8,6 +8,7 @@ .type __clone, %function __clone: # Save func and arg to stack + andi a1, a1, -16 addi a1, a1, -16 sw a0, 0(a1) sw a3, 4(a1) diff --git a/src/thread/riscv64/clone.s b/src/thread/riscv64/clone.s index db908248..0e6f41a8 100644 --- a/src/thread/riscv64/clone.s +++ b/src/thread/riscv64/clone.s @@ -8,6 +8,7 @@ .type __clone, %function __clone: # Save func and arg to stack + andi a1, a1, -16 addi a1, a1, -16 sd a0, 0(a1) sd a3, 8(a1) From b6b81f697b38ef915a5dbf1311baba164822e917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 12 Dec 2024 17:56:04 +0100 Subject: [PATCH 083/115] clone: clear the frame pointer in the child process on relevant ports This just mirrors what is done in the start code for the affected ports, as well as what is already done for the three x86 ports. Clearing the frame pointer helps protect FP-based unwinders from wrongly attempting to traverse into the parent thread's call frame stack. --- src/thread/aarch64/clone.s | 3 ++- src/thread/arm/clone.s | 3 ++- src/thread/loongarch64/clone.s | 1 + src/thread/m68k/clone.s | 3 ++- src/thread/microblaze/clone.s | 3 ++- src/thread/mips/clone.s | 3 ++- src/thread/mips64/clone.s | 3 ++- src/thread/mipsn32/clone.s | 3 ++- src/thread/or1k/clone.s | 3 ++- 9 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/thread/aarch64/clone.s b/src/thread/aarch64/clone.s index e3c83395..9ac272bd 100644 --- a/src/thread/aarch64/clone.s +++ b/src/thread/aarch64/clone.s @@ -24,7 +24,8 @@ __clone: // parent ret // child -1: ldp x1,x0,[sp],#16 +1: mov fp, 0 + ldp x1,x0,[sp],#16 blr x1 mov x8,#93 // SYS_exit svc #0 diff --git a/src/thread/arm/clone.s b/src/thread/arm/clone.s index bb0965da..4ff0c0e8 100644 --- a/src/thread/arm/clone.s +++ b/src/thread/arm/clone.s @@ -19,7 +19,8 @@ __clone: ldmfd sp!,{r4,r5,r6,r7} bx lr -1: mov r0,r6 +1: mov fp,#0 + mov r0,r6 bl 3f 2: mov r7,#1 svc 0 diff --git a/src/thread/loongarch64/clone.s b/src/thread/loongarch64/clone.s index a165b365..cb4aacfc 100644 --- a/src/thread/loongarch64/clone.s +++ b/src/thread/loongarch64/clone.s @@ -22,6 +22,7 @@ __clone: beqz $a0, 1f # whether child process jirl $zero, $ra, 0 # parent process return 1: + move $fp, $zero ld.d $t8, $sp, 0 # function pointer ld.d $a0, $sp, 8 # argument pointer jirl $ra, $t8, 0 # call the user's function diff --git a/src/thread/m68k/clone.s b/src/thread/m68k/clone.s index f6dfa06f..0134cf4e 100644 --- a/src/thread/m68k/clone.s +++ b/src/thread/m68k/clone.s @@ -18,7 +18,8 @@ __clone: beq 1f movem.l (%sp)+,%d2-%d5 rts -1: move.l %a1,-(%sp) +1: suba.l %fp,%fp + move.l %a1,-(%sp) jsr (%a0) move.l #1,%d0 trap #0 diff --git a/src/thread/microblaze/clone.s b/src/thread/microblaze/clone.s index b68cc5fc..64e3f074 100644 --- a/src/thread/microblaze/clone.s +++ b/src/thread/microblaze/clone.s @@ -22,7 +22,8 @@ __clone: rtsd r15, 8 nop -1: lwi r3, r1, 0 +1: add r19, r0, r0 + lwi r3, r1, 0 lwi r5, r1, 4 brald r15, r3 nop diff --git a/src/thread/mips/clone.s b/src/thread/mips/clone.s index 04463385..229b987e 100644 --- a/src/thread/mips/clone.s +++ b/src/thread/mips/clone.s @@ -27,7 +27,8 @@ __clone: addu $sp, $sp, 16 jr $ra nop -1: lw $25, 0($sp) +1: move $fp, $0 + lw $25, 0($sp) lw $4, 4($sp) jalr $25 nop diff --git a/src/thread/mips64/clone.s b/src/thread/mips64/clone.s index 2d86899a..8de3db6c 100644 --- a/src/thread/mips64/clone.s +++ b/src/thread/mips64/clone.s @@ -25,7 +25,8 @@ __clone: nop jr $ra nop -1: ld $25, 0($sp) # function pointer +1: move $fp, $0 + ld $25, 0($sp) # function pointer ld $4, 8($sp) # argument pointer jalr $25 # call the user's function nop diff --git a/src/thread/mipsn32/clone.s b/src/thread/mipsn32/clone.s index 4d3c8c7a..9571231a 100644 --- a/src/thread/mipsn32/clone.s +++ b/src/thread/mipsn32/clone.s @@ -25,7 +25,8 @@ __clone: nop jr $ra nop -1: lw $25, 0($sp) # function pointer +1: move $fp, $0 + lw $25, 0($sp) # function pointer lw $4, 4($sp) # argument pointer jalr $25 # call the user's function nop diff --git a/src/thread/or1k/clone.s b/src/thread/or1k/clone.s index 9a84aeba..b41488a2 100644 --- a/src/thread/or1k/clone.s +++ b/src/thread/or1k/clone.s @@ -25,7 +25,8 @@ __clone: l.jr r9 l.nop -1: l.lwz r11, 0(r1) +1: l.ori r2, r0, 0 + l.lwz r11, 0(r1) l.jalr r11 l.lwz r3, 4(r1) From a34ca6ead1f04283ebd04ffcc42f8dbc6995f2d1 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 22 Feb 2025 11:27:33 -0500 Subject: [PATCH 084/115] termios: fix input speed handling traditionally, our cfsetispeed just set the output speed. this was not conforming or reasonable behavior. use of the input baud bits in termios c_cflag depends on kernel support, which was added to linux along with TCSETS2 ioctl and arbitrary-baud functionality sometime in the 2.6 series. with older kernels, the separate input baud will not take, but this is the best behavior we can hope for anyway, certainly better than wrongly clobbering output baud setting. the nonstandard cfsetspeed is now moved to a separate file, since it no longer admits the weak alias implementation that made it namespace-safe. it now sets the output speed, and on success, sets the input speed to 0 (matched to output). --- src/termios/cfgetospeed.c | 2 +- src/termios/cfsetospeed.c | 10 +++++++--- src/termios/cfsetspeed.c | 11 +++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 src/termios/cfsetspeed.c diff --git a/src/termios/cfgetospeed.c b/src/termios/cfgetospeed.c index 55fa6f55..de46a1d8 100644 --- a/src/termios/cfgetospeed.c +++ b/src/termios/cfgetospeed.c @@ -9,5 +9,5 @@ speed_t cfgetospeed(const struct termios *tio) speed_t cfgetispeed(const struct termios *tio) { - return cfgetospeed(tio); + return (tio->c_cflag & CIBAUD) / (CIBAUD/CBAUD); } diff --git a/src/termios/cfsetospeed.c b/src/termios/cfsetospeed.c index c9cbdd9d..3eab092a 100644 --- a/src/termios/cfsetospeed.c +++ b/src/termios/cfsetospeed.c @@ -16,7 +16,11 @@ int cfsetospeed(struct termios *tio, speed_t speed) int cfsetispeed(struct termios *tio, speed_t speed) { - return speed ? cfsetospeed(tio, speed) : 0; + if (speed & ~CBAUD) { + errno = EINVAL; + return -1; + } + tio->c_cflag &= ~CIBAUD; + tio->c_cflag |= speed * (CIBAUD/CBAUD); + return 0; } - -weak_alias(cfsetospeed, cfsetspeed); diff --git a/src/termios/cfsetspeed.c b/src/termios/cfsetspeed.c new file mode 100644 index 00000000..2c369db9 --- /dev/null +++ b/src/termios/cfsetspeed.c @@ -0,0 +1,11 @@ +#define _BSD_SOURCE +#include +#include +#include + +int cfsetspeed(struct termios *tio, speed_t speed) +{ + int r = cfsetospeed(tio, speed); + if (!r) cfsetispeed(tio, 0); + return r; +} From 6915b34860459a963fb1ba468a4d5389dd65c67b Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 5 May 2025 09:23:32 -0400 Subject: [PATCH 085/115] dns resolver: reorder sockaddr union to make initialization safe some recent compilers have adopted a dubious interpretation of the C specification for union initializers, that when the initialized member is smaller than the size of the union, the remaining padding does not have to be zero-initialized. in the interests of not depending on any particular interpretation, place the larger member first so it's initialized and ensures the whole object is zero-filled. --- src/network/res_msend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/res_msend.c b/src/network/res_msend.c index 86c2fcf4..fcb52513 100644 --- a/src/network/res_msend.c +++ b/src/network/res_msend.c @@ -83,8 +83,8 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries, int fd; int timeout, attempts, retry_interval, servfail_retry; union { - struct sockaddr_in sin; struct sockaddr_in6 sin6; + struct sockaddr_in sin; } sa = {0}, ns[MAXNS] = {{0}}; socklen_t sl = sizeof sa.sin; int nns = 0; From 23febbd3c5d6b4e367faee4f39b8e8c3b95ab588 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 5 May 2025 09:27:29 -0400 Subject: [PATCH 086/115] align mbsnrtowcs behavior on partial character with new requirements POSIX 2024 added a requirement that mbsnrtowcs, like mbrtowc, consume any final partial character and store it in the mbstate_t object before returning. this was previously unspecified but documented as a potential future change. an internal mbstate_t object is added for the case where the argument is a null pointer. previously this was not needed since no operations could modify the internal object and not processing it at all gave the same behavior "as if" there were an internal object. --- src/multibyte/mbsnrtowcs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/multibyte/mbsnrtowcs.c b/src/multibyte/mbsnrtowcs.c index 931192e2..47cbdc00 100644 --- a/src/multibyte/mbsnrtowcs.c +++ b/src/multibyte/mbsnrtowcs.c @@ -2,11 +2,13 @@ size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st) { + static unsigned internal_state; size_t l, cnt=0, n2; wchar_t *ws, wbuf[256]; const char *s = *src; const char *tmp_s; + if (!st) st = (void *)&internal_state; if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf; else ws = wcs; @@ -41,8 +43,8 @@ size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, si s = 0; break; } - /* have to roll back partial character */ - *(unsigned *)st = 0; + s += n; + n -= n; break; } s += l; n -= l; From ae3a8c93a663b553e65f096498937083dad210d2 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 16 May 2025 09:10:19 -0400 Subject: [PATCH 087/115] fix strcasestr failing to find zero-length needle the loop condition ending on end-of-haystack ends before a zero-length needle can be matched, so just explicitly check it before the loop. --- src/string/strcasestr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/string/strcasestr.c b/src/string/strcasestr.c index af109f36..dc598bc3 100644 --- a/src/string/strcasestr.c +++ b/src/string/strcasestr.c @@ -4,6 +4,7 @@ char *strcasestr(const char *h, const char *n) { size_t l = strlen(n); + if (!l) return (char *)h; for (; *h; h++) if (!strncasecmp(h, n, l)) return (char *)h; return 0; } From fde29c04adbab9d5b081bf6717b5458188647f1c Mon Sep 17 00:00:00 2001 From: Casey Connolly Date: Wed, 23 Apr 2025 15:06:48 +0200 Subject: [PATCH 088/115] stdio: skip empty iovec when buffering is disabled When buffering on a FILE is disabled we still send both iovecs, even though the first one is always empty. Clean things up by skipping the empty iovec instead. --- src/stdio/__stdio_write.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stdio/__stdio_write.c b/src/stdio/__stdio_write.c index d2d89475..5356553d 100644 --- a/src/stdio/__stdio_write.c +++ b/src/stdio/__stdio_write.c @@ -11,6 +11,11 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len) size_t rem = iov[0].iov_len + iov[1].iov_len; int iovcnt = 2; ssize_t cnt; + + if (!iov->iov_len) { + iov++; + iovcnt--; + } for (;;) { cnt = syscall(SYS_writev, f->fd, iov, iovcnt); if (cnt == rem) { From 86373b4999bfd9a9379bc4a3ca877b1c80a2a340 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Fri, 3 Jan 2025 13:40:44 -0600 Subject: [PATCH 089/115] 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 From 18289e5dea03f46dbb2315bf51a261d1f9ebe3ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Neusch=C3=A4fer?= Date: Wed, 23 Oct 2024 14:46:39 +0200 Subject: [PATCH 090/115] ldso: fix typo in comment --- ldso/dlstart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ldso/dlstart.c b/ldso/dlstart.c index 259f5e18..4aac42bc 100644 --- a/ldso/dlstart.c +++ b/ldso/dlstart.c @@ -45,7 +45,7 @@ hidden void _dlstart_c(size_t *sp, size_t *dynv) /* If dynv is null, the entry point was started from loader * that is not fdpic-aware. We can assume normal fixed- * displacement ELF loading was performed, but when ldso was - * run as a command, finding the Ehdr is a heursitic: we + * run as a command, finding the Ehdr is a heuristic: we * have to assume Phdrs start in the first 4k of the file. */ base = aux[AT_BASE]; if (!base) base = aux[AT_PHDR] & -4096; From fcdff46a3203400e08a2264c34b3c7fb62bf6969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Neusch=C3=A4fer?= Date: Thu, 24 Oct 2024 01:19:30 +0200 Subject: [PATCH 091/115] statx: add Linux 6.11 fields/constants As of Linux 6.11, these fields and mask macros have been added to include/uapi/linux/stat.h. --- include/sys/stat.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/sys/stat.h b/include/sys/stat.h index c924ce2f..4f7dc2b1 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -123,6 +123,8 @@ int lchmod(const char *, mode_t); #define STATX_MNT_ID 0x1000U #define STATX_DIOALIGN 0x2000U #define STATX_MNT_ID_UNIQUE 0x4000U +#define STATX_SUBVOL 0x8000U +#define STATX_WRITE_ATOMIC 0x10000U #define STATX_ATTR_COMPRESSED 0x4 #define STATX_ATTR_IMMUTABLE 0x10 @@ -133,6 +135,7 @@ int lchmod(const char *, mode_t); #define STATX_ATTR_MOUNT_ROOT 0x2000 #define STATX_ATTR_VERITY 0x100000 #define STATX_ATTR_DAX 0x200000 +#define STATX_ATTR_WRITE_ATOMIC 0x400000 struct statx_timestamp { int64_t tv_sec; @@ -164,7 +167,12 @@ struct statx { uint32_t stx_dio_mem_align; uint32_t stx_dio_offset_align; uint64_t stx_subvol; - uint64_t __pad1[11]; + uint32_t stx_atomic_write_unit_min; + uint32_t stx_atomic_write_unit_max; + uint32_t stx_atomic_write_segments_max; + uint32_t __pad1[1]; + uint64_t __pad2[9]; + }; int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict); From ab4635fba6769e19fb411a1ab3c8aa7407e11188 Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Thu, 12 Oct 2023 20:31:48 +0200 Subject: [PATCH 092/115] make __getauxval a public ABI symbol This is needed so that libgcc can access AT_HWCAP without violating link namespace rules. Internally musl already used __getauxval symbol for the same reason, we just remove the hidden marking. --- src/include/sys/auxv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/sys/auxv.h b/src/include/sys/auxv.h index 9358a4a5..63c5bfe9 100644 --- a/src/include/sys/auxv.h +++ b/src/include/sys/auxv.h @@ -5,6 +5,6 @@ #include -hidden unsigned long __getauxval(unsigned long); +unsigned long __getauxval(unsigned long); #endif From caae5a8b272861607c25f8ed86087bae960a07f0 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 1 Jul 2025 11:57:40 -0400 Subject: [PATCH 093/115] fix register name usage in aarch64 clone.s the alias fp is only supported on some assemblers. use the actual register name x29 instead. --- src/thread/aarch64/clone.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread/aarch64/clone.s b/src/thread/aarch64/clone.s index 9ac272bd..aff8155b 100644 --- a/src/thread/aarch64/clone.s +++ b/src/thread/aarch64/clone.s @@ -24,7 +24,7 @@ __clone: // parent ret // child -1: mov fp, 0 +1: mov x29, 0 ldp x1,x0,[sp],#16 blr x1 mov x8,#93 // SYS_exit From f96e47a26102d537c29435f0abf9ec94676a030e Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 1 Jul 2025 21:30:18 -0400 Subject: [PATCH 094/115] printf: fix regression in large double formatting on ld128 archs commit 572a2e2eb91f00f2f25d301cfb50f435e7ae16b3 adjusted the buffer for decimal conversion to be a VLA that only uses the full size needed for long double when the argument type was long double. however, it failed to update a later expression for the positioning within the buffer, which still used a fixed offset of LDBL_MANT_DIG. this caused doubles with a large positive exponent to overflow below the start of the array, producing wrong output and potentially runaway wrong execution. this bug has not been present in any release, and has not been analyzed in depth for security considerations. it turns out the original buffer offset expression involving LDBL_MANT_DIG was incorrect as well, and only worked because the space reserved for expanding the exponent is roughly 3 times the size it needs to be when the exponent is positive, leaving plenty of extra space to compensate for the error. the actual offset should be in base-1000000000 slot units, not bits, and numerically equal to the number of slots that were previously allocated for mantissa expansion. in order to ensure consistency and make the code more comprehensible, commented subexpressions are replaced by intermediate named variables, and the newly introduced max_mant_slots is used for both the allocation and the buffer offset adjustment. the included +1 term accounts for a trailing zero slot that's always emitted. --- src/stdio/vfprintf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index 76733997..a68edabb 100644 --- a/src/stdio/vfprintf.c +++ b/src/stdio/vfprintf.c @@ -180,11 +180,11 @@ typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double) static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps) { - int bufsize = (ps==BIGLPRE) - ? (LDBL_MANT_DIG+28)/29 + 1 + // mantissa expansion - (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9 // exponent expansion - : (DBL_MANT_DIG+28)/29 + 1 + - (DBL_MAX_EXP+DBL_MANT_DIG+28+8)/9; + int max_mant_dig = (ps==BIGLPRE) ? LDBL_MANT_DIG : DBL_MANT_DIG; + int max_exp = (ps==BIGLPRE) ? LDBL_MAX_EXP : DBL_MAX_EXP; + int max_mant_slots = (max_mant_dig+28)/29 + 1; + int max_exp_slots = (max_exp+max_mant_dig+28+8)/9; + int bufsize = max_mant_slots + max_exp_slots; uint32_t big[bufsize]; uint32_t *a, *d, *r, *z; int e2=0, e, i, j, l; @@ -266,7 +266,7 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps) if (y) y *= 0x1p28, e2-=28; if (e2<0) a=r=z=big; - else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; + else a=r=z=big+sizeof(big)/sizeof(*big) - max_mant_slots - 1; do { *z = y; From bd981f3342b92f5b6a71b22ae7520a59ed4dc236 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 12 Jul 2025 21:48:59 -0400 Subject: [PATCH 095/115] elf.h: add AT_HWCAP3 and AT_HWCAP4 there are probably more new auxv keys that should be added, but these are added now specifically because we may need to mask them. --- include/elf.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/elf.h b/include/elf.h index 8b622f63..d6ae539a 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1040,6 +1040,8 @@ typedef struct { #define AT_RANDOM 25 #define AT_HWCAP2 26 +#define AT_HWCAP3 29 +#define AT_HWCAP4 30 #define AT_EXECFN 31 From 709fee55fd1f83faef91cf0542766da4421424f3 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 12 Jul 2025 21:56:08 -0400 Subject: [PATCH 096/115] aarch64: replace asm source file for __set_thread_area with inline asm this change both aligns with the intended future direction for most assembly usage, and makes it possible to add arch-specific setup logic based on hwcaps like we have for 32-bit arm. --- src/thread/aarch64/__set_thread_area.c | 5 +++++ src/thread/aarch64/__set_thread_area.s | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) create mode 100644 src/thread/aarch64/__set_thread_area.c delete mode 100644 src/thread/aarch64/__set_thread_area.s diff --git a/src/thread/aarch64/__set_thread_area.c b/src/thread/aarch64/__set_thread_area.c new file mode 100644 index 00000000..a348ee77 --- /dev/null +++ b/src/thread/aarch64/__set_thread_area.c @@ -0,0 +1,5 @@ +int __set_thread_area(void *p) +{ + __asm__ __volatile__ ("msr tpidr_el0,%0" : : "r"(p) : "memory"); + return 0; +} diff --git a/src/thread/aarch64/__set_thread_area.s b/src/thread/aarch64/__set_thread_area.s deleted file mode 100644 index fd0df34b..00000000 --- a/src/thread/aarch64/__set_thread_area.s +++ /dev/null @@ -1,7 +0,0 @@ -.global __set_thread_area -.hidden __set_thread_area -.type __set_thread_area,@function -__set_thread_area: - msr tpidr_el0,x0 - mov w0,#0 - ret From 8fd5d031876345e42ae3d11cc07b962f8625bc3b Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 16 Jul 2025 12:04:39 -0400 Subject: [PATCH 097/115] aarch64: mask off SME and unknown/future hwcap bits as stated in the comment added, the ABI for SME requires libc to be aware of and support the extension to the register file. this is necessary to handle lazy saving correctly across setjmp/longjmp, and on older kernels, in order not to introduce memory corruption bugs that may be exploitable vulnerabilities when creating new threads. previously, we did not expose __getauxval, the interface libgcc uses to determine runtime availability of SME, so it was not usable when following the intended ABI. since commit ab4635fba6769e19fb411a1ab3c8aa7407e11188 has now exposed this interface, a mitigation is needed to ensure SME is not used unless/until we have proper support for it. while SME is the current hwcap feature that needs this treatment, as-yet-undefined hwcap bits are also masked in case other new cpu features have similar ABI issues. this could be re-evaluated at some point in the future. for now, the masking is only on aarch64. arguably it should be considered for all archs, but whether it's needed is really a matter of how ABI policy & stability are handled by the maintainers of the arch psABI, and aarch64 is the one that's demonstrated a necessity. if it turns out something like this is needed for more/all archs, making a generalized framework for it would make sense. for now, it's stuffed into __set_thread_area the same way atomics detection is stuffed there for 32-bit arm and sh, as it's a convenient point for "arch-specific early setup code" without invasive changes. --- src/thread/aarch64/__set_thread_area.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/thread/aarch64/__set_thread_area.c b/src/thread/aarch64/__set_thread_area.c index a348ee77..2ec788e8 100644 --- a/src/thread/aarch64/__set_thread_area.c +++ b/src/thread/aarch64/__set_thread_area.c @@ -1,5 +1,27 @@ +#include +#include "libc.h" + +#define BITRANGE(a,b) (2*(1UL<<(b))-(1UL<<(a))) + int __set_thread_area(void *p) { __asm__ __volatile__ ("msr tpidr_el0,%0" : : "r"(p) : "memory"); + + /* Mask off hwcap bits for SME and unknown future features. This is + * necessary because SME is not safe to use without libc support for + * it, and we do not (yet) have such support. */ + for (size_t *v = libc.auxv; *v; v+=2) { + if (v[0]==AT_HWCAP) { + v[1] &= ~BITRANGE(42,63); /* 42-47 are SME */ + } else if (v[0]==AT_HWCAP2) { + v[1] &= ~(BITRANGE(23,30) + | BITRANGE(37,42) + | BITRANGE(57,62)); + } else if (v[0]==AT_HWCAP3 || v[0]==AT_HWCAP4) { + v[0] = AT_IGNORE; + v[1] = 0; + } + } + return 0; } From a6244de1c94588cd8cc965c15619d2649418f7a3 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 30 Jul 2025 09:32:02 -0400 Subject: [PATCH 098/115] fix erroneous definition of IN6_IS_ADDR_V4COMPAT v4-compatible addresses in ipv6 are a deprecated feature where the high 96 bits are all zero and an ipv4 address is stored in the low 32 bits. however, since :: and ::1 are the unspecified and loopback addresses, these two particular values are excluded from the definition of the v4-compat class. our version of the macro incorrectly assessed this condition by checking only the high 96 and low 8 bits. this incorrectly excluded the v4compat version of any ipv4 address ending in .1, not just ::1. rather than writing out non-obvious or error-prone conditions on the individual address bytes, just express the "not :: or ::1" condition naturally using the existing IN6_IS_ADDR_UNSPECIFIED and IN6_IS_ADDR_LOOPBACK macros, after checking that the high 96 bits are all zero. any vaguely reasonable compiler will collapse out the redundant tests of the upper bits as part of CSE. --- include/netinet/in.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/netinet/in.h b/include/netinet/in.h index fb628b61..60bbaa75 100644 --- a/include/netinet/in.h +++ b/include/netinet/in.h @@ -132,7 +132,8 @@ uint16_t ntohs(uint16_t); #define IN6_IS_ADDR_V4COMPAT(a) \ (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \ - ((uint32_t *) (a))[2] == 0 && ((uint8_t *) (a))[15] > 1) + ((uint32_t *) (a))[2] == 0 && \ + !IN6_IS_ADDR_UNSPECIFIED(a) && !IN6_IS_ADDR_LOOPBACK(a)) #define IN6_IS_ADDR_MC_NODELOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x1)) From f6944eb3c4ce1c97dc39dc36d32390dc9f70b67b Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Thu, 7 Aug 2025 15:35:14 -0400 Subject: [PATCH 099/115] powerpc[64]: fix missing ctr and xer regs in syscall asm clobberlists the ctr and xer special registers are call-clobbered and syscall-clobbered. failure to include them in the clobber list may result in wrong code that attempts to use a value which is no longer present in the register after the syscall. this has been reported to manifest newly with gcc 15. --- arch/powerpc/syscall_arch.h | 14 +++++++------- arch/powerpc64/syscall_arch.h | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/syscall_arch.h b/arch/powerpc/syscall_arch.h index 54c885cb..fe893af4 100644 --- a/arch/powerpc/syscall_arch.h +++ b/arch/powerpc/syscall_arch.h @@ -9,7 +9,7 @@ static inline long __syscall0(long n) register long r3 __asm__("r3"); __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "=r"(r3) - :: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -19,7 +19,7 @@ static inline long __syscall1(long n, long a) register long r3 __asm__("r3") = a; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3) - :: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -30,7 +30,7 @@ static inline long __syscall2(long n, long a, long b) register long r4 __asm__("r4") = b; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4) - :: "memory", "cr0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -42,7 +42,7 @@ static inline long __syscall3(long n, long a, long b, long c) register long r5 __asm__("r5") = c; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5) - :: "memory", "cr0", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -55,7 +55,7 @@ static inline long __syscall4(long n, long a, long b, long c, long d) register long r6 __asm__("r6") = d; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6) - :: "memory", "cr0", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -69,7 +69,7 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e) register long r7 __asm__("r7") = e; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7) - :: "memory", "cr0", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -84,7 +84,7 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo register long r8 __asm__("r8") = f; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7), "+r"(r8) - :: "memory", "cr0", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } diff --git a/arch/powerpc64/syscall_arch.h b/arch/powerpc64/syscall_arch.h index 7d34fbe4..4c5d3ae9 100644 --- a/arch/powerpc64/syscall_arch.h +++ b/arch/powerpc64/syscall_arch.h @@ -7,7 +7,7 @@ static inline long __syscall0(long n) register long r3 __asm__("r3"); __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "=r"(r3) - :: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -17,7 +17,7 @@ static inline long __syscall1(long n, long a) register long r3 __asm__("r3") = a; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3) - :: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -28,7 +28,7 @@ static inline long __syscall2(long n, long a, long b) register long r4 __asm__("r4") = b; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4) - :: "memory", "cr0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -40,7 +40,7 @@ static inline long __syscall3(long n, long a, long b, long c) register long r5 __asm__("r5") = c; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5) - :: "memory", "cr0", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -53,7 +53,7 @@ static inline long __syscall4(long n, long a, long b, long c, long d) register long r6 __asm__("r6") = d; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6) - :: "memory", "cr0", "r7", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -67,7 +67,7 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e) register long r7 __asm__("r7") = e; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7) - :: "memory", "cr0", "r8", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r8", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } @@ -82,7 +82,7 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo register long r8 __asm__("r8") = f; __asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:" : "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7), "+r"(r8) - :: "memory", "cr0", "r9", "r10", "r11", "r12"); + :: "memory", "cr0", "r9", "r10", "r11", "r12", "ctr", "xer"); return r3; } From 0b86d60badad6a69b37fc06d18b5763fbbf47b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 29 Jun 2024 04:04:34 +0200 Subject: [PATCH 100/115] riscv: fix setjmp assembly when compiling for ilp32f/lp64f. per the psABI, floating point register contents beyond the register size of the targeted ABI variant are never call-saved, so no hwcap-conditional logic is needed here and the assembly-time conditions are based purely on ABI variant macros, not the targeted ISA level. --- src/setjmp/riscv32/longjmp.S | 30 ++++++++++++++++++------------ src/setjmp/riscv32/setjmp.S | 30 ++++++++++++++++++------------ src/setjmp/riscv64/longjmp.S | 30 ++++++++++++++++++------------ src/setjmp/riscv64/setjmp.S | 30 ++++++++++++++++++------------ 4 files changed, 72 insertions(+), 48 deletions(-) diff --git a/src/setjmp/riscv32/longjmp.S b/src/setjmp/riscv32/longjmp.S index f9cb3318..b4e5458d 100644 --- a/src/setjmp/riscv32/longjmp.S +++ b/src/setjmp/riscv32/longjmp.S @@ -23,18 +23,24 @@ longjmp: lw ra, 52(a0) #ifndef __riscv_float_abi_soft - fld fs0, 56(a0) - fld fs1, 64(a0) - fld fs2, 72(a0) - fld fs3, 80(a0) - fld fs4, 88(a0) - fld fs5, 96(a0) - fld fs6, 104(a0) - fld fs7, 112(a0) - fld fs8, 120(a0) - fld fs9, 128(a0) - fld fs10, 136(a0) - fld fs11, 144(a0) +#ifdef __riscv_float_abi_double +#define FLX fld +#else +#define FLX flw +#endif + + FLX fs0, 56(a0) + FLX fs1, 64(a0) + FLX fs2, 72(a0) + FLX fs3, 80(a0) + FLX fs4, 88(a0) + FLX fs5, 96(a0) + FLX fs6, 104(a0) + FLX fs7, 112(a0) + FLX fs8, 120(a0) + FLX fs9, 128(a0) + FLX fs10, 136(a0) + FLX fs11, 144(a0) #endif seqz a0, a1 diff --git a/src/setjmp/riscv32/setjmp.S b/src/setjmp/riscv32/setjmp.S index 8a75cf55..5a1a41ef 100644 --- a/src/setjmp/riscv32/setjmp.S +++ b/src/setjmp/riscv32/setjmp.S @@ -23,18 +23,24 @@ setjmp: sw ra, 52(a0) #ifndef __riscv_float_abi_soft - fsd fs0, 56(a0) - fsd fs1, 64(a0) - fsd fs2, 72(a0) - fsd fs3, 80(a0) - fsd fs4, 88(a0) - fsd fs5, 96(a0) - fsd fs6, 104(a0) - fsd fs7, 112(a0) - fsd fs8, 120(a0) - fsd fs9, 128(a0) - fsd fs10, 136(a0) - fsd fs11, 144(a0) +#ifdef __riscv_float_abi_double +#define FSX fsd +#else +#define FSX fsw +#endif + + FSX fs0, 56(a0) + FSX fs1, 64(a0) + FSX fs2, 72(a0) + FSX fs3, 80(a0) + FSX fs4, 88(a0) + FSX fs5, 96(a0) + FSX fs6, 104(a0) + FSX fs7, 112(a0) + FSX fs8, 120(a0) + FSX fs9, 128(a0) + FSX fs10, 136(a0) + FSX fs11, 144(a0) #endif li a0, 0 diff --git a/src/setjmp/riscv64/longjmp.S b/src/setjmp/riscv64/longjmp.S index 41e2d210..982475c7 100644 --- a/src/setjmp/riscv64/longjmp.S +++ b/src/setjmp/riscv64/longjmp.S @@ -23,18 +23,24 @@ longjmp: ld ra, 104(a0) #ifndef __riscv_float_abi_soft - fld fs0, 112(a0) - fld fs1, 120(a0) - fld fs2, 128(a0) - fld fs3, 136(a0) - fld fs4, 144(a0) - fld fs5, 152(a0) - fld fs6, 160(a0) - fld fs7, 168(a0) - fld fs8, 176(a0) - fld fs9, 184(a0) - fld fs10, 192(a0) - fld fs11, 200(a0) +#ifdef __riscv_float_abi_double +#define FLX fld +#else +#define FLX flw +#endif + + FLX fs0, 112(a0) + FLX fs1, 120(a0) + FLX fs2, 128(a0) + FLX fs3, 136(a0) + FLX fs4, 144(a0) + FLX fs5, 152(a0) + FLX fs6, 160(a0) + FLX fs7, 168(a0) + FLX fs8, 176(a0) + FLX fs9, 184(a0) + FLX fs10, 192(a0) + FLX fs11, 200(a0) #endif seqz a0, a1 diff --git a/src/setjmp/riscv64/setjmp.S b/src/setjmp/riscv64/setjmp.S index 51249672..0795bf7d 100644 --- a/src/setjmp/riscv64/setjmp.S +++ b/src/setjmp/riscv64/setjmp.S @@ -23,18 +23,24 @@ setjmp: sd ra, 104(a0) #ifndef __riscv_float_abi_soft - fsd fs0, 112(a0) - fsd fs1, 120(a0) - fsd fs2, 128(a0) - fsd fs3, 136(a0) - fsd fs4, 144(a0) - fsd fs5, 152(a0) - fsd fs6, 160(a0) - fsd fs7, 168(a0) - fsd fs8, 176(a0) - fsd fs9, 184(a0) - fsd fs10, 192(a0) - fsd fs11, 200(a0) +#ifdef __riscv_float_abi_double +#define FSX fsd +#else +#define FSX fsw +#endif + + FSX fs0, 112(a0) + FSX fs1, 120(a0) + FSX fs2, 128(a0) + FSX fs3, 136(a0) + FSX fs4, 144(a0) + FSX fs5, 152(a0) + FSX fs6, 160(a0) + FSX fs7, 168(a0) + FSX fs8, 176(a0) + FSX fs9, 184(a0) + FSX fs10, 192(a0) + FSX fs11, 200(a0) #endif li a0, 0 From 0ccaf0572e9cccda2cced0f7ee659af4c1c6679a Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 19 Sep 2025 18:35:19 -0400 Subject: [PATCH 101/115] printf: fix buffer overflow in floating point decimal formatting commit f96e47a26102d537c29435f0abf9ec94676a030e introduced a new overflow past the end of the base-1e9 buffer for floating point to decimal conversion while fixing a different overflow below the start of the buffer. this bug has not been present in any release, and has not been analyzed in depth for security considerations. the root cause of the bug, incorrect size accounting for the mantissa, long predates the above commit, but was only exposed once the excessive offset causing overflow in the other direction was removed. the number of slots for expanding the mantissa was computed as if each slot could peel off at least 29 bits. this would be true if the mantissa were placed and expanded to the left of the radix point, but we don't do that because it would require repeated fmod and division. instead, we start the mantissa with 29 bits to the left of the radix point, so that they can be peeled off by conversion to integer and subtraction, followed by a multiplication by 1e9 to prepare for the next iteration. so while the first slot peels 29 bits, advancing to the next slot adds back somewhere between 20 and 21 bits: the length of the mantissa of 1e9. this means we need to account for a slot for every 8 bits of mantissa past the initial 29. add a comment to that effect and adjust the max_mant_slots formula. --- src/stdio/vfprintf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index a68edabb..514a44dd 100644 --- a/src/stdio/vfprintf.c +++ b/src/stdio/vfprintf.c @@ -182,7 +182,9 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps) { int max_mant_dig = (ps==BIGLPRE) ? LDBL_MANT_DIG : DBL_MANT_DIG; int max_exp = (ps==BIGLPRE) ? LDBL_MAX_EXP : DBL_MAX_EXP; - int max_mant_slots = (max_mant_dig+28)/29 + 1; + /* One slot for 29 bits left of radix point, a slot for every 29-21=8 + * bits right of the radix point, and one final zero slot. */ + int max_mant_slots = 1 + (max_mant_dig-29+7)/8 + 1; int max_exp_slots = (max_exp+max_mant_dig+28+8)/9; int bufsize = max_mant_slots + max_exp_slots; uint32_t big[bufsize]; From 1b76ff0767d01df72f692806ee5adee13c67ef88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 12 Oct 2025 05:35:19 +0200 Subject: [PATCH 102/115] s390x: shuffle register usage in __tls_get_offset to avoid r0 as address This fixes an error in 6af4f25b899e89e4b91f8c197ae5a6ce04bcce7b: The r0 register is special in addressing modes on s390x and is interpreted as constant zero, i.e. lg %r5, 8(%r0) would effectively become lg %r5, 8. So care should be taken to never use r0 as an address register in s390x assembly. --- src/thread/s390x/__tls_get_offset.s | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/thread/s390x/__tls_get_offset.s b/src/thread/s390x/__tls_get_offset.s index 405f118b..056c9110 100644 --- a/src/thread/s390x/__tls_get_offset.s +++ b/src/thread/s390x/__tls_get_offset.s @@ -1,17 +1,17 @@ .global __tls_get_offset .type __tls_get_offset,%function __tls_get_offset: - ear %r0, %a0 - sllg %r0, %r0, 32 - ear %r0, %a1 + ear %r3, %a0 + sllg %r3, %r3, 32 + ear %r3, %a1 la %r1, 0(%r2, %r12) - lg %r3, 0(%r1) - sllg %r4, %r3, 3 - lg %r5, 8(%r0) + lg %r0, 0(%r1) + sllg %r4, %r0, 3 + lg %r5, 8(%r3) lg %r2, 0(%r4, %r5) ag %r2, 8(%r1) - sgr %r2, %r0 + sgr %r2, %r3 br %r14 From 5c26c890ede40b5649d2ea23c51ea3ef34216486 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Mon, 15 Apr 2024 03:26:17 -0700 Subject: [PATCH 103/115] mallocng: prevent stray ';' at top-level The LOCK_OBJ_DEF macro is used with a trailing semicolon. However, since the macro definition ends with the closing brace of a function definition, the ISO C grammar does not allow an extra semicolon. To fix this, swap the order of the two definitions, and drop the semicolon from the __malloc_lock declaration. --- src/malloc/mallocng/glue.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/malloc/mallocng/glue.h b/src/malloc/mallocng/glue.h index 77f4c812..8c2586fb 100644 --- a/src/malloc/mallocng/glue.h +++ b/src/malloc/mallocng/glue.h @@ -62,8 +62,8 @@ __attribute__((__visibility__("hidden"))) extern int __malloc_lock[1]; #define LOCK_OBJ_DEF \ -int __malloc_lock[1]; \ -void __malloc_atfork(int who) { malloc_atfork(who); } +void __malloc_atfork(int who) { malloc_atfork(who); } \ +int __malloc_lock[1] static inline void rdlock() { From 4268281ab48896ca2a2f6f0a3bbcd332eee55834 Mon Sep 17 00:00:00 2001 From: RocketDev Date: Mon, 2 Mar 2026 00:21:58 +0800 Subject: [PATCH 104/115] getifaddr: fix typo ssl to sll sll_addr is a member of sockaddr_ll, but it is misspelled as ssl_addr in comment. Please cc me back when reply. Signed-off-by: RocketDev --- src/network/getifaddrs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/getifaddrs.c b/src/network/getifaddrs.c index 74df4d6c..55039bd8 100644 --- a/src/network/getifaddrs.c +++ b/src/network/getifaddrs.c @@ -13,8 +13,8 @@ /* getifaddrs() reports hardware addresses with PF_PACKET that implies * struct sockaddr_ll. But e.g. Infiniband socket address length is - * longer than sockaddr_ll.ssl_addr[8] can hold. Use this hack struct - * to extend ssl_addr - callers should be able to still use it. */ + * longer than sockaddr_ll.sll_addr[8] can hold. Use this hack struct + * to extend sll_addr - callers should be able to still use it. */ struct sockaddr_ll_hack { unsigned short sll_family, sll_protocol; int sll_ifindex; From 5c901bb36041035575e2732b75a6759849bf4560 Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Sun, 1 Mar 2026 15:28:33 +0100 Subject: [PATCH 105/115] update syscalls up to linux 6.19 Add two missing syscalls from v5.14 and new syscalls from v6.4 .. v6.19 add __NR_quotactl_fd from linux v5.14 see linux commit 9dfa23c8de925041b7b45637a1a80a98a22f19dd quota: Add mountpath based quota support linux commit fa8b90070a80bb1a3042b4b25af4b3ee2c4c27e1 quota: wire up quotactl_path linux commit 64c2c2c62f92339b176ea24403d8db16db36f9e6 quota: Change quotactl_path() systcall to an fd-based one add __NR_memfd_secret from linux v5.14 see linux commit 7bb7f2ac24a028b20fca466b9633847b289b156a arch, mm: wire up memfd_secret system call where relevant linux commit 1507f51255c9ff07d75909a84e7c0d7f3c4b2f49 mm: introduce memfd_secret system call to create "secret" memory areas note: was already added on x86 and s390, now on aarch64 and riscv*. add riscv __NR_riscv_hwprobe from linux v6.4 see linux commit ea3de9ce8aa280c5175c835bd3e94a3a9b814b74 RISC-V: Add a syscall for HW probing add x86_64 only map_shadow_stack syscall from linux v6.6 see linux commit c35559f94ebc3e3bc82e56e07161bb5986cd9761 x86/shstk: Introduce map_shadow_stack syscall add map_shadow_stack syscall from linux v6.7 see linux commit 2fd0ebad27bcd4c8fc61c61a98d4283c47054bcf arch: Reserve map_shadow_stack() syscall number for all architectures add futex_* syscalls from linux v6.7 see linux commit 9f6c532f59b20580acf8ede9409c9b8dce6e74e1 futex: Add sys_futex_wake() linux commit cb8c4312afca1b2dc64107e7e7cea81911055612 futex: Add sys_futex_wait() linux commit 0f4b5f972216782a4acb1ae00dcb55173847c2ff futex: Add sys_futex_requeue() add statmount, listmount syscalls from linux v6.8 see linux commit d8b0f5465012538cc4bb10ddc4affadbab73465b wire up syscalls for statmount/listmount linux commit b4c2bea8ceaa50cd42a8f73667389d801a3ecf2d add listmount(2) syscall linux commit 46eae99ef73302f9fb3dddcd67c374b3dffe8fd6 add statmount(2) syscall add lsm_* syscalls from linux v6.8 see linux commit 5f42375904b08890f2e8e7cd955c5bf0c2c0d05a LSM: wireup Linux Security Module syscalls linux commit ad4aff9ec25f400608283c10d634cc4eeda83a02 LSM: Create lsm_list_modules system call linux commit a04a1198088a1378d0389c250cc684f649bcc91e LSM: syscalls for current process attributes add mseal syscall from linux v6.10 see linux commit ff388fe5c481d39cc0a5940d1ad46f7920f1d646 mseal: wire up mseal syscall on sh add sync_file_range2 from linux v6.10 see linux commit 30766f1105d6d2459c3b9fe34a3e52b637a72950 sh: rework sync_file_range ABI on x86 add uretprobe from linux v6.11 see linux commit 54233a4254036efca91b9bffbd398ecf39e90555 uretprobe: change syscall number, again add *xattrat syscalls from linux v6.13 see linux commit 6140be90ec70c39fa844741ca3cc807dd0866394 fs/xattr: add *at family syscalls add open_tree_attr from linux v6.15 see linux commit c4a16820d90199409c9bf01c4f794e1e9e8d8fd8 fs: add open_tree_attr() add file_{get,set}attr from linux v6.17 see linux commit be7efb2d20d67f334a7de2aef77ae6c69367e646 fs: introduce file_getattr and file_setattr syscalls on x86 add uprobe from linux v6.18 see linux commit 56101b69c9190667f473b9f93f8b6d8209aaa816 uprobes/x86: Add uprobe syscall to speed up uprobe add listns from linux v6.19 see linux commit b36d4b6aa88ef039647228b98c59a875e92f8c8e arch: hookup listns() system call --- arch/aarch64/bits/syscall.h.in | 20 ++++++++++++++++++++ arch/arm/bits/syscall.h.in | 19 +++++++++++++++++++ arch/i386/bits/syscall.h.in | 19 +++++++++++++++++++ arch/loongarch64/bits/syscall.h.in | 14 ++++++++++++++ arch/m68k/bits/syscall.h.in | 19 +++++++++++++++++++ arch/microblaze/bits/syscall.h.in | 19 +++++++++++++++++++ arch/mips/bits/syscall.h.in | 19 +++++++++++++++++++ arch/mips64/bits/syscall.h.in | 19 +++++++++++++++++++ arch/mipsn32/bits/syscall.h.in | 19 +++++++++++++++++++ arch/or1k/bits/syscall.h.in | 19 +++++++++++++++++++ arch/powerpc/bits/syscall.h.in | 19 +++++++++++++++++++ arch/powerpc64/bits/syscall.h.in | 19 +++++++++++++++++++ arch/riscv32/bits/syscall.h.in | 20 ++++++++++++++++++++ arch/riscv64/bits/syscall.h.in | 21 +++++++++++++++++++++ arch/s390x/bits/syscall.h.in | 19 +++++++++++++++++++ arch/sh/bits/syscall.h.in | 20 ++++++++++++++++++++ arch/x32/bits/syscall.h.in | 21 +++++++++++++++++++++ arch/x86_64/bits/syscall.h.in | 21 +++++++++++++++++++++ 18 files changed, 346 insertions(+) diff --git a/arch/aarch64/bits/syscall.h.in b/arch/aarch64/bits/syscall.h.in index ea5a152a..bb158f36 100644 --- a/arch/aarch64/bits/syscall.h.in +++ b/arch/aarch64/bits/syscall.h.in @@ -296,12 +296,32 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 +#define __NR_memfd_secret 447 #define __NR_process_mrelease 448 #define __NR_futex_waitv 449 #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 diff --git a/arch/arm/bits/syscall.h.in b/arch/arm/bits/syscall.h.in index 157b304d..fb5fa975 100644 --- a/arch/arm/bits/syscall.h.in +++ b/arch/arm/bits/syscall.h.in @@ -396,6 +396,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -404,6 +405,24 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 #define __ARM_NR_breakpoint 0x0f0001 #define __ARM_NR_cacheflush 0x0f0002 diff --git a/arch/i386/bits/syscall.h.in b/arch/i386/bits/syscall.h.in index 55e91cc4..30e38405 100644 --- a/arch/i386/bits/syscall.h.in +++ b/arch/i386/bits/syscall.h.in @@ -433,6 +433,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -442,4 +443,22 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 diff --git a/arch/loongarch64/bits/syscall.h.in b/arch/loongarch64/bits/syscall.h.in index 2afb4ea1..66c0d7b9 100644 --- a/arch/loongarch64/bits/syscall.h.in +++ b/arch/loongarch64/bits/syscall.h.in @@ -305,6 +305,20 @@ #define __NR_futex_wake 454 #define __NR_futex_wait 455 #define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 #define __NR_fcntl __NR3264_fcntl #define __NR_statfs __NR3264_statfs #define __NR_fstatfs __NR3264_fstatfs diff --git a/arch/m68k/bits/syscall.h.in b/arch/m68k/bits/syscall.h.in index 5cd84602..548fd02d 100644 --- a/arch/m68k/bits/syscall.h.in +++ b/arch/m68k/bits/syscall.h.in @@ -413,6 +413,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -421,3 +422,21 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 diff --git a/arch/microblaze/bits/syscall.h.in b/arch/microblaze/bits/syscall.h.in index 40860e6d..e98944a9 100644 --- a/arch/microblaze/bits/syscall.h.in +++ b/arch/microblaze/bits/syscall.h.in @@ -434,6 +434,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -442,4 +443,22 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 diff --git a/arch/mips/bits/syscall.h.in b/arch/mips/bits/syscall.h.in index 55e35742..4048ae88 100644 --- a/arch/mips/bits/syscall.h.in +++ b/arch/mips/bits/syscall.h.in @@ -415,6 +415,7 @@ #define __NR_process_madvise 4440 #define __NR_epoll_pwait2 4441 #define __NR_mount_setattr 4442 +#define __NR_quotactl_fd 4443 #define __NR_landlock_create_ruleset 4444 #define __NR_landlock_add_rule 4445 #define __NR_landlock_restrict_self 4446 @@ -423,4 +424,22 @@ #define __NR_set_mempolicy_home_node 4450 #define __NR_cachestat 4451 #define __NR_fchmodat2 4452 +#define __NR_map_shadow_stack 4453 +#define __NR_futex_wake 4454 +#define __NR_futex_wait 4455 +#define __NR_futex_requeue 4456 +#define __NR_statmount 4457 +#define __NR_listmount 4458 +#define __NR_lsm_get_self_attr 4459 +#define __NR_lsm_set_self_attr 4460 +#define __NR_lsm_list_modules 4461 +#define __NR_mseal 4462 +#define __NR_setxattrat 4463 +#define __NR_getxattrat 4464 +#define __NR_listxattrat 4465 +#define __NR_removexattrat 4466 +#define __NR_open_tree_attr 4467 +#define __NR_file_getattr 4468 +#define __NR_file_setattr 4469 +#define __NR_listns 4470 diff --git a/arch/mips64/bits/syscall.h.in b/arch/mips64/bits/syscall.h.in index 50cec45a..1d80ebe6 100644 --- a/arch/mips64/bits/syscall.h.in +++ b/arch/mips64/bits/syscall.h.in @@ -345,6 +345,7 @@ #define __NR_process_madvise 5440 #define __NR_epoll_pwait2 5441 #define __NR_mount_setattr 5442 +#define __NR_quotactl_fd 5443 #define __NR_landlock_create_ruleset 5444 #define __NR_landlock_add_rule 5445 #define __NR_landlock_restrict_self 5446 @@ -353,4 +354,22 @@ #define __NR_set_mempolicy_home_node 5450 #define __NR_cachestat 5451 #define __NR_fchmodat2 5452 +#define __NR_map_shadow_stack 5453 +#define __NR_futex_wake 5454 +#define __NR_futex_wait 5455 +#define __NR_futex_requeue 5456 +#define __NR_statmount 5457 +#define __NR_listmount 5458 +#define __NR_lsm_get_self_attr 5459 +#define __NR_lsm_set_self_attr 5460 +#define __NR_lsm_list_modules 5461 +#define __NR_mseal 5462 +#define __NR_setxattrat 5463 +#define __NR_getxattrat 5464 +#define __NR_listxattrat 5465 +#define __NR_removexattrat 5466 +#define __NR_open_tree_attr 5467 +#define __NR_file_getattr 5468 +#define __NR_file_setattr 5469 +#define __NR_listns 5470 diff --git a/arch/mipsn32/bits/syscall.h.in b/arch/mipsn32/bits/syscall.h.in index 9a4bd301..34b2f395 100644 --- a/arch/mipsn32/bits/syscall.h.in +++ b/arch/mipsn32/bits/syscall.h.in @@ -369,6 +369,7 @@ #define __NR_process_madvise 6440 #define __NR_epoll_pwait2 6441 #define __NR_mount_setattr 6442 +#define __NR_quotactl_fd 6443 #define __NR_landlock_create_ruleset 6444 #define __NR_landlock_add_rule 6445 #define __NR_landlock_restrict_self 6446 @@ -377,4 +378,22 @@ #define __NR_set_mempolicy_home_node 6450 #define __NR_cachestat 6451 #define __NR_fchmodat2 6452 +#define __NR_map_shadow_stack 6453 +#define __NR_futex_wake 6454 +#define __NR_futex_wait 6455 +#define __NR_futex_requeue 6456 +#define __NR_statmount 6457 +#define __NR_listmount 6458 +#define __NR_lsm_get_self_attr 6459 +#define __NR_lsm_set_self_attr 6460 +#define __NR_lsm_list_modules 6461 +#define __NR_mseal 6462 +#define __NR_setxattrat 6463 +#define __NR_getxattrat 6464 +#define __NR_listxattrat 6465 +#define __NR_removexattrat 6466 +#define __NR_open_tree_attr 6467 +#define __NR_file_getattr 6468 +#define __NR_file_setattr 6469 +#define __NR_listns 6470 diff --git a/arch/or1k/bits/syscall.h.in b/arch/or1k/bits/syscall.h.in index 00812bf8..93c7fd2e 100644 --- a/arch/or1k/bits/syscall.h.in +++ b/arch/or1k/bits/syscall.h.in @@ -318,6 +318,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -326,4 +327,22 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 diff --git a/arch/powerpc/bits/syscall.h.in b/arch/powerpc/bits/syscall.h.in index ea95f3ed..5e633e4a 100644 --- a/arch/powerpc/bits/syscall.h.in +++ b/arch/powerpc/bits/syscall.h.in @@ -422,6 +422,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -430,4 +431,22 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 diff --git a/arch/powerpc64/bits/syscall.h.in b/arch/powerpc64/bits/syscall.h.in index 43551079..033082d7 100644 --- a/arch/powerpc64/bits/syscall.h.in +++ b/arch/powerpc64/bits/syscall.h.in @@ -394,6 +394,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -402,4 +403,22 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 diff --git a/arch/riscv32/bits/syscall.h.in b/arch/riscv32/bits/syscall.h.in index 9228d840..dcd0e9f7 100644 --- a/arch/riscv32/bits/syscall.h.in +++ b/arch/riscv32/bits/syscall.h.in @@ -289,12 +289,32 @@ #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 +#define __NR_memfd_secret 447 #define __NR_process_mrelease 448 #define __NR_futex_waitv 449 #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 #define __NR_futex __NR_futex_time64 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 #define __NR_sysriscv __NR_arch_specific_syscall #define __NR_riscv_flush_icache (__NR_sysriscv + 15) +#define __NR_riscv_hwprobe (__NR_sysriscv + 14) diff --git a/arch/riscv64/bits/syscall.h.in b/arch/riscv64/bits/syscall.h.in index e362bd0e..e196a11e 100644 --- a/arch/riscv64/bits/syscall.h.in +++ b/arch/riscv64/bits/syscall.h.in @@ -296,14 +296,35 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 +#define __NR_memfd_secret 447 #define __NR_process_mrelease 448 #define __NR_futex_waitv 449 #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 #define __NR_sysriscv __NR_arch_specific_syscall #define __NR_riscv_flush_icache (__NR_sysriscv + 15) +#define __NR_riscv_hwprobe (__NR_sysriscv + 14) diff --git a/arch/s390x/bits/syscall.h.in b/arch/s390x/bits/syscall.h.in index e60711a6..da9be41a 100644 --- a/arch/s390x/bits/syscall.h.in +++ b/arch/s390x/bits/syscall.h.in @@ -359,6 +359,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -368,4 +369,22 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 diff --git a/arch/sh/bits/syscall.h.in b/arch/sh/bits/syscall.h.in index 915a79cd..5613ebf4 100644 --- a/arch/sh/bits/syscall.h.in +++ b/arch/sh/bits/syscall.h.in @@ -357,6 +357,7 @@ #define __NR_pkey_alloc 385 #define __NR_pkey_free 386 #define __NR_rseq 387 +#define __NR_sync_file_range2 388 #define __NR_semget 393 #define __NR_semctl 394 #define __NR_shmget 395 @@ -406,6 +407,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -414,4 +416,22 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 diff --git a/arch/x32/bits/syscall.h.in b/arch/x32/bits/syscall.h.in index 1d065eea..7912034b 100644 --- a/arch/x32/bits/syscall.h.in +++ b/arch/x32/bits/syscall.h.in @@ -286,6 +286,8 @@ #define __NR_statx (0x40000000 + 332) #define __NR_io_pgetevents (0x40000000 + 333) #define __NR_rseq (0x40000000 + 334) +#define __NR_uretprobe (0x40000000 + 335) +#define __NR_uprobe (0x40000000 + 336) #define __NR_pidfd_send_signal (0x40000000 + 424) #define __NR_io_uring_setup (0x40000000 + 425) #define __NR_io_uring_enter (0x40000000 + 426) @@ -305,6 +307,7 @@ #define __NR_process_madvise (0x40000000 + 440) #define __NR_epoll_pwait2 (0x40000000 + 441) #define __NR_mount_setattr (0x40000000 + 442) +#define __NR_quotactl_fd (0x40000000 + 443) #define __NR_landlock_create_ruleset (0x40000000 + 444) #define __NR_landlock_add_rule (0x40000000 + 445) #define __NR_landlock_restrict_self (0x40000000 + 446) @@ -314,6 +317,24 @@ #define __NR_set_mempolicy_home_node (0x40000000 + 450) #define __NR_cachestat (0x40000000 + 451) #define __NR_fchmodat2 (0x40000000 + 452) +#define __NR_map_shadow_stack (0x40000000 + 453) +#define __NR_futex_wake (0x40000000 + 454) +#define __NR_futex_wait (0x40000000 + 455) +#define __NR_futex_requeue (0x40000000 + 456) +#define __NR_statmount (0x40000000 + 457) +#define __NR_listmount (0x40000000 + 458) +#define __NR_lsm_get_self_attr (0x40000000 + 459) +#define __NR_lsm_set_self_attr (0x40000000 + 460) +#define __NR_lsm_list_modules (0x40000000 + 461) +#define __NR_mseal (0x40000000 + 462) +#define __NR_setxattrat (0x40000000 + 463) +#define __NR_getxattrat (0x40000000 + 464) +#define __NR_listxattrat (0x40000000 + 465) +#define __NR_removexattrat (0x40000000 + 466) +#define __NR_open_tree_attr (0x40000000 + 467) +#define __NR_file_getattr (0x40000000 + 468) +#define __NR_file_setattr (0x40000000 + 469) +#define __NR_listns (0x40000000 + 470) #define __NR_rt_sigaction (0x40000000 + 512) diff --git a/arch/x86_64/bits/syscall.h.in b/arch/x86_64/bits/syscall.h.in index 6543bbba..66d150dd 100644 --- a/arch/x86_64/bits/syscall.h.in +++ b/arch/x86_64/bits/syscall.h.in @@ -333,6 +333,8 @@ #define __NR_statx 332 #define __NR_io_pgetevents 333 #define __NR_rseq 334 +#define __NR_uretprobe 335 +#define __NR_uprobe 336 #define __NR_pidfd_send_signal 424 #define __NR_io_uring_setup 425 #define __NR_io_uring_enter 426 @@ -352,6 +354,7 @@ #define __NR_process_madvise 440 #define __NR_epoll_pwait2 441 #define __NR_mount_setattr 442 +#define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 #define __NR_landlock_restrict_self 446 @@ -361,4 +364,22 @@ #define __NR_set_mempolicy_home_node 450 #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_map_shadow_stack 453 +#define __NR_futex_wake 454 +#define __NR_futex_wait 455 +#define __NR_futex_requeue 456 +#define __NR_statmount 457 +#define __NR_listmount 458 +#define __NR_lsm_get_self_attr 459 +#define __NR_lsm_set_self_attr 460 +#define __NR_lsm_list_modules 461 +#define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 +#define __NR_open_tree_attr 467 +#define __NR_file_getattr 468 +#define __NR_file_setattr 469 +#define __NR_listns 470 From b37d241dfe2d5a747089a2dc66864d564b6ea333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 27 Sep 2025 04:28:14 +0200 Subject: [PATCH 106/115] fenv: add missing C dummy functions for loongarch64 soft float analogous to fenv-sf.c for all other archs with softfloat variants. --- src/fenv/loongarch64/fenv-sf.c | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/fenv/loongarch64/fenv-sf.c diff --git a/src/fenv/loongarch64/fenv-sf.c b/src/fenv/loongarch64/fenv-sf.c new file mode 100644 index 00000000..41154673 --- /dev/null +++ b/src/fenv/loongarch64/fenv-sf.c @@ -0,0 +1,3 @@ +#ifdef __loongarch_soft_float +#include "../fenv.c" +#endif From 38b00812ef2ebc944063d70bf63a09a9ebb98dbf Mon Sep 17 00:00:00 2001 From: Jingyun Hua Date: Sat, 4 Jan 2025 16:41:44 +0800 Subject: [PATCH 107/115] loongarch64: add new reloc types and NT_LOONGARCH_HW_* into elf.h These new LoongArch reloc types(101 to 126) have been added in LoongArch psABI v2.30 and NT_LOONGARCH_HW_BREAK/NT_LOONGARCH_HW_WATCH sync with Linux 6.12 elf.h. --- include/elf.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/elf.h b/include/elf.h index d6ae539a..2555b906 100644 --- a/include/elf.h +++ b/include/elf.h @@ -712,6 +712,8 @@ typedef struct { #define NT_LOONGARCH_LSX 0xa02 #define NT_LOONGARCH_LASX 0xa03 #define NT_LOONGARCH_LBT 0xa04 +#define NT_LOONGARCH_HW_BREAK 0xa05 +#define NT_LOONGARCH_HW_WATCH 0xa06 @@ -3408,6 +3410,32 @@ enum #define R_LARCH_TLS_GD_HI20 98 #define R_LARCH_32_PCREL 99 #define R_LARCH_RELAX 100 +#define R_LARCH_DELETE 101 +#define R_LARCH_ALIGN 102 +#define R_LARCH_PCREL20_S2 103 +#define R_LARCH_CFA 104 +#define R_LARCH_ADD6 105 +#define R_LARCH_SUB6 106 +#define R_LARCH_ADD_ULEB128 107 +#define R_LARCH_SUB_ULEB128 108 +#define R_LARCH_64_PCREL 109 +#define R_LARCH_CALL36 110 +#define R_LARCH_TLS_DESC_PC_HI20 111 +#define R_LARCH_TLS_DESC_PC_LO12 112 +#define R_LARCH_TLS_DESC64_PC_LO20 113 +#define R_LARCH_TLS_DESC64_PC_HI12 114 +#define R_LARCH_TLS_DESC_HI20 115 +#define R_LARCH_TLS_DESC_LO12 116 +#define R_LARCH_TLS_DESC64_LO20 117 +#define R_LARCH_TLS_DESC64_HI12 118 +#define R_LARCH_TLS_DESC_LD 119 +#define R_LARCH_TLS_DESC_CALL 120 +#define R_LARCH_TLS_LE_HI20_R 121 +#define R_LARCH_TLS_LE_ADD_R 122 +#define R_LARCH_TLS_LE_LO12_R 123 +#define R_LARCH_TLS_LD_PCREL20_S2 124 +#define R_LARCH_TLS_GD_PCREL20_S2 125 +#define R_LARCH_TLS_DESC_PCREL20_S2 126 #ifdef __cplusplus } From b5146b83ab2bb91b42a7fc60fa07c41914f1ff54 Mon Sep 17 00:00:00 2001 From: JianTao Shan Date: Mon, 23 Sep 2024 02:52:29 +0000 Subject: [PATCH 108/115] loongarch64: add fpu and simd context to signal.h The signal stack extension field of loongarch64 is mutable, and the types are distinguished according to some magic. --- arch/loongarch64/bits/signal.h | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/loongarch64/bits/signal.h b/arch/loongarch64/bits/signal.h index 5a9ed8c9..70ce9402 100644 --- a/arch/loongarch64/bits/signal.h +++ b/arch/loongarch64/bits/signal.h @@ -18,6 +18,10 @@ #endif #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +#define SC_USED_FP (1U << 0) +#define SC_ADDRERR_RD (1U << 30) +#define SC_ADDRERR_WR (1U << 31) + typedef unsigned long greg_t, gregset_t[32]; struct sigcontext { @@ -26,6 +30,45 @@ struct sigcontext { unsigned sc_flags; unsigned long sc_extcontext[] __attribute__((__aligned__(16))); }; + +#define CONTEXT_INFO_ALIGN 16 +struct sctx_info { + unsigned magic; + unsigned size; + unsigned long padding; +}; + +#define FPU_CTX_MAGIC 0x46505501 +#define FPU_CTX_ALIGN 8 +struct fpu_context { + unsigned long regs[32]; + unsigned long fcc; + unsigned fcsr; +}; + +#define LSX_CTX_MAGIC 0x53580001 +#define LSX_CTX_ALIGN 16 +struct lsx_context { + unsigned long regs[2*32]; + unsigned long fcc; + unsigned fcsr; +}; + +#define LASX_CTX_MAGIC 0x41535801 +#define LASX_CTX_ALIGN 32 +struct lasx_context { + unsigned long regs[4*32]; + unsigned long fcc; + unsigned fcsr; +}; + +#define LBT_CTX_MAGIC 0x42540001 +#define LBT_CTX_ALIGN 8 +struct lbt_context { + unsigned long regs[4]; + unsigned eflags; + unsigned ftop; +}; #endif typedef struct { From 9355c443116969d93c920b57b3f8f3252a912ca5 Mon Sep 17 00:00:00 2001 From: Xing Li Date: Tue, 10 Sep 2024 09:17:57 +0800 Subject: [PATCH 109/115] loongarch64: add lsx and lasx regset definition --- arch/loongarch64/bits/user.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/loongarch64/bits/user.h b/arch/loongarch64/bits/user.h index fd9b7b22..e4aee0d3 100644 --- a/arch/loongarch64/bits/user.h +++ b/arch/loongarch64/bits/user.h @@ -22,3 +22,17 @@ typedef union { float f; } elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +typedef union +{ + __attribute__((__aligned__(16))) + double d[2]; + float f[4]; +} elf_lsxregset_t[32]; + +typedef union +{ + __attribute__((__aligned__(32))) + double d[4]; + float f[8]; +} elf_lasxregset_t[32]; From bb5693fa5e93a2cadcb82e238632714b7c71c5b6 Mon Sep 17 00:00:00 2001 From: Michal Biesek Date: Tue, 8 Aug 2023 11:46:09 +0200 Subject: [PATCH 110/115] sys/mman.h: add MADV_POPULATE_(READ|WRITE) from linux v5.14 Add madvise flags to populate(prefault) page tables see linux commit 4ca9b3859dac14bbef0c27d00667bb5b10917adb mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables --- include/sys/mman.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/sys/mman.h b/include/sys/mman.h index 3d5d0f9c..ba371539 100644 --- a/include/sys/mman.h +++ b/include/sys/mman.h @@ -95,6 +95,8 @@ extern "C" { #define MADV_KEEPONFORK 19 #define MADV_COLD 20 #define MADV_PAGEOUT 21 +#define MADV_POPULATE_READ 22 +#define MADV_POPULATE_WRITE 23 #define MADV_HWPOISON 100 #define MADV_SOFT_OFFLINE 101 #endif From 56df2e1fc1528ece18001ed430d714356ea10340 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 15 Mar 2026 16:24:56 -0400 Subject: [PATCH 111/115] sys/mman.h: add MADV_DONTNEED_LOCKED from linux v6.0 this flag works like MADV_DONTNEED but also applies to locked memory ranges. see linux commit 9457056ac426e5ed0671356509c8dcce69f8dee0 mm: madvise: MADV_DONTNEED_LOCKED --- include/sys/mman.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/sys/mman.h b/include/sys/mman.h index ba371539..0184f642 100644 --- a/include/sys/mman.h +++ b/include/sys/mman.h @@ -97,6 +97,7 @@ extern "C" { #define MADV_PAGEOUT 21 #define MADV_POPULATE_READ 22 #define MADV_POPULATE_WRITE 23 +#define MADV_DONTNEED_LOCKED 24 #define MADV_HWPOISON 100 #define MADV_SOFT_OFFLINE 101 #endif From 19f9aeaaba1bde5b541b7758cbf661ba29fb9cea Mon Sep 17 00:00:00 2001 From: Michal Biesek Date: Tue, 8 Aug 2023 21:41:06 +0200 Subject: [PATCH 112/115] sys/mman.h: add MADV_COLLAPSE from linux v6.1 Add madvise flag which performs a best-effort synchronous collapse of the native pages mapped by the memory range into Transparent Huge Pages (THPs) see linux commit 7d8faaf155454f8798ec56404faca29a82689c77 mm/madvise: introduce MADV_COLLAPSE sync hugepage collapse --- include/sys/mman.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/sys/mman.h b/include/sys/mman.h index 0184f642..aa2c4817 100644 --- a/include/sys/mman.h +++ b/include/sys/mman.h @@ -98,6 +98,7 @@ extern "C" { #define MADV_POPULATE_READ 22 #define MADV_POPULATE_WRITE 23 #define MADV_DONTNEED_LOCKED 24 +#define MADV_COLLAPSE 25 #define MADV_HWPOISON 100 #define MADV_SOFT_OFFLINE 101 #endif From 149d872970312e56a3052f51708b1da2c78ef641 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 17 Mar 2026 21:59:45 -0400 Subject: [PATCH 113/115] getgr*: validate group member lists from nscd backend this corrects missing validation when using alternate group database backends via nscd, as reported by 0rbitingZer0, which could result in a heap-based buffer overflow. while the source of truth for user (passwd) and group definitions is generally an equal or higher-privilege domain than the application, and compromise of nscd could inherently lead to bypass of some access controls, it is still worthwhile to harden against direct attacks from a compromised nscd. this patch adds validation in the least invasive way possible, erroring out at the point where a write past the end of the buffer would previously have occurred. a check is also added for member counts that would cause arithmetic overflow in the existing buffer size computations, including negative counts. this could be handled better by making adjustments where the arithmetic is performed, but the way it's done here avoids making any changes except for the actual bounds check. --- src/passwd/getgr_a.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/passwd/getgr_a.c b/src/passwd/getgr_a.c index afeb1ece..84550404 100644 --- a/src/passwd/getgr_a.c +++ b/src/passwd/getgr_a.c @@ -71,6 +71,10 @@ int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t goto cleanup_f; } + if (groupbuf[GRMEMCNT] > (size_t)(INT32_MAX-1)) { + rv = ENOMEM; + goto cleanup_f; + } if (groupbuf[GRNAMELEN] > SIZE_MAX - groupbuf[GRPASSWDLEN]) { rv = ENOMEM; goto cleanup_f; @@ -127,7 +131,13 @@ int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t if (groupbuf[GRMEMCNT]) { mem[0][0] = *buf + groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN]; for (ptr = mem[0][0], i = 0; ptr != mem[0][0]+grlist_len; ptr++) - if (!*ptr) mem[0][++i] = ptr+1; + if (!*ptr) + if (i Date: Sat, 23 Aug 2025 00:54:04 +0200 Subject: [PATCH 114/115] vdso: add support for GNU hash tables on some kernel builds, the vdso exports symbols with DT_GNU_HASH but omits DT_HASH, causing the vdso not to get used and for clock_gettime to fall back to using a syscall. our vdso resolver does not use the hash table anyway, but does need the symbol count from the standard sysv hash table. if it's missing, use the GNU hashtable to calculate the number of symbols. --- src/internal/vdso.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/internal/vdso.c b/src/internal/vdso.c index d46d3228..2b6e1ae2 100644 --- a/src/internal/vdso.c +++ b/src/internal/vdso.c @@ -40,6 +40,24 @@ static int checkver(Verdef *def, int vsym, const char *vername, char *strings) #define OK_TYPES (1< nsym) + nsym = buckets[i]; + } + if (nsym) { + hashval = buckets + gh[0] + (nsym - gh[1]); + do nsym++; + while (!(*hashval++ & 1)); + } + return nsym; +} + + void *__vdsosym(const char *vername, const char *name) { size_t i; @@ -60,6 +78,7 @@ void *__vdsosym(const char *vername, const char *name) char *strings = 0; Sym *syms = 0; Elf_Symndx *hashtab = 0; + uint32_t *ghashtab = 0; uint16_t *versym = 0; Verdef *verdef = 0; @@ -69,15 +88,20 @@ void *__vdsosym(const char *vername, const char *name) case DT_STRTAB: strings = p; break; case DT_SYMTAB: syms = p; break; case DT_HASH: hashtab = p; break; + case DT_GNU_HASH: ghashtab = p; break; case DT_VERSYM: versym = p; break; case DT_VERDEF: verdef = p; break; } } - if (!strings || !syms || !hashtab) return 0; + if (!strings || !syms) return 0; if (!verdef) versym = 0; + size_t nsym = 0; + + if (hashtab) nsym = hashtab[1]; + else if (ghashtab) nsym = count_syms_gnu(ghashtab); - for (i=0; i>4) & OK_BINDS)) continue; if (!syms[i].st_shndx) continue; From 9fa28ece75d8a2191de7c5bb53bed224c5947417 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 20 Mar 2026 11:40:00 -0400 Subject: [PATCH 115/115] release 1.2.6 --- VERSION | 2 +- WHATSNEW | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c813fe11..3c43790f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.5 +1.2.6 diff --git a/WHATSNEW b/WHATSNEW index 7bd90728..bb2cd9bd 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -2438,3 +2438,56 @@ arch-specific bugs fixed: - riscv64 icache flush operation was non-functional - sh sigsetjmp failed to properly restore call-saved register r8 on return - sh dlsym RTLD_NEXT did not identify calling module correctly + + + +1.2.6 release notes + +new features: +- posix_getdents interface (new in POSIX-2024) +- renameat2 interface (linux extension) +- iconv support for CP858 +- vdso clock_gettime for riscv{32,64}, powerpc{,64}, and s390x +- loongarch64 TLSDESC support +- exposed __getauxval for compiler runtime use detecting cpu features + +compatibility: +- initgroups no longer artificially limits number of supplementary groups +- getusershell now skips blank lines and comments +- exit is now explicitly thread-safe (possible future requirement) +- atexit now fails rather than deadlocking if called from late dtor +- strerror now has error strings for EUCLEAN and ENAVAIL +- isatty no longer collapses errors to ENOTTY +- sched.h namespace pollution with _GNU_SOURCE is reduced +- hasmntopt now matches only whole options, not arbitrary substrings +- shadow.h no longer declares an unimplemented sgetspent interface +- vdso with missing sysv hash table (only gnu hash) is now supported + +conformance: +- pwrite now handles O_APPEND correctly, reports error if it can't +- mbnrtowcs now conforms to new POSIX-2024 requirement for partial character +- iconv GBK now properly includes euro symbol +- strptime now accepts conversion specifiers added in POSIX-2024 +- inet_ntop IPv6 "zero compression" now conforms to RFC 5952 + +bugs fixed: +- iconv euc-kr decoder could do oob writes on invalid inputs (CVE-2025-26519) +- iconv shift_jis decoder could produce wrong outputs for some invalid inputs +- printf did not honor hex float precision correctly in some cases +- lost or delayed wakes in sem_post under race condition +- termios input speed handling was wrong +- strcasestr failed to match zero-length needle +- fma handled corner case with negative zero wrongly +- syslog LOG_MAKEPRI macro was incorrect +- timer_create is no longer affected by known pthread_barrier bugs +- sysconf(_SC_MINSIGSTKSZ) computed min size incorrectly +- statx emulation left some fields uninitialized +- mntent wrongly included final newline in parsed field output +- SIGEV_THREAD timers could abort process if SIGTIMER became unblocked +- bind_textdomain_codeset returned wrong value + +arch-specific bugs fixed: +- early dynamic linker handled page size wrong on dynamic pagesize archs +- arm and aarch64 crti/n files had wrong alignment +- m68k POLLWRNORM and POLLWRBAND values were incorrect +- x32 mq ABI was mismatched