summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYRIGHT4
-rw-r--r--INSTALL7
-rw-r--r--Makefile2
-rw-r--r--VERSION2
-rw-r--r--WHATSNEW42
-rw-r--r--arch/aarch64/bits/posix.h2
-rw-r--r--arch/aarch64/bits/reg.h2
-rw-r--r--arch/aarch64/bits/stat.h18
-rw-r--r--arch/aarch64/bits/stdint.h20
-rw-r--r--arch/aarch64/bits/syscall.h.in5
-rw-r--r--arch/arm/bits/posix.h2
-rw-r--r--arch/arm/bits/reg.h3
-rw-r--r--arch/arm/bits/stdint.h20
-rw-r--r--arch/arm/bits/syscall.h.in5
-rw-r--r--arch/arm/reloc.h2
-rw-r--r--arch/generic/bits/reg.h0
-rw-r--r--arch/generic/bits/stat.h (renamed from arch/riscv64/bits/stat.h)2
-rw-r--r--arch/generic/bits/stdint.h (renamed from arch/m68k/bits/stdint.h)9
-rw-r--r--arch/i386/bits/posix.h2
-rw-r--r--arch/i386/bits/reg.h2
-rw-r--r--arch/i386/bits/stdint.h20
-rw-r--r--arch/i386/bits/syscall.h.in6
-rw-r--r--arch/i386/crt_arch.h1
-rw-r--r--arch/loongarch64/atomic_arch.h53
-rw-r--r--arch/loongarch64/bits/alltypes.h.in18
-rw-r--r--arch/loongarch64/bits/fenv.h20
-rw-r--r--arch/loongarch64/bits/float.h16
-rw-r--r--arch/loongarch64/bits/hwcap.h14
-rw-r--r--arch/loongarch64/bits/setjmp.h1
-rw-r--r--arch/loongarch64/bits/signal.h101
-rw-r--r--arch/loongarch64/bits/syscall.h.in316
-rw-r--r--arch/loongarch64/bits/user.h24
-rw-r--r--arch/loongarch64/crt_arch.h13
-rw-r--r--arch/loongarch64/pthread_arch.h11
-rw-r--r--arch/loongarch64/reloc.h30
-rw-r--r--arch/loongarch64/syscall_arch.h137
-rw-r--r--arch/m68k/bits/poll.h2
-rw-r--r--arch/m68k/bits/posix.h2
-rw-r--r--arch/m68k/bits/reg.h2
-rw-r--r--arch/m68k/bits/syscall.h.in5
-rw-r--r--arch/microblaze/bits/posix.h2
-rw-r--r--arch/microblaze/bits/reg.h3
-rw-r--r--arch/microblaze/bits/stdint.h20
-rw-r--r--arch/microblaze/bits/syscall.h.in5
-rw-r--r--arch/mips/bits/posix.h2
-rw-r--r--arch/mips/bits/reg.h3
-rw-r--r--arch/mips/bits/stdint.h20
-rw-r--r--arch/mips/bits/syscall.h.in5
-rw-r--r--arch/mips64/bits/posix.h2
-rw-r--r--arch/mips64/bits/reg.h3
-rw-r--r--arch/mips64/bits/stdint.h20
-rw-r--r--arch/mips64/bits/syscall.h.in5
-rw-r--r--arch/mipsn32/bits/posix.h2
-rw-r--r--arch/mipsn32/bits/reg.h3
-rw-r--r--arch/mipsn32/bits/stdint.h20
-rw-r--r--arch/mipsn32/bits/syscall.h.in5
-rw-r--r--arch/or1k/bits/posix.h2
-rw-r--r--arch/or1k/bits/reg.h3
-rw-r--r--arch/or1k/bits/stdint.h20
-rw-r--r--arch/or1k/bits/syscall.h.in5
-rw-r--r--arch/powerpc/bits/hwcap.h2
-rw-r--r--arch/powerpc/bits/posix.h2
-rw-r--r--arch/powerpc/bits/reg.h3
-rw-r--r--arch/powerpc/bits/stdint.h20
-rw-r--r--arch/powerpc/bits/syscall.h.in5
-rw-r--r--arch/powerpc/syscall_arch.h6
-rw-r--r--arch/powerpc64/bits/hwcap.h2
-rw-r--r--arch/powerpc64/bits/posix.h2
-rw-r--r--arch/powerpc64/bits/reg.h3
-rw-r--r--arch/powerpc64/bits/stdint.h20
-rw-r--r--arch/powerpc64/bits/syscall.h.in5
-rw-r--r--arch/powerpc64/syscall_arch.h4
-rw-r--r--arch/riscv32/atomic_arch.h21
-rw-r--r--arch/riscv32/bits/alltypes.h.in18
-rw-r--r--arch/riscv32/bits/fenv.h17
-rw-r--r--arch/riscv32/bits/float.h16
-rw-r--r--arch/riscv32/bits/ipcstat.h1
-rw-r--r--arch/riscv32/bits/msg.h18
-rw-r--r--arch/riscv32/bits/sem.h18
-rw-r--r--arch/riscv32/bits/setjmp.h1
-rw-r--r--arch/riscv32/bits/shm.h31
-rw-r--r--arch/riscv32/bits/signal.h120
-rw-r--r--arch/riscv32/bits/syscall.h.in300
-rw-r--r--arch/riscv32/bits/user.h6
-rw-r--r--arch/riscv32/crt_arch.h19
-rw-r--r--arch/riscv32/kstat.h0
-rw-r--r--arch/riscv32/pthread_arch.h13
-rw-r--r--arch/riscv32/reloc.h22
-rw-r--r--arch/riscv32/syscall_arch.h79
-rw-r--r--arch/riscv64/bits/posix.h2
-rw-r--r--arch/riscv64/bits/reg.h2
-rw-r--r--arch/riscv64/bits/signal.h4
-rw-r--r--arch/riscv64/bits/stdint.h20
-rw-r--r--arch/riscv64/bits/syscall.h.in5
-rw-r--r--arch/riscv64/reloc.h1
-rw-r--r--arch/riscv64/syscall_arch.h3
-rw-r--r--arch/s390x/bits/posix.h2
-rw-r--r--arch/s390x/bits/reg.h2
-rw-r--r--arch/s390x/bits/stdint.h20
-rw-r--r--arch/s390x/bits/syscall.h.in6
-rw-r--r--arch/s390x/bits/user.h3
-rw-r--r--arch/s390x/reloc.h2
-rw-r--r--arch/s390x/syscall_arch.h4
-rw-r--r--arch/sh/bits/posix.h2
-rw-r--r--arch/sh/bits/stdint.h20
-rw-r--r--arch/sh/bits/syscall.h.in5
-rw-r--r--arch/sh/bits/user.h3
-rw-r--r--arch/x32/bits/posix.h2
-rw-r--r--arch/x32/bits/reg.h2
-rw-r--r--arch/x32/bits/stdint.h20
-rw-r--r--arch/x32/bits/syscall.h.in6
-rw-r--r--arch/x32/bits/user.h3
-rw-r--r--arch/x32/crt_arch.h1
-rw-r--r--arch/x86_64/bits/posix.h2
-rw-r--r--arch/x86_64/bits/reg.h2
-rw-r--r--arch/x86_64/bits/stdint.h20
-rw-r--r--arch/x86_64/bits/syscall.h.in6
-rw-r--r--arch/x86_64/bits/user.h3
-rw-r--r--arch/x86_64/crt_arch.h1
-rwxr-xr-xconfigure32
-rw-r--r--crt/aarch64/crti.s2
-rw-r--r--crt/arm/crti.s2
-rw-r--r--crt/crt1.c2
-rw-r--r--crt/mips/crtn.s4
-rw-r--r--crt/mips64/crtn.s4
-rw-r--r--crt/mipsn32/crtn.s4
-rw-r--r--include/dirent.h18
-rw-r--r--include/elf.h128
-rw-r--r--include/fcntl.h4
-rw-r--r--include/poll.h4
-rw-r--r--include/sched.h17
-rw-r--r--include/shadow.h1
-rw-r--r--include/stdc-predef.h5
-rw-r--r--include/stdio.h7
-rw-r--r--include/string.h3
-rw-r--r--include/sys/epoll.h12
-rw-r--r--include/sys/reg.h9
-rw-r--r--include/sys/stat.h72
-rw-r--r--include/sys/statvfs.h3
-rw-r--r--include/sys/uio.h8
-rw-r--r--include/sys/user.h9
-rw-r--r--include/syslog.h2
-rw-r--r--include/unistd.h8
-rw-r--r--ldso/dynlink.c38
-rw-r--r--src/complex/cacosh.c2
-rw-r--r--src/complex/catan.c25
-rw-r--r--src/complex/catanf.c28
-rw-r--r--src/complex/catanl.c24
-rw-r--r--src/conf/sysconf.c9
-rw-r--r--src/dirent/posix_getdents.c11
-rw-r--r--src/errno/__strerror.h2
-rw-r--r--src/exit/atexit.c12
-rw-r--r--src/exit/exit.c14
-rw-r--r--src/fenv/loongarch64/fenv.S78
-rw-r--r--src/fenv/riscv32/fenv-sf.c3
-rw-r--r--src/fenv/riscv32/fenv.S56
-rw-r--r--src/internal/atomic.h2
-rw-r--r--src/internal/dynlink.h4
-rw-r--r--src/internal/emulate_wait4.c55
-rw-r--r--src/internal/fork_impl.h2
-rw-r--r--src/internal/syscall.h23
-rw-r--r--src/ldso/loongarch64/dlsym.s7
-rw-r--r--src/ldso/loongarch64/tlsdesc.s37
-rw-r--r--src/ldso/riscv32/dlsym.s6
-rw-r--r--src/ldso/riscv64/tlsdesc.s32
-rw-r--r--src/ldso/sh/dlsym.s2
-rw-r--r--src/legacy/getusershell.c6
-rw-r--r--src/linux/cache.c3
-rw-r--r--src/linux/clone.c56
-rw-r--r--src/linux/preadv2.c17
-rw-r--r--src/linux/pwritev2.c17
-rw-r--r--src/linux/renameat2.c11
-rw-r--r--src/linux/statx.c44
-rw-r--r--src/linux/wait4.c2
-rw-r--r--src/locale/bind_textdomain_codeset.c6
-rw-r--r--src/locale/codepages.h11
-rw-r--r--src/locale/iconv.c17
-rw-r--r--src/math/acoshl.c10
-rw-r--r--src/math/fma.c2
-rw-r--r--src/math/powl.c42
-rw-r--r--src/math/riscv32/copysign.c15
-rw-r--r--src/math/riscv32/copysignf.c15
-rw-r--r--src/math/riscv32/fabs.c15
-rw-r--r--src/math/riscv32/fabsf.c15
-rw-r--r--src/math/riscv32/fma.c15
-rw-r--r--src/math/riscv32/fmaf.c15
-rw-r--r--src/math/riscv32/fmax.c15
-rw-r--r--src/math/riscv32/fmaxf.c15
-rw-r--r--src/math/riscv32/fmin.c15
-rw-r--r--src/math/riscv32/fminf.c15
-rw-r--r--src/math/riscv32/sqrt.c15
-rw-r--r--src/math/riscv32/sqrtf.c15
-rw-r--r--src/math/sqrtl.c4
-rw-r--r--src/misc/initgroups.c26
-rw-r--r--src/misc/mntent.c56
-rw-r--r--src/misc/syslog.c3
-rw-r--r--src/mq/x32/mq_open.c22
-rw-r--r--src/mq/x32/mq_setattr.c14
-rw-r--r--src/multibyte/mbrtowc.c2
-rw-r--r--src/multibyte/mbsnrtowcs.c6
-rw-r--r--src/network/dns_parse.c5
-rw-r--r--src/network/getnameinfo.c4
-rw-r--r--src/network/inet_ntop.c7
-rw-r--r--src/network/lookup_name.c2
-rw-r--r--src/network/res_msend.c2
-rw-r--r--src/process/_Fork.c28
-rw-r--r--src/process/posix_spawn.c7
-rw-r--r--src/process/waitpid.c2
-rw-r--r--src/regex/glob.c2
-rw-r--r--src/select/ppoll.c (renamed from src/linux/ppoll.c)2
-rw-r--r--src/setjmp/loongarch64/longjmp.S32
-rw-r--r--src/setjmp/loongarch64/setjmp.S34
-rw-r--r--src/setjmp/riscv32/longjmp.S42
-rw-r--r--src/setjmp/riscv32/setjmp.S41
-rw-r--r--src/signal/loongarch64/restore.s10
-rw-r--r--src/signal/loongarch64/sigsetjmp.s25
-rw-r--r--src/signal/riscv32/restore.s10
-rw-r--r--src/signal/riscv32/sigsetjmp.s23
-rw-r--r--src/signal/riscv64/restore.s2
-rw-r--r--src/signal/sh/sigsetjmp.s2
-rw-r--r--src/signal/sigaltstack.c4
-rw-r--r--src/signal/siglongjmp.c5
-rw-r--r--src/signal/sigpause.c2
-rw-r--r--src/stat/fchmodat.c7
-rw-r--r--src/stat/fstatat.c1
-rw-r--r--src/stat/statvfs.c1
-rw-r--r--src/stdio/__stdio_write.c5
-rw-r--r--src/stdio/pclose.c2
-rw-r--r--src/stdio/vfprintf.c40
-rw-r--r--src/stdio/vfwprintf.c4
-rw-r--r--src/stdio/vsnprintf.c5
-rw-r--r--src/stdio/vswprintf.c3
-rw-r--r--src/stdlib/qsort.c2
-rw-r--r--src/string/strcasestr.c1
-rw-r--r--src/termios/cfgetospeed.c2
-rw-r--r--src/termios/cfsetospeed.c10
-rw-r--r--src/termios/cfsetspeed.c11
-rw-r--r--src/thread/aarch64/clone.s3
-rw-r--r--src/thread/arm/clone.s3
-rw-r--r--src/thread/loongarch64/__set_thread_area.s7
-rw-r--r--src/thread/loongarch64/__unmapself.s7
-rw-r--r--src/thread/loongarch64/clone.s30
-rw-r--r--src/thread/loongarch64/syscall_cp.s29
-rw-r--r--src/thread/m68k/clone.s3
-rw-r--r--src/thread/microblaze/clone.s3
-rw-r--r--src/thread/mips/clone.s3
-rw-r--r--src/thread/mips64/clone.s3
-rw-r--r--src/thread/mipsn32/clone.s3
-rw-r--r--src/thread/or1k/clone.s5
-rw-r--r--src/thread/riscv32/__set_thread_area.s6
-rw-r--r--src/thread/riscv32/__unmapself.s7
-rw-r--r--src/thread/riscv32/clone.s35
-rw-r--r--src/thread/riscv32/syscall_cp.s29
-rw-r--r--src/thread/riscv64/clone.s1
-rw-r--r--src/thread/s390x/__tls_get_offset.s20
-rw-r--r--src/thread/sem_post.c2
-rw-r--r--src/thread/synccall.c8
-rw-r--r--src/time/__tz.c1
-rw-r--r--src/time/__utc.c3
-rw-r--r--src/time/__year_to_secs.c4
-rw-r--r--src/time/strftime.c8
-rw-r--r--src/time/strptime.c66
-rw-r--r--src/time/timer_create.c31
-rw-r--r--src/unistd/faccessat.c2
-rw-r--r--src/unistd/isatty.c6
-rw-r--r--src/unistd/pause.c6
-rw-r--r--src/unistd/pwrite.c11
-rw-r--r--src/unistd/pwritev.c10
-rw-r--r--src/unistd/setxid.c2
-rwxr-xr-xtools/install.sh2
270 files changed, 3465 insertions, 711 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/INSTALL b/INSTALL
index c583691d..ddbbbb2f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -97,11 +97,16 @@ and ABI combinations:
* OpenRISC 1000 (or1k)
-* RISC-V 64
+* RISC-V
+ * 32-bit and 64-bit
* Little endian
* Hard, soft, and hard-single/soft-double floating point ABIs
* Standard ELF; no shared-text NOMMU support
+* LoongArch
+ * 64-bit ISA
+ * Hard, soft, and hard-single/soft-double floating point ABIs
+
Build and Installation Procedure
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
diff --git a/VERSION b/VERSION
index e8ea05db..c813fe11 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.2.4
+1.2.5
diff --git a/WHATSNEW b/WHATSNEW
index c5c8c9f4..7bd90728 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -2396,3 +2396,45 @@ arch-specific bugs fixed:
- sigaction signal mask was bogus on or1k, microblaze, mips, and riscv
- powerpc-sf longjmp asm clobbered value argument
- or1k poll function passed timeout to syscall in wrong form
+
+
+
+1.2.5 release notes
+
+new features:
+- statx function (linux extension; via syscall and fallback using fstatat)
+- clone function is now usable and gives _Fork-like consistency in child
+- statvfs now provides f_type result
+- preadv2 and pwritev2 (linux extension) syscall wrappers
+- riscv64 TLSDESC support
+
+new ports:
+- loongarch64
+- riscv32
+
+compatibility:
+- DNS resolver can now handle answers with long CNAME chains
+- string.h no longer provides (C23-incompat) non-prototype decl of basename
+- fstatat statx backend now matches stat syscall non-automounting behavior
+- mntent interfaces now handle escaped whitespace in paths/options
+
+standards updates:
+- printf %lc of nul wchar now produces output
+- snprintf and swprintf no longer fail on n > INT_MAX
+- ppoll is now exposed in default feature profile
+
+bugs fixed:
+- some long DNS answers were wrongly rejected despite new TCP support
+- glob could wrongly return GLOB_NOMATCH if aborted before any matches
+- multithreaded set*id could malfunction from thread sequencing logic bug
+- certain use of threads after fork could deadlock thread-list lock
+- posix_spawn child could deadlock in race with async parent death
+- mbrtowc return value was wrong if argument n exceeded UINT_MAX
+- 80-bit extended acoshl and powl got some corner cases wrong
+- syslog incorrectly generated localized timestamps
+
+arch-specific bugs fixed:
+- arm (32-bit) TLSDESC malfunctioned due to addends being processed wrong
+- 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
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/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/aarch64/bits/stat.h b/arch/aarch64/bits/stat.h
deleted file mode 100644
index b7f4221b..00000000
--- a/arch/aarch64/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 __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/aarch64/bits/stdint.h b/arch/aarch64/bits/stdint.h
deleted file mode 100644
index 1bb147f2..00000000
--- a/arch/aarch64/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/aarch64/bits/syscall.h.in b/arch/aarch64/bits/syscall.h.in
index 5f420e61..ea5a152a 100644
--- a/arch/aarch64/bits/syscall.h.in
+++ b/arch/aarch64/bits/syscall.h.in
@@ -299,4 +299,9 @@
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
+#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
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/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/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/arm/bits/syscall.h.in b/arch/arm/bits/syscall.h.in
index 048fdea7..157b304d 100644
--- a/arch/arm/bits/syscall.h.in
+++ b/arch/arm/bits/syscall.h.in
@@ -399,6 +399,11 @@
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
+#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 __ARM_NR_breakpoint 0x0f0001
#define __ARM_NR_cacheflush 0x0f0002
diff --git a/arch/arm/reloc.h b/arch/arm/reloc.h
index d091d2ad..d98eb8af 100644
--- a/arch/arm/reloc.h
+++ b/arch/arm/reloc.h
@@ -26,7 +26,7 @@
#define REL_TPOFF R_ARM_TLS_TPOFF32
#define REL_TLSDESC R_ARM_TLS_DESC
-#define TLSDESC_BACKWARDS
+#define TLSDESC_BACKWARDS 1
#define CRTJMP(pc,sp) __asm__ __volatile__( \
"mov sp,%1 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
diff --git a/arch/generic/bits/reg.h b/arch/generic/bits/reg.h
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/arch/generic/bits/reg.h
diff --git a/arch/riscv64/bits/stat.h b/arch/generic/bits/stat.h
index b7f4221b..f6d9e864 100644
--- a/arch/riscv64/bits/stat.h
+++ b/arch/generic/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/m68k/bits/stdint.h b/arch/generic/bits/stdint.h
index d1b27121..86489187 100644
--- a/arch/m68k/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/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/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/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/i386/bits/syscall.h.in b/arch/i386/bits/syscall.h.in
index 46ffe1d9..55e91cc4 100644
--- a/arch/i386/bits/syscall.h.in
+++ b/arch/i386/bits/syscall.h.in
@@ -436,4 +436,10 @@
#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
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/loongarch64/atomic_arch.h b/arch/loongarch64/atomic_arch.h
new file mode 100644
index 00000000..2225d027
--- /dev/null
+++ b/arch/loongarch64/atomic_arch.h
@@ -0,0 +1,53 @@
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+ int v;
+ __asm__ __volatile__ (
+ "ll.w %0, %1"
+ : "=r"(v)
+ : "ZC"(*p));
+ return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+ int r;
+ __asm__ __volatile__ (
+ "sc.w %0, %1"
+ : "=r"(r), "=ZC"(*p)
+ : "0"(v) : "memory");
+ return r;
+}
+
+#define a_ll_p a_ll_p
+static inline void *a_ll_p(volatile void *p)
+{
+ void *v;
+ __asm__ __volatile__ (
+ "ll.d %0, %1"
+ : "=r"(v)
+ : "ZC"(*(void *volatile *)p));
+ return v;
+}
+
+#define a_sc_p a_sc_p
+static inline int a_sc_p(volatile void *p, void *v)
+{
+ long r;
+ __asm__ __volatile__ (
+ "sc.d %0, %1"
+ : "=r"(r), "=ZC"(*(void *volatile *)p)
+ : "0"(v)
+ : "memory");
+ return r;
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+ __asm__ __volatile__ ("dbar 0" : : : "memory");
+}
+
+#define a_pre_llsc a_barrier
+#define a_post_llsc a_barrier
diff --git a/arch/loongarch64/bits/alltypes.h.in b/arch/loongarch64/bits/alltypes.h.in
new file mode 100644
index 00000000..d1807aca
--- /dev/null
+++ b/arch/loongarch64/bits/alltypes.h.in
@@ -0,0 +1,18 @@
+#define _Addr long
+#define _Int64 long
+#define _Reg long
+
+#define __BYTE_ORDER 1234
+#define __LONG_MAX 0x7fffffffffffffffL
+
+#ifndef __cplusplus
+TYPEDEF int wchar_t;
+#endif
+
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
+
+TYPEDEF unsigned nlink_t;
+TYPEDEF int blksize_t;
diff --git a/arch/loongarch64/bits/fenv.h b/arch/loongarch64/bits/fenv.h
new file mode 100644
index 00000000..264cafb5
--- /dev/null
+++ b/arch/loongarch64/bits/fenv.h
@@ -0,0 +1,20 @@
+#define FE_INEXACT 0x010000
+#define FE_UNDERFLOW 0x020000
+#define FE_OVERFLOW 0x040000
+#define FE_DIVBYZERO 0x080000
+#define FE_INVALID 0x100000
+
+#define FE_ALL_EXCEPT 0x1F0000
+
+#define FE_TONEAREST 0x000
+#define FE_TOWARDZERO 0x100
+#define FE_UPWARD 0x200
+#define FE_DOWNWARD 0x300
+
+typedef unsigned fexcept_t;
+
+typedef struct {
+ unsigned __cw;
+} fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t *) -1)
diff --git a/arch/loongarch64/bits/float.h b/arch/loongarch64/bits/float.h
new file mode 100644
index 00000000..719c7908
--- /dev/null
+++ b/arch/loongarch64/bits/float.h
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
+#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
+#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
+#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
+
+#define LDBL_MANT_DIG 113
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+#define LDBL_DIG 33
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
+
+#define DECIMAL_DIG 36
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)
diff --git a/arch/loongarch64/bits/setjmp.h b/arch/loongarch64/bits/setjmp.h
new file mode 100644
index 00000000..3b15e87b
--- /dev/null
+++ b/arch/loongarch64/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long __jmp_buf[23];
diff --git a/arch/loongarch64/bits/signal.h b/arch/loongarch64/bits/signal.h
new file mode 100644
index 00000000..5a9ed8c9
--- /dev/null
+++ b/arch/loongarch64/bits/signal.h
@@ -0,0 +1,101 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 4096
+#define SIGSTKSZ 16384
+#endif
+
+#if defined(_GNU_SOURCE)
+#define LARCH_NGREG 32
+#define LARCH_REG_RA 1
+#define LARCH_REG_SP 3
+#define LARCH_REG_S0 23
+#define LARCH_REG_S1 24
+#define LARCH_REG_A0 4
+#define LARCH_REG_S2 25
+#define LARCH_REG_NARGS 8
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned long greg_t, gregset_t[32];
+
+struct sigcontext {
+ unsigned long sc_pc;
+ unsigned long sc_regs[32];
+ unsigned sc_flags;
+ unsigned long sc_extcontext[] __attribute__((__aligned__(16)));
+};
+#endif
+
+typedef struct {
+ unsigned long __pc;
+ unsigned long __gregs[32];
+ unsigned __flags;
+ unsigned long __extcontext[] __attribute__((__aligned__(16)));
+} mcontext_t;
+
+struct sigaltstack {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+};
+
+typedef struct __ucontext
+{
+ unsigned long uc_flags;
+ struct __ucontext *uc_link;
+ stack_t uc_stack;
+ sigset_t uc_sigmask;
+ long __uc_pad;
+ mcontext_t uc_mcontext;
+} ucontext_t;
+
+#define __uc_flags uc_flags
+
+#define SA_NOCLDSTOP 1
+#define SA_NOCLDWAIT 2
+#define SA_SIGINFO 4
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#endif
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT SIGABRT
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
diff --git a/arch/loongarch64/bits/syscall.h.in b/arch/loongarch64/bits/syscall.h.in
new file mode 100644
index 00000000..2afb4ea1
--- /dev/null
+++ b/arch/loongarch64/bits/syscall.h.in
@@ -0,0 +1,316 @@
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_io_getevents 4
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR3264_fcntl 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR_nfsservctl 42
+#define __NR3264_statfs 43
+#define __NR3264_fstatfs 44
+#define __NR3264_truncate 45
+#define __NR3264_ftruncate 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR3264_lseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR3264_sendfile 71
+#define __NR_pselect6 72
+#define __NR_ppoll 73
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_timerfd_settime 86
+#define __NR_timerfd_gettime 87
+#define __NR_utimensat 88
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_futex 98
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_nanosleep 101
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_gettime 108
+#define __NR_timer_getoverrun 109
+#define __NR_timer_settime 110
+#define __NR_timer_delete 111
+#define __NR_clock_settime 112
+#define __NR_clock_gettime 113
+#define __NR_clock_getres 114
+#define __NR_clock_nanosleep 115
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_sched_rr_get_interval 127
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigtimedwait 137
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_gettimeofday 169
+#define __NR_settimeofday 170
+#define __NR_adjtimex 171
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_timedsend 182
+#define __NR_mq_timedreceive 183
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semtimedop 192
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR3264_mmap 222
+#define __NR3264_fadvise64 223
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_recvmmsg 243
+#define __NR_arch_specific_syscall 244
+#define __NR_wait4 260
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_clock_adjtime 266
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_seccomp 277
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_mprotect 288
+#define __NR_pkey_alloc 289
+#define __NR_pkey_free 290
+#define __NR_statx 291
+#define __NR_io_pgetevents 292
+#define __NR_rseq 293
+#define __NR_kexec_file_load 294
+#define __NR_pidfd_send_signal 424
+#define __NR_io_uring_setup 425
+#define __NR_io_uring_enter 426
+#define __NR_io_uring_register 427
+#define __NR_open_tree 428
+#define __NR_move_mount 429
+#define __NR_fsopen 430
+#define __NR_fsconfig 431
+#define __NR_fsmount 432
+#define __NR_fspick 433
+#define __NR_pidfd_open 434
+#define __NR_clone3 435
+#define __NR_close_range 436
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
+#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_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_fcntl __NR3264_fcntl
+#define __NR_statfs __NR3264_statfs
+#define __NR_fstatfs __NR3264_fstatfs
+#define __NR_truncate __NR3264_truncate
+#define __NR_ftruncate __NR3264_ftruncate
+#define __NR_lseek __NR3264_lseek
+#define __NR_sendfile __NR3264_sendfile
+#define __NR_mmap __NR3264_mmap
+#define __NR_fadvise64 __NR3264_fadvise64
diff --git a/arch/loongarch64/bits/user.h b/arch/loongarch64/bits/user.h
new file mode 100644
index 00000000..fd9b7b22
--- /dev/null
+++ b/arch/loongarch64/bits/user.h
@@ -0,0 +1,24 @@
+#define ELF_NGREG 45
+#define ELF_NFPREG 34
+
+struct user_regs_struct {
+ unsigned long regs[32];
+ unsigned long orig_a0;
+ unsigned long csr_era;
+ unsigned long csr_badv;
+ unsigned long reserved[10];
+};
+
+struct user_fp_struct {
+ unsigned long fpr[32];
+ unsigned long fcc;
+ unsigned int fcsr;
+};
+
+typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
+
+typedef union {
+ double d;
+ float f;
+} elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
diff --git a/arch/loongarch64/crt_arch.h b/arch/loongarch64/crt_arch.h
new file mode 100644
index 00000000..e0760d9e
--- /dev/null
+++ b/arch/loongarch64/crt_arch.h
@@ -0,0 +1,13 @@
+__asm__(
+".text \n"
+".global " START "\n"
+".type " START ", @function\n"
+START ":\n"
+" move $fp, $zero\n"
+" move $a0, $sp\n"
+".weak _DYNAMIC\n"
+".hidden _DYNAMIC\n"
+" la.local $a1, _DYNAMIC\n"
+" bstrins.d $sp, $zero, 3, 0\n"
+" b " START "_c\n"
+);
diff --git a/arch/loongarch64/pthread_arch.h b/arch/loongarch64/pthread_arch.h
new file mode 100644
index 00000000..365f6ca8
--- /dev/null
+++ b/arch/loongarch64/pthread_arch.h
@@ -0,0 +1,11 @@
+static inline uintptr_t __get_tp()
+{
+ register uintptr_t tp __asm__("tp");
+ __asm__ ("" : "=r" (tp) );
+ return tp;
+}
+
+#define TLS_ABOVE_TP
+#define GAP_ABOVE_TP 0
+#define DTP_OFFSET 0
+#define MC_PC __pc
diff --git a/arch/loongarch64/reloc.h b/arch/loongarch64/reloc.h
new file mode 100644
index 00000000..a4db6a9c
--- /dev/null
+++ b/arch/loongarch64/reloc.h
@@ -0,0 +1,30 @@
+#ifdef __loongarch_soft_float
+#define FP_SUFFIX "-sf"
+#elif defined __loongarch_single_float
+#define FP_SUFFIX "-sp"
+#else
+#define FP_SUFFIX ""
+#endif
+
+#define LDSO_ARCH "loongarch64" FP_SUFFIX
+
+#define TPOFF_K 0
+
+#define REL_PLT R_LARCH_JUMP_SLOT
+#define REL_COPY R_LARCH_COPY
+#define REL_DTPMOD R_LARCH_TLS_DTPMOD64
+#define REL_DTPOFF R_LARCH_TLS_DTPREL64
+#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" )
+
+#define GETFUNCSYM(fp, sym, got) __asm__ ( \
+ ".hidden " #sym "\n" \
+ ".align 8 \n" \
+ " la.local $t1, "#sym" \n" \
+ " move %0, $t1 \n" \
+ : "=r"(*(fp)) : : "memory" )
diff --git a/arch/loongarch64/syscall_arch.h b/arch/loongarch64/syscall_arch.h
new file mode 100644
index 00000000..4d5e1885
--- /dev/null
+++ b/arch/loongarch64/syscall_arch.h
@@ -0,0 +1,137 @@
+#define __SYSCALL_LL_E(x) (x)
+#define __SYSCALL_LL_O(x) (x)
+
+#define SYSCALL_CLOBBERLIST \
+ "$t0", "$t1", "$t2", "$t3", \
+ "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
+
+static inline long __syscall0(long n)
+{
+ register long a7 __asm__("$a7") = n;
+ register long a0 __asm__("$a0");
+
+ __asm__ __volatile__ (
+ "syscall 0"
+ : "=r"(a0)
+ : "r"(a7)
+ : SYSCALL_CLOBBERLIST);
+ return a0;
+}
+
+static inline long __syscall1(long n, long a)
+{
+ register long a7 __asm__("$a7") = n;
+ register long a0 __asm__("$a0") = a;
+
+ __asm__ __volatile__ (
+ "syscall 0"
+ : "+r"(a0)
+ : "r"(a7)
+ : SYSCALL_CLOBBERLIST);
+ return a0;
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+ register long a7 __asm__("$a7") = n;
+ register long a0 __asm__("$a0") = a;
+ register long a1 __asm__("$a1") = b;
+
+ __asm__ __volatile__ (
+ "syscall 0"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1)
+ : SYSCALL_CLOBBERLIST);
+ return a0;
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+ register long a7 __asm__("$a7") = n;
+ register long a0 __asm__("$a0") = a;
+ register long a1 __asm__("$a1") = b;
+ register long a2 __asm__("$a2") = c;
+
+ __asm__ __volatile__ (
+ "syscall 0"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2)
+ : SYSCALL_CLOBBERLIST);
+ return a0;
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+ register long a7 __asm__("$a7") = n;
+ register long a0 __asm__("$a0") = a;
+ register long a1 __asm__("$a1") = b;
+ register long a2 __asm__("$a2") = c;
+ register long a3 __asm__("$a3") = d;
+
+ __asm__ __volatile__ (
+ "syscall 0"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2), "r"(a3)
+ : SYSCALL_CLOBBERLIST);
+ return a0;
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+ register long a7 __asm__("$a7") = n;
+ register long a0 __asm__("$a0") = a;
+ register long a1 __asm__("$a1") = b;
+ register long a2 __asm__("$a2") = c;
+ register long a3 __asm__("$a3") = d;
+ register long a4 __asm__("$a4") = e;
+
+ __asm__ __volatile__ (
+ "syscall 0"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2), "r"(a3), "r"(a4)
+ : SYSCALL_CLOBBERLIST);
+ return a0;
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+ register long a7 __asm__("$a7") = n;
+ register long a0 __asm__("$a0") = a;
+ register long a1 __asm__("$a1") = b;
+ register long a2 __asm__("$a2") = c;
+ register long a3 __asm__("$a3") = d;
+ register long a4 __asm__("$a4") = e;
+ register long a5 __asm__("$a5") = f;
+
+ __asm__ __volatile__ (
+ "syscall 0"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5)
+ : SYSCALL_CLOBBERLIST);
+ return a0;
+}
+
+static inline long __syscall7(long n, long a, long b, long c, long d, long e, long f, long g)
+{
+ register long a7 __asm__("$a7") = n;
+ register long a0 __asm__("$a0") = a;
+ register long a1 __asm__("$a1") = b;
+ register long a2 __asm__("$a2") = c;
+ register long a3 __asm__("$a3") = d;
+ register long a4 __asm__("$a4") = e;
+ register long a5 __asm__("$a5") = f;
+ register long a6 __asm__("$a6") = g;
+
+ __asm__ __volatile__ (
+ "syscall 0"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(a6)
+ : SYSCALL_CLOBBERLIST);
+ return a0;
+}
+
+#define VDSO_USEFUL
+#define VDSO_CGT_SYM "__vdso_clock_gettime"
+#define VDSO_CGT_VER "LINUX_5.10"
+
+#define IPC_64 0
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
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/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/m68k/bits/syscall.h.in b/arch/m68k/bits/syscall.h.in
index a0c63323..5cd84602 100644
--- a/arch/m68k/bits/syscall.h.in
+++ b/arch/m68k/bits/syscall.h.in
@@ -416,3 +416,8 @@
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
+#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
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/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/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/microblaze/bits/syscall.h.in b/arch/microblaze/bits/syscall.h.in
index 931d7919..40860e6d 100644
--- a/arch/microblaze/bits/syscall.h.in
+++ b/arch/microblaze/bits/syscall.h.in
@@ -437,4 +437,9 @@
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
+#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
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/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/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/mips/bits/syscall.h.in b/arch/mips/bits/syscall.h.in
index 63e3503a..55e35742 100644
--- a/arch/mips/bits/syscall.h.in
+++ b/arch/mips/bits/syscall.h.in
@@ -418,4 +418,9 @@
#define __NR_landlock_create_ruleset 4444
#define __NR_landlock_add_rule 4445
#define __NR_landlock_restrict_self 4446
+#define __NR_process_mrelease 4448
+#define __NR_futex_waitv 4449
+#define __NR_set_mempolicy_home_node 4450
+#define __NR_cachestat 4451
+#define __NR_fchmodat2 4452
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/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/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/mips64/bits/syscall.h.in b/arch/mips64/bits/syscall.h.in
index b89965d1..50cec45a 100644
--- a/arch/mips64/bits/syscall.h.in
+++ b/arch/mips64/bits/syscall.h.in
@@ -348,4 +348,9 @@
#define __NR_landlock_create_ruleset 5444
#define __NR_landlock_add_rule 5445
#define __NR_landlock_restrict_self 5446
+#define __NR_process_mrelease 5448
+#define __NR_futex_waitv 5449
+#define __NR_set_mempolicy_home_node 5450
+#define __NR_cachestat 5451
+#define __NR_fchmodat2 5452
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/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/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/mipsn32/bits/syscall.h.in b/arch/mipsn32/bits/syscall.h.in
index bb2d04a8..9a4bd301 100644
--- a/arch/mipsn32/bits/syscall.h.in
+++ b/arch/mipsn32/bits/syscall.h.in
@@ -372,4 +372,9 @@
#define __NR_landlock_create_ruleset 6444
#define __NR_landlock_add_rule 6445
#define __NR_landlock_restrict_self 6446
+#define __NR_process_mrelease 6448
+#define __NR_futex_waitv 6449
+#define __NR_set_mempolicy_home_node 6450
+#define __NR_cachestat 6451
+#define __NR_fchmodat2 6452
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/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/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/or1k/bits/syscall.h.in b/arch/or1k/bits/syscall.h.in
index 2b5f2052..00812bf8 100644
--- a/arch/or1k/bits/syscall.h.in
+++ b/arch/or1k/bits/syscall.h.in
@@ -321,4 +321,9 @@
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
+#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
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/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/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/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/powerpc/bits/syscall.h.in b/arch/powerpc/bits/syscall.h.in
index b1605a58..ea95f3ed 100644
--- a/arch/powerpc/bits/syscall.h.in
+++ b/arch/powerpc/bits/syscall.h.in
@@ -425,4 +425,9 @@
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
+#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
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/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
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/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/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/powerpc64/bits/syscall.h.in b/arch/powerpc64/bits/syscall.h.in
index b3a8fba0..43551079 100644
--- a/arch/powerpc64/bits/syscall.h.in
+++ b/arch/powerpc64/bits/syscall.h.in
@@ -397,4 +397,9 @@
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
+#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
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/riscv32/atomic_arch.h b/arch/riscv32/atomic_arch.h
new file mode 100644
index 00000000..4d418f63
--- /dev/null
+++ b/arch/riscv32/atomic_arch.h
@@ -0,0 +1,21 @@
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+ __asm__ __volatile__ ("fence rw,rw" : : : "memory");
+}
+
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+ int old, tmp;
+ __asm__ __volatile__ (
+ "\n1: lr.w.aqrl %0, (%2)\n"
+ " bne %0, %3, 1f\n"
+ " sc.w.aqrl %1, %4, (%2)\n"
+ " bnez %1, 1b\n"
+ "1:"
+ : "=&r"(old), "=&r"(tmp)
+ : "r"(p), "r"((long)t), "r"((long)s)
+ : "memory");
+ return old;
+}
diff --git a/arch/riscv32/bits/alltypes.h.in b/arch/riscv32/bits/alltypes.h.in
new file mode 100644
index 00000000..e2b6129e
--- /dev/null
+++ b/arch/riscv32/bits/alltypes.h.in
@@ -0,0 +1,18 @@
+#define _Addr int
+#define _Int64 long long
+#define _Reg int
+
+#define __BYTE_ORDER 1234
+#define __LONG_MAX 0x7fffffffL
+
+#ifndef __cplusplus
+TYPEDEF int wchar_t;
+#endif
+
+TYPEDEF int blksize_t;
+TYPEDEF unsigned int nlink_t;
+
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
diff --git a/arch/riscv32/bits/fenv.h b/arch/riscv32/bits/fenv.h
new file mode 100644
index 00000000..806ec40f
--- /dev/null
+++ b/arch/riscv32/bits/fenv.h
@@ -0,0 +1,17 @@
+#define FE_INVALID 16
+#define FE_DIVBYZERO 8
+#define FE_OVERFLOW 4
+#define FE_UNDERFLOW 2
+#define FE_INEXACT 1
+
+#define FE_ALL_EXCEPT 31
+
+#define FE_TONEAREST 0
+#define FE_DOWNWARD 2
+#define FE_UPWARD 3
+#define FE_TOWARDZERO 1
+
+typedef unsigned int fexcept_t;
+typedef unsigned int fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t *) -1)
diff --git a/arch/riscv32/bits/float.h b/arch/riscv32/bits/float.h
new file mode 100644
index 00000000..719c7908
--- /dev/null
+++ b/arch/riscv32/bits/float.h
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
+#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
+#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
+#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
+
+#define LDBL_MANT_DIG 113
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+#define LDBL_DIG 33
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
+
+#define DECIMAL_DIG 36
diff --git a/arch/riscv32/bits/ipcstat.h b/arch/riscv32/bits/ipcstat.h
new file mode 100644
index 00000000..4f4fcb0c
--- /dev/null
+++ b/arch/riscv32/bits/ipcstat.h
@@ -0,0 +1 @@
+#define IPC_STAT 0x102
diff --git a/arch/riscv32/bits/msg.h b/arch/riscv32/bits/msg.h
new file mode 100644
index 00000000..7bbbb2bf
--- /dev/null
+++ b/arch/riscv32/bits/msg.h
@@ -0,0 +1,18 @@
+struct msqid_ds {
+ struct ipc_perm msg_perm;
+ unsigned long __msg_stime_lo;
+ unsigned long __msg_stime_hi;
+ unsigned long __msg_rtime_lo;
+ unsigned long __msg_rtime_hi;
+ unsigned long __msg_ctime_lo;
+ unsigned long __msg_ctime_hi;
+ unsigned long msg_cbytes;
+ msgqnum_t msg_qnum;
+ msglen_t msg_qbytes;
+ pid_t msg_lspid;
+ pid_t msg_lrpid;
+ unsigned long __unused[2];
+ time_t msg_stime;
+ time_t msg_rtime;
+ time_t msg_ctime;
+};
diff --git a/arch/riscv32/bits/sem.h b/arch/riscv32/bits/sem.h
new file mode 100644
index 00000000..544e3d2a
--- /dev/null
+++ b/arch/riscv32/bits/sem.h
@@ -0,0 +1,18 @@
+struct semid_ds {
+ struct ipc_perm sem_perm;
+ unsigned long __sem_otime_lo;
+ unsigned long __sem_otime_hi;
+ unsigned long __sem_ctime_lo;
+ unsigned long __sem_ctime_hi;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned short sem_nsems;
+ char __sem_nsems_pad[sizeof(long)-sizeof(short)];
+#else
+ char __sem_nsems_pad[sizeof(long)-sizeof(short)];
+ unsigned short sem_nsems;
+#endif
+ long __unused3;
+ long __unused4;
+ time_t sem_otime;
+ time_t sem_ctime;
+};
diff --git a/arch/riscv32/bits/setjmp.h b/arch/riscv32/bits/setjmp.h
new file mode 100644
index 00000000..51e96276
--- /dev/null
+++ b/arch/riscv32/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long long __jmp_buf[19];
diff --git a/arch/riscv32/bits/shm.h b/arch/riscv32/bits/shm.h
new file mode 100644
index 00000000..725fb469
--- /dev/null
+++ b/arch/riscv32/bits/shm.h
@@ -0,0 +1,31 @@
+#define SHMLBA 4096
+
+struct shmid_ds {
+ struct ipc_perm shm_perm;
+ size_t shm_segsz;
+ unsigned long __shm_atime_lo;
+ unsigned long __shm_atime_hi;
+ unsigned long __shm_dtime_lo;
+ unsigned long __shm_dtime_hi;
+ unsigned long __shm_ctime_lo;
+ unsigned long __shm_ctime_hi;
+ pid_t shm_cpid;
+ pid_t shm_lpid;
+ unsigned long shm_nattch;
+ unsigned long __pad1;
+ unsigned long __pad2;
+ unsigned long __pad3;
+ time_t shm_atime;
+ time_t shm_dtime;
+ time_t shm_ctime;
+};
+
+struct shminfo {
+ unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+ int __used_ids;
+ unsigned long shm_tot, shm_rss, shm_swp;
+ unsigned long __swap_attempts, __swap_successes;
+};
diff --git a/arch/riscv32/bits/signal.h b/arch/riscv32/bits/signal.h
new file mode 100644
index 00000000..50b66ec9
--- /dev/null
+++ b/arch/riscv32/bits/signal.h
@@ -0,0 +1,120 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+# define MINSIGSTKSZ 2048
+# define SIGSTKSZ 8192
+#endif
+
+typedef unsigned long __riscv_mc_gp_state[32];
+
+struct __riscv_mc_f_ext_state {
+ unsigned int __f[32];
+ unsigned int __fcsr;
+};
+
+struct __riscv_mc_d_ext_state {
+ unsigned long long __f[32];
+ unsigned int __fcsr;
+};
+
+struct __riscv_mc_q_ext_state {
+ unsigned long long __f[64] __attribute__((__aligned__(16)));
+ unsigned int __fcsr;
+ unsigned int __reserved[3];
+};
+
+union __riscv_mc_fp_state {
+ struct __riscv_mc_f_ext_state __f;
+ struct __riscv_mc_d_ext_state __d;
+ struct __riscv_mc_q_ext_state __q;
+};
+
+typedef struct mcontext_t {
+ __riscv_mc_gp_state __gregs;
+ union __riscv_mc_fp_state __fpregs;
+} mcontext_t;
+
+#if defined(_GNU_SOURCE)
+#define REG_PC 0
+#define REG_RA 1
+#define REG_SP 2
+#define REG_TP 4
+#define REG_S0 8
+#define REG_S1 9
+#define REG_A0 10
+#define REG_S2 18
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned long greg_t;
+typedef unsigned long gregset_t[32];
+typedef union __riscv_mc_fp_state fpregset_t;
+struct sigcontext {
+ gregset_t gregs;
+ fpregset_t fpregs;
+};
+#endif
+
+struct sigaltstack {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+};
+
+typedef struct __ucontext
+{
+ unsigned long uc_flags;
+ struct __ucontext *uc_link;
+ stack_t uc_stack;
+ sigset_t uc_sigmask;
+ mcontext_t uc_mcontext;
+} ucontext_t;
+
+#define SA_NOCLDSTOP 1
+#define SA_NOCLDWAIT 2
+#define SA_SIGINFO 4
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTORER 0x04000000
+
+#endif
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT SIGABRT
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
diff --git a/arch/riscv32/bits/syscall.h.in b/arch/riscv32/bits/syscall.h.in
new file mode 100644
index 00000000..9228d840
--- /dev/null
+++ b/arch/riscv32/bits/syscall.h.in
@@ -0,0 +1,300 @@
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR_fcntl64 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR_nfsservctl 42
+#define __NR_statfs64 43
+#define __NR_fstatfs64 44
+#define __NR_truncate64 45
+#define __NR_ftruncate64 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR__llseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR_sendfile64 71
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_nanosleep 101
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_getoverrun 109
+#define __NR_timer_delete 111
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR_mmap2 222
+#define __NR_fadvise64_64 223
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_arch_specific_syscall 244
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_seccomp 277
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_mprotect 288
+#define __NR_pkey_alloc 289
+#define __NR_pkey_free 290
+#define __NR_statx 291
+#define __NR_rseq 293
+#define __NR_kexec_file_load 294
+#define __NR_clock_gettime64 403
+#define __NR_clock_settime64 404
+#define __NR_clock_adjtime64 405
+#define __NR_clock_getres_time64 406
+#define __NR_clock_nanosleep_time64 407
+#define __NR_timer_gettime64 408
+#define __NR_timer_settime64 409
+#define __NR_timerfd_gettime64 410
+#define __NR_timerfd_settime64 411
+#define __NR_utimensat_time64 412
+#define __NR_pselect6_time64 413
+#define __NR_ppoll_time64 414
+#define __NR_io_pgetevents_time64 416
+#define __NR_recvmmsg_time64 417
+#define __NR_mq_timedsend_time64 418
+#define __NR_mq_timedreceive_time64 419
+#define __NR_semtimedop_time64 420
+#define __NR_rt_sigtimedwait_time64 421
+#define __NR_futex_time64 422
+#define __NR_sched_rr_get_interval_time64 423
+#define __NR_pidfd_send_signal 424
+#define __NR_io_uring_setup 425
+#define __NR_io_uring_enter 426
+#define __NR_io_uring_register 427
+#define __NR_open_tree 428
+#define __NR_move_mount 429
+#define __NR_fsopen 430
+#define __NR_fsconfig 431
+#define __NR_fsmount 432
+#define __NR_fspick 433
+#define __NR_pidfd_open 434
+#define __NR_clone3 435
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
+#define __NR_process_madvise 440
+#define __NR_epoll_pwait2 441
+#define __NR_mount_setattr 442
+#define __NR_landlock_create_ruleset 444
+#define __NR_landlock_add_rule 445
+#define __NR_landlock_restrict_self 446
+#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_futex __NR_futex_time64
+
+#define __NR_sysriscv __NR_arch_specific_syscall
+#define __NR_riscv_flush_icache (__NR_sysriscv + 15)
diff --git a/arch/riscv32/bits/user.h b/arch/riscv32/bits/user.h
new file mode 100644
index 00000000..0d37de0b
--- /dev/null
+++ b/arch/riscv32/bits/user.h
@@ -0,0 +1,6 @@
+#include <signal.h>
+
+#define ELF_NGREG 32
+#define ELF_NFPREG 33
+typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
+typedef union __riscv_mc_fp_state elf_fpregset_t;
diff --git a/arch/riscv32/crt_arch.h b/arch/riscv32/crt_arch.h
new file mode 100644
index 00000000..6b93fcfd
--- /dev/null
+++ b/arch/riscv32/crt_arch.h
@@ -0,0 +1,19 @@
+__asm__(
+".section .sdata,\"aw\"\n"
+".text\n"
+".global " START "\n"
+".type " START ",%function\n"
+START ":\n"
+".weak __global_pointer$\n"
+".hidden __global_pointer$\n"
+".option push\n"
+".option norelax\n\t"
+"lla gp, __global_pointer$\n"
+".option pop\n\t"
+"mv a0, sp\n"
+".weak _DYNAMIC\n"
+".hidden _DYNAMIC\n\t"
+"lla a1, _DYNAMIC\n\t"
+"andi sp, sp, -16\n\t"
+"tail " START "_c"
+);
diff --git a/arch/riscv32/kstat.h b/arch/riscv32/kstat.h
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/arch/riscv32/kstat.h
diff --git a/arch/riscv32/pthread_arch.h b/arch/riscv32/pthread_arch.h
new file mode 100644
index 00000000..a20d7fba
--- /dev/null
+++ b/arch/riscv32/pthread_arch.h
@@ -0,0 +1,13 @@
+static inline uintptr_t __get_tp()
+{
+ uintptr_t tp;
+ __asm__ __volatile__("mv %0, tp" : "=r"(tp));
+ return tp;
+}
+
+#define TLS_ABOVE_TP
+#define GAP_ABOVE_TP 0
+
+#define DTP_OFFSET 0x800
+
+#define MC_PC __gregs[0]
diff --git a/arch/riscv32/reloc.h b/arch/riscv32/reloc.h
new file mode 100644
index 00000000..59d15f17
--- /dev/null
+++ b/arch/riscv32/reloc.h
@@ -0,0 +1,22 @@
+#if defined __riscv_float_abi_soft
+#define RISCV_FP_SUFFIX "-sf"
+#elif defined __riscv_float_abi_single
+#define RISCV_FP_SUFFIX "-sp"
+#elif defined __riscv_float_abi_double
+#define RISCV_FP_SUFFIX ""
+#endif
+
+#define LDSO_ARCH "riscv32" RISCV_FP_SUFFIX
+
+#define TPOFF_K 0
+
+#define REL_SYMBOLIC R_RISCV_32
+#define REL_PLT R_RISCV_JUMP_SLOT
+#define REL_RELATIVE R_RISCV_RELATIVE
+#define REL_COPY R_RISCV_COPY
+#define REL_DTPMOD R_RISCV_TLS_DTPMOD32
+#define REL_DTPOFF R_RISCV_TLS_DTPREL32
+#define REL_TPOFF R_RISCV_TLS_TPREL32
+
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+ "mv sp, %1 ; jr %0" : : "r"(pc), "r"(sp) : "memory" )
diff --git a/arch/riscv32/syscall_arch.h b/arch/riscv32/syscall_arch.h
new file mode 100644
index 00000000..70d2773f
--- /dev/null
+++ b/arch/riscv32/syscall_arch.h
@@ -0,0 +1,79 @@
+#define __SYSCALL_LL_E(x) \
+((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
+((union { long long ll; long l[2]; }){ .ll = x }).l[1]
+#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))
+
+#define __asm_syscall(...) \
+ __asm__ __volatile__ ("ecall\n\t" \
+ : "=r"(a0) : __VA_ARGS__ : "memory"); \
+ return a0; \
+
+static inline long __syscall0(long n)
+{
+ register long a7 __asm__("a7") = n;
+ register long a0 __asm__("a0");
+ __asm_syscall("r"(a7))
+}
+
+static inline long __syscall1(long n, long a)
+{
+ register long a7 __asm__("a7") = n;
+ register long a0 __asm__("a0") = a;
+ __asm_syscall("r"(a7), "0"(a0))
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+ register long a7 __asm__("a7") = n;
+ register long a0 __asm__("a0") = a;
+ register long a1 __asm__("a1") = b;
+ __asm_syscall("r"(a7), "0"(a0), "r"(a1))
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+ register long a7 __asm__("a7") = n;
+ register long a0 __asm__("a0") = a;
+ register long a1 __asm__("a1") = b;
+ register long a2 __asm__("a2") = c;
+ __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2))
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+ register long a7 __asm__("a7") = n;
+ register long a0 __asm__("a0") = a;
+ register long a1 __asm__("a1") = b;
+ register long a2 __asm__("a2") = c;
+ register long a3 __asm__("a3") = d;
+ __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3))
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+ register long a7 __asm__("a7") = n;
+ register long a0 __asm__("a0") = a;
+ register long a1 __asm__("a1") = b;
+ register long a2 __asm__("a2") = c;
+ register long a3 __asm__("a3") = d;
+ register long a4 __asm__("a4") = e;
+ __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+ register long a7 __asm__("a7") = n;
+ register long a0 __asm__("a0") = a;
+ register long a1 __asm__("a1") = b;
+ register long a2 __asm__("a2") = c;
+ register long a3 __asm__("a3") = d;
+ register long a4 __asm__("a4") = e;
+ register long a5 __asm__("a5") = f;
+ __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5))
+}
+
+#define VDSO_USEFUL
+#define VDSO_CGT_SYM "__vdso_clock_gettime"
+#define VDSO_CGT_VER "LINUX_4.15"
+
+#define IPC_64 0
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/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/riscv64/bits/signal.h b/arch/riscv64/bits/signal.h
index fd6157a3..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];
};
@@ -41,7 +41,9 @@ typedef struct mcontext_t {
#define REG_SP 2
#define REG_TP 4
#define REG_S0 8
+#define REG_S1 9
#define REG_A0 10
+#define REG_S2 18
#endif
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
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/riscv64/bits/syscall.h.in b/arch/riscv64/bits/syscall.h.in
index b534afe8..e362bd0e 100644
--- a/arch/riscv64/bits/syscall.h.in
+++ b/arch/riscv64/bits/syscall.h.in
@@ -299,6 +299,11 @@
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
+#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_sysriscv __NR_arch_specific_syscall
#define __NR_riscv_flush_icache (__NR_sysriscv + 15)
diff --git a/arch/riscv64/reloc.h b/arch/riscv64/reloc.h
index 1ca13811..7c7c0611 100644
--- a/arch/riscv64/reloc.h
+++ b/arch/riscv64/reloc.h
@@ -17,6 +17,7 @@
#define REL_DTPMOD R_RISCV_TLS_DTPMOD64
#define REL_DTPOFF R_RISCV_TLS_DTPREL64
#define REL_TPOFF R_RISCV_TLS_TPREL64
+#define REL_TLSDESC R_RISCV_TLSDESC
#define CRTJMP(pc,sp) __asm__ __volatile__( \
"mv sp, %1 ; jr %0" : : "r"(pc), "r"(sp) : "memory" )
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
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/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/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/s390x/bits/syscall.h.in b/arch/s390x/bits/syscall.h.in
index dfc38479..e60711a6 100644
--- a/arch/s390x/bits/syscall.h.in
+++ b/arch/s390x/bits/syscall.h.in
@@ -362,4 +362,10 @@
#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
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/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" )
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"
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/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/sh/bits/syscall.h.in b/arch/sh/bits/syscall.h.in
index ff14f54d..915a79cd 100644
--- a/arch/sh/bits/syscall.h.in
+++ b/arch/sh/bits/syscall.h.in
@@ -409,4 +409,9 @@
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
+#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
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/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/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/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/x32/bits/syscall.h.in b/arch/x32/bits/syscall.h.in
index 5d22fa17..1d065eea 100644
--- a/arch/x32/bits/syscall.h.in
+++ b/arch/x32/bits/syscall.h.in
@@ -308,6 +308,12 @@
#define __NR_landlock_create_ruleset (0x40000000 + 444)
#define __NR_landlock_add_rule (0x40000000 + 445)
#define __NR_landlock_restrict_self (0x40000000 + 446)
+#define __NR_memfd_secret (0x40000000 + 447)
+#define __NR_process_mrelease (0x40000000 + 448)
+#define __NR_futex_waitv (0x40000000 + 449)
+#define __NR_set_mempolicy_home_node (0x40000000 + 450)
+#define __NR_cachestat (0x40000000 + 451)
+#define __NR_fchmodat2 (0x40000000 + 452)
#define __NR_rt_sigaction (0x40000000 + 512)
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/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/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/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/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
diff --git a/arch/x86_64/bits/syscall.h.in b/arch/x86_64/bits/syscall.h.in
index c3882de7..6543bbba 100644
--- a/arch/x86_64/bits/syscall.h.in
+++ b/arch/x86_64/bits/syscall.h.in
@@ -355,4 +355,10 @@
#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
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/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"
diff --git a/configure b/configure
index 853bf05e..bc9fbe48 100755
--- a/configure
+++ b/configure
@@ -328,6 +328,7 @@ i?86*) ARCH=i386 ;;
x86_64-x32*|x32*|x86_64*x32) ARCH=x32 ;;
x86_64-nt64*) ARCH=nt64 ;;
x86_64*) ARCH=x86_64 ;;
+loongarch64*) ARCH=loongarch64 ;;
m68k*) ARCH=m68k ;;
mips64*|mipsisa64*) ARCH=mips64 ;;
mips*) ARCH=mips ;;
@@ -336,6 +337,7 @@ or1k*) ARCH=or1k ;;
powerpc64*|ppc64*) ARCH=powerpc64 ;;
powerpc*|ppc*) ARCH=powerpc ;;
riscv64*) ARCH=riscv64 ;;
+riscv32*) ARCH=riscv32 ;;
sh[1-9bel-]*|sh|superh*) ARCH=sh ;;
s390x*) ARCH=s390x ;;
unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
@@ -444,7 +446,20 @@ xno|x) printf "disabled\n" ; optimize=no ;;
*) printf "custom\n" ;;
esac
-test "$optimize" = no || tryflag CFLAGS_AUTO -Os || tryflag CFLAGS_AUTO -O2
+if test "$optimize" = no ; then :
+else
+tryflag CFLAGS_AUTO -O2
+tryflag CFLAGS_AUTO -fno-align-jumps
+tryflag CFLAGS_AUTO -fno-align-functions
+tryflag CFLAGS_AUTO -fno-align-loops
+tryflag CFLAGS_AUTO -fno-align-labels
+tryflag CFLAGS_AUTO -fira-region=one
+tryflag CFLAGS_AUTO -fira-hoist-pressure
+tryflag CFLAGS_AUTO -freorder-blocks-algorithm=simple \
+|| tryflag CFLAGS_AUTO -fno-reorder-blocks
+tryflag CFLAGS_AUTO -fno-prefetch-loop-arrays
+tryflag CFLAGS_AUTO -fno-tree-ch
+fi
test "$optimize" = yes && optimize="internal,malloc,string"
if fnmatch 'no|size' "$optimize" ; then :
@@ -658,6 +673,19 @@ if test "$ARCH" = "aarch64" ; then
trycppif __AARCH64EB__ "$t" && SUBARCH=${SUBARCH}_be
fi
+if test "$ARCH" = "loongarch64" ; then
+trycppif __loongarch_soft_float "$t" && SUBARCH=${SUBARCH}-sf
+trycppif __loongarch_single_float "$t" && SUBARCH=${SUBARCH}-sp
+printf "checking whether assembler support FCSRs... "
+echo "__asm__(\"movfcsr2gr \$t0,\$fcsr0\");" > "$tmpc"
+if $CC -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
+printf "yes\n"
+else
+printf "no\n"
+CFLAGS_AUTO="$CFLAGS_AUTO -DBROKEN_LOONGARCH_FCSR_ASM"
+fi
+fi
+
if test "$ARCH" = "m68k" ; then
if trycppif "__HAVE_68881__" ; then : ;
elif trycppif "__mcffpu__" ; then SUBARCH="-fp64"
@@ -700,7 +728,7 @@ trycppif __LITTLE_ENDIAN__ "$t" && SUBARCH=${SUBARCH}le
trycppif _SOFT_FLOAT "$t" && fail "$0: error: soft-float not supported on powerpc64"
fi
-if test "$ARCH" = "riscv64" ; then
+if test "$ARCH" = "riscv64" -o "$ARCH" = "riscv32" ; then
trycppif __riscv_float_abi_soft "$t" && SUBARCH=${SUBARCH}-sf
trycppif __riscv_float_abi_single "$t" && SUBARCH=${SUBARCH}-sp
fi
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
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}
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);
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
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 <bits/alltypes.h>
#include <bits/dirent.h>
+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/include/elf.h b/include/elf.h
index 23f2c4bc..8b622f63 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -315,7 +315,8 @@ typedef struct {
#define EM_RISCV 243
#define EM_BPF 247
#define EM_CSKY 252
-#define EM_NUM 253
+#define EM_LOONGARCH 258
+#define EM_NUM 259
#define EM_ALPHA 0x9026
@@ -558,6 +559,11 @@ typedef struct {
+typedef Elf32_Word Elf32_Relr;
+typedef Elf64_Xword Elf64_Relr;
+
+
+
#define ELF32_R_SYM(val) ((val) >> 8)
#define ELF32_R_TYPE(val) ((val) & 0xff)
#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
@@ -698,7 +704,14 @@ typedef struct {
#define NT_MIPS_DSP 0x800
#define NT_MIPS_FP_MODE 0x801
#define NT_MIPS_MSA 0x802
+#define NT_RISCV_CSR 0x900
+#define NT_RISCV_VECTOR 0x901
#define NT_VERSION 1
+#define NT_LOONGARCH_CPUCFG 0xa00
+#define NT_LOONGARCH_CSR 0xa01
+#define NT_LOONGARCH_LSX 0xa02
+#define NT_LOONGARCH_LASX 0xa03
+#define NT_LOONGARCH_LBT 0xa04
@@ -3249,6 +3262,7 @@ enum
#define R_RISCV_TLS_DTPREL64 9
#define R_RISCV_TLS_TPREL32 10
#define R_RISCV_TLS_TPREL64 11
+#define R_RISCV_TLSDESC 12
#define R_RISCV_BRANCH 16
#define R_RISCV_JAL 17
@@ -3275,16 +3289,11 @@ enum
#define R_RISCV_SUB16 38
#define R_RISCV_SUB32 39
#define R_RISCV_SUB64 40
-#define R_RISCV_GNU_VTINHERIT 41
-#define R_RISCV_GNU_VTENTRY 42
+#define R_RISCV_GOT32_PCREL 41
#define R_RISCV_ALIGN 43
#define R_RISCV_RVC_BRANCH 44
#define R_RISCV_RVC_JUMP 45
#define R_RISCV_RVC_LUI 46
-#define R_RISCV_GPREL_I 47
-#define R_RISCV_GPREL_S 48
-#define R_RISCV_TPREL_I 49
-#define R_RISCV_TPREL_S 50
#define R_RISCV_RELAX 51
#define R_RISCV_SUB6 52
#define R_RISCV_SET6 53
@@ -3292,6 +3301,111 @@ enum
#define R_RISCV_SET16 55
#define R_RISCV_SET32 56
#define R_RISCV_32_PCREL 57
+#define R_RISCV_IRELATIVE 58
+#define R_RISCV_PLT32 59
+#define R_RISCV_SET_ULEB128 60
+#define R_RISCV_SUB_ULEB128 61
+#define R_RISCV_TLSDESC_HI20 62
+#define R_RISCV_TLSDESC_LOAD_LO12 63
+#define R_RISCV_TLSDESC_ADD_LO12 64
+#define R_RISCV_TLSDESC_CALL 65
+
+#define EF_LARCH_ABI_MODIFIER_MASK 0x07
+#define EF_LARCH_ABI_SOFT_FLOAT 0x01
+#define EF_LARCH_ABI_SINGLE_FLOAT 0x02
+#define EF_LARCH_ABI_DOUBLE_FLOAT 0x03
+#define EF_LARCH_OBJABI_V1 0x40
+
+#define R_LARCH_NONE 0
+#define R_LARCH_32 1
+#define R_LARCH_64 2
+#define R_LARCH_RELATIVE 3
+#define R_LARCH_COPY 4
+#define R_LARCH_JUMP_SLOT 5
+#define R_LARCH_TLS_DTPMOD32 6
+#define R_LARCH_TLS_DTPMOD64 7
+#define R_LARCH_TLS_DTPREL32 8
+#define R_LARCH_TLS_DTPREL64 9
+#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
+#define R_LARCH_SOP_PUSH_ABSOLUTE 23
+#define R_LARCH_SOP_PUSH_DUP 24
+#define R_LARCH_SOP_PUSH_GPREL 25
+#define R_LARCH_SOP_PUSH_TLS_TPREL 26
+#define R_LARCH_SOP_PUSH_TLS_GOT 27
+#define R_LARCH_SOP_PUSH_TLS_GD 28
+#define R_LARCH_SOP_PUSH_PLT_PCREL 29
+#define R_LARCH_SOP_ASSERT 30
+#define R_LARCH_SOP_NOT 31
+#define R_LARCH_SOP_SUB 32
+#define R_LARCH_SOP_SL 33
+#define R_LARCH_SOP_SR 34
+#define R_LARCH_SOP_ADD 35
+#define R_LARCH_SOP_AND 36
+#define R_LARCH_SOP_IF_ELSE 37
+#define R_LARCH_SOP_POP_32_S_10_5 38
+#define R_LARCH_SOP_POP_32_U_10_12 39
+#define R_LARCH_SOP_POP_32_S_10_12 40
+#define R_LARCH_SOP_POP_32_S_10_16 41
+#define R_LARCH_SOP_POP_32_S_10_16_S2 42
+#define R_LARCH_SOP_POP_32_S_5_20 43
+#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44
+#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45
+#define R_LARCH_SOP_POP_32_U 46
+#define R_LARCH_ADD8 47
+#define R_LARCH_ADD16 48
+#define R_LARCH_ADD24 49
+#define R_LARCH_ADD32 50
+#define R_LARCH_ADD64 51
+#define R_LARCH_SUB8 52
+#define R_LARCH_SUB16 53
+#define R_LARCH_SUB24 54
+#define R_LARCH_SUB32 55
+#define R_LARCH_SUB64 56
+#define R_LARCH_GNU_VTINHERIT 57
+#define R_LARCH_GNU_VTENTRY 58
+#define R_LARCH_B16 64
+#define R_LARCH_B21 65
+#define R_LARCH_B26 66
+#define R_LARCH_ABS_HI20 67
+#define R_LARCH_ABS_LO12 68
+#define R_LARCH_ABS64_LO20 69
+#define R_LARCH_ABS64_HI12 70
+#define R_LARCH_PCALA_HI20 71
+#define R_LARCH_PCALA_LO12 72
+#define R_LARCH_PCALA64_LO20 73
+#define R_LARCH_PCALA64_HI12 74
+#define R_LARCH_GOT_PC_HI20 75
+#define R_LARCH_GOT_PC_LO12 76
+#define R_LARCH_GOT64_PC_LO20 77
+#define R_LARCH_GOT64_PC_HI12 78
+#define R_LARCH_GOT_HI20 79
+#define R_LARCH_GOT_LO12 80
+#define R_LARCH_GOT64_LO20 81
+#define R_LARCH_GOT64_HI12 82
+#define R_LARCH_TLS_LE_HI20 83
+#define R_LARCH_TLS_LE_LO12 84
+#define R_LARCH_TLS_LE64_LO20 85
+#define R_LARCH_TLS_LE64_HI12 86
+#define R_LARCH_TLS_IE_PC_HI20 87
+#define R_LARCH_TLS_IE_PC_LO12 88
+#define R_LARCH_TLS_IE64_PC_LO20 89
+#define R_LARCH_TLS_IE64_PC_HI12 90
+#define R_LARCH_TLS_IE_HI20 91
+#define R_LARCH_TLS_IE_LO12 92
+#define R_LARCH_TLS_IE64_LO20 93
+#define R_LARCH_TLS_IE64_HI12 94
+#define R_LARCH_TLS_LD_PC_HI20 95
+#define R_LARCH_TLS_LD_HI20 96
+#define R_LARCH_TLS_GD_PC_HI20 97
+#define R_LARCH_TLS_GD_HI20 98
+#define R_LARCH_32_PCREL 99
+#define R_LARCH_RELAX 100
#ifdef __cplusplus
}
diff --git a/include/fcntl.h b/include/fcntl.h
index 515f255d..53f98a8b 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -184,7 +184,6 @@ struct f_owner_ex {
#define SPLICE_F_MORE 4
#define SPLICE_F_GIFT 8
int fallocate(int, int, off_t, off_t);
-#define fallocate64 fallocate
int name_to_handle_at(int, const char *, struct file_handle *, int *, int);
int open_by_handle_at(int, struct file_handle *, int);
ssize_t readahead(int, off_t, size_t);
@@ -207,6 +206,9 @@ ssize_t tee(int, int, size_t, unsigned);
#define posix_fadvise64 posix_fadvise
#define posix_fallocate64 posix_fallocate
#define off64_t off_t
+#if defined(_GNU_SOURCE)
+#define fallocate64 fallocate
+#endif
#endif
#ifdef __cplusplus
diff --git a/include/poll.h b/include/poll.h
index 472e4b84..272dc34a 100644
--- a/include/poll.h
+++ b/include/poll.h
@@ -36,7 +36,7 @@ struct pollfd {
int poll (struct pollfd *, nfds_t, int);
-#ifdef _GNU_SOURCE
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#define __NEED_time_t
#define __NEED_struct_timespec
#define __NEED_sigset_t
@@ -45,7 +45,7 @@ int ppoll(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);
#endif
#if _REDIR_TIME64
-#ifdef _GNU_SOURCE
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
__REDIR(ppoll, __ppoll_time64);
#endif
#endif
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
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 *);
diff --git a/include/stdc-predef.h b/include/stdc-predef.h
index af1a2799..642bad2d 100644
--- a/include/stdc-predef.h
+++ b/include/stdc-predef.h
@@ -7,7 +7,12 @@
#define __STDC_IEC_559__ 1
#endif
+#if !defined(__STDC_UTF_16__)
#define __STDC_UTF_16__ 1
+#endif
+
+#if !defined(__STDC_UTF_32__)
#define __STDC_UTF_32__ 1
+#endif
#endif
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/include/string.h b/include/string.h
index db73d2a9..83e2b946 100644
--- a/include/string.h
+++ b/include/string.h
@@ -95,9 +95,6 @@ char *strchrnul(const char *, int);
char *strcasestr(const char *, const char *);
void *memrchr(const void *, int, size_t);
void *mempcpy(void *, const void *, size_t);
-#ifndef __cplusplus
-char *basename();
-#endif
#endif
#ifdef __cplusplus
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 <stdint.h>
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <fcntl.h>
#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);
diff --git a/include/sys/reg.h b/include/sys/reg.h
index b47452d0..0272e137 100644
--- a/include/sys/reg.h
+++ b/include/sys/reg.h
@@ -4,6 +4,15 @@
#include <limits.h>
#include <unistd.h>
+#include <bits/alltypes.h>
+
+#undef __WORDSIZE
+#if __LONG_MAX == 0x7fffffffL
+#define __WORDSIZE 32
+#else
+#define __WORDSIZE 64
+#endif
+
#include <bits/reg.h>
#endif
diff --git a/include/sys/stat.h b/include/sys/stat.h
index e6d0049c..c924ce2f 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -18,6 +18,13 @@ extern "C" {
#define __NEED_blkcnt_t
#define __NEED_struct_timespec
+#ifdef _GNU_SOURCE
+#define __NEED_int64_t
+#define __NEED_uint64_t
+#define __NEED_uint32_t
+#define __NEED_uint16_t
+#endif
+
#include <bits/alltypes.h>
#include <bits/stat.h>
@@ -98,6 +105,71 @@ int lchmod(const char *, mode_t);
#define S_IEXEC S_IXUSR
#endif
+#if defined(_GNU_SOURCE)
+#define STATX_TYPE 1U
+#define STATX_MODE 2U
+#define STATX_NLINK 4U
+#define STATX_UID 8U
+#define STATX_GID 0x10U
+#define STATX_ATIME 0x20U
+#define STATX_MTIME 0x40U
+#define STATX_CTIME 0x80U
+#define STATX_INO 0x100U
+#define STATX_SIZE 0x200U
+#define STATX_BLOCKS 0x400U
+#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
+#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;
+};
+
+struct statx {
+ uint32_t stx_mask;
+ uint32_t stx_blksize;
+ uint64_t stx_attributes;
+ uint32_t stx_nlink;
+ uint32_t stx_uid;
+ uint32_t stx_gid;
+ uint16_t stx_mode;
+ uint16_t __pad0[1];
+ uint64_t stx_ino;
+ uint64_t stx_size;
+ uint64_t stx_blocks;
+ uint64_t stx_attributes_mask;
+ struct statx_timestamp stx_atime;
+ struct statx_timestamp stx_btime;
+ struct statx_timestamp stx_ctime;
+ struct statx_timestamp stx_mtime;
+ uint32_t stx_rdev_major;
+ uint32_t stx_rdev_minor;
+ uint32_t stx_dev_major;
+ uint32_t stx_dev_minor;
+ uint64_t stx_mnt_id;
+ uint32_t stx_dio_mem_align;
+ uint32_t stx_dio_offset_align;
+ uint64_t stx_subvol;
+ uint64_t __pad1[11];
+};
+
+int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
+#endif
+
#if defined(_LARGEFILE64_SOURCE)
#define stat64 stat
#define fstat64 fstat
diff --git a/include/sys/statvfs.h b/include/sys/statvfs.h
index 57a6b806..71d9d1f9 100644
--- a/include/sys/statvfs.h
+++ b/include/sys/statvfs.h
@@ -23,7 +23,8 @@ struct statvfs {
unsigned long f_fsid;
#endif
unsigned long f_flag, f_namemax;
- int __reserved[6];
+ unsigned int f_type;
+ int __reserved[5];
};
int statvfs (const char *__restrict, struct statvfs *__restrict);
diff --git a/include/sys/uio.h b/include/sys/uio.h
index 90e5939e..5e99c7fa 100644
--- a/include/sys/uio.h
+++ b/include/sys/uio.h
@@ -39,6 +39,14 @@ ssize_t pwritev (int, const struct iovec *, int, off_t);
#ifdef _GNU_SOURCE
ssize_t process_vm_writev(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
ssize_t process_vm_readv(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
+ssize_t preadv2 (int, const struct iovec *, int, off_t, int);
+ssize_t pwritev2 (int, const struct iovec *, int, off_t, int);
+#define RWF_HIPRI 0x00000001
+#define RWF_DSYNC 0x00000002
+#define RWF_SYNC 0x00000004
+#define RWF_NOWAIT 0x00000008
+#define RWF_APPEND 0x00000010
+#define RWF_NOAPPEND 0x00000020
#endif
#ifdef __cplusplus
diff --git a/include/sys/user.h b/include/sys/user.h
index 96a03400..511caba3 100644
--- a/include/sys/user.h
+++ b/include/sys/user.h
@@ -8,6 +8,15 @@ extern "C" {
#include <stdint.h>
#include <unistd.h>
+#include <bits/alltypes.h>
+
+#undef __WORDSIZE
+#if __LONG_MAX == 0x7fffffffL
+#define __WORDSIZE 32
+#else
+#define __WORDSIZE 64
+#endif
+
#include <bits/user.h>
#ifdef __cplusplus
diff --git a/include/syslog.h b/include/syslog.h
index 5b4d2964..57599e07 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)
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 <bits/posix.h>
+#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
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index ceca3c98..715948f4 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -21,15 +21,17 @@
#include <sys/membarrier.h>
#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
@@ -157,6 +159,8 @@ static struct fdpic_dummy_loadmap app_dummy_loadmap;
struct debug *_dl_debug_addr = &debug;
+extern weak hidden char __ehdr_start[];
+
extern hidden int __malloc_replaced;
hidden void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;
@@ -358,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[16];
- 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:
@@ -515,7 +514,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
break;
#endif
case REL_TLSDESC:
- if (stride<3) addend = reloc_addr[1];
+ if (stride<3) addend = reloc_addr[!TLSDESC_BACKWARDS];
if (def.dso->tls_id > static_tls_cnt) {
struct td_index *new = malloc(sizeof *new);
if (!new) {
@@ -540,13 +539,13 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
+ addend;
#endif
}
-#ifdef TLSDESC_BACKWARDS
/* Some archs (32-bit ARM at least) invert the order of
* the descriptor members. Fix them up here. */
- size_t tmp = reloc_addr[0];
- reloc_addr[0] = reloc_addr[1];
- reloc_addr[1] = tmp;
-#endif
+ if (TLSDESC_BACKWARDS) {
+ size_t tmp = reloc_addr[0];
+ reloc_addr[0] = reloc_addr[1];
+ reloc_addr[1] = tmp;
+ }
break;
default:
error("Error relocating %s: unsupported relocation type %d",
@@ -617,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);
@@ -1725,7 +1725,7 @@ hidden void __dls2(unsigned char *base, size_t *sp)
} else {
ldso.base = base;
}
- Ehdr *ehdr = (void *)ldso.base;
+ Ehdr *ehdr = __ehdr_start ? (void *)__ehdr_start : (void *)ldso.base;
ldso.name = ldso.shortname = "libc.so";
ldso.phnum = ehdr->e_phnum;
ldso.phdr = laddr(&ldso, ehdr->e_phoff);
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)
{
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);
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;
diff --git a/src/dirent/posix_getdents.c b/src/dirent/posix_getdents.c
new file mode 100644
index 00000000..26c16ac6
--- /dev/null
+++ b/src/dirent/posix_getdents.c
@@ -0,0 +1,11 @@
+#include <dirent.h>
+#include <limits.h>
+#include <errno.h>
+#include "syscall.h"
+
+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;
+ return syscall(SYS_getdents, fd, buf, len);
+}
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")
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;
diff --git a/src/exit/exit.c b/src/exit/exit.c
index a6869b37..17b33cc6 100644
--- a/src/exit/exit.c
+++ b/src/exit/exit.c
@@ -1,6 +1,9 @@
#include <stdlib.h>
#include <stdint.h>
#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 (;;) __sys_pause();
+
__funcs_on_exit();
__libc_exit_fini();
__stdio_exit();
diff --git a/src/fenv/loongarch64/fenv.S b/src/fenv/loongarch64/fenv.S
new file mode 100644
index 00000000..9c38599e
--- /dev/null
+++ b/src/fenv/loongarch64/fenv.S
@@ -0,0 +1,78 @@
+#ifndef __loongarch_soft_float
+
+#ifdef BROKEN_LOONGARCH_FCSR_ASM
+#define FCSR $r0
+#else
+#define FCSR $fcsr0
+#endif
+
+.global feclearexcept
+.type feclearexcept,@function
+feclearexcept:
+ li.w $t0, 0x1f0000
+ and $a0, $a0, $t0
+ movfcsr2gr $t1, FCSR
+ andn $t1, $t1, $a0
+ movgr2fcsr FCSR, $t1
+ li.w $a0, 0
+ jr $ra
+
+.global feraiseexcept
+.type feraiseexcept,@function
+feraiseexcept:
+ li.w $t0, 0x1f0000
+ and $a0, $a0, $t0
+ movfcsr2gr $t1, FCSR
+ or $t1, $t1, $a0
+ movgr2fcsr FCSR, $t1
+ li.w $a0, 0
+ jr $ra
+
+.global fetestexcept
+.type fetestexcept,@function
+fetestexcept:
+ li.w $t0, 0x1f0000
+ and $a0, $a0, $t0
+ movfcsr2gr $t1, FCSR
+ and $a0, $t1, $a0
+ jr $ra
+
+.global fegetround
+.type fegetround,@function
+fegetround:
+ movfcsr2gr $t0, FCSR
+ andi $a0, $t0, 0x300
+ jr $ra
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,@function
+__fesetround:
+ li.w $t0, 0x300
+ and $a0, $a0, $t0
+ movfcsr2gr $t1, FCSR
+ andn $t1, $t1, $t0
+ or $t1, $t1, $a0
+ movgr2fcsr FCSR, $t1
+ li.w $a0, 0
+ jr $ra
+
+.global fegetenv
+.type fegetenv,@function
+fegetenv:
+ movfcsr2gr $t0, FCSR
+ st.w $t0, $a0, 0
+ li.w $a0, 0
+ jr $ra
+
+.global fesetenv
+.type fesetenv,@function
+fesetenv:
+ addi.d $t0, $a0, 1
+ beq $t0, $r0, 1f
+ ld.w $t0, $a0, 0
+1: movgr2fcsr FCSR, $t0
+ li.w $a0, 0
+ jr $ra
+
+#endif
diff --git a/src/fenv/riscv32/fenv-sf.c b/src/fenv/riscv32/fenv-sf.c
new file mode 100644
index 00000000..ecd3cb5c
--- /dev/null
+++ b/src/fenv/riscv32/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifndef __riscv_flen
+#include "../fenv.c"
+#endif
diff --git a/src/fenv/riscv32/fenv.S b/src/fenv/riscv32/fenv.S
new file mode 100644
index 00000000..0ea78bf9
--- /dev/null
+++ b/src/fenv/riscv32/fenv.S
@@ -0,0 +1,56 @@
+#ifdef __riscv_flen
+
+.global feclearexcept
+.type feclearexcept, %function
+feclearexcept:
+ csrc fflags, a0
+ li a0, 0
+ ret
+
+.global feraiseexcept
+.type feraiseexcept, %function
+feraiseexcept:
+ csrs fflags, a0
+ li a0, 0
+ ret
+
+.global fetestexcept
+.type fetestexcept, %function
+fetestexcept:
+ frflags t0
+ and a0, t0, a0
+ ret
+
+.global fegetround
+.type fegetround, %function
+fegetround:
+ frrm a0
+ ret
+
+.global __fesetround
+.type __fesetround, %function
+__fesetround:
+ fsrm t0, a0
+ li a0, 0
+ ret
+
+.global fegetenv
+.type fegetenv, %function
+fegetenv:
+ frcsr t0
+ sw t0, 0(a0)
+ li a0, 0
+ ret
+
+.global fesetenv
+.type fesetenv, %function
+fesetenv:
+ li t2, -1
+ li t1, 0
+ beq a0, t2, 1f
+ lw t1, 0(a0)
+1: fscsr t1
+ li a0, 0
+ ret
+
+#endif
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);
diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h
index 06f41d09..40c743e2 100644
--- a/src/internal/dynlink.h
+++ b/src/internal/dynlink.h
@@ -73,6 +73,10 @@ struct fdpic_dummy_loadmap {
#define DL_NOMMU_SUPPORT 0
#endif
+#ifndef TLSDESC_BACKWARDS
+#define TLSDESC_BACKWARDS 0
+#endif
+
#if !DL_FDPIC
#define IS_RELATIVE(x,s) ( \
(R_TYPE(x) == REL_RELATIVE) || \
diff --git a/src/internal/emulate_wait4.c b/src/internal/emulate_wait4.c
new file mode 100644
index 00000000..f6303412
--- /dev/null
+++ b/src/internal/emulate_wait4.c
@@ -0,0 +1,55 @@
+#include <sys/wait.h>
+#include "syscall.h"
+
+#ifndef SYS_wait4
+hidden long __emulate_wait4(int pid, int *status, int options, void *kru, int cp)
+{
+ idtype_t t;
+ int r;
+ siginfo_t info;
+
+ info.si_pid = 0;
+ if (pid < -1) {
+ t = P_PGID;
+ pid = -pid;
+ } else if (pid == -1) {
+ t = P_ALL;
+ } else if (pid == 0) {
+ t = P_PGID;
+ } else {
+ t = P_PID;
+ }
+
+ if (cp) r = __syscall_cp(SYS_waitid, t, pid, &info, options|WEXITED, kru);
+ else r = __syscall(SYS_waitid, t, pid, &info, options|WEXITED, kru);
+
+ if (r<0) return r;
+
+ if (info.si_pid && status) {
+ int sw=0;
+ switch (info.si_code) {
+ case CLD_CONTINUED:
+ sw = 0xffff;
+ break;
+ case CLD_DUMPED:
+ sw = info.si_status&0x7f | 0x80;
+ break;
+ case CLD_EXITED:
+ sw = (info.si_status&0xff) << 8;
+ break;
+ case CLD_KILLED:
+ sw = info.si_status&0x7f;
+ break;
+ case CLD_STOPPED:
+ case CLD_TRAPPED:
+ /* see ptrace(2); the high bits of si_status can contain */
+ /* PTRACE_EVENT_ values which must be preserved */
+ sw = (info.si_status << 8) + 0x7f;
+ break;
+ }
+ *status = sw;
+ }
+
+ return info.si_pid;
+}
+#endif
diff --git a/src/internal/fork_impl.h b/src/internal/fork_impl.h
index 354e733b..f995fce2 100644
--- a/src/internal/fork_impl.h
+++ b/src/internal/fork_impl.h
@@ -17,3 +17,5 @@ extern hidden volatile int *const __vmlock_lockptr;
hidden void __malloc_atfork(int);
hidden void __ldso_atfork(int);
hidden void __pthread_key_atfork(int);
+
+hidden void __post_Fork(int);
diff --git a/src/internal/syscall.h b/src/internal/syscall.h
index 4a446157..2d8a5c13 100644
--- a/src/internal/syscall.h
+++ b/src/internal/syscall.h
@@ -391,6 +391,29 @@ 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)
+#else
+hidden long __emulate_wait4(int, int *, int, void *, int);
+#define __sys_wait4(a,b,c,d) __emulate_wait4(a,b,c,d,0)
+#define __sys_wait4_cp(a,b,c,d) __emulate_wait4(a,b,c,d,1)
+#endif
+
+#define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d))
+#define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d))
+
hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned);
hidden void *__vdsosym(const char *, const char *);
diff --git a/src/ldso/loongarch64/dlsym.s b/src/ldso/loongarch64/dlsym.s
new file mode 100644
index 00000000..26fabcdb
--- /dev/null
+++ b/src/ldso/loongarch64/dlsym.s
@@ -0,0 +1,7 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ move $a2, $ra
+ la.global $t0, __dlsym
+ jr $t0
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
diff --git a/src/ldso/riscv32/dlsym.s b/src/ldso/riscv32/dlsym.s
new file mode 100644
index 00000000..2bafd72d
--- /dev/null
+++ b/src/ldso/riscv32/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym, %function
+dlsym:
+ mv a2, ra
+ tail __dlsym
diff --git a/src/ldso/riscv64/tlsdesc.s b/src/ldso/riscv64/tlsdesc.s
new file mode 100644
index 00000000..bef8b322
--- /dev/null
+++ b/src/ldso/riscv64/tlsdesc.s
@@ -0,0 +1,32 @@
+.text
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,%function
+__tlsdesc_static:
+ ld a0,8(a0)
+ jr t0
+
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,%function
+__tlsdesc_dynamic:
+ add sp,sp,-16
+ sd t1,(sp)
+ sd t2,8(sp)
+
+ ld t2,-8(tp) # t2=dtv
+
+ ld a0,8(a0) # a0=&{modidx,off}
+ ld t1,8(a0) # t1=off
+ ld a0,(a0) # a0=modidx
+ sll a0,a0,3 # a0=8*modidx
+
+ add a0,a0,t2 # a0=dtv+8*modidx
+ ld a0,(a0) # a0=dtv[modidx]
+ add a0,a0,t1 # a0=dtv[modidx]+off
+ sub a0,a0,tp # a0=dtv[modidx]+off-tp
+
+ ld t1,(sp)
+ ld t2,8(sp)
+ add sp,sp,16
+ jr t0
diff --git a/src/ldso/sh/dlsym.s b/src/ldso/sh/dlsym.s
index 11a6fff5..34f3c35c 100644
--- a/src/ldso/sh/dlsym.s
+++ b/src/ldso/sh/dlsym.s
@@ -5,7 +5,7 @@
dlsym:
mov.l L1, r0
1: braf r0
- mov.l @r15, r6
+ sts pr, r6
.align 2
L1: .long __dlsym@PLT-(1b+4-.)
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;
}
diff --git a/src/linux/cache.c b/src/linux/cache.c
index 0eb051c2..e76f7812 100644
--- a/src/linux/cache.c
+++ b/src/linux/cache.c
@@ -21,7 +21,7 @@ weak_alias(__cachectl, cachectl);
#ifdef SYS_riscv_flush_icache
#define VDSO_FLUSH_ICACHE_SYM "__vdso_flush_icache"
-#define VDSO_FLUSH_ICACHE_VER "LINUX_4.5"
+#define VDSO_FLUSH_ICACHE_VER "LINUX_4.15"
static void *volatile vdso_func;
@@ -45,6 +45,7 @@ int __riscv_flush_icache(void *start, void *end, unsigned long int flags)
if (!r) return r;
if (r != -ENOSYS) return __syscall_ret(r);
}
+ return syscall(SYS_riscv_flush_icache, start, end, flags);
}
weak_alias(__riscv_flush_icache, riscv_flush_icache);
#endif
diff --git a/src/linux/clone.c b/src/linux/clone.c
index 8c1af7d3..257c1cec 100644
--- a/src/linux/clone.c
+++ b/src/linux/clone.c
@@ -4,18 +4,62 @@
#include <sched.h>
#include "pthread_impl.h"
#include "syscall.h"
+#include "lock.h"
+#include "fork_impl.h"
+
+struct clone_start_args {
+ int (*func)(void *);
+ void *arg;
+ sigset_t sigmask;
+};
+
+static int clone_start(void *arg)
+{
+ struct clone_start_args *csa = arg;
+ __post_Fork(0);
+ __restore_sigs(&csa->sigmask);
+ return csa->func(csa->arg);
+}
int clone(int (*func)(void *), void *stack, int flags, void *arg, ...)
{
+ struct clone_start_args csa;
va_list ap;
- pid_t *ptid, *ctid;
- void *tls;
+ pid_t *ptid = 0, *ctid = 0;
+ void *tls = 0;
+
+ /* Flags that produce an invalid thread/TLS state are disallowed. */
+ int badflags = CLONE_THREAD | CLONE_SETTLS | CLONE_CHILD_CLEARTID;
+
+ if ((flags & badflags) || !stack)
+ return __syscall_ret(-EINVAL);
va_start(ap, arg);
- ptid = va_arg(ap, pid_t *);
- tls = va_arg(ap, void *);
- ctid = va_arg(ap, pid_t *);
+ if (flags & (CLONE_PIDFD | CLONE_PARENT_SETTID | CLONE_CHILD_SETTID))
+ ptid = va_arg(ap, pid_t *);
+ if (flags & CLONE_CHILD_SETTID) {
+ tls = va_arg(ap, void *);
+ ctid = va_arg(ap, pid_t *);
+ }
va_end(ap);
- return __syscall_ret(__clone(func, stack, flags, arg, ptid, tls, ctid));
+ /* If CLONE_VM is used, it's impossible to give the child a consistent
+ * thread structure. In this case, the best we can do is assume the
+ * caller is content with an extremely restrictive execution context
+ * like the one vfork() would provide. */
+ if (flags & CLONE_VM) return __syscall_ret(
+ __clone(func, stack, flags, arg, ptid, tls, ctid));
+
+ __block_all_sigs(&csa.sigmask);
+ LOCK(__abort_lock);
+
+ /* Setup the a wrapper start function for the child process to do
+ * mimic _Fork in producing a consistent execution state. */
+ csa.func = func;
+ csa.arg = arg;
+ int ret = __clone(clone_start, stack, flags, &csa, ptid, tls, ctid);
+
+ __post_Fork(ret);
+ __restore_sigs(&csa.sigmask);
+ return __syscall_ret(ret);
}
diff --git a/src/linux/preadv2.c b/src/linux/preadv2.c
new file mode 100644
index 00000000..5e7ab70f
--- /dev/null
+++ b/src/linux/preadv2.c
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <sys/uio.h>
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t preadv2(int fd, const struct iovec *iov, int count, off_t ofs, int flags)
+{
+#ifdef SYS_preadv
+ if (!flags) {
+ if (ofs==-1) return readv(fd, iov, count);
+ return syscall_cp(SYS_preadv, fd, iov, count,
+ (long)(ofs), (long)(ofs>>32));
+ }
+#endif
+ return syscall_cp(SYS_preadv2, fd, iov, count,
+ (long)(ofs), (long)(ofs>>32), flags);
+}
diff --git a/src/linux/pwritev2.c b/src/linux/pwritev2.c
new file mode 100644
index 00000000..ece90d7c
--- /dev/null
+++ b/src/linux/pwritev2.c
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <sys/uio.h>
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t pwritev2(int fd, const struct iovec *iov, int count, off_t ofs, int flags)
+{
+#ifdef SYS_pwritev
+ if (!flags) {
+ if (ofs==-1) return writev(fd, iov, count);
+ return syscall_cp(SYS_pwritev, fd, iov, count,
+ (long)(ofs), (long)(ofs>>32));
+ }
+#endif
+ return syscall_cp(SYS_pwritev2, fd, iov, count,
+ (long)(ofs), (long)(ofs>>32), flags);
+}
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 <stdio.h>
+#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);
+}
diff --git a/src/linux/statx.c b/src/linux/statx.c
new file mode 100644
index 00000000..4fb96e4b
--- /dev/null
+++ b/src/linux/statx.c
@@ -0,0 +1,44 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <string.h>
+#include <syscall.h>
+#include <sys/sysmacros.h>
+#include <errno.h>
+
+int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
+{
+ int ret = __syscall(SYS_statx, dirfd, path, flags, mask, stx);
+
+#ifndef SYS_fstatat
+ return __syscall_ret(ret);
+#endif
+
+ if (ret != -ENOSYS) return __syscall_ret(ret);
+
+ struct stat st;
+ 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);
+ 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;
+ stx->stx_uid = st.st_uid;
+ stx->stx_gid = st.st_gid;
+ stx->stx_size = st.st_size;
+ stx->stx_blksize = st.st_blksize;
+ stx->stx_blocks = st.st_blocks;
+ stx->stx_atime.tv_sec = st.st_atim.tv_sec;
+ stx->stx_atime.tv_nsec = st.st_atim.tv_nsec;
+ stx->stx_mtime.tv_sec = st.st_mtim.tv_sec;
+ 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_mask = STATX_BASIC_STATS;
+
+ return 0;
+}
diff --git a/src/linux/wait4.c b/src/linux/wait4.c
index ff2e3e66..fb08c0d0 100644
--- a/src/linux/wait4.c
+++ b/src/linux/wait4.c
@@ -26,7 +26,7 @@ pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru)
}
#endif
char *dest = ru ? (char *)&ru->ru_maxrss - 4*sizeof(long) : 0;
- r = __syscall(SYS_wait4, pid, status, options, dest);
+ r = __sys_wait4(pid, status, options, dest);
if (r>0 && ru && sizeof(time_t) > sizeof(long)) {
long kru[4];
memcpy(kru, dest, 4*sizeof(long));
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";
}
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"
diff --git a/src/locale/iconv.c b/src/locale/iconv.c
index 3047c27b..52178950 100644
--- a/src/locale/iconv.c
+++ b/src/locale/iconv.c
@@ -49,10 +49,10 @@ static const unsigned char charmaps[] =
"ucs4\0utf32\0\0\313"
"ucs2\0\0\314"
"eucjp\0\0\320"
-"shiftjis\0sjis\0\0\321"
+"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"
@@ -339,7 +339,10 @@ 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];
if (!c) goto ilseq;
break;
@@ -403,6 +406,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;
@@ -495,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;
@@ -538,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;
diff --git a/src/math/acoshl.c b/src/math/acoshl.c
index 8d4b43f6..943cec17 100644
--- a/src/math/acoshl.c
+++ b/src/math/acoshl.c
@@ -10,14 +10,18 @@ long double acoshl(long double x)
long double acoshl(long double x)
{
union ldshape u = {x};
- int e = u.i.se & 0x7fff;
+ int e = u.i.se;
if (e < 0x3fff + 1)
- /* |x| < 2, invalid if x < 1 or nan */
+ /* 0 <= x < 2, invalid if x < 1 */
return log1pl(x-1 + sqrtl((x-1)*(x-1)+2*(x-1)));
if (e < 0x3fff + 32)
- /* |x| < 0x1p32 */
+ /* 2 <= x < 0x1p32 */
return logl(2*x - 1/(x+sqrtl(x*x-1)));
+ if (e & 0x8000)
+ /* x < 0 or x = -0, invalid */
+ return (x - x) / (x - x);
+ /* 0x1p32 <= x or nan */
return logl(x) + 0.693147180559945309417232121458176568L;
}
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
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;
}
diff --git a/src/math/powl.c b/src/math/powl.c
index 5b6da07b..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"
@@ -212,25 +204,33 @@ long double powl(long double x, long double y)
}
if (x == 1.0)
return 1.0; /* 1**y = 1, even if y is nan */
- if (x == -1.0 && !isfinite(y))
- return 1.0; /* -1**inf = 1 */
if (y == 0.0)
return 1.0; /* x**0 = 1, even if x is nan */
if (y == 1.0)
return x;
- if (y >= LDBL_MAX) {
- if (x > 1.0 || x < -1.0)
- return INFINITY;
- if (x != 0.0)
- return 0.0;
- }
- if (y <= -LDBL_MAX) {
- if (x > 1.0 || x < -1.0)
+ /* if y*log2(x) < log2(LDBL_TRUE_MIN)-1 then x^y uflows to 0
+ if y*log2(x) > -log2(LDBL_TRUE_MIN)+1 > LDBL_MAX_EXP then x^y oflows
+ if |x|!=1 then |log2(x)| > |log(x)| > LDBL_EPSILON/2 so
+ x^y oflows/uflows if |y|*LDBL_EPSILON/2 > -log2(LDBL_TRUE_MIN)+1 */
+ if (fabsl(y) > 2*(-LDBL_MIN_EXP+LDBL_MANT_DIG+1)/LDBL_EPSILON) {
+ /* y is not an odd int */
+ if (x == -1.0)
+ return 1.0;
+ if (y == INFINITY) {
+ if (x > 1.0 || x < -1.0)
+ return INFINITY;
return 0.0;
- if (x != 0.0 || y == -INFINITY)
+ }
+ if (y == -INFINITY) {
+ if (x > 1.0 || x < -1.0)
+ return 0.0;
return INFINITY;
+ }
+ if ((x > 1.0 || x < -1.0) == (y > 0))
+ return huge * huge;
+ return twom10000 * twom10000;
}
- if (x >= LDBL_MAX) {
+ if (x == INFINITY) {
if (y > 0.0)
return INFINITY;
return 0.0;
@@ -253,7 +253,7 @@ long double powl(long double x, long double y)
yoddint = 1;
}
- if (x <= -LDBL_MAX) {
+ if (x == -INFINITY) {
if (y > 0.0) {
if (yoddint)
return -INFINITY;
diff --git a/src/math/riscv32/copysign.c b/src/math/riscv32/copysign.c
new file mode 100644
index 00000000..c7854178
--- /dev/null
+++ b/src/math/riscv32/copysign.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double copysign(double x, double y)
+{
+ __asm__ ("fsgnj.d %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+ return x;
+}
+
+#else
+
+#include "../copysign.c"
+
+#endif
diff --git a/src/math/riscv32/copysignf.c b/src/math/riscv32/copysignf.c
new file mode 100644
index 00000000..a125611a
--- /dev/null
+++ b/src/math/riscv32/copysignf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float copysignf(float x, float y)
+{
+ __asm__ ("fsgnj.s %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+ return x;
+}
+
+#else
+
+#include "../copysignf.c"
+
+#endif
diff --git a/src/math/riscv32/fabs.c b/src/math/riscv32/fabs.c
new file mode 100644
index 00000000..5290b6f0
--- /dev/null
+++ b/src/math/riscv32/fabs.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double fabs(double x)
+{
+ __asm__ ("fabs.d %0, %1" : "=f"(x) : "f"(x));
+ return x;
+}
+
+#else
+
+#include "../fabs.c"
+
+#endif
diff --git a/src/math/riscv32/fabsf.c b/src/math/riscv32/fabsf.c
new file mode 100644
index 00000000..f5032e35
--- /dev/null
+++ b/src/math/riscv32/fabsf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float fabsf(float x)
+{
+ __asm__ ("fabs.s %0, %1" : "=f"(x) : "f"(x));
+ return x;
+}
+
+#else
+
+#include "../fabsf.c"
+
+#endif
diff --git a/src/math/riscv32/fma.c b/src/math/riscv32/fma.c
new file mode 100644
index 00000000..99b05713
--- /dev/null
+++ b/src/math/riscv32/fma.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double fma(double x, double y, double z)
+{
+ __asm__ ("fmadd.d %0, %1, %2, %3" : "=f"(x) : "f"(x), "f"(y), "f"(z));
+ return x;
+}
+
+#else
+
+#include "../fma.c"
+
+#endif
diff --git a/src/math/riscv32/fmaf.c b/src/math/riscv32/fmaf.c
new file mode 100644
index 00000000..f9dc47ed
--- /dev/null
+++ b/src/math/riscv32/fmaf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float fmaf(float x, float y, float z)
+{
+ __asm__ ("fmadd.s %0, %1, %2, %3" : "=f"(x) : "f"(x), "f"(y), "f"(z));
+ return x;
+}
+
+#else
+
+#include "../fmaf.c"
+
+#endif
diff --git a/src/math/riscv32/fmax.c b/src/math/riscv32/fmax.c
new file mode 100644
index 00000000..023709cd
--- /dev/null
+++ b/src/math/riscv32/fmax.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double fmax(double x, double y)
+{
+ __asm__ ("fmax.d %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+ return x;
+}
+
+#else
+
+#include "../fmax.c"
+
+#endif
diff --git a/src/math/riscv32/fmaxf.c b/src/math/riscv32/fmaxf.c
new file mode 100644
index 00000000..863d2bd1
--- /dev/null
+++ b/src/math/riscv32/fmaxf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float fmaxf(float x, float y)
+{
+ __asm__ ("fmax.s %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+ return x;
+}
+
+#else
+
+#include "../fmaxf.c"
+
+#endif
diff --git a/src/math/riscv32/fmin.c b/src/math/riscv32/fmin.c
new file mode 100644
index 00000000..a4e3b067
--- /dev/null
+++ b/src/math/riscv32/fmin.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double fmin(double x, double y)
+{
+ __asm__ ("fmin.d %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+ return x;
+}
+
+#else
+
+#include "../fmin.c"
+
+#endif
diff --git a/src/math/riscv32/fminf.c b/src/math/riscv32/fminf.c
new file mode 100644
index 00000000..32156e80
--- /dev/null
+++ b/src/math/riscv32/fminf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float fminf(float x, float y)
+{
+ __asm__ ("fmin.s %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+ return x;
+}
+
+#else
+
+#include "../fminf.c"
+
+#endif
diff --git a/src/math/riscv32/sqrt.c b/src/math/riscv32/sqrt.c
new file mode 100644
index 00000000..867a504c
--- /dev/null
+++ b/src/math/riscv32/sqrt.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double sqrt(double x)
+{
+ __asm__ ("fsqrt.d %0, %1" : "=f"(x) : "f"(x));
+ return x;
+}
+
+#else
+
+#include "../sqrt.c"
+
+#endif
diff --git a/src/math/riscv32/sqrtf.c b/src/math/riscv32/sqrtf.c
new file mode 100644
index 00000000..610c2cf8
--- /dev/null
+++ b/src/math/riscv32/sqrtf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float sqrtf(float x)
+{
+ __asm__ ("fsqrt.s %0, %1" : "=f"(x) : "f"(x));
+ return x;
+}
+
+#else
+
+#include "../sqrtf.c"
+
+#endif
diff --git a/src/math/sqrtl.c b/src/math/sqrtl.c
index 1b9f19c7..a231b3f2 100644
--- a/src/math/sqrtl.c
+++ b/src/math/sqrtl.c
@@ -205,7 +205,7 @@ long double sqrtl(long double x)
top = (top + 0x3fff) >> 1;
/* r ~ 1/sqrt(m) */
- static const uint64_t three = 0xc0000000;
+ const uint64_t three = 0xc0000000;
uint64_t r, s, d, u, i;
i = (ix.hi >> 42) % 128;
r = (uint32_t)__rsqrt_tab[i] << 16;
@@ -227,7 +227,7 @@ long double sqrtl(long double x)
r = mul64(u, r) << 1;
/* |r sqrt(m) - 1| < 0x1.c001p-59, switch to 128bit */
- static const u128 threel = {.hi=three<<32, .lo=0};
+ const u128 threel = {.hi=three<<32, .lo=0};
u128 rl, sl, dl, ul;
rl.hi = r;
rl.lo = 0;
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 <grp.h>
#include <limits.h>
+#include <stdlib.h>
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;
}
diff --git a/src/misc/mntent.c b/src/misc/mntent.c
index d404fbe3..76f9c162 100644
--- a/src/misc/mntent.c
+++ b/src/misc/mntent.c
@@ -20,6 +20,42 @@ int endmntent(FILE *f)
return 1;
}
+static char *unescape_ent(char *beg)
+{
+ char *dest = beg;
+ const char *src = beg;
+ while (*src) {
+ const char *val;
+ unsigned char cval = 0;
+ if (*src != '\\') {
+ *dest++ = *src++;
+ continue;
+ }
+ if (src[1] == '\\') {
+ ++src;
+ *dest++ = *src++;
+ continue;
+ }
+ val = src + 1;
+ for (int i = 0; i < 3; ++i) {
+ if (*val >= '0' && *val <= '7') {
+ cval <<= 3;
+ cval += *val++ - '0';
+ } else {
+ break;
+ }
+ }
+ if (cval) {
+ *dest++ = cval;
+ src = val;
+ } else {
+ *dest++ = *src++;
+ }
+ }
+ *dest = 0;
+ return beg;
+}
+
struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen)
{
int n[8], use_internal = (linebuf == SENTINEL);
@@ -45,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%*s%n %n%*s%n %n%*s%n %n%*s%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);
@@ -55,10 +91,10 @@ struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int bufle
linebuf[n[5]] = 0;
linebuf[n[7]] = 0;
- mnt->mnt_fsname = linebuf+n[0];
- mnt->mnt_dir = linebuf+n[2];
- mnt->mnt_type = linebuf+n[4];
- mnt->mnt_opts = linebuf+n[6];
+ mnt->mnt_fsname = unescape_ent(linebuf+n[0]);
+ mnt->mnt_dir = unescape_ent(linebuf+n[2]);
+ mnt->mnt_type = unescape_ent(linebuf+n[4]);
+ mnt->mnt_opts = unescape_ent(linebuf+n[6]);
return mnt;
}
@@ -79,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++;
+ }
}
diff --git a/src/misc/syslog.c b/src/misc/syslog.c
index 7dc0c1be..710202f9 100644
--- a/src/misc/syslog.c
+++ b/src/misc/syslog.c
@@ -11,6 +11,7 @@
#include <fcntl.h>
#include "lock.h"
#include "fork_impl.h"
+#include "locale_impl.h"
static volatile int lock[1];
static char log_ident[32];
@@ -99,7 +100,7 @@ static void _vsyslog(int priority, const char *message, va_list ap)
now = time(NULL);
gmtime_r(&now, &tm);
- strftime(timebuf, sizeof timebuf, "%b %e %T", &tm);
+ strftime_l(timebuf, sizeof timebuf, "%b %e %T", &tm, C_LOCALE);
pid = (log_opt & LOG_PID) ? getpid() : 0;
l = snprintf(buf, sizeof buf, "<%d>%s %n%s%s%.0d%s: ",
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 <mqueue.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#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 <mqueue.h>
+#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;
+}
diff --git a/src/multibyte/mbrtowc.c b/src/multibyte/mbrtowc.c
index c94819e7..7824997e 100644
--- a/src/multibyte/mbrtowc.c
+++ b/src/multibyte/mbrtowc.c
@@ -8,7 +8,7 @@ size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate
static unsigned internal_state;
unsigned c;
const unsigned char *s = (const void *)src;
- const unsigned N = n;
+ const size_t N = n;
wchar_t dummy;
if (!st) st = (void *)&internal_state;
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;
diff --git a/src/network/dns_parse.c b/src/network/dns_parse.c
index 7f83e791..09813112 100644
--- a/src/network/dns_parse.c
+++ b/src/network/dns_parse.c
@@ -12,16 +12,15 @@ int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, c
p = r+12;
qdcount = r[4]*256 + r[5];
ancount = r[6]*256 + r[7];
- if (qdcount+ancount > 64) return -1;
while (qdcount--) {
while (p-r < rlen && *p-1U < 127) p++;
- if (p>r+rlen-6 || *p>193 || (*p==193 && p[1]>254))
+ if (p>r+rlen-6)
return -1;
p += 5 + !!*p;
}
while (ancount--) {
while (p-r < rlen && *p-1U < 127) p++;
- if (p>r+rlen-12 || *p>193 || (*p==193 && p[1]>254))
+ if (p>r+rlen-12)
return -1;
p += 1 + !!*p;
len = p[8]*256 + p[9];
diff --git a/src/network/getnameinfo.c b/src/network/getnameinfo.c
index 7abe0fa9..133c15b3 100644
--- a/src/network/getnameinfo.c
+++ b/src/network/getnameinfo.c
@@ -162,8 +162,10 @@ int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
query[3] = 0; /* don't need AD flag */
int rlen = __res_send(query, qlen, reply, sizeof reply);
buf[0] = 0;
- if (rlen > 0)
+ if (rlen > 0) {
+ if (rlen > sizeof reply) rlen = sizeof reply;
__dns_parse(reply, rlen, dns_parse_callback, buf);
+ }
}
if (!*buf) {
if (flags & NI_NAMEREQD) return EAI_NONAME;
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] = ':';
diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
index 4281482e..35218185 100644
--- a/src/network/lookup_name.c
+++ b/src/network/lookup_name.c
@@ -109,7 +109,7 @@ struct dpc_ctx {
#define RR_CNAME 5
#define RR_AAAA 28
-#define ABUF_SIZE 768
+#define ABUF_SIZE 4800
static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet, int plen)
{
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;
diff --git a/src/process/_Fork.c b/src/process/_Fork.c
index fb0fdc2c..9c07792d 100644
--- a/src/process/_Fork.c
+++ b/src/process/_Fork.c
@@ -5,24 +5,16 @@
#include "lock.h"
#include "pthread_impl.h"
#include "aio_impl.h"
+#include "fork_impl.h"
static void dummy(int x) { }
weak_alias(dummy, __aio_atfork);
-pid_t _Fork(void)
+void __post_Fork(int ret)
{
- pid_t ret;
- sigset_t set;
- __block_all_sigs(&set);
- LOCK(__abort_lock);
-#ifdef SYS_fork
- ret = __syscall(SYS_fork);
-#else
- ret = __syscall(SYS_clone, SIGCHLD, 0);
-#endif
if (!ret) {
pthread_t self = __pthread_self();
- self->tid = __syscall(SYS_gettid);
+ self->tid = __syscall(SYS_set_tid_address, &__thread_list_lock);
self->robust_list.off = 0;
self->robust_list.pending = 0;
self->next = self->prev = self;
@@ -32,6 +24,20 @@ pid_t _Fork(void)
}
UNLOCK(__abort_lock);
if (!ret) __aio_atfork(1);
+}
+
+pid_t _Fork(void)
+{
+ pid_t ret;
+ sigset_t set;
+ __block_all_sigs(&set);
+ LOCK(__abort_lock);
+#ifdef SYS_fork
+ ret = __syscall(SYS_fork);
+#else
+ ret = __syscall(SYS_clone, SIGCHLD, 0);
+#endif
+ __post_Fork(ret);
__restore_sigs(&set);
return __syscall_ret(ret);
}
diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c
index 728551b3..8294598b 100644
--- a/src/process/posix_spawn.c
+++ b/src/process/posix_spawn.c
@@ -4,6 +4,7 @@
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
+#include <errno.h>
#include <sys/wait.h>
#include "syscall.h"
#include "lock.h"
@@ -156,7 +157,11 @@ static int child(void *args_vp)
fail:
/* Since sizeof errno < PIPE_BUF, the write is atomic. */
ret = -ret;
- if (ret) while (__syscall(SYS_write, p, &ret, sizeof ret) < 0);
+ if (ret) {
+ int r;
+ do r = __syscall(SYS_write, p, &ret, sizeof ret);
+ while (r<0 && r!=-EPIPE);
+ }
_exit(127);
}
diff --git a/src/process/waitpid.c b/src/process/waitpid.c
index 1b65bf05..80231862 100644
--- a/src/process/waitpid.c
+++ b/src/process/waitpid.c
@@ -3,5 +3,5 @@
pid_t waitpid(pid_t pid, int *status, int options)
{
- return syscall_cp(SYS_wait4, pid, status, options, 0);
+ return sys_wait4_cp(pid, status, options, 0);
}
diff --git a/src/regex/glob.c b/src/regex/glob.c
index a4906446..87bae084 100644
--- a/src/regex/glob.c
+++ b/src/regex/glob.c
@@ -265,7 +265,7 @@ int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, i
if (append(&tail, pat, strlen(pat), 0))
return GLOB_NOSPACE;
cnt++;
- } else
+ } else if (!error)
return GLOB_NOMATCH;
}
diff --git a/src/linux/ppoll.c b/src/select/ppoll.c
index e614600a..9a0bf929 100644
--- a/src/linux/ppoll.c
+++ b/src/select/ppoll.c
@@ -1,4 +1,4 @@
-#define _GNU_SOURCE
+#define _BSD_SOURCE
#include <poll.h>
#include <signal.h>
#include <errno.h>
diff --git a/src/setjmp/loongarch64/longjmp.S b/src/setjmp/loongarch64/longjmp.S
new file mode 100644
index 00000000..896d2e26
--- /dev/null
+++ b/src/setjmp/loongarch64/longjmp.S
@@ -0,0 +1,32 @@
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+ ld.d $ra, $a0, 0
+ ld.d $sp, $a0, 8
+ ld.d $r21,$a0, 16
+ ld.d $fp, $a0, 24
+ ld.d $s0, $a0, 32
+ ld.d $s1, $a0, 40
+ ld.d $s2, $a0, 48
+ ld.d $s3, $a0, 56
+ ld.d $s4, $a0, 64
+ ld.d $s5, $a0, 72
+ ld.d $s6, $a0, 80
+ ld.d $s7, $a0, 88
+ ld.d $s8, $a0, 96
+#ifndef __loongarch_soft_float
+ fld.d $fs0, $a0, 104
+ fld.d $fs1, $a0, 112
+ fld.d $fs2, $a0, 120
+ fld.d $fs3, $a0, 128
+ fld.d $fs4, $a0, 136
+ fld.d $fs5, $a0, 144
+ fld.d $fs6, $a0, 152
+ fld.d $fs7, $a0, 160
+#endif
+ sltui $a0, $a1, 1
+ add.d $a0, $a0, $a1
+ jr $ra
diff --git a/src/setjmp/loongarch64/setjmp.S b/src/setjmp/loongarch64/setjmp.S
new file mode 100644
index 00000000..d158a3d2
--- /dev/null
+++ b/src/setjmp/loongarch64/setjmp.S
@@ -0,0 +1,34 @@
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+ st.d $ra, $a0, 0
+ st.d $sp, $a0, 8
+ st.d $r21,$a0, 16
+ st.d $fp, $a0, 24
+ st.d $s0, $a0, 32
+ st.d $s1, $a0, 40
+ st.d $s2, $a0, 48
+ st.d $s3, $a0, 56
+ st.d $s4, $a0, 64
+ st.d $s5, $a0, 72
+ st.d $s6, $a0, 80
+ st.d $s7, $a0, 88
+ st.d $s8, $a0, 96
+#ifndef __loongarch_soft_float
+ fst.d $fs0, $a0, 104
+ fst.d $fs1, $a0, 112
+ fst.d $fs2, $a0, 120
+ fst.d $fs3, $a0, 128
+ fst.d $fs4, $a0, 136
+ fst.d $fs5, $a0, 144
+ fst.d $fs6, $a0, 152
+ fst.d $fs7, $a0, 160
+#endif
+ move $a0, $zero
+ jr $ra
diff --git a/src/setjmp/riscv32/longjmp.S b/src/setjmp/riscv32/longjmp.S
new file mode 100644
index 00000000..f9cb3318
--- /dev/null
+++ b/src/setjmp/riscv32/longjmp.S
@@ -0,0 +1,42 @@
+.global __longjmp
+.global _longjmp
+.global longjmp
+.type __longjmp, %function
+.type _longjmp, %function
+.type longjmp, %function
+__longjmp:
+_longjmp:
+longjmp:
+ lw s0, 0(a0)
+ lw s1, 4(a0)
+ lw s2, 8(a0)
+ lw s3, 12(a0)
+ lw s4, 16(a0)
+ lw s5, 20(a0)
+ lw s6, 24(a0)
+ lw s7, 28(a0)
+ lw s8, 32(a0)
+ lw s9, 36(a0)
+ lw s10, 40(a0)
+ lw s11, 44(a0)
+ lw sp, 48(a0)
+ 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)
+#endif
+
+ seqz a0, a1
+ add a0, a0, a1
+ ret
diff --git a/src/setjmp/riscv32/setjmp.S b/src/setjmp/riscv32/setjmp.S
new file mode 100644
index 00000000..8a75cf55
--- /dev/null
+++ b/src/setjmp/riscv32/setjmp.S
@@ -0,0 +1,41 @@
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp, %function
+.type _setjmp, %function
+.type setjmp, %function
+__setjmp:
+_setjmp:
+setjmp:
+ sw s0, 0(a0)
+ sw s1, 4(a0)
+ sw s2, 8(a0)
+ sw s3, 12(a0)
+ sw s4, 16(a0)
+ sw s5, 20(a0)
+ sw s6, 24(a0)
+ sw s7, 28(a0)
+ sw s8, 32(a0)
+ sw s9, 36(a0)
+ sw s10, 40(a0)
+ sw s11, 44(a0)
+ sw sp, 48(a0)
+ 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)
+#endif
+
+ li a0, 0
+ ret
diff --git a/src/signal/loongarch64/restore.s b/src/signal/loongarch64/restore.s
new file mode 100644
index 00000000..d90a8ebb
--- /dev/null
+++ b/src/signal/loongarch64/restore.s
@@ -0,0 +1,10 @@
+.global __restore_rt
+.global __restore
+.hidden __restore_rt
+.hidden __restore
+.type __restore_rt,@function
+.type __restore,@function
+__restore_rt:
+__restore:
+ li.w $a7, 139
+ syscall 0
diff --git a/src/signal/loongarch64/sigsetjmp.s b/src/signal/loongarch64/sigsetjmp.s
new file mode 100644
index 00000000..9c0e3ae2
--- /dev/null
+++ b/src/signal/loongarch64/sigsetjmp.s
@@ -0,0 +1,25 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+sigsetjmp:
+__sigsetjmp:
+ beq $a1, $zero, 1f
+ st.d $ra, $a0, 184
+ st.d $s0, $a0, 200 #184+8+8
+ move $s0, $a0
+
+ la.global $t0, setjmp
+ jirl $ra, $t0, 0
+
+ move $a1, $a0 # Return from 'setjmp' or 'longjmp'
+ move $a0, $s0
+ ld.d $ra, $a0, 184
+ ld.d $s0, $a0, 200 #184+8+8
+
+.hidden __sigsetjmp_tail
+ la.global $t0, __sigsetjmp_tail
+ jr $t0
+1:
+ la.global $t0, setjmp
+ jr $t0
diff --git a/src/signal/riscv32/restore.s b/src/signal/riscv32/restore.s
new file mode 100644
index 00000000..5a0af695
--- /dev/null
+++ b/src/signal/riscv32/restore.s
@@ -0,0 +1,10 @@
+.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
+ ecall
diff --git a/src/signal/riscv32/sigsetjmp.s b/src/signal/riscv32/sigsetjmp.s
new file mode 100644
index 00000000..c1caeab1
--- /dev/null
+++ b/src/signal/riscv32/sigsetjmp.s
@@ -0,0 +1,23 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp, %function
+.type __sigsetjmp, %function
+sigsetjmp:
+__sigsetjmp:
+ bnez a1, 1f
+ tail setjmp
+1:
+
+ sw ra, 152(a0)
+ sw s0, 164(a0)
+ mv s0, a0
+
+ call setjmp
+
+ mv a1, a0
+ mv a0, s0
+ lw s0, 164(a0)
+ lw ra, 152(a0)
+
+.hidden __sigsetjmp_tail
+ tail __sigsetjmp_tail
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
diff --git a/src/signal/sh/sigsetjmp.s b/src/signal/sh/sigsetjmp.s
index 1e2270be..f0f604e2 100644
--- a/src/signal/sh/sigsetjmp.s
+++ b/src/signal/sh/sigsetjmp.s
@@ -27,7 +27,7 @@ __sigsetjmp:
mov.l 3f, r0
4: braf r0
- mov.l @(4+8,r4), r8
+ mov.l @(4+8,r6), r8
9: mov.l 5f, r0
6: braf r0
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 <signal.h>
#include <errno.h>
+#include <unistd.h>
#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;
}
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);
}
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);
}
diff --git a/src/stat/fchmodat.c b/src/stat/fchmodat.c
index bc581050..92c9d1b0 100644
--- a/src/stat/fchmodat.c
+++ b/src/stat/fchmodat.c
@@ -5,13 +5,16 @@
int fchmodat(int fd, const char *path, mode_t mode, int flag)
{
- if (!flag) return syscall(SYS_fchmodat, fd, path, mode, flag);
+ if (!flag) return syscall(SYS_fchmodat, fd, path, mode);
+
+ int ret = __syscall(SYS_fchmodat2, fd, path, mode, flag);
+ if (ret != -ENOSYS) return __syscall_ret(ret);
if (flag != AT_SYMLINK_NOFOLLOW)
return __syscall_ret(-EINVAL);
struct stat st;
- int ret, fd2;
+ int fd2;
char proc[15+3*sizeof(int)];
if (fstatat(fd, path, &st, flag))
diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
index 04506375..9eed063b 100644
--- a/src/stat/fstatat.c
+++ b/src/stat/fstatat.c
@@ -36,6 +36,7 @@ static int fstatat_statx(int fd, const char *restrict path, struct stat *restric
{
struct statx stx;
+ flag |= AT_NO_AUTOMOUNT;
int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
if (ret) return ret;
diff --git a/src/stat/statvfs.c b/src/stat/statvfs.c
index bfbb5fee..bc12da8b 100644
--- a/src/stat/statvfs.c
+++ b/src/stat/statvfs.c
@@ -39,6 +39,7 @@ static void fixup(struct statvfs *out, const struct statfs *in)
out->f_fsid = in->f_fsid.__val[0];
out->f_flag = in->f_flags;
out->f_namemax = in->f_namelen;
+ out->f_type = in->f_type;
}
int statvfs(const char *restrict path, struct statvfs *restrict buf)
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) {
diff --git a/src/stdio/pclose.c b/src/stdio/pclose.c
index 080a4262..c64da405 100644
--- a/src/stdio/pclose.c
+++ b/src/stdio/pclose.c
@@ -7,7 +7,7 @@ int pclose(FILE *f)
int status, r;
pid_t pid = f->pipe_pid;
fclose(f);
- while ((r=__syscall(SYS_wait4, pid, &status, 0, 0)) == -EINTR);
+ while ((r=__sys_wait4(pid, &status, 0, 0)) == -EINTR);
if (r<0) return __syscall_ret(r);
return status;
}
diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index a712d80f..76733997 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -52,7 +52,7 @@ static const unsigned char states[]['z'-'A'+1] = {
S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
- S('c') = CHAR, S('C') = INT,
+ S('c') = INT, S('C') = UINT,
S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
S('m') = NOARG,
S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
@@ -62,7 +62,7 @@ static const unsigned char states[]['z'-'A'+1] = {
S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
- S('c') = INT, S('s') = PTR, S('n') = PTR,
+ S('c') = UINT, S('s') = PTR, S('n') = PTR,
S('l') = LLPRE,
}, { /* 2: ll-prefixed */
S('d') = LLONG, S('i') = LLONG,
@@ -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;
}
@@ -177,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;
@@ -211,18 +216,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;
@@ -437,7 +435,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
unsigned st, ps;
int cnt=0, l=0;
size_t i;
- char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];
+ char buf[sizeof(uintmax_t)*3];
const char *prefix;
int t, pl;
wchar_t wc[2], *ws;
@@ -563,11 +561,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) && p<z-a+1) p=z-a+1;
- } if (0) {
+ goto ifmt_tail;
case 'd': case 'i':
pl=1;
if (arg.i>INTMAX_MAX) {
@@ -579,7 +577,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) {
@@ -588,6 +586,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
}
p = MAX(p, z-a + !arg.i);
break;
+ narrow_c:
case 'c':
*(a=z-(p=1))=arg.i;
fl &= ~ZERO_PAD;
@@ -602,6 +601,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
fl &= ~ZERO_PAD;
break;
case 'C':
+ if (!arg.i) goto narrow_c;
wc[0] = arg.i;
wc[1] = 0;
arg.p = wc;
@@ -622,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;
}
diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c
index 53697701..59d5471b 100644
--- a/src/stdio/vfwprintf.c
+++ b/src/stdio/vfwprintf.c
@@ -45,7 +45,7 @@ static const unsigned char states[]['z'-'A'+1] = {
S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
- S('c') = CHAR, S('C') = INT,
+ S('c') = INT, S('C') = UINT,
S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
S('m') = NOARG,
S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
@@ -55,7 +55,7 @@ static const unsigned char states[]['z'-'A'+1] = {
S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
- S('c') = INT, S('s') = PTR, S('n') = PTR,
+ S('c') = UINT, S('s') = PTR, S('n') = PTR,
S('l') = LLPRE,
}, { /* 2: ll-prefixed */
S('d') = LLONG, S('i') = LLONG,
diff --git a/src/stdio/vsnprintf.c b/src/stdio/vsnprintf.c
index b3510a63..409b9c85 100644
--- a/src/stdio/vsnprintf.c
+++ b/src/stdio/vsnprintf.c
@@ -45,11 +45,6 @@ int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
.cookie = &c,
};
- if (n > INT_MAX) {
- errno = EOVERFLOW;
- return -1;
- }
-
*c.s = 0;
return vfprintf(&f, fmt, ap);
}
diff --git a/src/stdio/vswprintf.c b/src/stdio/vswprintf.c
index fc223cf2..5e9a4dad 100644
--- a/src/stdio/vswprintf.c
+++ b/src/stdio/vswprintf.c
@@ -51,9 +51,6 @@ int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_lis
if (!n) {
return -1;
- } else if (n > INT_MAX) {
- errno = EOVERFLOW;
- return -1;
}
r = vfwprintf(&f, fmt, ap);
sw_write(&f, 0, 0);
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
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;
}
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 <termios.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+int cfsetspeed(struct termios *tio, speed_t speed)
+{
+ int r = cfsetospeed(tio, speed);
+ if (!r) cfsetispeed(tio, 0);
+ return r;
+}
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/__set_thread_area.s b/src/thread/loongarch64/__set_thread_area.s
new file mode 100644
index 00000000..021307fc
--- /dev/null
+++ b/src/thread/loongarch64/__set_thread_area.s
@@ -0,0 +1,7 @@
+.global __set_thread_area
+.hidden __set_thread_area
+.type __set_thread_area,@function
+__set_thread_area:
+ move $tp, $a0
+ move $a0, $zero
+ jr $ra
diff --git a/src/thread/loongarch64/__unmapself.s b/src/thread/loongarch64/__unmapself.s
new file mode 100644
index 00000000..719ad056
--- /dev/null
+++ b/src/thread/loongarch64/__unmapself.s
@@ -0,0 +1,7 @@
+.global __unmapself
+.type __unmapself, @function
+__unmapself:
+ li.d $a7, 215 # call munmap
+ syscall 0
+ li.d $a7, 93 # call exit
+ syscall 0
diff --git a/src/thread/loongarch64/clone.s b/src/thread/loongarch64/clone.s
new file mode 100644
index 00000000..cb4aacfc
--- /dev/null
+++ b/src/thread/loongarch64/clone.s
@@ -0,0 +1,30 @@
+#__clone(func, stack, flags, arg, ptid, tls, ctid)
+# a0, a1, a2, a3, a4, a5, a6
+# sys_clone(flags, stack, ptid, ctid, tls)
+# a0, a1, a2, a3, a4
+
+.global __clone
+.hidden __clone
+.type __clone,@function
+__clone:
+ bstrins.d $a1, $zero, 3, 0 #stack to 16 align
+ # Save function pointer and argument pointer on new thread stack
+ addi.d $a1, $a1, -16
+ st.d $a0, $a1, 0 # save function pointer
+ st.d $a3, $a1, 8 # save argument pointer
+ or $a0, $a2, $zero
+ or $a2, $a4, $zero
+ or $a3, $a6, $zero
+ or $a4, $a5, $zero
+ ori $a7, $zero, 220
+ syscall 0 # call 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
+ ori $a7, $zero, 93
+ syscall 0 # child process exit
diff --git a/src/thread/loongarch64/syscall_cp.s b/src/thread/loongarch64/syscall_cp.s
new file mode 100644
index 00000000..c057a97b
--- /dev/null
+++ b/src/thread/loongarch64/syscall_cp.s
@@ -0,0 +1,29 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscall_cp_asm,@function
+
+__syscall_cp_asm:
+__cp_begin:
+ ld.w $a0, $a0, 0
+ bnez $a0, __cp_cancel
+ move $t8, $a1 # reserve system call number
+ move $a0, $a2
+ move $a1, $a3
+ move $a2, $a4
+ move $a3, $a5
+ move $a4, $a6
+ move $a5, $a7
+ move $a7, $t8
+ syscall 0
+__cp_end:
+ jr $ra
+__cp_cancel:
+ la.local $t8, __cancel
+ jr $t8
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 2473ac20..b41488a2 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
@@ -23,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)
diff --git a/src/thread/riscv32/__set_thread_area.s b/src/thread/riscv32/__set_thread_area.s
new file mode 100644
index 00000000..828154d2
--- /dev/null
+++ b/src/thread/riscv32/__set_thread_area.s
@@ -0,0 +1,6 @@
+.global __set_thread_area
+.type __set_thread_area, %function
+__set_thread_area:
+ mv tp, a0
+ li a0, 0
+ ret
diff --git a/src/thread/riscv32/__unmapself.s b/src/thread/riscv32/__unmapself.s
new file mode 100644
index 00000000..2849119c
--- /dev/null
+++ b/src/thread/riscv32/__unmapself.s
@@ -0,0 +1,7 @@
+.global __unmapself
+.type __unmapself, %function
+__unmapself:
+ li a7, 215 # SYS_munmap
+ ecall
+ li a7, 93 # SYS_exit
+ ecall
diff --git a/src/thread/riscv32/clone.s b/src/thread/riscv32/clone.s
new file mode 100644
index 00000000..e2116e33
--- /dev/null
+++ b/src/thread/riscv32/clone.s
@@ -0,0 +1,35 @@
+# __clone(func, stack, flags, arg, ptid, tls, ctid)
+# a0, a1, a2, a3, a4, a5, a6
+
+# syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+# a7 a0, a1, a2, a3, a4
+
+.global __clone
+.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)
+
+ # Call SYS_clone
+ mv a0, a2
+ mv a2, a4
+ mv a3, a5
+ mv a4, a6
+ li a7, 220 # SYS_clone
+ ecall
+
+ beqz a0, 1f
+ # Parent
+ ret
+
+ # Child
+1: lw a1, 0(sp)
+ lw a0, 4(sp)
+ jalr a1
+
+ # Exit
+ li a7, 93 # SYS_exit
+ ecall
diff --git a/src/thread/riscv32/syscall_cp.s b/src/thread/riscv32/syscall_cp.s
new file mode 100644
index 00000000..079d1ba0
--- /dev/null
+++ b/src/thread/riscv32/syscall_cp.s
@@ -0,0 +1,29 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscall_cp_asm, %function
+__syscall_cp_asm:
+__cp_begin:
+ lw t0, 0(a0)
+ bnez t0, __cp_cancel
+
+ mv t0, a1
+ mv a0, a2
+ mv a1, a3
+ mv a2, a4
+ mv a3, a5
+ mv a4, a6
+ mv a5, a7
+ lw a6, 0(sp)
+ mv a7, t0
+ ecall
+__cp_end:
+ ret
+__cp_cancel:
+ tail __cancel
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)
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
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;
}
diff --git a/src/thread/synccall.c b/src/thread/synccall.c
index a6b177c0..38597254 100644
--- a/src/thread/synccall.c
+++ b/src/thread/synccall.c
@@ -11,7 +11,7 @@ weak_alias(dummy_0, __tl_unlock);
static int target_tid;
static void (*callback)(void *), *context;
-static sem_t target_sem, caller_sem;
+static sem_t target_sem, caller_sem, exit_sem;
static void dummy(void *p)
{
@@ -33,7 +33,7 @@ static void handler(int sig)
/* Inform caller we've complered the callback and wait
* for the caller to release us to return. */
sem_post(&caller_sem);
- sem_wait(&target_sem);
+ sem_wait(&exit_sem);
/* Inform caller we are returning and state is destroyable. */
sem_post(&caller_sem);
@@ -62,6 +62,7 @@ void __synccall(void (*func)(void *), void *ctx)
sem_init(&target_sem, 0, 0);
sem_init(&caller_sem, 0, 0);
+ sem_init(&exit_sem, 0, 0);
if (!libc.threads_minus_1 || __syscall(SYS_gettid) != self->tid)
goto single_threaded;
@@ -107,12 +108,13 @@ single_threaded:
/* Only release the caught threads once all threads, including the
* caller, have returned from the callback function. */
for (i=0; i<count; i++)
- sem_post(&target_sem);
+ sem_post(&exit_sem);
for (i=0; i<count; i++)
sem_wait(&caller_sem);
sem_destroy(&caller_sem);
sem_destroy(&target_sem);
+ sem_destroy(&exit_sem);
pthread_setcancelstate(cs, 0);
__tl_unlock();
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";
diff --git a/src/time/__year_to_secs.c b/src/time/__year_to_secs.c
index 2824ec6d..b42f5a6d 100644
--- a/src/time/__year_to_secs.c
+++ b/src/time/__year_to_secs.c
@@ -10,9 +10,9 @@ long long __year_to_secs(long long year, int *is_leap)
return 31536000*(y-70) + 86400*leaps;
}
- int cycles, centuries, leaps, rem;
+ int cycles, centuries, leaps, rem, dummy;
- if (!is_leap) is_leap = &(int){0};
+ if (!is_leap) is_leap = &dummy;
cycles = (year-100) / 400;
rem = (year-100) % 400;
if (rem < 0) {
diff --git a/src/time/strftime.c b/src/time/strftime.c
index cc53d536..c40246db 100644
--- a/src/time/strftime.c
+++ b/src/time/strftime.c
@@ -3,6 +3,7 @@
#include <string.h>
#include <langinfo.h>
#include <locale.h>
+#include <ctype.h>
#include <time.h>
#include <limits.h>
#include "locale_impl.h"
@@ -233,7 +234,12 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st
pad = 0;
if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
if ((plus = (*f == '+'))) f++;
- width = strtoul(f, &p, 10);
+ if (isdigit(*f)) {
+ width = strtoul(f, &p, 10);
+ } else {
+ width = 0;
+ p = (void *)f;
+ }
if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
if (!width && p!=f) width = 1;
} else {
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+1<sizeof tmp; i++) {
+ tmp[i] = *s++;
+ }
+ tmp[i] = 0;
+ char *p = strptime(tmp, "%12Y-%m-%d", tm);
+ if (!p) return 0;
+ s -= tmp+i-p;
+ break;
case 'H':
dest = &tm->tm_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;
diff --git a/src/time/timer_create.c b/src/time/timer_create.c
index cd32c945..cc6c2236 100644
--- a/src/time/timer_create.c
+++ b/src/time/timer_create.c
@@ -1,6 +1,7 @@
#include <time.h>
#include <setjmp.h>
#include <limits.h>
+#include <semaphore.h>
#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;
};
@@ -21,10 +22,16 @@ 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();
__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;
@@ -42,7 +49,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 (;;) {
@@ -61,7 +75,7 @@ static void *start(void *arg)
int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict res)
{
- volatile static int init = 0;
+ static volatile int init = 0;
pthread_t td;
pthread_attr_t attr;
int r;
@@ -90,7 +104,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);
}
@@ -99,7 +116,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 +138,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;
diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c
index 557503eb..43052dd7 100644
--- a/src/unistd/faccessat.c
+++ b/src/unistd/faccessat.c
@@ -53,7 +53,7 @@ int faccessat(int fd, const char *filename, int amode, int flag)
if (pid<0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret))
ret = -EBUSY;
__syscall(SYS_close, p[0]);
- __syscall(SYS_wait4, pid, &status, __WCLONE, 0);
+ __sys_wait4(pid, &status, __WCLONE, 0);
__restore_sigs(&set);
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;
}
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();
}
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 <unistd.h>
+#include <sys/uio.h>
+#include <fcntl.h>
#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 <sys/uio.h>
#include <unistd.h>
+#include <fcntl.h>
#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));
}
diff --git a/src/unistd/setxid.c b/src/unistd/setxid.c
index 487c1a16..a629ed4b 100644
--- a/src/unistd/setxid.c
+++ b/src/unistd/setxid.c
@@ -30,5 +30,5 @@ int __setxid(int nr, int id, int eid, int sid)
* trigger the safety kill above. */
struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .ret = 1 };
__synccall(do_setxid, &c);
- return __syscall_ret(c.ret);
+ return __syscall_ret(c.ret > 0 ? -EAGAIN : c.ret);
}
diff --git a/tools/install.sh b/tools/install.sh
index d913b60b..855a8ca2 100755
--- a/tools/install.sh
+++ b/tools/install.sh
@@ -48,7 +48,9 @@ trap 'rm -f "$tmp"' EXIT INT QUIT TERM HUP
umask 077
if test "$symlink" ; then
+umask 000
ln -s "$1" "$tmp"
+umask 077
else
cat < "$1" > "$tmp"
chmod "$mode" "$tmp"