diff options
288 files changed, 3734 insertions, 819 deletions
@@ -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. @@ -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 @@ -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 @@ -1 +1 @@ -1.2.3 +1.2.5 @@ -2327,3 +2327,114 @@ bugs fixed:  arch-specific bugs fixed:  - powerpc (32-bit) struct shmid_ds layout was wrong for some fields  - time64 struct layout was wrong in sound ioctl fallback (32-bit archs) + + + +1.2.4 release notes + +new features: +- large dns record lookups via tcp fallback +- new getaddrinfo EAI_NODATA result to distinguish NODATA/NxDomain +- support for new RELR compressed format for relative relocations +- sysconf keys for querying signal stack size requirements +- real vfork on riscv64 + +performance: +- mallocng no longer uses MADV_FREE (high performance cost, little gain) +- vdso clock_gettime is supported once again on 32-bit arm + +compatibility: +- gethostbyname family now distinguishes NO_DATA from HOST_NOT_FOUND +- res_send now works with caller-provided edns0 queries +- arpa/nameser.h RR types list is now up-to-date +- previously-missing POSIX confstr keys have been added +- mntent interfaces now accept missing fields +- alt signal stack, if any, is now used for internal signals +- the LFS64 macros are no longer exposed without _LARGEFILE64_SOURCE +- memmem (POSIX-future) is now exposed in default feature profile +- pthread_atfork now admits calls from an application-provided malloc +- debugger tracking of shared libraries now works on MIPS PIE binaries +- sendmsg now supports up to SCM_MAX_FD fds in SCM_RIGHTS messages + +bugs fixed: +- gethostbyname[2]_r wrongly returned nonzero (error) on negative result +- parallel v4/v6 address queries could fail on query id collisions +- spurious getaddrinfo/AI_ADDRCONFIG failures due to errno clobbering +- dns search domains ending in dot (including lone dot) broke lookups +- ipv6 servers in resolv.conf broke lookups on systems with v6 disabled +- systems with bindv6only failed to query both v4 and v6 nameservers +- res_mkquery mishandled consecutive final dots in name +- res_send could malfunction for very small answer buffer sizes +- resolver dns backend accepted answers with wrong (A vs AAAA) RR type +- getservbyport_r returned junk or ENOENT (vs ERANGE) on buffer size errors +- dns result parsing of malformed responses could process uninitialized data +- freopen didn't reset stream orientation (byte/wide) & encoding rule +- fwprintf didn't print most fields on open_wmemstream FILEs +- wide printf %lc ignored field width +- wide printf erroneously processed %n after encoding errors +- use of wide printf %9$ argument slot overflowed undersized buffer +- swprintf malfunctioned on nul character in output +- strverscmp ordered digit sequences vs nondigits incorrectly +- timer_create/SIGEV_THREAD failure leaked the thread +- semaphores were subject to missed-wake under certain usage patterns +- several possible rare deadlocks with lock handling at thread exit +- several possible rare deadlocks with aio and multithreaded fork +- dynamic linker relro processing was broken on archs w/variable pagesize +- async cancellation could run cancellation handlers in invalid context +- pthread_detach was wrongly a cancellation point in rare race code path +- use-after-close/double-close errors in mq_notify error paths +- mq_notify event thread wrongly ran with signals unmasked +- wcs{,n}cmp, wmemcmp returned wrong results when difference overflowed +- accept4, pipe2, and dup3 handled unknown flags wrong in fallback cases +- CPU_SETSIZE macro had wrong unit +- select fallback for pre-time64 kernels truncated timeout (vs clamping) + +arch-specific bugs fixed: +- x32 new socketcalls took fallback path due to pointer sign extension +- x32 wait4 didn't fill rusage structure (time64 regression) +- x32 semtimedop mismatched timespec ABI with kernel (time64 regression) +- 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/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/aarch64/bits/stat.h b/arch/generic/bits/stat.h index b7f4221b..f6d9e864 100644 --- a/arch/aarch64/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/aarch64/bits/stdint.h b/arch/generic/bits/stdint.h index 1bb147f2..86489187 100644 --- a/arch/aarch64/bits/stdint.h +++ b/arch/generic/bits/stdint.h @@ -12,9 +12,18 @@ typedef uint32_t uint_fast32_t;  #define UINT_FAST16_MAX UINT32_MAX  #define UINT_FAST32_MAX UINT32_MAX +#if __LONG_MAX == 0x7fffffffL +#define INTPTR_MIN      INT32_MIN +#define INTPTR_MAX      INT32_MAX +#define UINTPTR_MAX     UINT32_MAX +#define PTRDIFF_MIN     INT32_MIN +#define PTRDIFF_MAX     INT32_MAX +#define SIZE_MAX        UINT32_MAX +#else  #define INTPTR_MIN      INT64_MIN  #define INTPTR_MAX      INT64_MAX  #define UINTPTR_MAX     UINT64_MAX  #define PTRDIFF_MIN     INT64_MIN  #define PTRDIFF_MAX     INT64_MAX  #define SIZE_MAX        UINT64_MAX +#endif diff --git a/arch/i386/bits/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/stdint.h b/arch/m68k/bits/stdint.h deleted file mode 100644 index d1b27121..00000000 --- a/arch/m68k/bits/stdint.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef int32_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast16_t; -typedef uint32_t uint_fast32_t; - -#define INT_FAST16_MIN  INT32_MIN -#define INT_FAST32_MIN  INT32_MIN - -#define INT_FAST16_MAX  INT32_MAX -#define INT_FAST32_MAX  INT32_MAX - -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN      INT32_MIN -#define INTPTR_MAX      INT32_MAX -#define UINTPTR_MAX     UINT32_MAX -#define PTRDIFF_MIN     INT32_MIN -#define PTRDIFF_MAX     INT32_MAX -#define SIZE_MAX        UINT32_MAX diff --git a/arch/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..fe893af4 100644 --- a/arch/powerpc/syscall_arch.h +++ b/arch/powerpc/syscall_arch.h @@ -9,7 +9,7 @@ static inline long __syscall0(long n)  	register long r3 __asm__("r3");  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "=r"(r3) -	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -19,7 +19,7 @@ static inline long __syscall1(long n, long a)  	register long r3 __asm__("r3") = a;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3) -	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -30,7 +30,7 @@ static inline long __syscall2(long n, long a, long b)  	register long r4 __asm__("r4") = b;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4) -	:: "memory", "cr0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -42,7 +42,7 @@ static inline long __syscall3(long n, long a, long b, long c)  	register long r5 __asm__("r5") = c;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5) -	:: "memory", "cr0", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -55,7 +55,7 @@ static inline long __syscall4(long n, long a, long b, long c, long d)  	register long r6 __asm__("r6") = d;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6) -	:: "memory", "cr0", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -69,7 +69,7 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e)  	register long r7 __asm__("r7") = e;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7) -	:: "memory", "cr0", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -84,7 +84,7 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo  	register long r8 __asm__("r8") = f;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7), "+r"(r8) -	:: "memory", "cr0", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -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..4c5d3ae9 100644 --- a/arch/powerpc64/syscall_arch.h +++ b/arch/powerpc64/syscall_arch.h @@ -7,7 +7,7 @@ static inline long __syscall0(long n)  	register long r3 __asm__("r3");  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "=r"(r3) -	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -17,7 +17,7 @@ static inline long __syscall1(long n, long a)  	register long r3 __asm__("r3") = a;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3) -	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -28,7 +28,7 @@ static inline long __syscall2(long n, long a, long b)  	register long r4 __asm__("r4") = b;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4) -	:: "memory", "cr0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -40,7 +40,7 @@ static inline long __syscall3(long n, long a, long b, long c)  	register long r5 __asm__("r5") = c;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5) -	:: "memory", "cr0", "r6", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -53,7 +53,7 @@ static inline long __syscall4(long n, long a, long b, long c, long d)  	register long r6 __asm__("r6") = d;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6) -	:: "memory", "cr0", "r7", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r7", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -67,7 +67,7 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e)  	register long r7 __asm__("r7") = e;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7) -	:: "memory", "cr0", "r8", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r8", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  } @@ -82,9 +82,13 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo  	register long r8 __asm__("r8") = f;  	__asm__ __volatile__("sc ; bns+ 1f ; neg %1, %1 ; 1:"  	: "+r"(r0), "+r"(r3), "+r"(r4), "+r"(r5), "+r"(r6), "+r"(r7), "+r"(r8) -	:: "memory", "cr0", "r9", "r10", "r11", "r12"); +	:: "memory", "cr0", "r9", "r10", "r11", "r12", "ctr", "xer");  	return r3;  }  #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/stat.h b/arch/riscv64/bits/stat.h deleted file mode 100644 index b7f4221b..00000000 --- a/arch/riscv64/bits/stat.h +++ /dev/null @@ -1,18 +0,0 @@ -struct stat { -	dev_t st_dev; -	ino_t st_ino; -	mode_t st_mode; -	nlink_t st_nlink; -	uid_t st_uid; -	gid_t st_gid; -	dev_t st_rdev; -	unsigned long __pad; -	off_t st_size; -	blksize_t st_blksize; -	int __pad2; -	blkcnt_t st_blocks; -	struct timespec st_atim; -	struct timespec st_mtim; -	struct timespec st_ctim; -	unsigned __unused[2]; -}; diff --git a/arch/riscv64/bits/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" @@ -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} @@ -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..d6ae539a 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 @@ -1027,6 +1040,8 @@ typedef struct {  #define AT_RANDOM	25  #define AT_HWCAP2	26 +#define AT_HWCAP3	29 +#define AT_HWCAP4	30  #define AT_EXECFN	31 @@ -3249,6 +3264,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 +3291,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 +3303,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/netinet/in.h b/include/netinet/in.h index fb628b61..60bbaa75 100644 --- a/include/netinet/in.h +++ b/include/netinet/in.h @@ -132,7 +132,8 @@ uint16_t ntohs(uint16_t);  #define IN6_IS_ADDR_V4COMPAT(a) \          (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \ -         ((uint32_t *) (a))[2] == 0 && ((uint8_t *) (a))[15] > 1) +         ((uint32_t *) (a))[2] == 0 && \ +         !IN6_IS_ADDR_UNSPECIFIED(a) && !IN6_IS_ADDR_LOOPBACK(a))  #define IN6_IS_ADDR_MC_NODELOCAL(a) \          (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x1)) 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 fda4b484..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,15 +115,15 @@ __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 128 +#define CPU_SETSIZE 1024  #define CPU_SET(i, set) CPU_SET_S(i,sizeof(cpu_set_t),set)  #define CPU_CLR(i, set) CPU_CLR_S(i,sizeof(cpu_set_t),set) 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..4f7dc2b1 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,79 @@ 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_SUBVOL 0x8000U +#define STATX_WRITE_ATOMIC 0x10000U + +#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 +#define STATX_ATTR_WRITE_ATOMIC 0x400000 + +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; +	uint32_t stx_atomic_write_unit_min; +	uint32_t stx_atomic_write_unit_max; +	uint32_t stx_atomic_write_segments_max; +	uint32_t __pad1[1]; +	uint64_t __pad2[9]; + +}; + +int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict); +#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/dlstart.c b/ldso/dlstart.c index 259f5e18..4aac42bc 100644 --- a/ldso/dlstart.c +++ b/ldso/dlstart.c @@ -45,7 +45,7 @@ hidden void _dlstart_c(size_t *sp, size_t *dynv)  		/* If dynv is null, the entry point was started from loader  		 * that is not fdpic-aware. We can assume normal fixed-  		 * displacement ELF loading was performed, but when ldso was -		 * run as a command, finding the Ehdr is a heursitic: we +		 * run as a command, finding the Ehdr is a heuristic: we  		 * have to assume Phdrs start in the first 4k of the file. */  		base = aux[AT_BASE];  		if (!base) base = aux[AT_PHDR] & -4096; diff --git a/ldso/dynlink.c b/ldso/dynlink.c index fde5f346..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; @@ -345,7 +349,8 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)  static struct symdef get_lfs64(const char *name)  { -	static const char *p, lfs64_list[] = +	const char *p; +	static const char lfs64_list[] =  		"aio_cancel\0aio_error\0aio_fsync\0aio_read\0aio_return\0"  		"aio_suspend\0aio_write\0alphasort\0creat\0fallocate\0"  		"fgetpos\0fopen\0freopen\0fseeko\0fsetpos\0fstat\0" @@ -357,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: @@ -514,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) { @@ -539,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", @@ -616,6 +616,7 @@ static void reclaim_gaps(struct dso *dso)  	for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) {  		if (ph->p_type!=PT_LOAD) continue;  		if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue; +		if (ph->p_memsz == 0) continue;  		reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);  		reclaim(dso, ph->p_vaddr+ph->p_memsz,  			ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE); @@ -1724,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/include/sys/auxv.h b/src/include/sys/auxv.h index 9358a4a5..63c5bfe9 100644 --- a/src/include/sys/auxv.h +++ b/src/include/sys/auxv.h @@ -5,6 +5,6 @@  #include <features.h> -hidden unsigned long __getauxval(unsigned long); +unsigned long __getauxval(unsigned long);  #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/ipc/semtimedop.c b/src/ipc/semtimedop.c index 1632e7b0..a104af21 100644 --- a/src/ipc/semtimedop.c +++ b/src/ipc/semtimedop.c @@ -7,7 +7,8 @@  #define IS32BIT(x) !((x)+0x80000000ULL>>32)  #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) -#if !defined(SYS_semtimedop) && !defined(SYS_ipc) +#if !defined(SYS_semtimedop) && !defined(SYS_ipc) || \ +	SYS_semtimedop == SYS_semtimedop_time64  #define NO_TIME32 1  #else  #define NO_TIME32 0 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 83650e34..fb08c0d0 100644 --- a/src/linux/wait4.c +++ b/src/linux/wait4.c @@ -12,7 +12,7 @@ pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru)  	if (ru) {  		long long kru64[18];  		r = __syscall(SYS_wait4_time64, pid, status, options, kru64); -		if (!r) { +		if (r > 0) {  			ru->ru_utime = (struct timeval)  				{ .tv_sec = kru64[0], .tv_usec = kru64[1] };  			ru->ru_stime = (struct timeval) @@ -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/getopt.c b/src/misc/getopt.c index c3f66995..b02b81c3 100644 --- a/src/misc/getopt.c +++ b/src/misc/getopt.c @@ -87,7 +87,8 @@ int getopt(int argc, char * const argv[], const char *optstring)  	if (optstring[i] == ':') {  		optarg = 0;  		if (optstring[i+1] != ':' || optpos) { -			optarg = argv[optind++] + optpos; +			optarg = argv[optind++]; +			if (optpos) optarg += optpos;  			optpos = 0;  		}  		if (optind > argc) { 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/nftw.c b/src/misc/nftw.c index fcd25a73..71bc62ee 100644 --- a/src/misc/nftw.c +++ b/src/misc/nftw.c @@ -31,6 +31,8 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int,  	int err;  	struct FTW lev; +	st.st_dev = st.st_ino = 0; +  	if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {  		if (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st))  			type = FTW_SLN; @@ -46,7 +48,7 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int,  		type = FTW_F;  	} -	if ((flags & FTW_MOUNT) && h && st.st_dev != h->dev) +	if ((flags & FTW_MOUNT) && h && type != FTW_NS && st.st_dev != h->dev)  		return 0;  	new.chain = h; 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/accept4.c b/src/network/accept4.c index 59ab1726..765a38ed 100644 --- a/src/network/accept4.c +++ b/src/network/accept4.c @@ -9,6 +9,10 @@ int accept4(int fd, struct sockaddr *restrict addr, socklen_t *restrict len, int  	if (!flg) return accept(fd, addr, len);  	int ret = socketcall_cp(accept4, fd, addr, len, flg, 0, 0);  	if (ret>=0 || (errno != ENOSYS && errno != EINVAL)) return ret; +	if (flg & ~(SOCK_CLOEXEC|SOCK_NONBLOCK)) { +		errno = EINVAL; +		return -1; +	}  	ret = accept(fd, addr, len);  	if (ret<0) return ret;  	if (flg & SOCK_CLOEXEC) diff --git a/src/network/dns_parse.c b/src/network/dns_parse.c index e6ee19d9..09813112 100644 --- a/src/network/dns_parse.c +++ b/src/network/dns_parse.c @@ -1,7 +1,7 @@  #include <string.h>  #include "lookup.h" -int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, const void *, int, const void *), void *ctx) +int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, const void *, int, const void *, int), void *ctx)  {  	int qdcount, ancount;  	const unsigned char *p; @@ -12,21 +12,20 @@ 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>193 || (*p==193 && p[1]>254) || p>r+rlen-6) +		if (p>r+rlen-6)  			return -1;  		p += 5 + !!*p;  	}  	while (ancount--) {  		while (p-r < rlen && *p-1U < 127) p++; -		if (*p>193 || (*p==193 && p[1]>254) || p>r+rlen-6) +		if (p>r+rlen-12)  			return -1;  		p += 1 + !!*p;  		len = p[8]*256 + p[9]; -		if (p+len > r+rlen) return -1; -		if (callback(ctx, p[1], p+10, len, r) < 0) return -1; +		if (len+10 > r+rlen-p) return -1; +		if (callback(ctx, p[1], p+10, len, r, rlen) < 0) return -1;  		p += 10 + len;  	}  	return 0; diff --git a/src/network/getifaddrs.c b/src/network/getifaddrs.c index fed75bd8..74df4d6c 100644 --- a/src/network/getifaddrs.c +++ b/src/network/getifaddrs.c @@ -39,8 +39,8 @@ struct ifaddrs_storage {  };  struct ifaddrs_ctx { -	struct ifaddrs_storage *first; -	struct ifaddrs_storage *last; +	struct ifaddrs *first; +	struct ifaddrs *last;  	struct ifaddrs_storage *hash[IFADDRS_HASH_SIZE];  }; @@ -195,9 +195,9 @@ static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h)  	}  	if (ifs->ifa.ifa_name) { -		if (!ctx->first) ctx->first = ifs; -		if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa; -		ctx->last = ifs; +		if (!ctx->first) ctx->first = &ifs->ifa; +		if (ctx->last) ctx->last->ifa_next = &ifs->ifa; +		ctx->last = &ifs->ifa;  	} else {  		free(ifs);  	} @@ -210,7 +210,7 @@ int getifaddrs(struct ifaddrs **ifap)  	int r;  	memset(ctx, 0, sizeof *ctx);  	r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx); -	if (r == 0) *ifap = &ctx->first->ifa; -	else freeifaddrs(&ctx->first->ifa); +	if (r == 0) *ifap = ctx->first; +	else freeifaddrs(ctx->first);  	return r;  } diff --git a/src/network/getnameinfo.c b/src/network/getnameinfo.c index 949e1811..133c15b3 100644 --- a/src/network/getnameinfo.c +++ b/src/network/getnameinfo.c @@ -58,6 +58,7 @@ static void reverse_hosts(char *buf, const unsigned char *a, unsigned scopeid, i  		if ((p=strchr(line, '#'))) *p++='\n', *p=0;  		for (p=line; *p && !isspace(*p); p++); +		if (!*p) continue;  		*p++ = 0;  		if (__lookup_ipliteral(&iplit, line, AF_UNSPEC)<=0)  			continue; @@ -108,10 +109,10 @@ static void reverse_services(char *buf, int port, int dgram)  	__fclose_ca(f);  } -static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet) +static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet, int plen)  {  	if (rr != RR_PTR) return 0; -	if (__dn_expand(packet, (const unsigned char *)packet + 512, +	if (__dn_expand(packet, (const unsigned char *)packet + plen,  	    data, c, 256) <= 0)  		*(char *)c = 0;  	return 0; @@ -161,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/getservbyport_r.c b/src/network/getservbyport_r.c index b7f21c6b..e4cc3079 100644 --- a/src/network/getservbyport_r.c +++ b/src/network/getservbyport_r.c @@ -26,7 +26,7 @@ int getservbyport_r(int port, const char *prots,  	/* Align buffer */  	i = (uintptr_t)buf & sizeof(char *)-1;  	if (!i) i = sizeof(char *); -	if (buflen < 3*sizeof(char *)-i) +	if (buflen <= 3*sizeof(char *)-i)  		return ERANGE;  	buf += sizeof(char *)-i;  	buflen -= sizeof(char *)-i; @@ -46,6 +46,8 @@ int getservbyport_r(int port, const char *prots,  	case EAI_MEMORY:  	case EAI_SYSTEM:  		return ENOMEM; +	case EAI_OVERFLOW: +		return ERANGE;  	default:  		return ENOENT;  	case 0: 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.h b/src/network/lookup.h index ef662725..54b2f8b5 100644 --- a/src/network/lookup.h +++ b/src/network/lookup.h @@ -50,6 +50,6 @@ hidden int __lookup_ipliteral(struct address buf[static 1], const char *name, in  hidden int __get_resolv_conf(struct resolvconf *, char *, size_t);  hidden int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *); -hidden int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *); +hidden int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *, int), void *);  #endif diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c index 5f6867cb..35218185 100644 --- a/src/network/lookup_name.c +++ b/src/network/lookup_name.c @@ -109,15 +109,15 @@ 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) +static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet, int plen)  {  	char tmp[256];  	int family;  	struct dpc_ctx *ctx = c;  	if (rr == RR_CNAME) { -		if (__dn_expand(packet, (const unsigned char *)packet + ABUF_SIZE, +		if (__dn_expand(packet, (const unsigned char *)packet + plen,  		    data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))  			strcpy(ctx->canon, tmp);  		return 0; @@ -179,6 +179,7 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static  	for (i=nq-1; i>=0; i--) {  		ctx.rrtype = qtypes[i]; +		if (alens[i] > sizeof(abuf[i])) alens[i] = sizeof abuf[i];  		__dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);  	} diff --git a/src/network/res_msend.c b/src/network/res_msend.c index 11c6aa0e..fcb52513 100644 --- a/src/network/res_msend.c +++ b/src/network/res_msend.c @@ -25,7 +25,8 @@ static void cleanup(void *p)  static unsigned long mtime()  {  	struct timespec ts; -	clock_gettime(CLOCK_REALTIME, &ts); +	if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0 && errno == ENOSYS) +		clock_gettime(CLOCK_REALTIME, &ts);  	return (unsigned long)ts.tv_sec * 1000  		+ ts.tv_nsec / 1000000;  } @@ -82,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; @@ -132,6 +133,22 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,  		family = AF_INET;  		sl = sizeof sa.sin;  	} + +	/* Convert any IPv4 addresses in a mixed environment to v4-mapped */ +	if (fd >= 0 && family == AF_INET6) { +		setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0); +		for (i=0; i<nns; i++) { +			if (ns[i].sin.sin_family != AF_INET) continue; +			memcpy(ns[i].sin6.sin6_addr.s6_addr+12, +				&ns[i].sin.sin_addr, 4); +			memcpy(ns[i].sin6.sin6_addr.s6_addr, +				"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); +			ns[i].sin6.sin6_family = AF_INET6; +			ns[i].sin6.sin6_flowinfo = 0; +			ns[i].sin6.sin6_scope_id = 0; +		} +	} +  	sa.sin.sin_family = family;  	if (fd < 0 || bind(fd, (void *)&sa, sl) < 0) {  		if (fd >= 0) close(fd); @@ -151,21 +168,6 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,  	pthread_cleanup_push(cleanup, pfd);  	pthread_setcancelstate(cs, 0); -	/* Convert any IPv4 addresses in a mixed environment to v4-mapped */ -	if (family == AF_INET6) { -		setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0); -		for (i=0; i<nns; i++) { -			if (ns[i].sin.sin_family != AF_INET) continue; -			memcpy(ns[i].sin6.sin6_addr.s6_addr+12, -				&ns[i].sin.sin_addr, 4); -			memcpy(ns[i].sin6.sin6_addr.s6_addr, -				"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); -			ns[i].sin6.sin6_family = AF_INET6; -			ns[i].sin6.sin6_flowinfo = 0; -			ns[i].sin6.sin6_scope_id = 0; -		} -	} -  	memset(alens, 0, sizeof *alens * nqueries);  	retry_interval = timeout / attempts; @@ -286,7 +288,7 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,  			};  			step_mh(&mh, apos[i]);  			r = recvmsg(pfd[i].fd, &mh, 0); -			if (r < 0) goto out; +			if (r <= 0) goto out;  			apos[i] += r;  			if (apos[i] < 2) continue;  			int alen = alen_buf[i][0]*256 + alen_buf[i][1]; 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/select/poll.c b/src/select/poll.c index c84c8a99..7883dfab 100644 --- a/src/select/poll.c +++ b/src/select/poll.c @@ -8,8 +8,13 @@ int poll(struct pollfd *fds, nfds_t n, int timeout)  #ifdef SYS_poll  	return syscall_cp(SYS_poll, fds, n, timeout);  #else +#if SYS_ppoll_time64 == SYS_ppoll +	typedef long long ppoll_ts_t[2]; +#else +	typedef long ppoll_ts_t[2]; +#endif  	return syscall_cp(SYS_ppoll, fds, n, timeout>=0 ? -		&((struct timespec){ .tv_sec = timeout/1000, -		.tv_nsec = timeout%1000*1000000 }) : 0, 0, _NSIG/8); +		((ppoll_ts_t){ timeout/1000, timeout%1000*1000000 }) : 0, +		0, _NSIG/8);  #endif  } 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/select/select.c b/src/select/select.c index 8a786884..f1d72863 100644 --- a/src/select/select.c +++ b/src/select/select.c @@ -33,6 +33,7 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict  			((syscall_arg_t[]){ 0, _NSIG/8 }));  	if (SYS_pselect6 == SYS_pselect6_time64 || r!=-ENOSYS)  		return __syscall_ret(r); +	s = CLAMP(s);  #endif  #ifdef SYS_select  	return syscall_cp(SYS_select, n, rfds, wfds, efds, 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..b4e5458d --- /dev/null +++ b/src/setjmp/riscv32/longjmp.S @@ -0,0 +1,48 @@ +.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 +#ifdef __riscv_float_abi_double +#define FLX fld +#else +#define FLX flw +#endif + +	FLX fs0,  56(a0) +	FLX fs1,  64(a0) +	FLX fs2,  72(a0) +	FLX fs3,  80(a0) +	FLX fs4,  88(a0) +	FLX fs5,  96(a0) +	FLX fs6,  104(a0) +	FLX fs7,  112(a0) +	FLX fs8,  120(a0) +	FLX fs9,  128(a0) +	FLX fs10, 136(a0) +	FLX fs11, 144(a0) +#endif + +	seqz a0, a1 +	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..5a1a41ef --- /dev/null +++ b/src/setjmp/riscv32/setjmp.S @@ -0,0 +1,47 @@ +.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 +#ifdef __riscv_float_abi_double +#define FSX fsd +#else +#define FSX fsw +#endif + +	FSX fs0,  56(a0) +	FSX fs1,  64(a0) +	FSX fs2,  72(a0) +	FSX fs3,  80(a0) +	FSX fs4,  88(a0) +	FSX fs5,  96(a0) +	FSX fs6,  104(a0) +	FSX fs7,  112(a0) +	FSX fs8,  120(a0) +	FSX fs9,  128(a0) +	FSX fs10, 136(a0) +	FSX fs11, 144(a0) +#endif + +	li a0, 0 +	ret diff --git a/src/setjmp/riscv64/longjmp.S b/src/setjmp/riscv64/longjmp.S index 41e2d210..982475c7 100644 --- a/src/setjmp/riscv64/longjmp.S +++ b/src/setjmp/riscv64/longjmp.S @@ -23,18 +23,24 @@ longjmp:  	ld ra,    104(a0)  #ifndef __riscv_float_abi_soft -	fld fs0,  112(a0) -	fld fs1,  120(a0) -	fld fs2,  128(a0) -	fld fs3,  136(a0) -	fld fs4,  144(a0) -	fld fs5,  152(a0) -	fld fs6,  160(a0) -	fld fs7,  168(a0) -	fld fs8,  176(a0) -	fld fs9,  184(a0) -	fld fs10, 192(a0) -	fld fs11, 200(a0) +#ifdef __riscv_float_abi_double +#define FLX fld +#else +#define FLX flw +#endif + +	FLX fs0,  112(a0) +	FLX fs1,  120(a0) +	FLX fs2,  128(a0) +	FLX fs3,  136(a0) +	FLX fs4,  144(a0) +	FLX fs5,  152(a0) +	FLX fs6,  160(a0) +	FLX fs7,  168(a0) +	FLX fs8,  176(a0) +	FLX fs9,  184(a0) +	FLX fs10, 192(a0) +	FLX fs11, 200(a0)  #endif  	seqz a0, a1 diff --git a/src/setjmp/riscv64/setjmp.S b/src/setjmp/riscv64/setjmp.S index 51249672..0795bf7d 100644 --- a/src/setjmp/riscv64/setjmp.S +++ b/src/setjmp/riscv64/setjmp.S @@ -23,18 +23,24 @@ setjmp:  	sd ra,    104(a0)  #ifndef __riscv_float_abi_soft -	fsd fs0,  112(a0) -	fsd fs1,  120(a0) -	fsd fs2,  128(a0) -	fsd fs3,  136(a0) -	fsd fs4,  144(a0) -	fsd fs5,  152(a0) -	fsd fs6,  160(a0) -	fsd fs7,  168(a0) -	fsd fs8,  176(a0) -	fsd fs9,  184(a0) -	fsd fs10, 192(a0) -	fsd fs11, 200(a0) +#ifdef __riscv_float_abi_double +#define FSX fsd +#else +#define FSX fsw +#endif + +	FSX fs0,  112(a0) +	FSX fs1,  120(a0) +	FSX fs2,  128(a0) +	FSX fs3,  136(a0) +	FSX fs4,  144(a0) +	FSX fs5,  152(a0) +	FSX fs6,  160(a0) +	FSX fs7,  168(a0) +	FSX fs8,  176(a0) +	FSX fs9,  184(a0) +	FSX fs10, 192(a0) +	FSX fs11, 200(a0)  #endif  	li a0, 0 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 45557951..514a44dd 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, @@ -132,7 +132,7 @@ static void pop_arg(union arg *arg, int type, va_list *ap)  static void out(FILE *f, const char *s, size_t l)  { -	if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f); +	if (!ferror(f)) __fwritex((void *)s, l, f);  }  static void pad(FILE *f, char c, int w, int l, int fl) @@ -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,16 @@ 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 max_mant_dig = (ps==BIGLPRE) ? LDBL_MANT_DIG : DBL_MANT_DIG; +	int max_exp = (ps==BIGLPRE) ? LDBL_MAX_EXP : DBL_MAX_EXP; +	/* One slot for 29 bits left of radix point, a slot for every 29-21=8 +	 * bits right of the radix point, and one final zero slot. */ +	int max_mant_slots = 1 + (max_mant_dig-29+7)/8 + 1; +	int max_exp_slots = (max_exp+max_mant_dig+28+8)/9; +	int bufsize = max_mant_slots + max_exp_slots; +	uint32_t big[bufsize];  	uint32_t *a, *d, *r, *z;  	int e2=0, e, i, j, l;  	char buf[9+LDBL_MANT_DIG/4], *s; @@ -211,18 +218,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; @@ -268,7 +268,7 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)  	if (y) y *= 0x1p28, e2-=28;  	if (e2<0) a=r=z=big; -	else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; +	else a=r=z=big+sizeof(big)/sizeof(*big) - max_mant_slots - 1;  	do {  		*z = y; @@ -437,7 +437,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; @@ -530,6 +530,9 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,  		if (!f) continue; +		/* Do not process any new directives once in error state. */ +		if (ferror(f)) return -1; +  		z = buf + sizeof(buf);  		prefix = "-+   0X0x";  		pl = 0; @@ -560,11 +563,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) { @@ -576,7 +579,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) { @@ -585,6 +588,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; @@ -599,6 +603,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; @@ -619,7 +624,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;  		} @@ -674,7 +679,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)  	FLOCK(f);  	olderr = f->flags & F_ERR; -	if (f->mode < 1) f->flags &= ~F_ERR; +	f->flags &= ~F_ERR;  	if (!f->buf_size) {  		saved_buf = f->buf;  		f->buf = internal_buf; @@ -690,7 +695,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)  		f->buf_size = 0;  		f->wpos = f->wbase = f->wend = 0;  	} -	if (f->flags & F_ERR) ret = -1; +	if (ferror(f)) ret = -1;  	f->flags |= olderr;  	FUNLOCK(f);  	va_end(ap2); diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c index 85b036c3..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, @@ -125,7 +125,13 @@ static void pop_arg(union arg *arg, int type, va_list *ap)  static void out(FILE *f, const wchar_t *s, size_t l)  { -	while (l-- && !(f->flags & F_ERR)) fputwc(*s++, f); +	while (l-- && !ferror(f)) fputwc(*s++, f); +} + +static void pad(FILE *f, int n, int fl) +{ +	if ((fl & LEFT_ADJ) || !n || ferror(f)) return; +	fprintf(f, "%*s", n, "");  }  static int getint(wchar_t **s) { @@ -242,6 +248,10 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_  		}  		if (!f) continue; + +		/* Do not process any new directives once in error state. */ +		if (ferror(f)) return -1; +  		t = s[-1];  		if (ps && (t&15)==3) t&=~32; @@ -258,25 +268,22 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_  			}  			continue;  		case 'c': +		case 'C':  			if (w<1) w=1; -			if (w>1 && !(fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, ""); -			fputwc(btowc(arg.i), f); -			if (w>1 && (fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, ""); +			pad(f, w-1, fl); +			out(f, &(wchar_t){t=='C' ? arg.i : btowc(arg.i)}, 1); +			pad(f, w-1, fl^LEFT_ADJ);  			l = w;  			continue; -		case 'C': -			fputwc(arg.i, f); -			l = 1; -			continue;  		case 'S':  			a = arg.p;  			z = a + wcsnlen(a, p<0 ? INT_MAX : p);  			if (p<0 && *z) goto overflow;  			p = z-a;  			if (w<p) w=p; -			if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, ""); +			pad(f, w-p, fl);  			out(f, a, p); -			if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, ""); +			pad(f, w-p, fl^LEFT_ADJ);  			l=w;  			continue;  		case 'm': @@ -289,14 +296,14 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_  			if (p<0 && *bs) goto overflow;  			p=l;  			if (w<p) w=p; -			if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, ""); +			pad(f, w-p, fl);  			bs = arg.p;  			while (l--) {  				i=mbtowc(&wc, bs, MB_LEN_MAX);  				bs+=i; -				fputwc(wc, f); +				out(f, &wc, 1);  			} -			if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, ""); +			pad(f, w-p, fl^LEFT_ADJ);  			l=w;  			continue;  		} @@ -340,8 +347,8 @@ overflow:  int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)  {  	va_list ap2; -	int nl_type[NL_ARGMAX] = {0}; -	union arg nl_arg[NL_ARGMAX]; +	int nl_type[NL_ARGMAX+1] = {0}; +	union arg nl_arg[NL_ARGMAX+1];  	int olderr;  	int ret; @@ -357,7 +364,7 @@ int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)  	olderr = f->flags & F_ERR;  	f->flags &= ~F_ERR;  	ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type); -	if (f->flags & F_ERR) ret = -1; +	if (ferror(f)) ret = -1;  	f->flags |= olderr;  	FUNLOCK(f);  	va_end(ap2); 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 7f98c5c9..5e9a4dad 100644 --- a/src/stdio/vswprintf.c +++ b/src/stdio/vswprintf.c @@ -18,6 +18,7 @@ static size_t sw_write(FILE *f, const unsigned char *s, size_t l)  	if (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1)  		return -1;  	while (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) { +		if (!i) i=1;  		s+=i;  		l-=i;  		c->l--; @@ -50,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/string/wmemcmp.c b/src/string/wmemcmp.c index 2a193263..717d77b1 100644 --- a/src/string/wmemcmp.c +++ b/src/string/wmemcmp.c @@ -3,5 +3,5 @@  int wmemcmp(const wchar_t *l, const wchar_t *r, size_t n)  {  	for (; n && *l==*r; n--, l++, r++); -	return n ? *l-*r : 0; +	return n ? (*l < *r ? -1 : *l > *r) : 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/__set_thread_area.c b/src/thread/aarch64/__set_thread_area.c new file mode 100644 index 00000000..2ec788e8 --- /dev/null +++ b/src/thread/aarch64/__set_thread_area.c @@ -0,0 +1,27 @@ +#include <elf.h> +#include "libc.h" + +#define BITRANGE(a,b) (2*(1UL<<(b))-(1UL<<(a))) + +int __set_thread_area(void *p) +{ +	__asm__ __volatile__ ("msr tpidr_el0,%0" : : "r"(p) : "memory"); + +	/* Mask off hwcap bits for SME and unknown future features. This is +	 * necessary because SME is not safe to use without libc support for +	 * it, and we do not (yet) have such support. */ +	for (size_t *v = libc.auxv; *v; v+=2) { +		if (v[0]==AT_HWCAP) { +			v[1] &= ~BITRANGE(42,63); /* 42-47 are SME */ +		} else if (v[0]==AT_HWCAP2) { +			v[1] &= ~(BITRANGE(23,30) +			        | BITRANGE(37,42) +			        | BITRANGE(57,62)); +		} else if (v[0]==AT_HWCAP3 || v[0]==AT_HWCAP4) { +			v[0] = AT_IGNORE; +			v[1] = 0; +		} +	} + +	return 0; +} diff --git a/src/thread/aarch64/clone.s b/src/thread/aarch64/clone.s index e3c83395..aff8155b 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 x29, 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/aarch64/__set_thread_area.s b/src/thread/loongarch64/__set_thread_area.s index fd0df34b..021307fc 100644 --- a/src/thread/aarch64/__set_thread_area.s +++ b/src/thread/loongarch64/__set_thread_area.s @@ -2,6 +2,6 @@  .hidden __set_thread_area  .type   __set_thread_area,@function  __set_thread_area: -	msr tpidr_el0,x0 -	mov w0,#0 -	ret +	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..056c9110 100644 --- a/src/thread/s390x/__tls_get_offset.s +++ b/src/thread/s390x/__tls_get_offset.s @@ -1,17 +1,17 @@  	.global __tls_get_offset  	.type __tls_get_offset,%function  __tls_get_offset: -	stmg  %r14, %r15, 112(%r15) -	aghi  %r15, -160 +	ear   %r3, %a0 +	sllg  %r3, %r3, 32 +	ear   %r3, %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    %r0, 0(%r1) +	sllg  %r4, %r0, 3 +	lg    %r5, 8(%r3) +	lg    %r2, 0(%r4, %r5) +	ag    %r2, 8(%r1) +	sgr   %r2, %r3 -	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/dup3.c b/src/unistd/dup3.c index f919f791..40798bde 100644 --- a/src/unistd/dup3.c +++ b/src/unistd/dup3.c @@ -9,12 +9,14 @@ int __dup3(int old, int new, int flags)  	int r;  #ifdef SYS_dup2  	if (old==new) return __syscall_ret(-EINVAL); -	if (flags & O_CLOEXEC) { +	if (flags) {  		while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);  		if (r!=-ENOSYS) return __syscall_ret(r); +		if (flags & ~O_CLOEXEC) return __syscall_ret(-EINVAL);  	}  	while ((r=__syscall(SYS_dup2, old, new))==-EBUSY); -	if (flags & O_CLOEXEC) __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC); +	if (r >= 0 && (flags & O_CLOEXEC)) +		__syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);  #else  	while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);  #endif 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/pipe2.c b/src/unistd/pipe2.c index f24f74fb..a096990b 100644 --- a/src/unistd/pipe2.c +++ b/src/unistd/pipe2.c @@ -8,6 +8,7 @@ int pipe2(int fd[2], int flag)  	if (!flag) return pipe(fd);  	int ret = __syscall(SYS_pipe2, fd, flag);  	if (ret != -ENOSYS) return __syscall_ret(ret); +	if (flag & ~(O_CLOEXEC|O_NONBLOCK)) return __syscall_ret(-EINVAL);  	ret = pipe(fd);  	if (ret) return ret;  	if (flag & O_CLOEXEC) { 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"  | 
