diff options
Diffstat (limited to 'system/musl/amalgamation.patch')
-rw-r--r-- | system/musl/amalgamation.patch | 6528 |
1 files changed, 10 insertions, 6518 deletions
diff --git a/system/musl/amalgamation.patch b/system/musl/amalgamation.patch index 96dd545d9..d4d4465dc 100644 --- a/system/musl/amalgamation.patch +++ b/system/musl/amalgamation.patch @@ -1,2702 +1,3 @@ -diff --git a/Makefile b/Makefile -index 308ddaae..e23a8332 100644 ---- a/Makefile -+++ b/Makefile -@@ -116,17 +116,14 @@ obj/crt/Scrt1.o obj/crt/rcrt1.o: CFLAGS_ALL += -fPIC - OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=$(srcdir)/src/%)) - $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.lo): CFLAGS += -O3 - --MEMOPS_SRCS = src/string/memcpy.c src/string/memmove.c src/string/memcmp.c src/string/memset.c --$(MEMOPS_SRCS:%.c=obj/%.o) $(MEMOPS_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS) -- --NOSSP_SRCS = $(wildcard crt/*.c) \ -- src/env/__libc_start_main.c src/env/__init_tls.c \ -- src/env/__stack_chk_fail.c \ -- src/thread/__set_thread_area.c src/thread/$(ARCH)/__set_thread_area.c \ -- src/string/memset.c src/string/$(ARCH)/memset.c \ -- src/string/memcpy.c src/string/$(ARCH)/memcpy.c \ -- ldso/dlstart.c ldso/dynlink.c --$(NOSSP_SRCS:%.c=obj/%.o) $(NOSSP_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP) -+MEMOPS_OBJS = $(filter %/memcpy.o %/memmove.o %/memcmp.o %/memset.o, $(LIBC_OBJS)) -+$(MEMOPS_OBJS) $(MEMOPS_OBJS:%.o=%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS) -+ -+NOSSP_OBJS = $(CRT_OBJS) $(LDSO_OBJS) $(filter \ -+ %/__libc_start_main.o %/__init_tls.o %/__stack_chk_fail.o \ -+ %/__set_thread_area.o %/memset.o %/memcpy.o \ -+ , $(LIBC_OBJS)) -+$(NOSSP_OBJS) $(NOSSP_OBJS:%.o=%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP) - - $(CRT_OBJS): CFLAGS_ALL += -DCRT - -diff --git a/arch/aarch64/bits/hwcap.h b/arch/aarch64/bits/hwcap.h -index 11396d31..8541e329 100644 ---- a/arch/aarch64/bits/hwcap.h -+++ b/arch/aarch64/bits/hwcap.h -@@ -14,3 +14,15 @@ - #define HWCAP_JSCVT (1 << 13) - #define HWCAP_FCMA (1 << 14) - #define HWCAP_LRCPC (1 << 15) -+#define HWCAP_DCPOP (1 << 16) -+#define HWCAP_SHA3 (1 << 17) -+#define HWCAP_SM3 (1 << 18) -+#define HWCAP_SM4 (1 << 19) -+#define HWCAP_ASIMDDP (1 << 20) -+#define HWCAP_SHA512 (1 << 21) -+#define HWCAP_SVE (1 << 22) -+#define HWCAP_ASIMDFHM (1 << 23) -+#define HWCAP_DIT (1 << 24) -+#define HWCAP_USCAT (1 << 25) -+#define HWCAP_ILRCPC (1 << 26) -+#define HWCAP_FLAGM (1 << 27) -diff --git a/arch/aarch64/bits/signal.h b/arch/aarch64/bits/signal.h -index 1c67313d..b71261f5 100644 ---- a/arch/aarch64/bits/signal.h -+++ b/arch/aarch64/bits/signal.h -@@ -25,6 +25,7 @@ typedef struct sigcontext { - #define FPSIMD_MAGIC 0x46508001 - #define ESR_MAGIC 0x45535201 - #define EXTRA_MAGIC 0x45585401 -+#define SVE_MAGIC 0x53564501 - struct _aarch64_ctx { - unsigned int magic; - unsigned int size; -@@ -45,6 +46,44 @@ struct extra_context { - unsigned int size; - unsigned int __reserved[3]; - }; -+struct sve_context { -+ struct _aarch64_ctx head; -+ unsigned short vl; -+ unsigned short __reserved[3]; -+}; -+#define SVE_VQ_BYTES 16 -+#define SVE_VQ_MIN 1 -+#define SVE_VQ_MAX 512 -+#define SVE_VL_MIN (SVE_VQ_MIN * SVE_VQ_BYTES) -+#define SVE_VL_MAX (SVE_VQ_MAX * SVE_VQ_BYTES) -+#define SVE_NUM_ZREGS 32 -+#define SVE_NUM_PREGS 16 -+#define sve_vl_valid(vl) \ -+ ((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX) -+#define sve_vq_from_vl(vl) ((vl) / SVE_VQ_BYTES) -+#define sve_vl_from_vq(vq) ((vq) * SVE_VQ_BYTES) -+#define SVE_SIG_ZREG_SIZE(vq) ((unsigned)(vq) * SVE_VQ_BYTES) -+#define SVE_SIG_PREG_SIZE(vq) ((unsigned)(vq) * (SVE_VQ_BYTES / 8)) -+#define SVE_SIG_FFR_SIZE(vq) SVE_SIG_PREG_SIZE(vq) -+#define SVE_SIG_REGS_OFFSET \ -+ ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1)) \ -+ / SVE_VQ_BYTES * SVE_VQ_BYTES) -+#define SVE_SIG_ZREGS_OFFSET SVE_SIG_REGS_OFFSET -+#define SVE_SIG_ZREG_OFFSET(vq, n) \ -+ (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREG_SIZE(vq) * (n)) -+#define SVE_SIG_ZREGS_SIZE(vq) \ -+ (SVE_SIG_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_SIG_ZREGS_OFFSET) -+#define SVE_SIG_PREGS_OFFSET(vq) \ -+ (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREGS_SIZE(vq)) -+#define SVE_SIG_PREG_OFFSET(vq, n) \ -+ (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREG_SIZE(vq) * (n)) -+#define SVE_SIG_PREGS_SIZE(vq) \ -+ (SVE_SIG_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_SIG_PREGS_OFFSET(vq)) -+#define SVE_SIG_FFR_OFFSET(vq) \ -+ (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREGS_SIZE(vq)) -+#define SVE_SIG_REGS_SIZE(vq) \ -+ (SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET) -+#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq)) - #else - typedef struct { - long double __regs[18+256]; -diff --git a/arch/aarch64/pthread_arch.h b/arch/aarch64/pthread_arch.h -index b2e2d8f1..e8499d8e 100644 ---- a/arch/aarch64/pthread_arch.h -+++ b/arch/aarch64/pthread_arch.h -@@ -2,10 +2,11 @@ static inline struct pthread *__pthread_self() - { - char *self; - __asm__ __volatile__ ("mrs %0,tpidr_el0" : "=r"(self)); -- return (void*)(self + 16 - sizeof(struct pthread)); -+ return (void*)(self - sizeof(struct pthread)); - } - - #define TLS_ABOVE_TP --#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 16) -+#define GAP_ABOVE_TP 16 -+#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread)) - - #define MC_PC pc -diff --git a/arch/aarch64/reloc.h b/arch/aarch64/reloc.h -index 51b66e23..40cf0b28 100644 ---- a/arch/aarch64/reloc.h -+++ b/arch/aarch64/reloc.h -@@ -10,7 +10,7 @@ - - #define NO_LEGACY_INITFINI - --#define TPOFF_K 16 -+#define TPOFF_K 0 - - #define REL_SYMBOLIC R_AARCH64_ABS64 - #define REL_GOT R_AARCH64_GLOB_DAT -diff --git a/arch/arm/atomic_arch.h b/arch/arm/atomic_arch.h -index c5c56f81..62458b45 100644 ---- a/arch/arm/atomic_arch.h -+++ b/arch/arm/atomic_arch.h -@@ -7,8 +7,8 @@ - extern uintptr_t __attribute__((__visibility__("hidden"))) - __a_cas_ptr, __a_barrier_ptr; - --#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__) && !__thumb__) \ -- || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 -+#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \ -+ || __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 - - #define a_ll a_ll - static inline int a_ll(volatile int *p) -@@ -91,4 +91,16 @@ static inline int a_clz_32(uint32_t x) - return x; - } - -+#if __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 -+ -+#define a_ctz_32 a_ctz_32 -+static inline int a_ctz_32(uint32_t x) -+{ -+ uint32_t xr; -+ __asm__ ("rbit %0, %1" : "=r"(xr) : "r"(x)); -+ return a_clz_32(xr); -+} -+ -+#endif -+ - #endif -diff --git a/arch/arm/bits/syscall.h.in b/arch/arm/bits/syscall.h.in -index c594152e..1920516a 100644 ---- a/arch/arm/bits/syscall.h.in -+++ b/arch/arm/bits/syscall.h.in -@@ -359,4 +359,5 @@ - #define __ARM_NR_usr26 0x0f0003 - #define __ARM_NR_usr32 0x0f0004 - #define __ARM_NR_set_tls 0x0f0005 -+#define __ARM_NR_get_tls 0x0f0006 - -diff --git a/arch/arm/pthread_arch.h b/arch/arm/pthread_arch.h -index 197752ef..8f2ae8f8 100644 ---- a/arch/arm/pthread_arch.h -+++ b/arch/arm/pthread_arch.h -@@ -1,11 +1,11 @@ --#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6ZK__) && !__thumb__) \ -+#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \ - || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 - - static inline pthread_t __pthread_self() - { - char *p; - __asm__ __volatile__ ( "mrc p15,0,%0,c13,c0,3" : "=r"(p) ); -- return (void *)(p+8-sizeof(struct pthread)); -+ return (void *)(p-sizeof(struct pthread)); - } - - #else -@@ -21,12 +21,13 @@ static inline pthread_t __pthread_self() - extern uintptr_t __attribute__((__visibility__("hidden"))) __a_gettp_ptr; - register uintptr_t p __asm__("r0"); - __asm__ __volatile__ ( BLX " %1" : "=r"(p) : "r"(__a_gettp_ptr) : "cc", "lr" ); -- return (void *)(p+8-sizeof(struct pthread)); -+ return (void *)(p-sizeof(struct pthread)); - } - - #endif - - #define TLS_ABOVE_TP --#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8) -+#define GAP_ABOVE_TP 8 -+#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread)) - - #define MC_PC arm_pc -diff --git a/arch/arm/reloc.h b/arch/arm/reloc.h -index b175711d..4b00bf64 100644 ---- a/arch/arm/reloc.h -+++ b/arch/arm/reloc.h -@@ -16,7 +16,7 @@ - - #define NO_LEGACY_INITFINI - --#define TPOFF_K 8 -+#define TPOFF_K 0 - - #define REL_SYMBOLIC R_ARM_ABS32 - #define REL_GOT R_ARM_GLOB_DAT -diff --git a/arch/arm/syscall_arch.h b/arch/arm/syscall_arch.h -index 6023303b..53fb155c 100644 ---- a/arch/arm/syscall_arch.h -+++ b/arch/arm/syscall_arch.h -@@ -3,74 +3,99 @@ - ((union { long long ll; long l[2]; }){ .ll = x }).l[1] - #define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x)) - -+#ifdef __thumb__ -+ -+/* Avoid use of r7 in asm constraints when producing thumb code, -+ * since it's reserved as frame pointer and might not be supported. */ -+#define __ASM____R7__ -+#define __asm_syscall(...) do { \ -+ __asm__ __volatile__ ( "mov %1,r7 ; mov r7,%2 ; svc 0 ; mov r7,%1" \ -+ : "=r"(r0), "=&r"((int){0}) : __VA_ARGS__ : "memory"); \ -+ return r0; \ -+ } while (0) -+ -+#else -+ -+#define __ASM____R7__ __asm__("r7") - #define __asm_syscall(...) do { \ - __asm__ __volatile__ ( "svc 0" \ - : "=r"(r0) : __VA_ARGS__ : "memory"); \ - return r0; \ - } while (0) -+#endif -+ -+/* For thumb2, we can allow 8-bit immediate syscall numbers, saving a -+ * register in the above dance around r7. Does not work for thumb1 where -+ * only movs, not mov, supports immediates, and we can't use movs because -+ * it doesn't support high regs. */ -+#ifdef __thumb2__ -+#define R7_OPERAND "rI"(r7) -+#else -+#define R7_OPERAND "r"(r7) -+#endif - - static inline long __syscall0(long n) - { -- register long r7 __asm__("r7") = n; -+ register long r7 __ASM____R7__ = n; - register long r0 __asm__("r0"); -- __asm_syscall("r"(r7)); -+ __asm_syscall(R7_OPERAND); - } - - static inline long __syscall1(long n, long a) - { -- register long r7 __asm__("r7") = n; -+ register long r7 __ASM____R7__ = n; - register long r0 __asm__("r0") = a; -- __asm_syscall("r"(r7), "0"(r0)); -+ __asm_syscall(R7_OPERAND, "0"(r0)); - } - - static inline long __syscall2(long n, long a, long b) - { -- register long r7 __asm__("r7") = n; -+ register long r7 __ASM____R7__ = n; - register long r0 __asm__("r0") = a; - register long r1 __asm__("r1") = b; -- __asm_syscall("r"(r7), "0"(r0), "r"(r1)); -+ __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1)); - } - - static inline long __syscall3(long n, long a, long b, long c) - { -- register long r7 __asm__("r7") = n; -+ register long r7 __ASM____R7__ = n; - register long r0 __asm__("r0") = a; - register long r1 __asm__("r1") = b; - register long r2 __asm__("r2") = c; -- __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2)); -+ __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2)); - } - - static inline long __syscall4(long n, long a, long b, long c, long d) - { -- register long r7 __asm__("r7") = n; -+ register long r7 __ASM____R7__ = n; - register long r0 __asm__("r0") = a; - register long r1 __asm__("r1") = b; - register long r2 __asm__("r2") = c; - register long r3 __asm__("r3") = d; -- __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3)); -+ __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3)); - } - - static inline long __syscall5(long n, long a, long b, long c, long d, long e) - { -- register long r7 __asm__("r7") = n; -+ register long r7 __ASM____R7__ = n; - register long r0 __asm__("r0") = a; - register long r1 __asm__("r1") = b; - register long r2 __asm__("r2") = c; - register long r3 __asm__("r3") = d; - register long r4 __asm__("r4") = e; -- __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)); -+ __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)); - } - - static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f) - { -- register long r7 __asm__("r7") = n; -+ register long r7 __ASM____R7__ = n; - register long r0 __asm__("r0") = a; - register long r1 __asm__("r1") = b; - register long r2 __asm__("r2") = c; - register long r3 __asm__("r3") = d; - register long r4 __asm__("r4") = e; - register long r5 __asm__("r5") = f; -- __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)); -+ __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)); - } - - #define VDSO_USEFUL -@@ -78,3 +103,5 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo - #define VDSO_CGT_VER "LINUX_2.6" - - #define SYSCALL_FADVISE_6_ARG -+ -+#define SYSCALL_IPC_BROKEN_MODE -diff --git a/arch/generic/bits/kd.h b/arch/generic/bits/kd.h -new file mode 100644 -index 00000000..33b873f4 ---- /dev/null -+++ b/arch/generic/bits/kd.h -@@ -0,0 +1 @@ -+#include <linux/kd.h> -diff --git a/arch/generic/bits/ptrace.h b/arch/generic/bits/ptrace.h -new file mode 100644 -index 00000000..e69de29b -diff --git a/arch/generic/bits/soundcard.h b/arch/generic/bits/soundcard.h -new file mode 100644 -index 00000000..fade986f ---- /dev/null -+++ b/arch/generic/bits/soundcard.h -@@ -0,0 +1 @@ -+#include <linux/soundcard.h> -diff --git a/arch/generic/bits/termios.h b/arch/generic/bits/termios.h -index 434c02c8..124f71d2 100644 ---- a/arch/generic/bits/termios.h -+++ b/arch/generic/bits/termios.h -@@ -51,6 +51,7 @@ struct termios { - #define ONLRET 0000040 - #define OFILL 0000100 - #define OFDEL 0000200 -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) - #define NLDLY 0000400 - #define NL0 0000000 - #define NL1 0000400 -@@ -70,6 +71,7 @@ struct termios { - #define FFDLY 0100000 - #define FF0 0000000 - #define FF1 0100000 -+#endif - - #define VTDLY 0040000 - #define VT0 0000000 -diff --git a/arch/generic/bits/vt.h b/arch/generic/bits/vt.h -new file mode 100644 -index 00000000..834abfbc ---- /dev/null -+++ b/arch/generic/bits/vt.h -@@ -0,0 +1 @@ -+#include <linux/vt.h> -diff --git a/arch/i386/atomic_arch.h b/arch/i386/atomic_arch.h -index 7d2a48a5..047fb68d 100644 ---- a/arch/i386/atomic_arch.h -+++ b/arch/i386/atomic_arch.h -@@ -92,10 +92,10 @@ static inline int a_ctz_64(uint64_t x) - return r; - } - --#define a_ctz_l a_ctz_l --static inline int a_ctz_l(unsigned long x) -+#define a_ctz_32 a_ctz_32 -+static inline int a_ctz_32(uint32_t x) - { -- long r; -+ int r; - __asm__( "bsf %1,%0" : "=r"(r) : "r"(x) ); - return r; - } -diff --git a/arch/i386/bits/limits.h b/arch/i386/bits/limits.h -index 65a3dd64..c340ceb2 100644 ---- a/arch/i386/bits/limits.h -+++ b/arch/i386/bits/limits.h -@@ -1,6 +1,6 @@ - #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ - || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) --#define PAGE_SIZE 4096 -+#define PAGESIZE 4096 - #define LONG_BIT 32 - #endif - -diff --git a/arch/i386/bits/ptrace.h b/arch/i386/bits/ptrace.h -new file mode 100644 -index 00000000..7d0efbf3 ---- /dev/null -+++ b/arch/i386/bits/ptrace.h -@@ -0,0 +1,11 @@ -+#define PTRACE_GET_THREAD_AREA 25 -+#define PTRACE_SET_THREAD_AREA 26 -+#define PTRACE_SYSEMU 31 -+#define PTRACE_SYSEMU_SINGLESTEP 32 -+#define PTRACE_SINGLEBLOCK 33 -+ -+#define PT_GET_THREAD_AREA PTRACE_GET_THREAD_AREA -+#define PT_SET_THREAD_AREA PTRACE_SET_THREAD_AREA -+#define PT_SYSEMU PTRACE_SYSEMU -+#define PT_SYSEMU_SINGLESTEP PTRACE_SYSEMU_SINGLESTEP -+#define PT_STEPBLOCK PTRACE_SINGLEBLOCK -diff --git a/arch/i386/bits/user.h b/arch/i386/bits/user.h -index 0e343930..33fea986 100644 ---- a/arch/i386/bits/user.h -+++ b/arch/i386/bits/user.h -@@ -37,8 +37,8 @@ struct user { - int u_debugreg[8]; - }; - --#define PAGE_MASK (~(PAGE_SIZE-1)) --#define NBPG PAGE_SIZE -+#define PAGE_MASK (~(PAGESIZE-1)) -+#define NBPG PAGESIZE - #define UPAGES 1 - #define HOST_TEXT_START_ADDR (u.start_code) - #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -diff --git a/arch/m68k/atomic_arch.h b/arch/m68k/atomic_arch.h -new file mode 100644 -index 00000000..b369649a ---- /dev/null -+++ b/arch/m68k/atomic_arch.h -@@ -0,0 +1,8 @@ -+#define a_cas a_cas -+static inline int a_cas(volatile int *p, int t, int s) -+{ -+ __asm__ __volatile__ ( -+ "cas.l %0, %2, (%1)" -+ : "+d"(t) : "a"(p), "d"(s) : "memory", "cc"); -+ return t; -+} -diff --git a/arch/m68k/bits/alltypes.h.in b/arch/m68k/bits/alltypes.h.in -new file mode 100644 -index 00000000..a4a8141f ---- /dev/null -+++ b/arch/m68k/bits/alltypes.h.in -@@ -0,0 +1,31 @@ -+#define _Addr int -+#define _Int64 long long -+#define _Reg int -+ -+TYPEDEF __builtin_va_list va_list; -+TYPEDEF __builtin_va_list __isoc_va_list; -+ -+#ifndef __cplusplus -+TYPEDEF long wchar_t; -+#endif -+ -+#if __mcffpu__ -+TYPEDEF float float_t; -+TYPEDEF double double_t; -+#else -+TYPEDEF long double float_t; -+TYPEDEF long double double_t; -+#endif -+ -+TYPEDEF struct { long long __ll; long double __ld; } max_align_t; -+ -+TYPEDEF long time_t; -+TYPEDEF long suseconds_t; -+ -+TYPEDEF struct { union { int __i[9]; volatile int __vi[9]; unsigned __s[9]; } __u; } pthread_attr_t; -+TYPEDEF struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t; -+TYPEDEF struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } mtx_t; -+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } pthread_cond_t; -+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } cnd_t; -+TYPEDEF struct { union { int __i[8]; volatile int __vi[8]; void *__p[8]; } __u; } pthread_rwlock_t; -+TYPEDEF struct { union { int __i[5]; volatile int __vi[5]; void *__p[5]; } __u; } pthread_barrier_t; -diff --git a/arch/m68k/bits/endian.h b/arch/m68k/bits/endian.h -new file mode 100644 -index 00000000..ef074b77 ---- /dev/null -+++ b/arch/m68k/bits/endian.h -@@ -0,0 +1 @@ -+#define __BYTE_ORDER __BIG_ENDIAN -diff --git a/arch/m68k/bits/fcntl.h b/arch/m68k/bits/fcntl.h -new file mode 100644 -index 00000000..f1c8400f ---- /dev/null -+++ b/arch/m68k/bits/fcntl.h -@@ -0,0 +1,40 @@ -+#define O_CREAT 0100 -+#define O_EXCL 0200 -+#define O_NOCTTY 0400 -+#define O_TRUNC 01000 -+#define O_APPEND 02000 -+#define O_NONBLOCK 04000 -+#define O_DSYNC 010000 -+#define O_SYNC 04010000 -+#define O_RSYNC 04010000 -+#define O_DIRECTORY 040000 -+#define O_NOFOLLOW 0100000 -+#define O_CLOEXEC 02000000 -+ -+#define O_ASYNC 020000 -+#define O_DIRECT 0200000 -+#define O_LARGEFILE 0400000 -+#define O_NOATIME 01000000 -+#define O_PATH 010000000 -+#define O_TMPFILE 020200000 -+#define O_NDELAY O_NONBLOCK -+ -+#define F_DUPFD 0 -+#define F_GETFD 1 -+#define F_SETFD 2 -+#define F_GETFL 3 -+#define F_SETFL 4 -+ -+#define F_SETOWN 8 -+#define F_GETOWN 9 -+#define F_SETSIG 10 -+#define F_GETSIG 11 -+ -+#define F_GETLK 12 -+#define F_SETLK 13 -+#define F_SETLKW 14 -+ -+#define F_SETOWN_EX 15 -+#define F_GETOWN_EX 16 -+ -+#define F_GETOWNER_UIDS 17 -diff --git a/arch/m68k/bits/fenv.h b/arch/m68k/bits/fenv.h -new file mode 100644 -index 00000000..c90a4a58 ---- /dev/null -+++ b/arch/m68k/bits/fenv.h -@@ -0,0 +1,29 @@ -+#if __HAVE_68881__ || __mcffpu__ -+ -+#define FE_INEXACT 8 -+#define FE_DIVBYZERO 16 -+#define FE_UNDERFLOW 32 -+#define FE_OVERFLOW 64 -+#define FE_INVALID 128 -+ -+#define FE_ALL_EXCEPT 0xf8 -+ -+#define FE_TONEAREST 0 -+#define FE_TOWARDZERO 16 -+#define FE_DOWNWARD 32 -+#define FE_UPWARD 48 -+ -+#else -+ -+#define FE_ALL_EXCEPT 0 -+#define FE_TONEAREST 0 -+ -+#endif -+ -+typedef unsigned fexcept_t; -+ -+typedef struct { -+ unsigned __control_register, __status_register, __instruction_address; -+} fenv_t; -+ -+#define FE_DFL_ENV ((const fenv_t *) -1) -diff --git a/arch/m68k/bits/float.h b/arch/m68k/bits/float.h -new file mode 100644 -index 00000000..0e6899d5 ---- /dev/null -+++ b/arch/m68k/bits/float.h -@@ -0,0 +1,39 @@ -+#if !__mcffpu__ -+ -+#define FLT_EVAL_METHOD 2 -+ -+#define LDBL_TRUE_MIN 3.6451995318824746025e-4951L -+#define LDBL_MIN 1.68105157155604675313e-4932L -+#define LDBL_MAX 1.1897314953572317650e+4932L -+#define LDBL_EPSILON 1.0842021724855044340e-19L -+ -+#define LDBL_MANT_DIG 64 -+#define LDBL_MIN_EXP (-16382) -+#define LDBL_MAX_EXP 16384 -+ -+#define LDBL_DIG 18 -+#define LDBL_MIN_10_EXP (-4931) -+#define LDBL_MAX_10_EXP 4932 -+ -+#define DECIMAL_DIG 21 -+ -+#else -+ -+#define FLT_EVAL_METHOD 0 -+ -+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L -+#define LDBL_MIN 2.22507385850720138309e-308L -+#define LDBL_MAX 1.79769313486231570815e+308L -+#define LDBL_EPSILON 2.22044604925031308085e-16L -+ -+#define LDBL_MANT_DIG 53 -+#define LDBL_MIN_EXP (-1021) -+#define LDBL_MAX_EXP 1024 -+ -+#define LDBL_DIG 15 -+#define LDBL_MIN_10_EXP (-307) -+#define LDBL_MAX_10_EXP 308 -+ -+#define DECIMAL_DIG 17 -+ -+#endif -diff --git a/arch/m68k/bits/limits.h b/arch/m68k/bits/limits.h -new file mode 100644 -index 00000000..fbc6d238 ---- /dev/null -+++ b/arch/m68k/bits/limits.h -@@ -0,0 +1,7 @@ -+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ -+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -+#define LONG_BIT 32 -+#endif -+ -+#define LONG_MAX 0x7fffffffL -+#define LLONG_MAX 0x7fffffffffffffffLL -diff --git a/arch/m68k/bits/posix.h b/arch/m68k/bits/posix.h -new file mode 100644 -index 00000000..30a38714 ---- /dev/null -+++ b/arch/m68k/bits/posix.h -@@ -0,0 +1,2 @@ -+#define _POSIX_V6_ILP32_OFFBIG 1 -+#define _POSIX_V7_ILP32_OFFBIG 1 -diff --git a/arch/m68k/bits/ptrace.h b/arch/m68k/bits/ptrace.h -new file mode 100644 -index 00000000..da93e7a7 ---- /dev/null -+++ b/arch/m68k/bits/ptrace.h -@@ -0,0 +1,2 @@ -+#define PTRACE_GET_THREAD_AREA 25 -+#define PTRACE_SINGLEBLOCK 33 -diff --git a/arch/m68k/bits/reg.h b/arch/m68k/bits/reg.h -new file mode 100644 -index 00000000..99201f70 ---- /dev/null -+++ b/arch/m68k/bits/reg.h -@@ -0,0 +1,45 @@ -+#undef __WORDSIZE -+#define __WORDSIZE 32 -+#define PT_D1 0 -+#define PT_D2 1 -+#define PT_D3 2 -+#define PT_D4 3 -+#define PT_D5 4 -+#define PT_D6 5 -+#define PT_D7 6 -+#define PT_A0 7 -+#define PT_A1 8 -+#define PT_A2 9 -+#define PT_A3 10 -+#define PT_A4 11 -+#define PT_A5 12 -+#define PT_A6 13 -+#define PT_D0 14 -+#define PT_USP 15 -+#define PT_ORIG_D0 16 -+#define PT_SR 17 -+#define PT_PC 18 -+ -+#if __mcffpu__ -+#define PT_FP0 21 -+#define PT_FP1 23 -+#define PT_FP2 25 -+#define PT_FP3 27 -+#define PT_FP4 29 -+#define PT_FP5 31 -+#define PT_FP6 33 -+#define PT_FP7 35 -+#else -+#define PT_FP0 21 -+#define PT_FP1 24 -+#define PT_FP2 27 -+#define PT_FP3 30 -+#define PT_FP4 33 -+#define PT_FP5 36 -+#define PT_FP6 39 -+#define PT_FP7 42 -+#endif -+ -+#define PT_FPCR 45 -+#define PT_FPSR 46 -+#define PT_FPIAR 47 -diff --git a/arch/m68k/bits/setjmp.h b/arch/m68k/bits/setjmp.h -new file mode 100644 -index 00000000..5e091fb4 ---- /dev/null -+++ b/arch/m68k/bits/setjmp.h -@@ -0,0 +1 @@ -+typedef unsigned long __jmp_buf[39]; -diff --git a/arch/m68k/bits/signal.h b/arch/m68k/bits/signal.h -new file mode 100644 -index 00000000..2c369ca3 ---- /dev/null -+++ b/arch/m68k/bits/signal.h -@@ -0,0 +1,140 @@ -+#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 -+ -+#ifdef _GNU_SOURCE -+enum { R_D0 = 0 }; -+#define R_D0 R_D0 -+enum { R_D1 = 1 }; -+#define R_D1 R_D1 -+enum { R_D2 = 2 }; -+#define R_D2 R_D2 -+enum { R_D3 = 3 }; -+#define R_D3 R_D3 -+enum { R_D4 = 4 }; -+#define R_D4 R_D4 -+enum { R_D5 = 5 }; -+#define R_D5 R_D5 -+enum { R_D6 = 6 }; -+#define R_D6 R_D6 -+enum { R_D7 = 7 }; -+#define R_D7 R_D7 -+enum { R_A0 = 8 }; -+#define R_A0 R_A0 -+enum { R_A1 = 9 }; -+#define R_A1 R_A1 -+enum { R_A2 = 10 }; -+#define R_A2 R_A2 -+enum { R_A3 = 11 }; -+#define R_A3 R_A3 -+enum { R_A4 = 12 }; -+#define R_A4 R_A4 -+enum { R_A5 = 13 }; -+#define R_A5 R_A5 -+enum { R_A6 = 14 }; -+#define R_A6 R_A6 -+enum { R_A7 = 15 }; -+#define R_A7 R_A7 -+enum { R_SP = 15 }; -+#define R_SP R_SP -+enum { R_PC = 16 }; -+#define R_PC R_PC -+enum { R_PS = 17 }; -+#define R_PS R_PS -+#endif -+ -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -+ -+struct sigcontext { -+ unsigned long sc_mask, sc_usp, sc_d0, sc_d1, sc_a0, sc_a1; -+ unsigned short sc_sr; -+ unsigned long sc_pc; -+ unsigned short sc_formatvec; -+ unsigned long sc_fpregs[6], sc_fpcntl[3]; -+ unsigned char sc_fpstate[216]; -+}; -+ -+typedef int greg_t, gregset_t[18]; -+typedef struct { -+ int f_pcr, f_psr, f_fpiaddr, f_fpregs[8][3]; -+} fpregset_t; -+ -+typedef struct { -+ int version; -+ gregset_t gregs; -+ fpregset_t fpregs; -+} mcontext_t; -+#else -+typedef struct { -+ int __version; -+ int __gregs[18]; -+ int __fpregs[27]; -+} mcontext_t; -+#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; -+ mcontext_t uc_mcontext; -+ long __reserved[80]; -+ sigset_t uc_sigmask; -+} 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 29 -+#define SIGPWR 30 -+#define SIGSYS 31 -+#define SIGUNUSED SIGSYS -+ -+#define _NSIG 65 -diff --git a/arch/m68k/bits/stat.h b/arch/m68k/bits/stat.h -new file mode 100644 -index 00000000..0f7b66a1 ---- /dev/null -+++ b/arch/m68k/bits/stat.h -@@ -0,0 +1,21 @@ -+/* copied from kernel definition, but with padding replaced -+ * by the corresponding correctly-sized userspace types. */ -+ -+struct stat { -+ dev_t st_dev; -+ short __st_dev_padding; -+ long __st_ino_truncated; -+ mode_t st_mode; -+ nlink_t st_nlink; -+ uid_t st_uid; -+ gid_t st_gid; -+ dev_t st_rdev; -+ short __st_rdev_padding; -+ off_t st_size; -+ blksize_t st_blksize; -+ blkcnt_t st_blocks; -+ struct timespec st_atim; -+ struct timespec st_mtim; -+ struct timespec st_ctim; -+ ino_t st_ino; -+}; -diff --git a/arch/m68k/bits/stdint.h b/arch/m68k/bits/stdint.h -new file mode 100644 -index 00000000..d1b27121 ---- /dev/null -+++ b/arch/m68k/bits/stdint.h -@@ -0,0 +1,20 @@ -+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 -new file mode 100644 -index 00000000..89cf114c ---- /dev/null -+++ b/arch/m68k/bits/syscall.h.in -@@ -0,0 +1,361 @@ -+#define __NR_restart_syscall 0 -+#define __NR_exit 1 -+#define __NR_fork 2 -+#define __NR_read 3 -+#define __NR_write 4 -+#define __NR_open 5 -+#define __NR_close 6 -+#define __NR_waitpid 7 -+#define __NR_creat 8 -+#define __NR_link 9 -+#define __NR_unlink 10 -+#define __NR_execve 11 -+#define __NR_chdir 12 -+#define __NR_time 13 -+#define __NR_mknod 14 -+#define __NR_chmod 15 -+#define __NR_chown 16 -+#define __NR_oldstat 18 -+#define __NR_lseek 19 -+#define __NR_getpid 20 -+#define __NR_mount 21 -+#define __NR_umount 22 -+#define __NR_setuid 23 -+#define __NR_getuid 24 -+#define __NR_stime 25 -+#define __NR_ptrace 26 -+#define __NR_alarm 27 -+#define __NR_oldfstat 28 -+#define __NR_pause 29 -+#define __NR_utime 30 -+#define __NR_access 33 -+#define __NR_nice 34 -+#define __NR_sync 36 -+#define __NR_kill 37 -+#define __NR_rename 38 -+#define __NR_mkdir 39 -+#define __NR_rmdir 40 -+#define __NR_dup 41 -+#define __NR_pipe 42 -+#define __NR_times 43 -+#define __NR_brk 45 -+#define __NR_setgid 46 -+#define __NR_getgid 47 -+#define __NR_signal 48 -+#define __NR_geteuid 49 -+#define __NR_getegid 50 -+#define __NR_acct 51 -+#define __NR_umount2 52 -+#define __NR_ioctl 54 -+#define __NR_fcntl 55 -+#define __NR_setpgid 57 -+#define __NR_umask 60 -+#define __NR_chroot 61 -+#define __NR_ustat 62 -+#define __NR_dup2 63 -+#define __NR_getppid 64 -+#define __NR_getpgrp 65 -+#define __NR_setsid 66 -+#define __NR_sigaction 67 -+#define __NR_sgetmask 68 -+#define __NR_ssetmask 69 -+#define __NR_setreuid 70 -+#define __NR_setregid 71 -+#define __NR_sigsuspend 72 -+#define __NR_sigpending 73 -+#define __NR_sethostname 74 -+#define __NR_setrlimit 75 -+#define __NR_getrlimit 76 -+#define __NR_getrusage 77 -+#define __NR_gettimeofday 78 -+#define __NR_settimeofday 79 -+#define __NR_getgroups 80 -+#define __NR_setgroups 81 -+#define __NR_select 82 -+#define __NR_symlink 83 -+#define __NR_oldlstat 84 -+#define __NR_readlink 85 -+#define __NR_uselib 86 -+#define __NR_swapon 87 -+#define __NR_reboot 88 -+#define __NR_readdir 89 -+#define __NR_mmap 90 -+#define __NR_munmap 91 -+#define __NR_truncate 92 -+#define __NR_ftruncate 93 -+#define __NR_fchmod 94 -+#define __NR_fchown 95 -+#define __NR_getpriority 96 -+#define __NR_setpriority 97 -+#define __NR_statfs 99 -+#define __NR_fstatfs 100 -+#define __NR_socketcall 102 -+#define __NR_syslog 103 -+#define __NR_setitimer 104 -+#define __NR_getitimer 105 -+#define __NR_stat 106 -+#define __NR_lstat 107 -+#define __NR_fstat 108 -+#define __NR_vhangup 111 -+#define __NR_wait4 114 -+#define __NR_swapoff 115 -+#define __NR_sysinfo 116 -+#define __NR_ipc 117 -+#define __NR_fsync 118 -+#define __NR_sigreturn 119 -+#define __NR_clone 120 -+#define __NR_setdomainname 121 -+#define __NR_uname 122 -+#define __NR_cacheflush 123 -+#define __NR_adjtimex 124 -+#define __NR_mprotect 125 -+#define __NR_sigprocmask 126 -+#define __NR_create_module 127 -+#define __NR_init_module 128 -+#define __NR_delete_module 129 -+#define __NR_get_kernel_syms 130 -+#define __NR_quotactl 131 -+#define __NR_getpgid 132 -+#define __NR_fchdir 133 -+#define __NR_bdflush 134 -+#define __NR_sysfs 135 -+#define __NR_personality 136 -+#define __NR_setfsuid 138 -+#define __NR_setfsgid 139 -+#define __NR__llseek 140 -+#define __NR_getdents 141 -+#define __NR__newselect 142 -+#define __NR_flock 143 -+#define __NR_msync 144 -+#define __NR_readv 145 -+#define __NR_writev 146 -+#define __NR_getsid 147 -+#define __NR_fdatasync 148 -+#define __NR__sysctl 149 -+#define __NR_mlock 150 -+#define __NR_munlock 151 -+#define __NR_mlockall 152 -+#define __NR_munlockall 153 -+#define __NR_sched_setparam 154 -+#define __NR_sched_getparam 155 -+#define __NR_sched_setscheduler 156 -+#define __NR_sched_getscheduler 157 -+#define __NR_sched_yield 158 -+#define __NR_sched_get_priority_max 159 -+#define __NR_sched_get_priority_min 160 -+#define __NR_sched_rr_get_interval 161 -+#define __NR_nanosleep 162 -+#define __NR_mremap 163 -+#define __NR_setresuid 164 -+#define __NR_getresuid 165 -+#define __NR_getpagesize 166 -+#define __NR_query_module 167 -+#define __NR_poll 168 -+#define __NR_nfsservctl 169 -+#define __NR_setresgid 170 -+#define __NR_getresgid 171 -+#define __NR_prctl 172 -+#define __NR_rt_sigreturn 173 -+#define __NR_rt_sigaction 174 -+#define __NR_rt_sigprocmask 175 -+#define __NR_rt_sigpending 176 -+#define __NR_rt_sigtimedwait 177 -+#define __NR_rt_sigqueueinfo 178 -+#define __NR_rt_sigsuspend 179 -+#define __NR_pread64 180 -+#define __NR_pwrite64 181 -+#define __NR_lchown 182 -+#define __NR_getcwd 183 -+#define __NR_capget 184 -+#define __NR_capset 185 -+#define __NR_sigaltstack 186 -+#define __NR_sendfile 187 -+#define __NR_getpmsg 188 -+#define __NR_putpmsg 189 -+#define __NR_vfork 190 -+#define __NR_ugetrlimit 191 -+#define __NR_mmap2 192 -+#define __NR_truncate64 193 -+#define __NR_ftruncate64 194 -+#define __NR_stat64 195 -+#define __NR_lstat64 196 -+#define __NR_fstat64 197 -+#define __NR_chown32 198 -+#define __NR_getuid32 199 -+#define __NR_getgid32 200 -+#define __NR_geteuid32 201 -+#define __NR_getegid32 202 -+#define __NR_setreuid32 203 -+#define __NR_setregid32 204 -+#define __NR_getgroups32 205 -+#define __NR_setgroups32 206 -+#define __NR_fchown32 207 -+#define __NR_setresuid32 208 -+#define __NR_getresuid32 209 -+#define __NR_setresgid32 210 -+#define __NR_getresgid32 211 -+#define __NR_lchown32 212 -+#define __NR_setuid32 213 -+#define __NR_setgid32 214 -+#define __NR_setfsuid32 215 -+#define __NR_setfsgid32 216 -+#define __NR_pivot_root 217 -+#define __NR_getdents64 220 -+#define __NR_gettid 221 -+#define __NR_tkill 222 -+#define __NR_setxattr 223 -+#define __NR_lsetxattr 224 -+#define __NR_fsetxattr 225 -+#define __NR_getxattr 226 -+#define __NR_lgetxattr 227 -+#define __NR_fgetxattr 228 -+#define __NR_listxattr 229 -+#define __NR_llistxattr 230 -+#define __NR_flistxattr 231 -+#define __NR_removexattr 232 -+#define __NR_lremovexattr 233 -+#define __NR_fremovexattr 234 -+#define __NR_futex 235 -+#define __NR_sendfile64 236 -+#define __NR_mincore 237 -+#define __NR_madvise 238 -+#define __NR_fcntl64 239 -+#define __NR_readahead 240 -+#define __NR_io_setup 241 -+#define __NR_io_destroy 242 -+#define __NR_io_getevents 243 -+#define __NR_io_submit 244 -+#define __NR_io_cancel 245 -+#define __NR_fadvise64 246 -+#define __NR_exit_group 247 -+#define __NR_lookup_dcookie 248 -+#define __NR_epoll_create 249 -+#define __NR_epoll_ctl 250 -+#define __NR_epoll_wait 251 -+#define __NR_remap_file_pages 252 -+#define __NR_set_tid_address 253 -+#define __NR_timer_create 254 -+#define __NR_timer_settime 255 -+#define __NR_timer_gettime 256 -+#define __NR_timer_getoverrun 257 -+#define __NR_timer_delete 258 -+#define __NR_clock_settime 259 -+#define __NR_clock_gettime 260 -+#define __NR_clock_getres 261 -+#define __NR_clock_nanosleep 262 -+#define __NR_statfs64 263 -+#define __NR_fstatfs64 264 -+#define __NR_tgkill 265 -+#define __NR_utimes 266 -+#define __NR_fadvise64_64 267 -+#define __NR_mbind 268 -+#define __NR_get_mempolicy 269 -+#define __NR_set_mempolicy 270 -+#define __NR_mq_open 271 -+#define __NR_mq_unlink 272 -+#define __NR_mq_timedsend 273 -+#define __NR_mq_timedreceive 274 -+#define __NR_mq_notify 275 -+#define __NR_mq_getsetattr 276 -+#define __NR_waitid 277 -+#define __NR_add_key 279 -+#define __NR_request_key 280 -+#define __NR_keyctl 281 -+#define __NR_ioprio_set 282 -+#define __NR_ioprio_get 283 -+#define __NR_inotify_init 284 -+#define __NR_inotify_add_watch 285 -+#define __NR_inotify_rm_watch 286 -+#define __NR_migrate_pages 287 -+#define __NR_openat 288 -+#define __NR_mkdirat 289 -+#define __NR_mknodat 290 -+#define __NR_fchownat 291 -+#define __NR_futimesat 292 -+#define __NR_fstatat64 293 -+#define __NR_unlinkat 294 -+#define __NR_renameat 295 -+#define __NR_linkat 296 -+#define __NR_symlinkat 297 -+#define __NR_readlinkat 298 -+#define __NR_fchmodat 299 -+#define __NR_faccessat 300 -+#define __NR_pselect6 301 -+#define __NR_ppoll 302 -+#define __NR_unshare 303 -+#define __NR_set_robust_list 304 -+#define __NR_get_robust_list 305 -+#define __NR_splice 306 -+#define __NR_sync_file_range 307 -+#define __NR_tee 308 -+#define __NR_vmsplice 309 -+#define __NR_move_pages 310 -+#define __NR_sched_setaffinity 311 -+#define __NR_sched_getaffinity 312 -+#define __NR_kexec_load 313 -+#define __NR_getcpu 314 -+#define __NR_epoll_pwait 315 -+#define __NR_utimensat 316 -+#define __NR_signalfd 317 -+#define __NR_timerfd_create 318 -+#define __NR_eventfd 319 -+#define __NR_fallocate 320 -+#define __NR_timerfd_settime 321 -+#define __NR_timerfd_gettime 322 -+#define __NR_signalfd4 323 -+#define __NR_eventfd2 324 -+#define __NR_epoll_create1 325 -+#define __NR_dup3 326 -+#define __NR_pipe2 327 -+#define __NR_inotify_init1 328 -+#define __NR_preadv 329 -+#define __NR_pwritev 330 -+#define __NR_rt_tgsigqueueinfo 331 -+#define __NR_perf_event_open 332 -+#define __NR_get_thread_area 333 -+#define __NR_set_thread_area 334 -+#define __NR_atomic_cmpxchg_32 335 -+#define __NR_atomic_barrier 336 -+#define __NR_fanotify_init 337 -+#define __NR_fanotify_mark 338 -+#define __NR_prlimit64 339 -+#define __NR_name_to_handle_at 340 -+#define __NR_open_by_handle_at 341 -+#define __NR_clock_adjtime 342 -+#define __NR_syncfs 343 -+#define __NR_setns 344 -+#define __NR_process_vm_readv 345 -+#define __NR_process_vm_writev 346 -+#define __NR_kcmp 347 -+#define __NR_finit_module 348 -+#define __NR_sched_setattr 349 -+#define __NR_sched_getattr 350 -+#define __NR_renameat2 351 -+#define __NR_getrandom 352 -+#define __NR_memfd_create 353 -+#define __NR_bpf 354 -+#define __NR_execveat 355 -+#define __NR_socket 356 -+#define __NR_socketpair 357 -+#define __NR_bind 358 -+#define __NR_connect 359 -+#define __NR_listen 360 -+#define __NR_accept4 361 -+#define __NR_getsockopt 362 -+#define __NR_setsockopt 363 -+#define __NR_getsockname 364 -+#define __NR_getpeername 365 -+#define __NR_sendto 366 -+#define __NR_sendmsg 367 -+#define __NR_recvfrom 368 -+#define __NR_recvmsg 369 -+#define __NR_shutdown 370 -+#define __NR_recvmmsg 371 -+#define __NR_sendmmsg 372 -+#define __NR_userfaultfd 373 -+#define __NR_membarrier 374 -+#define __NR_mlock2 375 -+#define __NR_copy_file_range 376 -+#define __NR_preadv2 377 -+#define __NR_pwritev2 378 -+#define __NR_statx 379 -diff --git a/arch/m68k/bits/user.h b/arch/m68k/bits/user.h -new file mode 100644 -index 00000000..9a4ca128 ---- /dev/null -+++ b/arch/m68k/bits/user.h -@@ -0,0 +1,33 @@ -+#undef __WORDSIZE -+#define __WORDSIZE 32 -+ -+struct user_m68kfp_struct { -+ unsigned long fpregs[24], fpcntl[3]; -+}; -+ -+struct user_regs_struct { -+ long d1, d2, d3, d4, d5, d6, d7; -+ long a0, a1, a2, a3, a4, a5, a6; -+ long d0, usp, orig_d0; -+ short stkadj, sr; -+ long pc; -+ short fmtvec, __pad; -+}; -+ -+struct user { -+ struct user_regs_struct regs; -+ int u_fpvalid; -+ struct user_m68kfp_struct m68kfp; -+ unsigned long u_tsize, u_dsize, u_ssize, start_code, start_stack; -+ long signal; -+ int reserved; -+ unsigned long u_ar0; -+ struct user_m68kfp_struct *u_fpstate; -+ unsigned long magic; -+ char u_comm[32]; -+}; -+ -+#define NBPG 4096 -+#define UPAGES 1 -+#define HOST_TEXT_START_ADDR (u.start_code) -+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -diff --git a/arch/m68k/crt_arch.h b/arch/m68k/crt_arch.h -new file mode 100644 -index 00000000..48a42f29 ---- /dev/null -+++ b/arch/m68k/crt_arch.h -@@ -0,0 +1,14 @@ -+__asm__( -+".text\n" -+".weak _DYNAMIC \n" -+".hidden _DYNAMIC \n" -+".global " START "\n" -+START ":\n" -+" suba.l %fp,%fp \n" -+" movea.l %sp,%a0 \n" -+" lea _DYNAMIC-.-8,%a1 \n" -+" pea (%pc,%a1) \n" -+" pea (%a0) \n" -+" lea " START "_c-.-8,%a1 \n" -+" jsr (%pc,%a1) \n" -+); -diff --git a/arch/m68k/pthread_arch.h b/arch/m68k/pthread_arch.h -new file mode 100644 -index 00000000..02d5b8a0 ---- /dev/null -+++ b/arch/m68k/pthread_arch.h -@@ -0,0 +1,13 @@ -+static inline struct pthread *__pthread_self() -+{ -+ uintptr_t tp = __syscall(SYS_get_thread_area); -+ return (pthread_t)(tp - 0x7000 - sizeof(struct pthread)); -+} -+ -+#define TLS_ABOVE_TP -+#define GAP_ABOVE_TP 0 -+#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000) -+ -+#define DTP_OFFSET 0x8000 -+ -+#define MC_PC gregs[R_PC] -diff --git a/arch/m68k/reloc.h b/arch/m68k/reloc.h -new file mode 100644 -index 00000000..f920b39e ---- /dev/null -+++ b/arch/m68k/reloc.h -@@ -0,0 +1,30 @@ -+#if __HAVE_68881__ -+#define FP_SUFFIX "" -+#elif __mcffpu__ -+#define FP_SUFFIX "-fp64" -+#else -+#define FP_SUFFIX "-sf" -+#endif -+ -+#define LDSO_ARCH "m68k" FP_SUFFIX -+ -+#define TPOFF_K (-0x7000) -+ -+#define REL_SYMBOLIC R_68K_32 -+#define REL_OFFSET R_68K_PC32 -+#define REL_GOT R_68K_GLOB_DAT -+#define REL_PLT R_68K_JMP_SLOT -+#define REL_RELATIVE R_68K_RELATIVE -+#define REL_COPY R_68K_COPY -+#define REL_DTPMOD R_68K_TLS_DTPMOD32 -+#define REL_DTPOFF R_68K_TLS_DTPREL32 -+#define REL_TPOFF R_68K_TLS_TPREL32 -+ -+#define CRTJMP(pc,sp) __asm__ __volatile__( \ -+ "move.l %1,%%sp ; jmp (%0)" : : "r"(pc), "r"(sp) : "memory" ) -+ -+#define GETFUNCSYM(fp, sym, got) __asm__ ( \ -+ ".hidden " #sym "\n" \ -+ "lea " #sym "-.-8,%0 \n" \ -+ "lea (%%pc,%0),%0 \n" \ -+ : "=a"(*fp) : : "memory" ) -diff --git a/arch/m68k/syscall_arch.h b/arch/m68k/syscall_arch.h -new file mode 100644 -index 00000000..af79c306 ---- /dev/null -+++ b/arch/m68k/syscall_arch.h -@@ -0,0 +1,91 @@ -+#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)) -+ -+static __inline long __syscall0(long n) -+{ -+ register unsigned long d0 __asm__("d0") = n; -+ __asm__ __volatile__ ("trap #0" : "+r"(d0) -+ : -+ : "memory"); -+ return d0; -+} -+ -+static inline long __syscall1(long n, long a) -+{ -+ register unsigned long d0 __asm__("d0") = n; -+ register unsigned long d1 __asm__("d1") = a; -+ __asm__ __volatile__ ("trap #0" : "+r"(d0) -+ : "r"(d1) -+ : "memory"); -+ return d0; -+} -+ -+static inline long __syscall2(long n, long a, long b) -+{ -+ register unsigned long d0 __asm__("d0") = n; -+ register unsigned long d1 __asm__("d1") = a; -+ register unsigned long d2 __asm__("d2") = b; -+ __asm__ __volatile__ ("trap #0" : "+r"(d0) -+ : "r"(d1), "r"(d2) -+ : "memory"); -+ return d0; -+} -+ -+static inline long __syscall3(long n, long a, long b, long c) -+{ -+ register unsigned long d0 __asm__("d0") = n; -+ register unsigned long d1 __asm__("d1") = a; -+ register unsigned long d2 __asm__("d2") = b; -+ register unsigned long d3 __asm__("d3") = c; -+ __asm__ __volatile__ ("trap #0" : "+r"(d0) -+ : "r"(d1), "r"(d2), "r"(d3) -+ : "memory"); -+ return d0; -+} -+ -+static inline long __syscall4(long n, long a, long b, long c, long d) -+{ -+ register unsigned long d0 __asm__("d0") = n; -+ register unsigned long d1 __asm__("d1") = a; -+ register unsigned long d2 __asm__("d2") = b; -+ register unsigned long d3 __asm__("d3") = c; -+ register unsigned long d4 __asm__("d4") = d; -+ __asm__ __volatile__ ("trap #0" : "+r"(d0) -+ : "r"(d1), "r"(d2), "r"(d3), "r"(d4) -+ : "memory"); -+ return d0; -+} -+ -+static inline long __syscall5(long n, long a, long b, long c, long d, long e) -+{ -+ register unsigned long d0 __asm__("d0") = n; -+ register unsigned long d1 __asm__("d1") = a; -+ register unsigned long d2 __asm__("d2") = b; -+ register unsigned long d3 __asm__("d3") = c; -+ register unsigned long d4 __asm__("d4") = d; -+ register unsigned long d5 __asm__("d5") = e; -+ __asm__ __volatile__ ("trap #0" : "+r"(d0) -+ : "r"(d1), "r"(d2), "r"(d3), "r"(d4), "r"(d5) -+ : "memory"); -+ return d0; -+} -+ -+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f) -+{ -+ register unsigned long d0 __asm__("d0") = n; -+ register unsigned long d1 __asm__("d1") = a; -+ register unsigned long d2 __asm__("d2") = b; -+ register unsigned long d3 __asm__("d3") = c; -+ register unsigned long d4 __asm__("d4") = d; -+ register unsigned long d5 __asm__("d5") = e; -+ register unsigned long a0 __asm__("a0") = f; -+ __asm__ __volatile__ ("trap #0" : "+r"(d0) -+ : "r"(d1), "r"(d2), "r"(d3), "r"(d4), "r"(d5), "r"(a0) -+ : "memory"); -+ return d0; -+} -+ -+#define SYSCALL_USE_SOCKETCALL -+#define SYSCALL_IPC_BROKEN_MODE -diff --git a/arch/microblaze/syscall_arch.h b/arch/microblaze/syscall_arch.h -index 8e2de7ea..6cf631ad 100644 ---- a/arch/microblaze/syscall_arch.h -+++ b/arch/microblaze/syscall_arch.h -@@ -102,3 +102,5 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo - #define SYSCALL_NO_INLINE - - #endif -+ -+#define SYSCALL_IPC_BROKEN_MODE -diff --git a/arch/mips/bits/hwcap.h b/arch/mips/bits/hwcap.h -index 05cffba4..13e86fe7 100644 ---- a/arch/mips/bits/hwcap.h -+++ b/arch/mips/bits/hwcap.h -@@ -1,2 +1,3 @@ - #define HWCAP_MIPS_R6 (1 << 0) - #define HWCAP_MIPS_MSA (1 << 1) -+#define HWCAP_MIPS_CRC32 (1 << 2) -diff --git a/arch/mips/bits/mman.h b/arch/mips/bits/mman.h -index c68aea88..9027bb63 100644 ---- a/arch/mips/bits/mman.h -+++ b/arch/mips/bits/mman.h -@@ -18,6 +18,7 @@ - #define MAP_STACK 0x40000 - #undef MAP_HUGETLB - #define MAP_HUGETLB 0x80000 -+#undef MAP_SYNC - - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - #undef MADV_SOFT_OFFLINE -diff --git a/arch/mips/bits/ptrace.h b/arch/mips/bits/ptrace.h -new file mode 100644 -index 00000000..77a01c06 ---- /dev/null -+++ b/arch/mips/bits/ptrace.h -@@ -0,0 +1,9 @@ -+#define PTRACE_GET_THREAD_AREA 25 -+#define PTRACE_SET_THREAD_AREA 26 -+#define PTRACE_PEEKTEXT_3264 0xc0 -+#define PTRACE_PEEKDATA_3264 0xc1 -+#define PTRACE_POKETEXT_3264 0xc2 -+#define PTRACE_POKEDATA_3264 0xc3 -+#define PTRACE_GET_THREAD_AREA_3264 0xc4 -+#define PTRACE_GET_WATCH_REGS 0xd0 -+#define PTRACE_SET_WATCH_REGS 0xd1 -diff --git a/arch/mips/bits/socket.h b/arch/mips/bits/socket.h -index 191ebdb5..b82c7d34 100644 ---- a/arch/mips/bits/socket.h -+++ b/arch/mips/bits/socket.h -@@ -45,6 +45,7 @@ struct cmsghdr { - #define SO_BSDCOMPAT 14 - #define SO_PASSCRED 17 - #define SO_PEERCRED 18 -+#define SO_PEERSEC 30 - #define SO_SNDBUFFORCE 31 - #define SO_RCVBUFFORCE 33 - -diff --git a/arch/mips/bits/termios.h b/arch/mips/bits/termios.h -index 6a1205d7..f7b9dd2e 100644 ---- a/arch/mips/bits/termios.h -+++ b/arch/mips/bits/termios.h -@@ -52,6 +52,7 @@ struct termios { - #define ONLRET 0000040 - #define OFILL 0000100 - #define OFDEL 0000200 -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) - #define NLDLY 0000400 - #define NL0 0000000 - #define NL1 0000400 -@@ -71,6 +72,7 @@ struct termios { - #define FFDLY 0100000 - #define FF0 0000000 - #define FF1 0100000 -+#endif - - #define VTDLY 0040000 - #define VT0 0000000 -@@ -163,5 +165,5 @@ struct termios { - #define EXTPROC 0200000 - - #define XTABS 0014000 --#define TIOCSER_TEMT 1 -+#define TIOCSER_TEMT 0x01 - #endif -diff --git a/arch/mips/pthread_arch.h b/arch/mips/pthread_arch.h -index e5812655..5fea15ad 100644 ---- a/arch/mips/pthread_arch.h -+++ b/arch/mips/pthread_arch.h -@@ -11,6 +11,7 @@ static inline struct pthread *__pthread_self() - } - - #define TLS_ABOVE_TP -+#define GAP_ABOVE_TP 0 - #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000) - - #define DTP_OFFSET 0x8000 -diff --git a/arch/mips64/bits/hwcap.h b/arch/mips64/bits/hwcap.h -index 05cffba4..13e86fe7 100644 ---- a/arch/mips64/bits/hwcap.h -+++ b/arch/mips64/bits/hwcap.h -@@ -1,2 +1,3 @@ - #define HWCAP_MIPS_R6 (1 << 0) - #define HWCAP_MIPS_MSA (1 << 1) -+#define HWCAP_MIPS_CRC32 (1 << 2) -diff --git a/arch/mips64/bits/mman.h b/arch/mips64/bits/mman.h -index c68aea88..9027bb63 100644 ---- a/arch/mips64/bits/mman.h -+++ b/arch/mips64/bits/mman.h -@@ -18,6 +18,7 @@ - #define MAP_STACK 0x40000 - #undef MAP_HUGETLB - #define MAP_HUGETLB 0x80000 -+#undef MAP_SYNC - - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - #undef MADV_SOFT_OFFLINE -diff --git a/arch/mips64/bits/ptrace.h b/arch/mips64/bits/ptrace.h -new file mode 100644 -index 00000000..77a01c06 ---- /dev/null -+++ b/arch/mips64/bits/ptrace.h -@@ -0,0 +1,9 @@ -+#define PTRACE_GET_THREAD_AREA 25 -+#define PTRACE_SET_THREAD_AREA 26 -+#define PTRACE_PEEKTEXT_3264 0xc0 -+#define PTRACE_PEEKDATA_3264 0xc1 -+#define PTRACE_POKETEXT_3264 0xc2 -+#define PTRACE_POKEDATA_3264 0xc3 -+#define PTRACE_GET_THREAD_AREA_3264 0xc4 -+#define PTRACE_GET_WATCH_REGS 0xd0 -+#define PTRACE_SET_WATCH_REGS 0xd1 -diff --git a/arch/mips64/bits/socket.h b/arch/mips64/bits/socket.h -index cf801797..5aff0d91 100644 ---- a/arch/mips64/bits/socket.h -+++ b/arch/mips64/bits/socket.h -@@ -61,6 +61,7 @@ struct cmsghdr { - #define SO_BSDCOMPAT 14 - #define SO_PASSCRED 17 - #define SO_PEERCRED 18 -+#define SO_PEERSEC 30 - #define SO_SNDBUFFORCE 31 - #define SO_RCVBUFFORCE 33 - -diff --git a/arch/mips64/bits/termios.h b/arch/mips64/bits/termios.h -index 6a1205d7..f7b9dd2e 100644 ---- a/arch/mips64/bits/termios.h -+++ b/arch/mips64/bits/termios.h -@@ -52,6 +52,7 @@ struct termios { - #define ONLRET 0000040 - #define OFILL 0000100 - #define OFDEL 0000200 -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) - #define NLDLY 0000400 - #define NL0 0000000 - #define NL1 0000400 -@@ -71,6 +72,7 @@ struct termios { - #define FFDLY 0100000 - #define FF0 0000000 - #define FF1 0100000 -+#endif - - #define VTDLY 0040000 - #define VT0 0000000 -@@ -163,5 +165,5 @@ struct termios { - #define EXTPROC 0200000 - - #define XTABS 0014000 --#define TIOCSER_TEMT 1 -+#define TIOCSER_TEMT 0x01 - #endif -diff --git a/arch/mips64/pthread_arch.h b/arch/mips64/pthread_arch.h -index e5812655..5fea15ad 100644 ---- a/arch/mips64/pthread_arch.h -+++ b/arch/mips64/pthread_arch.h -@@ -11,6 +11,7 @@ static inline struct pthread *__pthread_self() - } - - #define TLS_ABOVE_TP -+#define GAP_ABOVE_TP 0 - #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000) - - #define DTP_OFFSET 0x8000 -diff --git a/arch/mipsn32/bits/hwcap.h b/arch/mipsn32/bits/hwcap.h -index 05cffba4..13e86fe7 100644 ---- a/arch/mipsn32/bits/hwcap.h -+++ b/arch/mipsn32/bits/hwcap.h -@@ -1,2 +1,3 @@ - #define HWCAP_MIPS_R6 (1 << 0) - #define HWCAP_MIPS_MSA (1 << 1) -+#define HWCAP_MIPS_CRC32 (1 << 2) -diff --git a/arch/mipsn32/bits/mman.h b/arch/mipsn32/bits/mman.h -index c68aea88..9027bb63 100644 ---- a/arch/mipsn32/bits/mman.h -+++ b/arch/mipsn32/bits/mman.h -@@ -18,6 +18,7 @@ - #define MAP_STACK 0x40000 - #undef MAP_HUGETLB - #define MAP_HUGETLB 0x80000 -+#undef MAP_SYNC - - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - #undef MADV_SOFT_OFFLINE -diff --git a/arch/mipsn32/bits/ptrace.h b/arch/mipsn32/bits/ptrace.h -new file mode 100644 -index 00000000..77a01c06 ---- /dev/null -+++ b/arch/mipsn32/bits/ptrace.h -@@ -0,0 +1,9 @@ -+#define PTRACE_GET_THREAD_AREA 25 -+#define PTRACE_SET_THREAD_AREA 26 -+#define PTRACE_PEEKTEXT_3264 0xc0 -+#define PTRACE_PEEKDATA_3264 0xc1 -+#define PTRACE_POKETEXT_3264 0xc2 -+#define PTRACE_POKEDATA_3264 0xc3 -+#define PTRACE_GET_THREAD_AREA_3264 0xc4 -+#define PTRACE_GET_WATCH_REGS 0xd0 -+#define PTRACE_SET_WATCH_REGS 0xd1 -diff --git a/arch/mipsn32/bits/socket.h b/arch/mipsn32/bits/socket.h -index 191ebdb5..b82c7d34 100644 ---- a/arch/mipsn32/bits/socket.h -+++ b/arch/mipsn32/bits/socket.h -@@ -45,6 +45,7 @@ struct cmsghdr { - #define SO_BSDCOMPAT 14 - #define SO_PASSCRED 17 - #define SO_PEERCRED 18 -+#define SO_PEERSEC 30 - #define SO_SNDBUFFORCE 31 - #define SO_RCVBUFFORCE 33 - -diff --git a/arch/mipsn32/bits/termios.h b/arch/mipsn32/bits/termios.h -index 6a1205d7..f7b9dd2e 100644 ---- a/arch/mipsn32/bits/termios.h -+++ b/arch/mipsn32/bits/termios.h -@@ -52,6 +52,7 @@ struct termios { - #define ONLRET 0000040 - #define OFILL 0000100 - #define OFDEL 0000200 -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) - #define NLDLY 0000400 - #define NL0 0000000 - #define NL1 0000400 -@@ -71,6 +72,7 @@ struct termios { - #define FFDLY 0100000 - #define FF0 0000000 - #define FF1 0100000 -+#endif - - #define VTDLY 0040000 - #define VT0 0000000 -@@ -163,5 +165,5 @@ struct termios { - #define EXTPROC 0200000 - - #define XTABS 0014000 --#define TIOCSER_TEMT 1 -+#define TIOCSER_TEMT 0x01 - #endif -diff --git a/arch/mipsn32/pthread_arch.h b/arch/mipsn32/pthread_arch.h -index e5812655..5fea15ad 100644 ---- a/arch/mipsn32/pthread_arch.h -+++ b/arch/mipsn32/pthread_arch.h -@@ -11,6 +11,7 @@ static inline struct pthread *__pthread_self() - } - - #define TLS_ABOVE_TP -+#define GAP_ABOVE_TP 0 - #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000) - - #define DTP_OFFSET 0x8000 -diff --git a/arch/or1k/bits/limits.h b/arch/or1k/bits/limits.h -index 483b6749..3a811c99 100644 ---- a/arch/or1k/bits/limits.h -+++ b/arch/or1k/bits/limits.h -@@ -1,6 +1,6 @@ - #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ - || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) --#define PAGE_SIZE 8192 -+#define PAGESIZE 8192 - #define LONG_BIT 32 - #endif - -diff --git a/arch/or1k/pthread_arch.h b/arch/or1k/pthread_arch.h -index 7decd769..521b9c53 100644 ---- a/arch/or1k/pthread_arch.h -+++ b/arch/or1k/pthread_arch.h -@@ -12,6 +12,7 @@ static inline struct pthread *__pthread_self() - } - - #define TLS_ABOVE_TP -+#define GAP_ABOVE_TP 0 - #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread)) - - #define MC_PC regs.pc -diff --git a/arch/powerpc/bits/hwcap.h b/arch/powerpc/bits/hwcap.h -index 82c92a93..803de9b5 100644 ---- a/arch/powerpc/bits/hwcap.h -+++ b/arch/powerpc/bits/hwcap.h -@@ -38,3 +38,6 @@ - #define PPC_FEATURE2_HTM_NOSC 0x01000000 - #define PPC_FEATURE2_ARCH_3_00 0x00800000 - #define PPC_FEATURE2_HAS_IEEE128 0x00400000 -+#define PPC_FEATURE2_DARN 0x00200000 -+#define PPC_FEATURE2_SCV 0x00100000 -+#define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 -diff --git a/arch/powerpc/bits/mman.h b/arch/powerpc/bits/mman.h -index 95ec4358..b3a675a8 100644 ---- a/arch/powerpc/bits/mman.h -+++ b/arch/powerpc/bits/mman.h -@@ -4,6 +4,7 @@ - #define MAP_NORESERVE 0x40 - #undef MAP_LOCKED - #define MAP_LOCKED 0x80 -+#undef MAP_SYNC - - #undef MCL_CURRENT - #define MCL_CURRENT 0x2000 -diff --git a/arch/powerpc/bits/ptrace.h b/arch/powerpc/bits/ptrace.h -new file mode 100644 -index 00000000..75086ca0 ---- /dev/null -+++ b/arch/powerpc/bits/ptrace.h -@@ -0,0 +1,23 @@ -+#define PTRACE_GETVRREGS 0x12 -+#define PTRACE_SETVRREGS 0x13 -+#define PTRACE_GETEVRREGS 0x14 -+#define PTRACE_SETEVRREGS 0x15 -+#define PTRACE_GETREGS64 0x16 -+#define PTRACE_SETREGS64 0x17 -+#define PTRACE_GET_DEBUGREG 0x19 -+#define PTRACE_SET_DEBUGREG 0x1a -+#define PTRACE_GETVSRREGS 0x1b -+#define PTRACE_SETVSRREGS 0x1c -+#define PTRACE_SINGLEBLOCK 0x100 -+ -+#define PT_GETVRREGS PTRACE_GETVRREGS -+#define PT_SETVRREGS PTRACE_SETVRREGS -+#define PT_GETEVRREGS PTRACE_GETEVRREGS -+#define PT_SETEVRREGS PTRACE_SETEVRREGS -+#define PT_GETREGS64 PTRACE_GETREGS64 -+#define PT_SETREGS64 PTRACE_SETREGS64 -+#define PT_GET_DEBUGREG PTRACE_GET_DEBUGREG -+#define PT_SET_DEBUGREG PTRACE_SET_DEBUGREG -+#define PT_GETVSRREGS PTRACE_GETVSRREGS -+#define PT_SETVSRREGS PTRACE_SETVSRREGS -+#define PT_STEPBLOCK PTRACE_SINGLEBLOCK -diff --git a/arch/powerpc/bits/socket.h b/arch/powerpc/bits/socket.h -index 2fee8777..a94b8bdb 100644 ---- a/arch/powerpc/bits/socket.h -+++ b/arch/powerpc/bits/socket.h -@@ -36,6 +36,7 @@ struct cmsghdr { - #define SO_PASSCRED 20 - #define SO_PEERCRED 21 - #define SO_ACCEPTCONN 30 -+#define SO_PEERSEC 31 - #define SO_SNDBUFFORCE 32 - #define SO_RCVBUFFORCE 33 - #define SO_PROTOCOL 38 -diff --git a/arch/powerpc/bits/syscall.h.in b/arch/powerpc/bits/syscall.h.in -index 20833915..7ce94bbd 100644 ---- a/arch/powerpc/bits/syscall.h.in -+++ b/arch/powerpc/bits/syscall.h.in -@@ -368,4 +368,7 @@ - #define __NR_pwritev2 381 - #define __NR_kexec_file_load 382 - #define __NR_statx 383 -+#define __NR_pkey_alloc 384 -+#define __NR_pkey_free 385 -+#define __NR_pkey_mprotect 386 - -diff --git a/arch/powerpc/bits/termios.h b/arch/powerpc/bits/termios.h -index 0b09630c..e3f22e86 100644 ---- a/arch/powerpc/bits/termios.h -+++ b/arch/powerpc/bits/termios.h -@@ -53,6 +53,7 @@ struct termios { - #define ONLRET 0000040 - #define OFILL 0000100 - #define OFDEL 0000200 -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) - #define NLDLY 0001400 - #define NL0 0000000 - #define NL1 0000400 -@@ -74,6 +75,7 @@ struct termios { - #define BSDLY 0100000 - #define BS0 0000000 - #define BS1 0100000 -+#endif - - #define VTDLY 0200000 - #define VT0 0000000 -@@ -165,5 +167,5 @@ struct termios { - #define EXTPROC 0x10000000 - - #define XTABS 00006000 --#define TIOCSER_TEMT 1 -+#define TIOCSER_TEMT 0x01 - #endif -diff --git a/arch/powerpc/pthread_arch.h b/arch/powerpc/pthread_arch.h -index 7c5c4fad..79e5a09f 100644 ---- a/arch/powerpc/pthread_arch.h -+++ b/arch/powerpc/pthread_arch.h -@@ -11,6 +11,7 @@ static inline struct pthread *__pthread_self() - } - - #define TLS_ABOVE_TP -+#define GAP_ABOVE_TP 0 - #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000) - - #define DTP_OFFSET 0x8000 -diff --git a/arch/powerpc64/bits/hwcap.h b/arch/powerpc64/bits/hwcap.h -index 82c92a93..803de9b5 100644 ---- a/arch/powerpc64/bits/hwcap.h -+++ b/arch/powerpc64/bits/hwcap.h -@@ -38,3 +38,6 @@ - #define PPC_FEATURE2_HTM_NOSC 0x01000000 - #define PPC_FEATURE2_ARCH_3_00 0x00800000 - #define PPC_FEATURE2_HAS_IEEE128 0x00400000 -+#define PPC_FEATURE2_DARN 0x00200000 -+#define PPC_FEATURE2_SCV 0x00100000 -+#define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 -diff --git a/arch/powerpc64/bits/mman.h b/arch/powerpc64/bits/mman.h -index 95ec4358..b3a675a8 100644 ---- a/arch/powerpc64/bits/mman.h -+++ b/arch/powerpc64/bits/mman.h -@@ -4,6 +4,7 @@ - #define MAP_NORESERVE 0x40 - #undef MAP_LOCKED - #define MAP_LOCKED 0x80 -+#undef MAP_SYNC - - #undef MCL_CURRENT - #define MCL_CURRENT 0x2000 -diff --git a/arch/powerpc64/bits/ptrace.h b/arch/powerpc64/bits/ptrace.h -new file mode 100644 -index 00000000..75086ca0 ---- /dev/null -+++ b/arch/powerpc64/bits/ptrace.h -@@ -0,0 +1,23 @@ -+#define PTRACE_GETVRREGS 0x12 -+#define PTRACE_SETVRREGS 0x13 -+#define PTRACE_GETEVRREGS 0x14 -+#define PTRACE_SETEVRREGS 0x15 -+#define PTRACE_GETREGS64 0x16 -+#define PTRACE_SETREGS64 0x17 -+#define PTRACE_GET_DEBUGREG 0x19 -+#define PTRACE_SET_DEBUGREG 0x1a -+#define PTRACE_GETVSRREGS 0x1b -+#define PTRACE_SETVSRREGS 0x1c -+#define PTRACE_SINGLEBLOCK 0x100 -+ -+#define PT_GETVRREGS PTRACE_GETVRREGS -+#define PT_SETVRREGS PTRACE_SETVRREGS -+#define PT_GETEVRREGS PTRACE_GETEVRREGS -+#define PT_SETEVRREGS PTRACE_SETEVRREGS -+#define PT_GETREGS64 PTRACE_GETREGS64 -+#define PT_SETREGS64 PTRACE_SETREGS64 -+#define PT_GET_DEBUGREG PTRACE_GET_DEBUGREG -+#define PT_SET_DEBUGREG PTRACE_SET_DEBUGREG -+#define PT_GETVSRREGS PTRACE_GETVSRREGS -+#define PT_SETVSRREGS PTRACE_SETVSRREGS -+#define PT_STEPBLOCK PTRACE_SINGLEBLOCK -diff --git a/arch/powerpc64/bits/socket.h b/arch/powerpc64/bits/socket.h -index 2f748ae8..0f3c9aac 100644 ---- a/arch/powerpc64/bits/socket.h -+++ b/arch/powerpc64/bits/socket.h -@@ -54,6 +54,7 @@ struct cmsghdr { - #define SO_PASSCRED 20 - #define SO_PEERCRED 21 - #define SO_ACCEPTCONN 30 -+#define SO_PEERSEC 31 - #define SO_SNDBUFFORCE 32 - #define SO_RCVBUFFORCE 33 - #define SO_PROTOCOL 38 -diff --git a/arch/powerpc64/bits/syscall.h.in b/arch/powerpc64/bits/syscall.h.in -index 936f43c0..1da1ecc0 100644 ---- a/arch/powerpc64/bits/syscall.h.in -+++ b/arch/powerpc64/bits/syscall.h.in -@@ -359,4 +359,7 @@ - #define __NR_pwritev2 381 - #define __NR_kexec_file_load 382 - #define __NR_statx 383 -+#define __NR_pkey_alloc 384 -+#define __NR_pkey_free 385 -+#define __NR_pkey_mprotect 386 - -diff --git a/arch/powerpc64/bits/termios.h b/arch/powerpc64/bits/termios.h -index 0b09630c..e3f22e86 100644 ---- a/arch/powerpc64/bits/termios.h -+++ b/arch/powerpc64/bits/termios.h -@@ -53,6 +53,7 @@ struct termios { - #define ONLRET 0000040 - #define OFILL 0000100 - #define OFDEL 0000200 -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) - #define NLDLY 0001400 - #define NL0 0000000 - #define NL1 0000400 -@@ -74,6 +75,7 @@ struct termios { - #define BSDLY 0100000 - #define BS0 0000000 - #define BS1 0100000 -+#endif - - #define VTDLY 0200000 - #define VT0 0000000 -@@ -165,5 +167,5 @@ struct termios { - #define EXTPROC 0x10000000 - - #define XTABS 00006000 --#define TIOCSER_TEMT 1 -+#define TIOCSER_TEMT 0x01 - #endif -diff --git a/arch/powerpc64/pthread_arch.h b/arch/powerpc64/pthread_arch.h -index 2f976fe2..37b75e29 100644 ---- a/arch/powerpc64/pthread_arch.h -+++ b/arch/powerpc64/pthread_arch.h -@@ -6,6 +6,7 @@ static inline struct pthread *__pthread_self() - } - - #define TLS_ABOVE_TP -+#define GAP_ABOVE_TP 0 - #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000) - - #define DTP_OFFSET 0x8000 -diff --git a/arch/s390x/bits/limits.h b/arch/s390x/bits/limits.h -index 792a30b9..86ef7663 100644 ---- a/arch/s390x/bits/limits.h -+++ b/arch/s390x/bits/limits.h -@@ -1,6 +1,6 @@ - #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ - || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) --#define PAGE_SIZE 4096 -+#define PAGESIZE 4096 - #define LONG_BIT 64 - #endif - -diff --git a/arch/s390x/bits/ptrace.h b/arch/s390x/bits/ptrace.h -new file mode 100644 -index 00000000..d50e3262 ---- /dev/null -+++ b/arch/s390x/bits/ptrace.h -@@ -0,0 +1,9 @@ -+#define PTRACE_SINGLEBLOCK 12 -+#define PTRACE_PEEKUSR_AREA 0x5000 -+#define PTRACE_POKEUSR_AREA 0x5001 -+#define PTRACE_GET_LAST_BREAK 0x5006 -+#define PTRACE_ENABLE_TE 0x5009 -+#define PTRACE_DISABLE_TE 0x5010 -+#define PTRACE_TE_ABORT_RAND 0x5011 -+ -+#define PT_STEPBLOCK PTRACE_SINGLEBLOCK -diff --git a/arch/s390x/bits/syscall.h.in b/arch/s390x/bits/syscall.h.in -index 4fe1a64f..409e9155 100644 ---- a/arch/s390x/bits/syscall.h.in -+++ b/arch/s390x/bits/syscall.h.in -@@ -322,4 +322,6 @@ - #define __NR_pwritev2 377 - #define __NR_s390_guarded_storage 378 - #define __NR_statx 379 -+#define __NR_s390_sthyi 380 -+#define __NR_kexec_file_load 381 - -diff --git a/arch/s390x/bits/user.h b/arch/s390x/bits/user.h -index 17bce16f..ff3f0483 100644 ---- a/arch/s390x/bits/user.h -+++ b/arch/s390x/bits/user.h -@@ -54,8 +54,8 @@ struct user { - char u_comm[32]; - }; - --#define PAGE_MASK (~(PAGE_SIZE-1)) --#define NBPG PAGE_SIZE -+#define PAGE_MASK (~(PAGESIZE-1)) -+#define NBPG PAGESIZE - #define UPAGES 1 - #define HOST_TEXT_START_ADDR (u.start_code) - #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -diff --git a/arch/sh/bits/limits.h b/arch/sh/bits/limits.h -index 65a3dd64..c340ceb2 100644 ---- a/arch/sh/bits/limits.h -+++ b/arch/sh/bits/limits.h -@@ -1,6 +1,6 @@ - #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ - || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) --#define PAGE_SIZE 4096 -+#define PAGESIZE 4096 - #define LONG_BIT 32 - #endif - -diff --git a/arch/sh/pthread_arch.h b/arch/sh/pthread_arch.h -index 2756e7ec..a7dd27a6 100644 ---- a/arch/sh/pthread_arch.h -+++ b/arch/sh/pthread_arch.h -@@ -2,10 +2,16 @@ static inline struct pthread *__pthread_self() - { - char *self; - __asm__ __volatile__ ("stc gbr,%0" : "=r" (self) ); -- return (struct pthread *) (self + 8 - sizeof(struct pthread)); -+ return (struct pthread *) (self - sizeof(struct pthread)); - } - - #define TLS_ABOVE_TP --#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8) -+#define GAP_ABOVE_TP 8 -+#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread)) - - #define MC_PC sc_pc -+ -+#ifdef __FDPIC__ -+#define MC_GOT sc_regs[12] -+#define CANCEL_GOT (*(uintptr_t *)((char *)__syscall_cp_asm+sizeof(uintptr_t))) -+#endif -diff --git a/arch/sh/reloc.h b/arch/sh/reloc.h -index 0238ce07..a1f16cb1 100644 ---- a/arch/sh/reloc.h -+++ b/arch/sh/reloc.h -@@ -20,7 +20,7 @@ - - #define LDSO_ARCH "sh" ENDIAN_SUFFIX FP_SUFFIX ABI_SUFFIX - --#define TPOFF_K 8 -+#define TPOFF_K 0 - - #define REL_SYMBOLIC R_SH_DIR32 - #define REL_OFFSET R_SH_REL32 -diff --git a/arch/sh/syscall_arch.h b/arch/sh/syscall_arch.h -index 84758fe0..48f61d94 100644 ---- a/arch/sh/syscall_arch.h -+++ b/arch/sh/syscall_arch.h -@@ -86,3 +86,5 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo - register long r1 __asm__("r1") = f; - __asm_syscall(22, "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "0"(r0), "r"(r1)); - } -+ -+#define SYSCALL_IPC_BROKEN_MODE -diff --git a/arch/x32/atomic_arch.h b/arch/x32/atomic_arch.h -index a744c299..918c2d4e 100644 ---- a/arch/x32/atomic_arch.h -+++ b/arch/x32/atomic_arch.h -@@ -106,8 +106,8 @@ static inline int a_ctz_64(uint64_t x) - return x; - } - --#define a_ctz_l a_ctz_l --static inline int a_ctz_l(unsigned long x) -+#define a_ctz_32 a_ctz_32 -+static inline int a_ctz_32(uint32_t x) - { - __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) ); - return x; -diff --git a/arch/x32/bits/limits.h b/arch/x32/bits/limits.h -index 65a3dd64..c340ceb2 100644 ---- a/arch/x32/bits/limits.h -+++ b/arch/x32/bits/limits.h -@@ -1,6 +1,6 @@ - #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ - || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) --#define PAGE_SIZE 4096 -+#define PAGESIZE 4096 - #define LONG_BIT 32 - #endif - -diff --git a/arch/x32/bits/ptrace.h b/arch/x32/bits/ptrace.h -new file mode 100644 -index 00000000..7f8a09b5 ---- /dev/null -+++ b/arch/x32/bits/ptrace.h -@@ -0,0 +1,13 @@ -+#define PTRACE_GET_THREAD_AREA 25 -+#define PTRACE_SET_THREAD_AREA 26 -+#define PTRACE_ARCH_PRCTL 30 -+#define PTRACE_SYSEMU 31 -+#define PTRACE_SYSEMU_SINGLESTEP 32 -+#define PTRACE_SINGLEBLOCK 33 -+ -+#define PT_GET_THREAD_AREA PTRACE_GET_THREAD_AREA -+#define PT_SET_THREAD_AREA PTRACE_SET_THREAD_AREA -+#define PT_ARCH_PRCTL PTRACE_ARCH_PRCTL -+#define PT_SYSEMU PTRACE_SYSEMU -+#define PT_SYSEMU_SINGLESTEP PTRACE_SYSEMU_SINGLESTEP -+#define PT_STEPBLOCK PTRACE_SINGLEBLOCK -diff --git a/arch/x32/bits/user.h b/arch/x32/bits/user.h -index 471bb19d..4073cc06 100644 ---- a/arch/x32/bits/user.h -+++ b/arch/x32/bits/user.h -@@ -34,8 +34,8 @@ struct user { - unsigned long u_debugreg[8]; - }; - --#define PAGE_MASK (~(PAGE_SIZE-1)) --#define NBPG PAGE_SIZE -+#define PAGE_MASK (~(PAGESIZE-1)) -+#define NBPG PAGESIZE - #define UPAGES 1 - #define HOST_TEXT_START_ADDR (u.start_code) - #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -diff --git a/arch/x86_64/bits/limits.h b/arch/x86_64/bits/limits.h -index 792a30b9..86ef7663 100644 ---- a/arch/x86_64/bits/limits.h -+++ b/arch/x86_64/bits/limits.h -@@ -1,6 +1,6 @@ - #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ - || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) --#define PAGE_SIZE 4096 -+#define PAGESIZE 4096 - #define LONG_BIT 64 - #endif - -diff --git a/arch/x86_64/bits/ptrace.h b/arch/x86_64/bits/ptrace.h -new file mode 100644 -index 00000000..7f8a09b5 ---- /dev/null -+++ b/arch/x86_64/bits/ptrace.h -@@ -0,0 +1,13 @@ -+#define PTRACE_GET_THREAD_AREA 25 -+#define PTRACE_SET_THREAD_AREA 26 -+#define PTRACE_ARCH_PRCTL 30 -+#define PTRACE_SYSEMU 31 -+#define PTRACE_SYSEMU_SINGLESTEP 32 -+#define PTRACE_SINGLEBLOCK 33 -+ -+#define PT_GET_THREAD_AREA PTRACE_GET_THREAD_AREA -+#define PT_SET_THREAD_AREA PTRACE_SET_THREAD_AREA -+#define PT_ARCH_PRCTL PTRACE_ARCH_PRCTL -+#define PT_SYSEMU PTRACE_SYSEMU -+#define PT_SYSEMU_SINGLESTEP PTRACE_SYSEMU_SINGLESTEP -+#define PT_STEPBLOCK PTRACE_SINGLEBLOCK -diff --git a/arch/x86_64/bits/user.h b/arch/x86_64/bits/user.h -index 471bb19d..4073cc06 100644 ---- a/arch/x86_64/bits/user.h -+++ b/arch/x86_64/bits/user.h -@@ -34,8 +34,8 @@ struct user { - unsigned long u_debugreg[8]; - }; - --#define PAGE_MASK (~(PAGE_SIZE-1)) --#define NBPG PAGE_SIZE -+#define PAGE_MASK (~(PAGESIZE-1)) -+#define NBPG PAGESIZE - #define UPAGES 1 - #define HOST_TEXT_START_ADDR (u.start_code) - #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -diff --git a/configure b/configure -index 1e59c461..f940af9a 100755 ---- a/configure -+++ b/configure -@@ -320,6 +320,7 @@ i?86*) ARCH=i386 ;; - x86_64-x32*|x32*|x86_64*x32) ARCH=x32 ;; - x86_64-nt64*) ARCH=nt64 ;; - x86_64*) ARCH=x86_64 ;; -+m68k*) ARCH=m68k ;; - mips64*|mipsisa64*) ARCH=mips64 ;; - mips*) ARCH=mips ;; - microblaze*) ARCH=microblaze ;; -@@ -590,10 +591,12 @@ tryldflag LDFLAGS_AUTO -Wl,--no-undefined - # versions built without shared library support and pcc are broken. - tryldflag LDFLAGS_AUTO -Wl,--exclude-libs=ALL - --# Linking with -Bsymbolic-functions is no longer mandatory for --# the dynamic linker to work, but enable it if it works as --# a linking optimization. --tryldflag LDFLAGS_AUTO -Wl,-Bsymbolic-functions -+# Public data symbols must be interposable to allow for copy -+# relocations, but otherwise we want to bind symbols at libc link -+# time to eliminate startup relocations and PLT overhead. Use -+# --dynamic-list rather than -Bsymbolic-functions for greater -+# control over what symbols are left unbound. -+tryldflag LDFLAGS_AUTO -Wl,--dynamic-list="$srcdir/dynamic.list" - - # Find compiler runtime library - test -z "$LIBCC" && tryldflag LIBCC -lgcc && tryldflag LIBCC -lgcc_eh -@@ -639,6 +642,13 @@ if test "$ARCH" = "aarch64" ; then - trycppif __AARCH64EB__ "$t" && SUBARCH=${SUBARCH}_be - fi - -+if test "$ARCH" = "m68k" ; then -+if trycppif "__HAVE_68881__" ; then : ; -+elif trycppif "__mcffpu__" ; then SUBARCH="-fp64" -+else SUBARCH="-sf" -+fi -+fi -+ - if test "$ARCH" = "mips" ; then - trycppif "__mips_isa_rev >= 6" "$t" && SUBARCH=${SUBARCH}r6 - trycppif "_MIPSEL || __MIPSEL || __MIPSEL__" "$t" && SUBARCH=${SUBARCH}el -diff --git a/dynamic.list b/dynamic.list -new file mode 100644 -index 00000000..686f8eb4 ---- /dev/null -+++ b/dynamic.list -@@ -0,0 +1,44 @@ -+{ -+environ; -+__environ; -+ -+stdin; -+stdout; -+stderr; -+ -+malloc; -+calloc; -+realloc; -+free; -+memalign; -+posix_memalign; -+aligned_alloc; -+malloc_usable_size; -+ -+timezone; -+daylight; -+tzname; -+__timezone; -+__daylight; -+__tzname; -+ -+signgam; -+__signgam; -+ -+optarg; -+optind; -+opterr; -+optreset; -+__optreset; -+ -+getdate_err; -+ -+h_errno; -+ -+program_invocation_name; -+program_invocation_short_name; -+__progname; -+__progname_full; -+ -+__stack_chk_guard; -+}; -diff --git a/include/alltypes.h.in b/include/alltypes.h.in -index 6a9c105f..622ca01d 100644 ---- a/include/alltypes.h.in -+++ b/include/alltypes.h.in -@@ -7,10 +7,10 @@ TYPEDEF _Addr regoff_t; - TYPEDEF _Reg register_t; - - TYPEDEF signed char int8_t; --TYPEDEF short int16_t; --TYPEDEF int int32_t; --TYPEDEF _Int64 int64_t; --TYPEDEF _Int64 intmax_t; -+TYPEDEF signed short int16_t; -+TYPEDEF signed int int32_t; -+TYPEDEF signed _Int64 int64_t; -+TYPEDEF signed _Int64 intmax_t; - TYPEDEF unsigned char uint8_t; - TYPEDEF unsigned short uint16_t; - TYPEDEF unsigned int uint32_t; -diff --git a/include/elf.h b/include/elf.h -index e79915fe..c2297353 100644 ---- a/include/elf.h -+++ b/include/elf.h -@@ -623,6 +623,7 @@ typedef struct { - - - #define NT_PRSTATUS 1 -+#define NT_PRFPREG 2 - #define NT_FPREGSET 2 - #define NT_PRPSINFO 3 - #define NT_PRXREG 4 -@@ -644,6 +645,19 @@ typedef struct { - #define NT_PPC_VMX 0x100 - #define NT_PPC_SPE 0x101 - #define NT_PPC_VSX 0x102 -+#define NT_PPC_TAR 0x103 -+#define NT_PPC_PPR 0x104 -+#define NT_PPC_DSCR 0x105 -+#define NT_PPC_EBB 0x106 -+#define NT_PPC_PMU 0x107 -+#define NT_PPC_TM_CGPR 0x108 -+#define NT_PPC_TM_CFPR 0x109 -+#define NT_PPC_TM_CVMX 0x10a -+#define NT_PPC_TM_CVSX 0x10b -+#define NT_PPC_TM_SPR 0x10c -+#define NT_PPC_TM_CTAR 0x10d -+#define NT_PPC_TM_CPPR 0x10e -+#define NT_PPC_TM_CDSCR 0x10f - #define NT_386_TLS 0x200 - #define NT_386_IOPERM 0x201 - #define NT_X86_XSTATE 0x202 -@@ -656,14 +670,21 @@ typedef struct { - #define NT_S390_LAST_BREAK 0x306 - #define NT_S390_SYSTEM_CALL 0x307 - #define NT_S390_TDB 0x308 -+#define NT_S390_VXRS_LOW 0x309 -+#define NT_S390_VXRS_HIGH 0x30a -+#define NT_S390_GS_CB 0x30b -+#define NT_S390_GS_BC 0x30c -+#define NT_S390_RI_CB 0x30d - #define NT_ARM_VFP 0x400 - #define NT_ARM_TLS 0x401 - #define NT_ARM_HW_BREAK 0x402 - #define NT_ARM_HW_WATCH 0x403 - #define NT_ARM_SYSTEM_CALL 0x404 -+#define NT_ARM_SVE 0x405 - #define NT_METAG_CBUF 0x500 - #define NT_METAG_RPIPE 0x501 - #define NT_METAG_TLS 0x502 -+#define NT_ARC_V2 0x600 - #define NT_VERSION 1 - - -@@ -721,7 +742,8 @@ typedef struct { - #define DT_ENCODING 32 - #define DT_PREINIT_ARRAY 32 - #define DT_PREINIT_ARRAYSZ 33 --#define DT_NUM 34 -+#define DT_SYMTAB_SHNDX 34 -+#define DT_NUM 35 - #define DT_LOOS 0x6000000d - #define DT_HIOS 0x6ffff000 - #define DT_LOPROC 0x70000000 -@@ -821,6 +843,8 @@ typedef struct { - #define DF_1_SYMINTPOSE 0x00800000 - #define DF_1_GLOBAUDIT 0x01000000 - #define DF_1_SINGLETON 0x02000000 -+#define DF_1_STUB 0x04000000 -+#define DF_1_PIE 0x08000000 - - #define DTF_1_PARINIT 0x00000001 - #define DTF_1_CONFEXP 0x00000002 -@@ -1002,6 +1026,14 @@ typedef struct { - #define AT_L2_CACHESHAPE 36 - #define AT_L3_CACHESHAPE 37 - -+#define AT_L1I_CACHESIZE 40 -+#define AT_L1I_CACHEGEOMETRY 41 -+#define AT_L1D_CACHESIZE 42 -+#define AT_L1D_CACHEGEOMETRY 43 -+#define AT_L2_CACHESIZE 44 -+#define AT_L2_CACHEGEOMETRY 45 -+#define AT_L3_CACHESIZE 46 -+#define AT_L3_CACHEGEOMETRY 47 - - - -@@ -1097,7 +1129,25 @@ typedef struct { - #define R_68K_GLOB_DAT 20 - #define R_68K_JMP_SLOT 21 - #define R_68K_RELATIVE 22 --#define R_68K_NUM 23 -+#define R_68K_TLS_GD32 25 -+#define R_68K_TLS_GD16 26 -+#define R_68K_TLS_GD8 27 -+#define R_68K_TLS_LDM32 28 -+#define R_68K_TLS_LDM16 29 -+#define R_68K_TLS_LDM8 30 -+#define R_68K_TLS_LDO32 31 -+#define R_68K_TLS_LDO16 32 -+#define R_68K_TLS_LDO8 33 -+#define R_68K_TLS_IE32 34 -+#define R_68K_TLS_IE16 35 -+#define R_68K_TLS_IE8 36 -+#define R_68K_TLS_LE32 37 -+#define R_68K_TLS_LE16 38 -+#define R_68K_TLS_LE8 39 -+#define R_68K_TLS_DTPMOD32 40 -+#define R_68K_TLS_DTPREL32 41 -+#define R_68K_TLS_TPREL32 42 -+#define R_68K_NUM 43 - - #define R_386_NONE 0 - #define R_386_32 1 -@@ -2233,6 +2283,7 @@ enum - - #define PPC64_OPT_TLS 1 - #define PPC64_OPT_MULTI_TOC 2 -+#define PPC64_OPT_LOCALENTRY 4 - - #define STO_PPC64_LOCAL_BIT 5 - #define STO_PPC64_LOCAL_MASK 0xe0 -diff --git a/include/limits.h b/include/limits.h -index f9805a1e..02c2139d 100644 ---- a/include/limits.h -+++ b/include/limits.h -@@ -9,7 +9,7 @@ - - /* Support signed or unsigned plain-char */ - --#if '\0'-1 > 0 -+#if '\xff' > 0 - #define CHAR_MIN 0 - #define CHAR_MAX 255 - #else -@@ -40,14 +40,9 @@ - || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - - #define PIPE_BUF 4096 --#ifdef PAGE_SIZE --#define PAGESIZE PAGE_SIZE --#endif - #define FILESIZEBITS 64 - #define NAME_MAX 255 --#define SYMLINK_MAX 255 - #define PATH_MAX 4096 --#define NZERO 20 - #define NGROUPS_MAX 32 - #define ARG_MAX 131072 - #define IOV_MAX 1024 -@@ -82,13 +77,22 @@ - #define RE_DUP_MAX 255 - - #define NL_ARGMAX 9 --#define NL_LANGMAX 32 - #define NL_MSGMAX 32767 - #define NL_SETMAX 255 - #define NL_TEXTMAX 2048 - - #endif - -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) -+ -+#ifdef PAGESIZE -+#define PAGE_SIZE PAGESIZE -+#endif -+#define NZERO 20 -+#define NL_LANGMAX 32 -+ -+#endif -+ - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \ - || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700) - -diff --git a/include/math.h b/include/math.h -index 6ac91da2..fea34686 100644 ---- a/include/math.h -+++ b/include/math.h -@@ -27,7 +27,7 @@ extern "C" { - #define MATH_ERREXCEPT 2 - #define math_errhandling 2 - --#define FP_ILOGBNAN (-1-(int)(((unsigned)-1)>>1)) -+#define FP_ILOGBNAN (-1-0x7fffffff) - #define FP_ILOGB0 FP_ILOGBNAN - - #define FP_NAN 0 -diff --git a/include/net/if_arp.h b/include/net/if_arp.h -index c832ff95..27becc83 100644 ---- a/include/net/if_arp.h -+++ b/include/net/if_arp.h -@@ -59,6 +59,7 @@ struct arphdr { - #define ARPHRD_LAPB 516 - #define ARPHRD_DDCMP 517 - #define ARPHRD_RAWHDLC 518 -+#define ARPHRD_RAWIP 519 - - #define ARPHRD_TUNNEL 768 - #define ARPHRD_TUNNEL6 769 -diff --git a/include/netinet/if_ether.h b/include/netinet/if_ether.h -index 97134d75..ecd6c73c 100644 ---- a/include/netinet/if_ether.h -+++ b/include/netinet/if_ether.h -@@ -5,6 +5,7 @@ - #include <sys/types.h> - - #define ETH_ALEN 6 -+#define ETH_TLEN 2 - #define ETH_HLEN 14 - #define ETH_ZLEN 60 - #define ETH_DATA_LEN 1500 -@@ -17,6 +18,7 @@ - #define ETH_P_PUP 0x0200 - #define ETH_P_PUPAT 0x0201 - #define ETH_P_TSN 0x22F0 -+#define ETH_P_ERSPAN2 0x22EB - #define ETH_P_IP 0x0800 - #define ETH_P_X25 0x0805 - #define ETH_P_ARP 0x0806 -@@ -53,6 +55,8 @@ - #define ETH_P_AOE 0x88A2 - #define ETH_P_8021AD 0x88A8 - #define ETH_P_802_EX1 0x88B5 -+#define ETH_P_ERSPAN 0x88BE -+#define ETH_P_PREAUTH 0x88C7 - #define ETH_P_TIPC 0x88CA - #define ETH_P_MACSEC 0x88E5 - #define ETH_P_8021AH 0x88E7 -@@ -66,11 +70,13 @@ - #define ETH_P_IBOE 0x8915 - #define ETH_P_80221 0x8917 - #define ETH_P_HSR 0x892F -+#define ETH_P_NSH 0x894F - #define ETH_P_LOOPBACK 0x9000 - #define ETH_P_QINQ1 0x9100 - #define ETH_P_QINQ2 0x9200 - #define ETH_P_QINQ3 0x9300 - #define ETH_P_EDSA 0xDADA -+#define ETH_P_IFE 0xED3E - #define ETH_P_AF_IUCV 0xFBFB - - #define ETH_P_802_3_MIN 0x0600 -@@ -100,6 +106,7 @@ - #define ETH_P_IEEE802154 0x00F6 - #define ETH_P_CAIF 0x00F7 - #define ETH_P_XDSA 0x00F8 -+#define ETH_P_MAP 0x00F9 - - struct ethhdr { - uint8_t h_dest[ETH_ALEN]; -diff --git a/include/netinet/in.h b/include/netinet/in.h -index f18b478d..192679a6 100644 ---- a/include/netinet/in.h -+++ b/include/netinet/in.h -@@ -363,6 +363,7 @@ struct ip6_mtuinfo { - #define IPV6_TRANSPARENT 75 - #define IPV6_UNICAST_IF 76 - #define IPV6_RECVFRAGSIZE 77 -+#define IPV6_FREEBIND 78 - - #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP - #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP -diff --git a/include/netinet/tcp.h b/include/netinet/tcp.h -index 4d20936a..1e2acfbf 100644 ---- a/include/netinet/tcp.h -+++ b/include/netinet/tcp.h -@@ -34,6 +34,8 @@ - #define TCP_FASTOPEN_CONNECT 30 - #define TCP_ULP 31 - #define TCP_MD5SIG_EXT 32 -+#define TCP_FASTOPEN_KEY 33 -+#define TCP_FASTOPEN_NO_COOKIE 34 - - #define TCP_ESTABLISHED 1 - #define TCP_SYN_SENT 2 -@@ -54,6 +56,16 @@ enum { - TCP_NLA_SNDBUF_LIMITED, - TCP_NLA_DATA_SEGS_OUT, - TCP_NLA_TOTAL_RETRANS, -+ TCP_NLA_PACING_RATE, -+ TCP_NLA_DELIVERY_RATE, -+ TCP_NLA_SND_CWND, -+ TCP_NLA_REORDERING, -+ TCP_NLA_MIN_RTT, -+ TCP_NLA_RECUR_RETRANS, -+ TCP_NLA_DELIVERY_RATE_APP_LMT, -+ TCP_NLA_SNDQ_SIZE, -+ TCP_NLA_CA_STATE, -+ TCP_NLA_SND_SSTHRESH, - }; - - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -@@ -220,6 +232,14 @@ struct tcp_md5sig { - uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN]; - }; - -+struct tcp_diag_md5sig { -+ uint8_t tcpm_family; -+ uint8_t tcpm_prefixlen; -+ uint16_t tcpm_keylen; -+ uint32_t tcpm_addr[4]; -+ uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN]; -+}; -+ - struct tcp_repair_window { - uint32_t snd_wl1; - uint32_t snd_wnd; -diff --git a/include/signal.h b/include/signal.h -index 2c8b3d55..a4f85cca 100644 ---- a/include/signal.h -+++ b/include/signal.h -@@ -210,7 +210,7 @@ int sigpending(sigset_t *); - int sigwait(const sigset_t *__restrict, int *__restrict); - int sigwaitinfo(const sigset_t *__restrict, siginfo_t *__restrict); - int sigtimedwait(const sigset_t *__restrict, siginfo_t *__restrict, const struct timespec *__restrict); --int sigqueue(pid_t, int, const union sigval); -+int sigqueue(pid_t, int, union sigval); - - int pthread_sigmask(int, const sigset_t *__restrict, sigset_t *__restrict); - int pthread_kill(pthread_t, int); -@@ -231,6 +231,8 @@ int sigrelse(int); - void (*sigset(int, void (*)(int)))(int); - #define TRAP_BRKPT 1 - #define TRAP_TRACE 2 -+#define TRAP_BRANCH 3 -+#define TRAP_HWBKPT 4 - #define POLL_IN 1 - #define POLL_OUT 2 - #define POLL_MSG 3 -diff --git a/include/stdio.h b/include/stdio.h -index 7c4f9ee4..afadd912 100644 ---- a/include/stdio.h -+++ b/include/stdio.h -@@ -49,6 +49,7 @@ extern "C" { - - typedef union _G_fpos64_t { - char __opaque[16]; -+ long long __lldata; - double __align; - } fpos_t; - diff --git a/include/stdlib.h b/include/stdlib.h index 42ca8336..4bbaded0 100644 --- a/include/stdlib.h @@ -2736,369 +37,6 @@ index 42ca8336..4bbaded0 100644 int mkostemps (char *, int, int); void *valloc (size_t); void *memalign(size_t, size_t); -diff --git a/include/string.h b/include/string.h -index ce1dc300..795a2abc 100644 ---- a/include/string.h -+++ b/include/string.h -@@ -82,6 +82,7 @@ void *memccpy (void *__restrict, const void *__restrict, int, size_t); - char *strsep(char **, const char *); - size_t strlcat (char *, const char *, size_t); - size_t strlcpy (char *, const char *, size_t); -+void explicit_bzero (void *, size_t); - #endif - - #ifdef _GNU_SOURCE -diff --git a/include/sys/epoll.h b/include/sys/epoll.h -index ffe2311f..ac81a841 100644 ---- a/include/sys/epoll.h -+++ b/include/sys/epoll.h -@@ -21,6 +21,7 @@ enum EPOLL_EVENTS { __EPOLL_DUMMY }; - #define EPOLLPRI 0x002 - #define EPOLLOUT 0x004 - #define EPOLLRDNORM 0x040 -+#define EPOLLNVAL 0x020 - #define EPOLLRDBAND 0x080 - #define EPOLLWRNORM 0x100 - #define EPOLLWRBAND 0x200 -diff --git a/include/sys/kd.h b/include/sys/kd.h -index 793fd59f..42122b9c 100644 ---- a/include/sys/kd.h -+++ b/include/sys/kd.h -@@ -1,8 +1 @@ --#ifndef _SYS_KD_H --#define _SYS_KD_H -- --#define _LINUX_TYPES_H --#include <linux/kd.h> --#undef _LINUX_TYPES_H -- --#endif -+#include <bits/kd.h> -diff --git a/include/sys/mman.h b/include/sys/mman.h -index 8a5149c9..99d02a2e 100644 ---- a/include/sys/mman.h -+++ b/include/sys/mman.h -@@ -20,6 +20,7 @@ extern "C" { - - #define MAP_SHARED 0x01 - #define MAP_PRIVATE 0x02 -+#define MAP_SHARED_VALIDATE 0x03 - #define MAP_TYPE 0x0f - #define MAP_FIXED 0x10 - #define MAP_ANON 0x20 -@@ -33,8 +34,23 @@ extern "C" { - #define MAP_NONBLOCK 0x10000 - #define MAP_STACK 0x20000 - #define MAP_HUGETLB 0x40000 -+#define MAP_SYNC 0x80000 -+#define MAP_FIXED_NOREPLACE 0x100000 - #define MAP_FILE 0 - -+#define MAP_HUGE_SHIFT 26 -+#define MAP_HUGE_MASK 0x3f -+#define MAP_HUGE_64KB (16 << 26) -+#define MAP_HUGE_512KB (19 << 26) -+#define MAP_HUGE_1MB (20 << 26) -+#define MAP_HUGE_2MB (21 << 26) -+#define MAP_HUGE_8MB (23 << 26) -+#define MAP_HUGE_16MB (24 << 26) -+#define MAP_HUGE_256MB (28 << 26) -+#define MAP_HUGE_1GB (30 << 26) -+#define MAP_HUGE_2GB (31 << 26) -+#define MAP_HUGE_16GB (34U << 26) -+ - #define PROT_NONE 0 - #define PROT_READ 1 - #define PROT_WRITE 2 -@@ -72,10 +88,23 @@ extern "C" { - #define MADV_NOHUGEPAGE 15 - #define MADV_DONTDUMP 16 - #define MADV_DODUMP 17 -+#define MADV_WIPEONFORK 18 -+#define MADV_KEEPONFORK 19 - #define MADV_HWPOISON 100 - #define MADV_SOFT_OFFLINE 101 - #endif - -+#ifdef _GNU_SOURCE -+#define MREMAP_MAYMOVE 1 -+#define MREMAP_FIXED 2 -+ -+#define MLOCK_ONFAULT 0x01 -+ -+#define MFD_CLOEXEC 0x0001U -+#define MFD_ALLOW_SEALING 0x0002U -+#define MFD_HUGETLB 0x0004U -+#endif -+ - #include <bits/mman.h> - - void *mmap (void *, size_t, int, int, int, off_t); -@@ -92,14 +121,13 @@ int mlockall (int); - int munlockall (void); - - #ifdef _GNU_SOURCE --#define MREMAP_MAYMOVE 1 --#define MREMAP_FIXED 2 - void *mremap (void *, size_t, size_t, int, ...); - int remap_file_pages (void *, size_t, int, size_t, int); -+int memfd_create (const char *, unsigned); -+int mlock2 (const void *, size_t, unsigned); - #endif - - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) --#define MLOCK_ONFAULT 0x01 - int madvise (void *, size_t, int); - int mincore (void *, size_t, unsigned char *); - #endif -diff --git a/include/sys/msg.h b/include/sys/msg.h -index 139f22b7..be6afc34 100644 ---- a/include/sys/msg.h -+++ b/include/sys/msg.h -@@ -27,6 +27,7 @@ typedef unsigned long msglen_t; - - #define MSG_STAT 11 - #define MSG_INFO 12 -+#define MSG_STAT_ANY 13 - - struct msginfo { - int msgpool, msgmap, msgmax, msgmnb, msgmni, msgssz, msgtql; -diff --git a/include/sys/prctl.h b/include/sys/prctl.h -index 24f4f8bd..af76408c 100644 ---- a/include/sys/prctl.h -+++ b/include/sys/prctl.h -@@ -130,6 +130,21 @@ struct prctl_mm_map { - #define PR_CAP_AMBIENT_LOWER 3 - #define PR_CAP_AMBIENT_CLEAR_ALL 4 - -+#define PR_SVE_SET_VL 50 -+#define PR_SVE_SET_VL_ONEXEC (1 << 18) -+#define PR_SVE_GET_VL 51 -+#define PR_SVE_VL_LEN_MASK 0xffff -+#define PR_SVE_VL_INHERIT (1 << 17) -+ -+#define PR_GET_SPECULATION_CTRL 52 -+#define PR_SET_SPECULATION_CTRL 53 -+#define PR_SPEC_STORE_BYPASS 0 -+#define PR_SPEC_NOT_AFFECTED 0 -+#define PR_SPEC_PRCTL (1UL << 0) -+#define PR_SPEC_ENABLE (1UL << 1) -+#define PR_SPEC_DISABLE (1UL << 2) -+#define PR_SPEC_FORCE_DISABLE (1UL << 3) -+ - int prctl (int, ...); - - #ifdef __cplusplus -diff --git a/include/sys/ptrace.h b/include/sys/ptrace.h -index d9d45408..229e1f3d 100644 ---- a/include/sys/ptrace.h -+++ b/include/sys/ptrace.h -@@ -40,6 +40,7 @@ extern "C" { - #define PTRACE_GETSIGMASK 0x420a - #define PTRACE_SETSIGMASK 0x420b - #define PTRACE_SECCOMP_GET_FILTER 0x420c -+#define PTRACE_SECCOMP_GET_METADATA 0x420d - - #define PT_READ_I PTRACE_PEEKTEXT - #define PT_READ_D PTRACE_PEEKDATA -@@ -83,15 +84,23 @@ extern "C" { - #define PTRACE_EVENT_VFORK_DONE 5 - #define PTRACE_EVENT_EXIT 6 - #define PTRACE_EVENT_SECCOMP 7 -+#define PTRACE_EVENT_STOP 128 - - #define PTRACE_PEEKSIGINFO_SHARED 1 - --struct ptrace_peeksiginfo_args { -+#include <bits/ptrace.h> -+ -+struct __ptrace_peeksiginfo_args { - uint64_t off; - uint32_t flags; - int32_t nr; - }; - -+struct __ptrace_seccomp_metadata { -+ uint64_t filter_off; -+ uint64_t flags; -+}; -+ - long ptrace(int, ...); - - #ifdef __cplusplus -diff --git a/include/sys/random.h b/include/sys/random.h -new file mode 100644 -index 00000000..4ee7bf2c ---- /dev/null -+++ b/include/sys/random.h -@@ -0,0 +1,19 @@ -+#ifndef _SYS_RANDOM_H -+#define _SYS_RANDOM_H -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define __NEED_size_t -+#define __NEED_ssize_t -+#include <bits/alltypes.h> -+ -+#define GRND_NONBLOCK 0x0001 -+#define GRND_RANDOM 0x0002 -+ -+ssize_t getrandom(void *, size_t, unsigned); -+ -+#ifdef __cplusplus -+} -+#endif -+#endif -diff --git a/include/sys/sem.h b/include/sys/sem.h -index e7c36980..61cdb83d 100644 ---- a/include/sys/sem.h -+++ b/include/sys/sem.h -@@ -33,6 +33,7 @@ extern "C" { - - #define SEM_STAT 18 - #define SEM_INFO 19 -+#define SEM_STAT_ANY 20 - - struct seminfo { - int semmap; -diff --git a/include/sys/shm.h b/include/sys/shm.h -index 67be822b..662fde59 100644 ---- a/include/sys/shm.h -+++ b/include/sys/shm.h -@@ -35,11 +35,25 @@ extern "C" { - #define SHM_UNLOCK 12 - #define SHM_STAT 13 - #define SHM_INFO 14 -+#define SHM_STAT_ANY 15 - #define SHM_DEST 01000 - #define SHM_LOCKED 02000 - #define SHM_HUGETLB 04000 - #define SHM_NORESERVE 010000 - -+#define SHM_HUGE_SHIFT 26 -+#define SHM_HUGE_MASK 0x3f -+#define SHM_HUGE_64KB (16 << 26) -+#define SHM_HUGE_512KB (19 << 26) -+#define SHM_HUGE_1MB (20 << 26) -+#define SHM_HUGE_2MB (21 << 26) -+#define SHM_HUGE_8MB (23 << 26) -+#define SHM_HUGE_16MB (24 << 26) -+#define SHM_HUGE_256MB (28 << 26) -+#define SHM_HUGE_1GB (30 << 26) -+#define SHM_HUGE_2GB (31 << 26) -+#define SHM_HUGE_16GB (34U << 26) -+ - typedef unsigned long shmatt_t; - - void *shmat(int, const void *, int); -diff --git a/include/sys/socket.h b/include/sys/socket.h -index 051d20e0..14be6e99 100644 ---- a/include/sys/socket.h -+++ b/include/sys/socket.h -@@ -108,7 +108,8 @@ struct linger { - #define PF_VSOCK 40 - #define PF_KCM 41 - #define PF_QIPCRTR 42 --#define PF_MAX 43 -+#define PF_SMC 43 -+#define PF_MAX 44 - - #define AF_UNSPEC PF_UNSPEC - #define AF_LOCAL PF_LOCAL -@@ -156,6 +157,7 @@ struct linger { - #define AF_VSOCK PF_VSOCK - #define AF_KCM PF_KCM - #define AF_QIPCRTR PF_QIPCRTR -+#define AF_SMC PF_SMC - #define AF_MAX PF_MAX - - #ifndef SO_DEBUG -@@ -181,6 +183,7 @@ struct linger { - #define SO_RCVTIMEO 20 - #define SO_SNDTIMEO 21 - #define SO_ACCEPTCONN 30 -+#define SO_PEERSEC 31 - #define SO_SNDBUFFORCE 32 - #define SO_RCVBUFFORCE 33 - #define SO_PROTOCOL 38 -@@ -201,7 +204,6 @@ struct linger { - #define SO_TIMESTAMP 29 - #define SCM_TIMESTAMP SO_TIMESTAMP - --#define SO_PEERSEC 31 - #define SO_PASSSEC 34 - #define SO_TIMESTAMPNS 35 - #define SCM_TIMESTAMPNS SO_TIMESTAMPNS -@@ -230,6 +232,7 @@ struct linger { - #define SO_COOKIE 57 - #define SCM_TIMESTAMPING_PKTINFO 58 - #define SO_PEERGROUPS 59 -+#define SO_ZEROCOPY 60 - - #ifndef SOL_SOCKET - #define SOL_SOCKET 1 -@@ -261,6 +264,7 @@ struct linger { - #define SOL_ALG 279 - #define SOL_NFC 280 - #define SOL_KCM 281 -+#define SOL_TLS 282 - - #define SOMAXCONN 128 - -@@ -282,6 +286,7 @@ struct linger { - #define MSG_MORE 0x8000 - #define MSG_WAITFORONE 0x10000 - #define MSG_BATCH 0x40000 -+#define MSG_ZEROCOPY 0x4000000 - #define MSG_FASTOPEN 0x20000000 - #define MSG_CMSG_CLOEXEC 0x40000000 - -diff --git a/include/sys/soundcard.h b/include/sys/soundcard.h -index fade986f..5ca77646 100644 ---- a/include/sys/soundcard.h -+++ b/include/sys/soundcard.h -@@ -1 +1 @@ --#include <linux/soundcard.h> -+#include <bits/soundcard.h> -diff --git a/include/sys/statvfs.h b/include/sys/statvfs.h -index e0839eca..ef07d684 100644 ---- a/include/sys/statvfs.h -+++ b/include/sys/statvfs.h -@@ -42,6 +42,7 @@ int fstatvfs (int, struct statvfs *); - #define ST_IMMUTABLE 512 - #define ST_NOATIME 1024 - #define ST_NODIRATIME 2048 -+#define ST_RELATIME 4096 - - #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE) - #define statvfs64 statvfs -diff --git a/include/sys/vt.h b/include/sys/vt.h -index 834abfbc..5000de49 100644 ---- a/include/sys/vt.h -+++ b/include/sys/vt.h -@@ -1 +1 @@ --#include <linux/vt.h> -+#include <bits/vt.h> -diff --git a/include/tar.h b/include/tar.h -index be589842..2eba66ec 100644 ---- a/include/tar.h -+++ b/include/tar.h -@@ -1,9 +1,13 @@ - #ifndef _TAR_H - #define _TAR_H - -+#include <features.h> -+ - #define TSUID 04000 - #define TSGID 02000 -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) - #define TSVTX 01000 -+#endif - #define TUREAD 00400 - #define TUWRITE 00200 - #define TUEXEC 00100 diff --git a/include/time.h b/include/time.h index 672b3fc3..c5946dd0 100644 --- a/include/time.h @@ -3120,47 +58,10 @@ index 672b3fc3..c5946dd0 100644 #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ -diff --git a/include/uchar.h b/include/uchar.h -index 8dabf1ed..7e5c4d40 100644 ---- a/include/uchar.h -+++ b/include/uchar.h -@@ -3,7 +3,9 @@ - - #ifdef __cplusplus - extern "C" { --#else -+#endif -+ -+#if __cplusplus < 201103L - typedef unsigned short char16_t; - typedef unsigned char32_t; - #endif diff --git a/include/unistd.h b/include/unistd.h -index 09190af4..1bdd3292 100644 +index 9485da7a..1bdd3292 100644 --- a/include/unistd.h +++ b/include/unistd.h -@@ -128,12 +128,11 @@ long fpathconf(int, int); - long sysconf(int); - size_t confstr(int, char *, size_t); - -+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - #define F_ULOCK 0 - #define F_LOCK 1 - #define F_TLOCK 2 - #define F_TEST 3 -- --#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - int setreuid(uid_t, uid_t); - int setregid(gid_t, gid_t); - int lockf(int, int, off_t); -@@ -176,6 +175,7 @@ int acct(const char *); - long syscall(long, ...); - int execvpe(const char *, char *const [], char *const []); - int issetugid(void); -+int getentropy(void *, size_t); - #endif - - #ifdef _GNU_SOURCE @@ -274,6 +274,7 @@ int eaccess(const char *, int); #define _PC_ALLOC_SIZE_MIN 18 #define _PC_SYMLINK_MAX 19 @@ -3186,328 +87,6 @@ index 09190af4..1bdd3292 100644 #ifdef __cplusplus } -diff --git a/ldso/dynlink.c b/ldso/dynlink.c -index 9bf6924b..87281ddb 100644 ---- a/ldso/dynlink.c -+++ b/ldso/dynlink.c -@@ -133,6 +133,9 @@ static struct dso *const nodeps_dummy; - - struct debug *_dl_debug_addr = &debug; - -+__attribute__((__visibility__("hidden"))) -+extern int __malloc_replaced; -+ - __attribute__((__visibility__("hidden"))) - void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0; - -@@ -158,10 +161,26 @@ static void *laddr(const struct dso *p, size_t v) - for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++); - return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr); - } -+static void *laddr_pg(const struct dso *p, size_t v) -+{ -+ size_t j=0; -+ size_t pgsz = PAGE_SIZE; -+ if (!p->loadmap) return p->base + v; -+ for (j=0; ; j++) { -+ size_t a = p->loadmap->segs[j].p_vaddr; -+ size_t b = a + p->loadmap->segs[j].p_memsz; -+ a &= -pgsz; -+ b += pgsz-1; -+ b &= -pgsz; -+ if (v-a<b-a) break; -+ } -+ return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr); -+} - #define fpaddr(p, v) ((void (*)())&(struct funcdesc){ \ - laddr(p, v), (p)->got }) - #else - #define laddr(p, v) (void *)((p)->base + (v)) -+#define laddr_pg(p, v) laddr(p, v) - #define fpaddr(p, v) ((void (*)())laddr(p, v)) - #endif - -@@ -366,6 +385,14 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri - sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0; - tls_val = def.sym ? def.sym->st_value : 0; - -+ if ((type == REL_TPOFF || type == REL_TPOFF_NEG) -+ && runtime && def.dso->tls_id > static_tls_cnt) { -+ error("Error relocating %s: %s: initial-exec TLS " -+ "resolves to dynamic definition in %s", -+ dso->name, name, def.dso->name); -+ longjmp(*rtld_fail, 1); -+ } -+ - switch(type) { - case REL_NONE: - break; -@@ -419,7 +446,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri - #endif - case REL_TLSDESC: - if (stride<3) addend = reloc_addr[1]; -- if (runtime && def.dso->tls_id >= static_tls_cnt) { -+ if (runtime && def.dso->tls_id > static_tls_cnt) { - struct td_index *new = malloc(sizeof *new); - if (!new) { - error( -@@ -476,23 +503,16 @@ static void redo_lazy_relocs() - /* A huge hack: to make up for the wastefulness of shared libraries - * needing at least a page of dirty memory even if they have no global - * data, we reclaim the gaps at the beginning and end of writable maps -- * and "donate" them to the heap by setting up minimal malloc -- * structures and then freeing them. */ -+ * and "donate" them to the heap. */ - - static void reclaim(struct dso *dso, size_t start, size_t end) - { -- size_t *a, *z; -+ void __malloc_donate(char *, char *); - if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end; - if (end >= dso->relro_start && end < dso->relro_end) end = dso->relro_start; -- start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t); -- end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t); -- if (start>end || end-start < 4*sizeof(size_t)) return; -- a = laddr(dso, start); -- z = laddr(dso, end); -- a[-2] = 1; -- a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1; -- z[1] = 1; -- free(a); -+ if (start >= end) return; -+ char *base = laddr_pg(dso, start); -+ __malloc_donate(base, base+(end-start)); - } - - static void reclaim_gaps(struct dso *dso) -@@ -500,7 +520,6 @@ static void reclaim_gaps(struct dso *dso) - Phdr *ph = dso->phdr; - size_t phcnt = dso->phnum; - -- if (DL_FDPIC) return; // FIXME - 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; -@@ -695,18 +714,17 @@ static void *map_library(int fd, struct dso *dso) - dso->phnum = eh->e_phnum; - dso->phentsize = eh->e_phentsize; - } -- /* Reuse the existing mapping for the lowest-address LOAD */ -- if ((ph->p_vaddr & -PAGE_SIZE) == addr_min && !DL_NOMMU_SUPPORT) -- continue; - this_min = ph->p_vaddr & -PAGE_SIZE; - this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE; - off_start = ph->p_offset & -PAGE_SIZE; - prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) | - ((ph->p_flags&PF_W) ? PROT_WRITE: 0) | - ((ph->p_flags&PF_X) ? PROT_EXEC : 0)); -- if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED) -- goto error; -- if (ph->p_memsz > ph->p_filesz) { -+ /* Reuse the existing mapping for the lowest-address LOAD */ -+ if ((ph->p_vaddr & -PAGE_SIZE) != addr_min || DL_NOMMU_SUPPORT) -+ if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED) -+ goto error; -+ if (ph->p_memsz > ph->p_filesz && (ph->p_flags&PF_W)) { - size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz; - size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE; - memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1); -@@ -1583,8 +1601,9 @@ _Noreturn void __dls3(size_t *sp) - libc.tls_head = tls_tail = &app.tls; - app.tls_id = tls_cnt = 1; - #ifdef TLS_ABOVE_TP -- app.tls.offset = 0; -- tls_offset = app.tls.size -+ app.tls.offset = GAP_ABOVE_TP; -+ app.tls.offset += -GAP_ABOVE_TP & (app.tls.align-1); -+ tls_offset = app.tls.offset + app.tls.size - + ( -((uintptr_t)app.tls.image + app.tls.size) - & (app.tls.align-1) ); - #else -@@ -1683,6 +1702,12 @@ _Noreturn void __dls3(size_t *sp) - if (ldso_fail) _exit(127); - if (ldd_mode) _exit(0); - -+ /* Determine if malloc was interposed by a replacement implementation -+ * so that calloc and the memalign family can harden against the -+ * possibility of incomplete replacement. */ -+ if (find_sym(head, "malloc", 1).dso != &ldso) -+ __malloc_replaced = 1; -+ - /* Switch to runtime mode: any further failures in the dynamic - * linker are a reportable failure rather than a fatal startup - * error. */ -@@ -1861,8 +1886,17 @@ static void *addr2dso(size_t a) - return p; - } - } else { -+ Phdr *ph = p->phdr; -+ size_t phcnt = p->phnum; -+ size_t entsz = p->phentsize; -+ size_t base = (size_t)p->base; -+ for (; phcnt--; ph=(void *)((char *)ph+entsz)) { -+ if (ph->p_type != PT_LOAD) continue; -+ if (a-base-ph->p_vaddr < ph->p_memsz) -+ return p; -+ } - if (a-(size_t)p->map < p->map_len) -- return p; -+ return 0; - } - } - return 0; -@@ -1926,16 +1960,18 @@ failed: - return 0; - } - --int dladdr(const void *addr, Dl_info *info) -+int dladdr(const void *addr_arg, Dl_info *info) - { -+ size_t addr = (size_t)addr_arg; - struct dso *p; - Sym *sym, *bestsym; - uint32_t nsym; - char *strings; -- void *best = 0; -+ size_t best = 0; -+ size_t besterr = -1; - - pthread_rwlock_rdlock(&lock); -- p = addr2dso((size_t)addr); -+ p = addr2dso(addr); - pthread_rwlock_unlock(&lock); - - if (!p) return 0; -@@ -1945,11 +1981,12 @@ int dladdr(const void *addr, Dl_info *info) - nsym = count_syms(p); - - if (DL_FDPIC) { -- size_t idx = ((size_t)addr-(size_t)p->funcdescs) -+ size_t idx = (addr-(size_t)p->funcdescs) - / sizeof(*p->funcdescs); - if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) { -- best = p->funcdescs + idx; -+ best = (size_t)(p->funcdescs + idx); - bestsym = sym + idx; -+ besterr = 0; - } - } - -@@ -1957,25 +1994,35 @@ int dladdr(const void *addr, Dl_info *info) - if (sym->st_value - && (1<<(sym->st_info&0xf) & OK_TYPES) - && (1<<(sym->st_info>>4) & OK_BINDS)) { -- void *symaddr = laddr(p, sym->st_value); -- if (symaddr > addr || symaddr < best) -+ size_t symaddr = (size_t)laddr(p, sym->st_value); -+ if (symaddr > addr || symaddr <= best) - continue; - best = symaddr; - bestsym = sym; -+ besterr = addr - symaddr; - if (addr == symaddr) - break; - } - } - -- if (!best) return 0; -- -- if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC) -- best = p->funcdescs + (bestsym - p->syms); -+ if (bestsym && besterr > bestsym->st_size-1) { -+ best = 0; -+ bestsym = 0; -+ } - - info->dli_fname = p->name; - info->dli_fbase = p->map; -+ -+ if (!best) { -+ info->dli_sname = 0; -+ info->dli_saddr = 0; -+ return 1; -+ } -+ -+ if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC) -+ best = (size_t)(p->funcdescs + (bestsym - p->syms)); - info->dli_sname = strings + bestsym->st_name; -- info->dli_saddr = best; -+ info->dli_saddr = (void *)best; - - return 1; - } -diff --git a/src/complex/casin.c b/src/complex/casin.c -index dfdda988..01ed6184 100644 ---- a/src/complex/casin.c -+++ b/src/complex/casin.c -@@ -12,5 +12,6 @@ double complex casin(double complex z) - x = creal(z); - y = cimag(z); - w = CMPLX(1.0 - (x - y)*(x + y), -2.0*x*y); -- return clog(CMPLX(-y, x) + csqrt(w)); -+ double complex r = clog(CMPLX(-y, x) + csqrt(w)); -+ return CMPLX(cimag(r), -creal(r)); - } -diff --git a/src/complex/casinf.c b/src/complex/casinf.c -index 93f0e335..4fcb76fc 100644 ---- a/src/complex/casinf.c -+++ b/src/complex/casinf.c -@@ -10,5 +10,6 @@ float complex casinf(float complex z) - x = crealf(z); - y = cimagf(z); - w = CMPLXF(1.0 - (x - y)*(x + y), -2.0*x*y); -- return clogf(CMPLXF(-y, x) + csqrtf(w)); -+ float complex r = clogf(CMPLXF(-y, x) + csqrtf(w)); -+ return CMPLXF(cimagf(r), -crealf(r)); - } -diff --git a/src/complex/casinl.c b/src/complex/casinl.c -index 0916c60f..3b7ceba7 100644 ---- a/src/complex/casinl.c -+++ b/src/complex/casinl.c -@@ -15,6 +15,7 @@ long double complex casinl(long double complex z) - x = creall(z); - y = cimagl(z); - w = CMPLXL(1.0 - (x - y)*(x + y), -2.0*x*y); -- return clogl(CMPLXL(-y, x) + csqrtl(w)); -+ long double complex r = clogl(CMPLXL(-y, x) + csqrtl(w)); -+ return CMPLXL(cimagl(r), -creall(r)); - } - #endif -diff --git a/src/complex/catan.c b/src/complex/catan.c -index 39ce6cf2..7dc2afeb 100644 ---- a/src/complex/catan.c -+++ b/src/complex/catan.c -@@ -91,29 +91,17 @@ double complex catan(double complex z) - x = creal(z); - y = cimag(z); - -- if (x == 0.0 && y > 1.0) -- goto ovrf; -- - x2 = x * x; - a = 1.0 - x2 - (y * y); -- if (a == 0.0) -- goto ovrf; - - t = 0.5 * atan2(2.0 * x, a); - w = _redupi(t); - - t = y - 1.0; - a = x2 + (t * t); -- if (a == 0.0) -- goto ovrf; - - t = y + 1.0; - a = (x2 + t * t)/a; -- w = w + (0.25 * log(a)) * I; -- return w; -- --ovrf: -- // FIXME -- w = MAXNUM + MAXNUM * I; -+ w = CMPLX(w, 0.25 * log(a)); - return w; - } diff --git a/src/conf/confstr.c b/src/conf/confstr.c index 02cb1aa2..8f870a69 100644 --- a/src/conf/confstr.c @@ -3524,7 +103,7 @@ index 02cb1aa2..8f870a69 100644 return 0; } diff --git a/src/conf/fpathconf.c b/src/conf/fpathconf.c -index 8eb037e6..b6a9d63e 100644 +index e6aca5cf..b6a9d63e 100644 --- a/src/conf/fpathconf.c +++ b/src/conf/fpathconf.c @@ -4,7 +4,7 @@ @@ -3536,82 +115,21 @@ index 8eb037e6..b6a9d63e 100644 [_PC_LINK_MAX] = _POSIX_LINK_MAX, [_PC_MAX_CANON] = _POSIX_MAX_CANON, [_PC_MAX_INPUT] = _POSIX_MAX_INPUT, -@@ -24,8 +24,9 @@ long fpathconf(int fd, int name) - [_PC_REC_MIN_XFER_SIZE] = 4096, +@@ -25,7 +25,8 @@ long fpathconf(int fd, int name) [_PC_REC_XFER_ALIGN] = 4096, [_PC_ALLOC_SIZE_MIN] = 4096, -- [_PC_SYMLINK_MAX] = SYMLINK_MAX, + [_PC_SYMLINK_MAX] = -1, - [_PC_2_SYMLINKS] = 1 -+ [_PC_SYMLINK_MAX] = -1, + [_PC_2_SYMLINKS] = 1, + [_PC_TIMESTAMP_RESOLUTION] = 100000000, }; if (name >= sizeof(values)/sizeof(values[0])) { errno = EINVAL; diff --git a/src/conf/sysconf.c b/src/conf/sysconf.c -index 9ce330a5..483e1635 100644 +index 45ef1c16..483e1635 100644 --- a/src/conf/sysconf.c +++ b/src/conf/sysconf.c -@@ -18,6 +18,7 @@ - #define JT_PHYS_PAGES JT(8) - #define JT_AVPHYS_PAGES JT(9) - #define JT_ZERO JT(10) -+#define JT_DELAYTIMER_MAX JT(11) - - #define RLIM(x) (-32768|(RLIMIT_ ## x)) - -@@ -33,7 +34,7 @@ long sysconf(int name) - [_SC_TZNAME_MAX] = TZNAME_MAX, - [_SC_JOB_CONTROL] = 1, - [_SC_SAVED_IDS] = 1, -- [_SC_REALTIME_SIGNALS] = 1, -+ [_SC_REALTIME_SIGNALS] = VER, - [_SC_PRIORITY_SCHEDULING] = -1, - [_SC_TIMERS] = VER, - [_SC_ASYNCHRONOUS_IO] = VER, -@@ -50,7 +51,7 @@ long sysconf(int name) - [_SC_AIO_LISTIO_MAX] = -1, - [_SC_AIO_MAX] = -1, - [_SC_AIO_PRIO_DELTA_MAX] = JT_ZERO, /* ?? */ -- [_SC_DELAYTIMER_MAX] = _POSIX_DELAYTIMER_MAX, -+ [_SC_DELAYTIMER_MAX] = JT_DELAYTIMER_MAX, - [_SC_MQ_OPEN_MAX] = -1, - [_SC_MQ_PRIO_MAX] = JT_MQ_PRIO_MAX, - [_SC_VERSION] = VER, -@@ -111,8 +112,8 @@ long sysconf(int name) - [_SC_XOPEN_XPG4] = -1, - [_SC_NZERO] = NZERO, - [_SC_XBS5_ILP32_OFF32] = -1, -- [_SC_XBS5_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO, -- [_SC_XBS5_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO, -+ [_SC_XBS5_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1, -+ [_SC_XBS5_LP64_OFF64] = sizeof(long)==8 ? 1 : -1, - [_SC_XBS5_LPBIG_OFFBIG] = -1, - [_SC_XOPEN_LEGACY] = -1, - [_SC_XOPEN_REALTIME] = -1, -@@ -141,8 +142,8 @@ long sysconf(int name) - [_SC_STREAMS] = JT_ZERO, - [_SC_2_PBS_CHECKPOINT] = -1, - [_SC_V6_ILP32_OFF32] = -1, -- [_SC_V6_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO, -- [_SC_V6_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO, -+ [_SC_V6_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1, -+ [_SC_V6_LP64_OFF64] = sizeof(long)==8 ? 1 : -1, - [_SC_V6_LPBIG_OFFBIG] = -1, - [_SC_HOST_NAME_MAX] = HOST_NAME_MAX, - [_SC_TRACE] = -1, -@@ -153,8 +154,8 @@ long sysconf(int name) - [_SC_IPV6] = VER, - [_SC_RAW_SOCKETS] = VER, - [_SC_V7_ILP32_OFF32] = -1, -- [_SC_V7_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO, -- [_SC_V7_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO, -+ [_SC_V7_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1, -+ [_SC_V7_LP64_OFF64] = sizeof(long)==8 ? 1 : -1, - [_SC_V7_LPBIG_OFFBIG] = -1, - [_SC_SS_REPL_MAX] = -1, - [_SC_TRACE_EVENT_NAME_MAX] = -1, -@@ -164,6 +165,7 @@ long sysconf(int name) +@@ -165,6 +165,7 @@ long sysconf(int name) [_SC_XOPEN_STREAMS] = JT_ZERO, [_SC_THREAD_ROBUST_PRIO_INHERIT] = -1, [_SC_THREAD_ROBUST_PRIO_PROTECT] = -1, @@ -3619,789 +137,6 @@ index 9ce330a5..483e1635 100644 }; if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) { -@@ -190,6 +192,8 @@ long sysconf(int name) - return PAGE_SIZE; - case JT_SEM_VALUE_MAX & 255: - return SEM_VALUE_MAX; -+ case JT_DELAYTIMER_MAX & 255: -+ return DELAYTIMER_MAX; - case JT_NPROCESSORS_CONF & 255: - case JT_NPROCESSORS_ONLN & 255: ; - unsigned char set[128] = {1}; -diff --git a/src/dirent/__dirent.h b/src/dirent/__dirent.h -index 101b0368..828a5f17 100644 ---- a/src/dirent/__dirent.h -+++ b/src/dirent/__dirent.h -@@ -1,9 +1,11 @@ - struct __dirstream - { -- int fd; - off_t tell; -+ int fd; - int buf_pos; - int buf_end; - volatile int lock[1]; -+ /* Any changes to this struct must preserve the property: -+ * offsetof(struct __dirent, buf) % sizeof(off_t) == 0 */ - char buf[2048]; - }; -diff --git a/src/dirent/readdir.c b/src/dirent/readdir.c -index 2cf0632c..eef92f79 100644 ---- a/src/dirent/readdir.c -+++ b/src/dirent/readdir.c -@@ -1,10 +1,12 @@ - #include <dirent.h> - #include <errno.h> -+#include <stddef.h> - #include "__dirent.h" - #include "syscall.h" - #include "libc.h" - --int __getdents(int, struct dirent *, size_t); -+typedef char dirstream_buf_alignment_check[1-2*(int)( -+ offsetof(struct __dirstream, buf) % sizeof(off_t))]; - - struct dirent *readdir(DIR *dir) - { -diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c -index b125eb1f..31d324a8 100644 ---- a/src/env/__init_tls.c -+++ b/src/env/__init_tls.c -@@ -15,7 +15,8 @@ int __init_tp(void *p) - int r = __set_thread_area(TP_ADJ(p)); - if (r < 0) return -1; - if (!r) libc.can_do_threads = 1; -- td->tid = __syscall(SYS_set_tid_address, &td->tid); -+ td->detach_state = DT_JOINABLE; -+ td->tid = __syscall(SYS_set_tid_address, &td->detach_state); - td->locale = &libc.global_locale; - td->robust_list.head = &td->robust_list.head; - return 0; -@@ -103,13 +104,19 @@ static void static_init_tls(size_t *aux) - - main_tls.size += (-main_tls.size - (uintptr_t)main_tls.image) - & (main_tls.align-1); -- if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN; --#ifndef TLS_ABOVE_TP -+#ifdef TLS_ABOVE_TP -+ main_tls.offset = GAP_ABOVE_TP; -+ main_tls.offset += -GAP_ABOVE_TP & (main_tls.align-1); -+#else - main_tls.offset = main_tls.size; - #endif -+ if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN; - - libc.tls_align = main_tls.align; - libc.tls_size = 2*sizeof(void *) + sizeof(struct pthread) -+#ifdef TLS_ABOVE_TP -+ + main_tls.offset -+#endif - + main_tls.size + main_tls.align - + MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN; - -diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c -index 2d758af7..0583f686 100644 ---- a/src/env/__libc_start_main.c -+++ b/src/env/__libc_start_main.c -@@ -42,11 +42,13 @@ void __init_libc(char **envp, char *pn) - && !aux[AT_SECURE]) return; - - struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; -+ int r = - #ifdef SYS_poll - __syscall(SYS_poll, pfd, 3, 0); - #else - __syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8); - #endif -+ if (r<0) a_crash(); - for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL) - if (__sys_open("/dev/null", O_RDWR)<0) - a_crash(); -diff --git a/src/errno/__errno_location.c b/src/errno/__errno_location.c -index 7172a1be..ad9f9241 100644 ---- a/src/errno/__errno_location.c -+++ b/src/errno/__errno_location.c -@@ -1,3 +1,4 @@ -+#include <errno.h> - #include "pthread_impl.h" - - int *__errno_location(void) -diff --git a/src/errno/__strerror.h b/src/errno/__strerror.h -index 915044b5..2f04d400 100644 ---- a/src/errno/__strerror.h -+++ b/src/errno/__strerror.h -@@ -100,5 +100,6 @@ E(EREMOTEIO, "Remote I/O error") - E(EDQUOT, "Quota exceeded") - E(ENOMEDIUM, "No medium found") - E(EMEDIUMTYPE, "Wrong medium type") -+E(EMULTIHOP, "Multihop attempted") - - E(0, "No error information") -diff --git a/src/exit/abort.c b/src/exit/abort.c -index ecc0f735..5e5a87c3 100644 ---- a/src/exit/abort.c -+++ b/src/exit/abort.c -@@ -1,13 +1,31 @@ - #include <stdlib.h> - #include <signal.h> -+#include <string.h> - #include "syscall.h" - #include "pthread_impl.h" - #include "atomic.h" - - _Noreturn void abort(void) - { -+ struct sigaction abrtaction; -+ sigset_t abrtset; -+ - raise(SIGABRT); - __block_all_sigs(0); -+ -+ /* Unblock just SIGABRT, and set default handler */ -+ sigemptyset(&abrtset); -+ sigaddset(&abrtset, SIGABRT); -+ sigprocmask(SIG_UNBLOCK, &abrtset, 0); -+ -+ memset(&abrtaction, 0, sizeof(struct sigaction)); -+ abrtaction.sa_handler = SIG_DFL; -+ -+ sigaction(SIGABRT, &abrtaction, NULL); -+ -+ raise(SIGABRT); -+ -+ /* Ok, give up. */ - a_crash(); - raise(SIGKILL); - _Exit(127); -diff --git a/src/fenv/m68k/fenv.c b/src/fenv/m68k/fenv.c -new file mode 100644 -index 00000000..e60949d1 ---- /dev/null -+++ b/src/fenv/m68k/fenv.c -@@ -0,0 +1,84 @@ -+#include <fenv.h> -+ -+#if __HAVE_68881__ || __mcffpu__ -+ -+static unsigned getsr() -+{ -+ unsigned v; -+ __asm__ __volatile__ ("fmove.l %%fpsr,%0" : "=dm"(v)); -+ return v; -+} -+ -+static void setsr(unsigned v) -+{ -+ __asm__ __volatile__ ("fmove.l %0,%%fpsr" : : "dm"(v)); -+} -+ -+static unsigned getcr() -+{ -+ unsigned v; -+ __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=dm"(v)); -+ return v; -+} -+ -+static void setcr(unsigned v) -+{ -+ __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "dm"(v)); -+} -+ -+int feclearexcept(int mask) -+{ -+ if (mask & ~FE_ALL_EXCEPT) return -1; -+ setsr(getsr() & ~mask); -+ return 0; -+} -+ -+int feraiseexcept(int mask) -+{ -+ if (mask & ~FE_ALL_EXCEPT) return -1; -+ setsr(getsr() | mask); -+ return 0; -+} -+ -+int fetestexcept(int mask) -+{ -+ return getsr() & mask; -+} -+ -+int fegetround(void) -+{ -+ return getcr() & FE_UPWARD; -+} -+ -+int __fesetround(int r) -+{ -+ setcr((getcr() & ~FE_UPWARD) | r); -+ return 0; -+} -+ -+int fegetenv(fenv_t *envp) -+{ -+ envp->__control_register = getcr(); -+ envp->__status_register = getsr(); -+ __asm__ __volatile__ ("fmove.l %%fpiar,%0" -+ : "=dm"(envp->__instruction_address)); -+ return 0; -+} -+ -+int fesetenv(const fenv_t *envp) -+{ -+ static const fenv_t default_env = { 0 }; -+ if (envp == FE_DFL_ENV) -+ envp = &default_env; -+ setcr(envp->__control_register); -+ setsr(envp->__status_register); -+ __asm__ __volatile__ ("fmove.l %0,%%fpiar" -+ : : "dm"(envp->__instruction_address)); -+ return 0; -+} -+ -+#else -+ -+#include "../fenv.c" -+ -+#endif -diff --git a/src/internal/atomic.h b/src/internal/atomic.h -index ab473dd7..f938879b 100644 ---- a/src/internal/atomic.h -+++ b/src/internal/atomic.h -@@ -251,6 +251,22 @@ static inline void a_crash() - } - #endif - -+#ifndef a_ctz_32 -+#define a_ctz_32 a_ctz_32 -+static inline int a_ctz_32(uint32_t x) -+{ -+#ifdef a_clz_32 -+ return 31-a_clz_32(x&-x); -+#else -+ static const char debruijn32[32] = { -+ 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, -+ 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14 -+ }; -+ return debruijn32[(x&-x)*0x076be629 >> 27]; -+#endif -+} -+#endif -+ - #ifndef a_ctz_64 - #define a_ctz_64 a_ctz_64 - static inline int a_ctz_64(uint64_t x) -@@ -261,22 +277,23 @@ static inline int a_ctz_64(uint64_t x) - 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, - 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12 - }; -- static const char debruijn32[32] = { -- 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, -- 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14 -- }; - if (sizeof(long) < 8) { - uint32_t y = x; - if (!y) { - y = x>>32; -- return 32 + debruijn32[(y&-y)*0x076be629 >> 27]; -+ return 32 + a_ctz_32(y); - } -- return debruijn32[(y&-y)*0x076be629 >> 27]; -+ return a_ctz_32(y); - } - return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58]; - } - #endif - -+static inline int a_ctz_l(unsigned long x) -+{ -+ return (sizeof(long) < 8) ? a_ctz_32(x) : a_ctz_64(x); -+} -+ - #ifndef a_clz_64 - #define a_clz_64 a_clz_64 - static inline int a_clz_64(uint64_t x) -@@ -298,17 +315,4 @@ static inline int a_clz_64(uint64_t x) - } - #endif - --#ifndef a_ctz_l --#define a_ctz_l a_ctz_l --static inline int a_ctz_l(unsigned long x) --{ -- static const char debruijn32[32] = { -- 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, -- 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14 -- }; -- if (sizeof(long) == 8) return a_ctz_64(x); -- return debruijn32[(x&-x)*0x076be629 >> 27]; --} --#endif -- - #endif -diff --git a/src/internal/libm.h b/src/internal/libm.h -index df864111..a2505f7e 100644 ---- a/src/internal/libm.h -+++ b/src/internal/libm.h -@@ -28,6 +28,17 @@ union ldshape { - uint16_t se; - } i; - }; -+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN -+/* This is the m68k variant of 80-bit long double, and this definition only works -+ * on archs where the alignment requirement of uint64_t is <= 4. */ -+union ldshape { -+ long double f; -+ struct { -+ uint16_t se; -+ uint16_t pad; -+ uint64_t m; -+ } i; -+}; - #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN - union ldshape { - long double f; -diff --git a/src/internal/m68k/syscall.s b/src/internal/m68k/syscall.s -new file mode 100644 -index 00000000..9972a34d ---- /dev/null -+++ b/src/internal/m68k/syscall.s -@@ -0,0 +1,9 @@ -+.global __syscall -+.hidden __syscall -+.type __syscall,%function -+__syscall: -+ movem.l %d2-%d5,-(%sp) -+ movem.l 20(%sp),%d0-%d5/%a0 -+ trap #0 -+ movem.l (%sp)+,%d2-%d5 -+ rts -diff --git a/src/internal/malloc_impl.h b/src/internal/malloc_impl.h -new file mode 100644 -index 00000000..5d025b06 ---- /dev/null -+++ b/src/internal/malloc_impl.h -@@ -0,0 +1,45 @@ -+#ifndef MALLOC_IMPL_H -+#define MALLOC_IMPL_H -+ -+void *__mmap(void *, size_t, int, int, int, off_t); -+int __munmap(void *, size_t); -+void *__mremap(void *, size_t, size_t, int, ...); -+int __madvise(void *, size_t, int); -+ -+struct chunk { -+ size_t psize, csize; -+ struct chunk *next, *prev; -+}; -+ -+struct bin { -+ volatile int lock[2]; -+ struct chunk *head; -+ struct chunk *tail; -+}; -+ -+#define SIZE_ALIGN (4*sizeof(size_t)) -+#define SIZE_MASK (-SIZE_ALIGN) -+#define OVERHEAD (2*sizeof(size_t)) -+#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN) -+#define DONTCARE 16 -+#define RECLAIM 163840 -+ -+#define CHUNK_SIZE(c) ((c)->csize & -2) -+#define CHUNK_PSIZE(c) ((c)->psize & -2) -+#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c))) -+#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c))) -+#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD) -+#define CHUNK_TO_MEM(c) (void *)((char *)(c) + OVERHEAD) -+#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head)) -+ -+#define C_INUSE ((size_t)1) -+ -+#define IS_MMAPPED(c) !((c)->csize & (C_INUSE)) -+ -+__attribute__((__visibility__("hidden"))) -+void __bin_chunk(struct chunk *); -+ -+__attribute__((__visibility__("hidden"))) -+extern int __malloc_replaced; -+ -+#endif -diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h -index f6a4f2c2..3826bd8e 100644 ---- a/src/internal/pthread_impl.h -+++ b/src/internal/pthread_impl.h -@@ -19,38 +19,36 @@ struct pthread { - void **dtv, *unused1, *unused2; - uintptr_t sysinfo; - uintptr_t canary, canary2; -- pid_t tid, pid; - - /* Part 2 -- implementation details, non-ABI. */ -- int tsd_used, errno_val; -- volatile int cancel, canceldisable, cancelasync; -- int detached; -+ int tid; -+ int errno_val; -+ volatile int detach_state; -+ volatile int cancel; -+ volatile unsigned char canceldisable, cancelasync; -+ unsigned char tsd_used:1; -+ unsigned char unblock_cancel:1; -+ unsigned char dlerror_flag:1; - unsigned char *map_base; - size_t map_size; - void *stack; - size_t stack_size; -+ size_t guard_size; - void *start_arg; - void *(*start)(void *); - void *result; - struct __ptcb *cancelbuf; - void **tsd; -- volatile int dead; - struct { - volatile void *volatile head; - long off; - volatile void *volatile pending; - } robust_list; -- int unblock_cancel; - volatile int timer_id; - locale_t locale; - volatile int killlock[1]; -- volatile int exitlock[1]; -- volatile int startlock[2]; -- unsigned long sigmask[_NSIG/8/sizeof(long)]; - char *dlerror_buf; -- int dlerror_flag; - void *stdio_locks; -- size_t guard_size; - - /* Part 3 -- the positions of these fields relative to - * the end of the structure is external and internal ABI. */ -@@ -58,6 +56,22 @@ struct pthread { - void **dtv_copy; - }; - -+struct start_sched_args { -+ void *start_arg; -+ void *(*start_fn)(void *); -+ sigset_t mask; -+ pthread_attr_t *attr; -+ volatile int futex; -+}; -+ -+enum { -+ DT_EXITED = 0, -+ DT_EXITING, -+ DT_JOINABLE, -+ DT_DETACHED, -+ DT_DYNAMIC, -+}; -+ - struct __timer { - int timerid; - pthread_t thread; -@@ -147,8 +161,8 @@ static inline void __wake(volatile void *addr, int cnt, int priv) - static inline void __futexwait(volatile void *addr, int val, int priv) - { - if (priv) priv = FUTEX_PRIVATE; -- __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val) != -ENOSYS || -- __syscall(SYS_futex, addr, FUTEX_WAIT, val); -+ __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS || -+ __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0); - } - - void __acquire_ptc(void); -diff --git a/src/internal/stdio_impl.h b/src/internal/stdio_impl.h -index 7cdf729d..1127a492 100644 ---- a/src/internal/stdio_impl.h -+++ b/src/internal/stdio_impl.h -@@ -9,7 +9,7 @@ - - #define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0) - #define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0) --#define FUNLOCK(f) if (__need_unlock) __unlockfile((f)); else -+#define FUNLOCK(f) do { if (__need_unlock) __unlockfile((f)); } while (0) - - #define F_PERM 1 - #define F_NORD 4 -diff --git a/src/ipc/msgctl.c b/src/ipc/msgctl.c -index 4372c719..ea9b2337 100644 ---- a/src/ipc/msgctl.c -+++ b/src/ipc/msgctl.c -@@ -1,12 +1,34 @@ - #include <sys/msg.h> -+#include <endian.h> - #include "syscall.h" - #include "ipc.h" - -+#if __BYTE_ORDER != __BIG_ENDIAN -+#undef SYSCALL_IPC_BROKEN_MODE -+#endif -+ - int msgctl(int q, int cmd, struct msqid_ds *buf) - { -+#ifdef SYSCALL_IPC_BROKEN_MODE -+ struct msqid_ds tmp; -+ if (cmd == IPC_SET) { -+ tmp = *buf; -+ tmp.msg_perm.mode *= 0x10000U; -+ buf = &tmp; -+ } -+#endif - #ifdef SYS_msgctl -- return syscall(SYS_msgctl, q, cmd | IPC_64, buf); -+ int r = __syscall(SYS_msgctl, q, cmd | IPC_64, buf); - #else -- return syscall(SYS_ipc, IPCOP_msgctl, q, cmd | IPC_64, 0, buf, 0); -+ int r = __syscall(SYS_ipc, IPCOP_msgctl, q, cmd | IPC_64, 0, buf, 0); -+#endif -+#ifdef SYSCALL_IPC_BROKEN_MODE -+ if (r >= 0) switch (cmd) { -+ case IPC_STAT: -+ case MSG_STAT: -+ case MSG_STAT_ANY: -+ buf->msg_perm.mode >>= 16; -+ } - #endif -+ return __syscall_ret(r); - } -diff --git a/src/ipc/semctl.c b/src/ipc/semctl.c -index 673a9a8c..941e2813 100644 ---- a/src/ipc/semctl.c -+++ b/src/ipc/semctl.c -@@ -1,8 +1,13 @@ - #include <sys/sem.h> - #include <stdarg.h> -+#include <endian.h> - #include "syscall.h" - #include "ipc.h" - -+#if __BYTE_ORDER != __BIG_ENDIAN -+#undef SYSCALL_IPC_BROKEN_MODE -+#endif -+ - union semun { - int val; - struct semid_ds *buf; -@@ -20,9 +25,26 @@ int semctl(int id, int num, int cmd, ...) - arg = va_arg(ap, union semun); - va_end(ap); - } -+#ifdef SYSCALL_IPC_BROKEN_MODE -+ struct semid_ds tmp; -+ if (cmd == IPC_SET) { -+ tmp = *arg.buf; -+ tmp.sem_perm.mode *= 0x10000U; -+ arg.buf = &tmp; -+ } -+#endif - #ifdef SYS_semctl -- return syscall(SYS_semctl, id, num, cmd | IPC_64, arg.buf); -+ int r = __syscall(SYS_semctl, id, num, cmd | IPC_64, arg.buf); - #else -- return syscall(SYS_ipc, IPCOP_semctl, id, num, cmd | IPC_64, &arg.buf); -+ int r = __syscall(SYS_ipc, IPCOP_semctl, id, num, cmd | IPC_64, &arg.buf); -+#endif -+#ifdef SYSCALL_IPC_BROKEN_MODE -+ if (r >= 0) switch (cmd) { -+ case IPC_STAT: -+ case SEM_STAT: -+ case SEM_STAT_ANY: -+ arg.buf->sem_perm.mode >>= 16; -+ } - #endif -+ return __syscall_ret(r); - } -diff --git a/src/ipc/shmctl.c b/src/ipc/shmctl.c -index e2879f20..c951a581 100644 ---- a/src/ipc/shmctl.c -+++ b/src/ipc/shmctl.c -@@ -1,12 +1,34 @@ - #include <sys/shm.h> -+#include <endian.h> - #include "syscall.h" - #include "ipc.h" - -+#if __BYTE_ORDER != __BIG_ENDIAN -+#undef SYSCALL_IPC_BROKEN_MODE -+#endif -+ - int shmctl(int id, int cmd, struct shmid_ds *buf) - { -+#ifdef SYSCALL_IPC_BROKEN_MODE -+ struct shmid_ds tmp; -+ if (cmd == IPC_SET) { -+ tmp = *buf; -+ tmp.shm_perm.mode *= 0x10000U; -+ buf = &tmp; -+ } -+#endif - #ifdef SYS_shmctl -- return syscall(SYS_shmctl, id, cmd | IPC_64, buf); -+ int r = __syscall(SYS_shmctl, id, cmd | IPC_64, buf); - #else -- return syscall(SYS_ipc, IPCOP_shmctl, id, cmd | IPC_64, 0, buf, 0); -+ int r = __syscall(SYS_ipc, IPCOP_shmctl, id, cmd | IPC_64, 0, buf, 0); -+#endif -+#ifdef SYSCALL_IPC_BROKEN_MODE -+ if (r >= 0) switch (cmd) { -+ case IPC_STAT: -+ case SHM_STAT: -+ case SHM_STAT_ANY: -+ buf->shm_perm.mode >>= 16; -+ } - #endif -+ return __syscall_ret(r); - } -diff --git a/src/ldso/aarch64/tlsdesc.s b/src/ldso/aarch64/tlsdesc.s -index 8ed5c267..8e4004d7 100644 ---- a/src/ldso/aarch64/tlsdesc.s -+++ b/src/ldso/aarch64/tlsdesc.s -@@ -14,7 +14,7 @@ __tlsdesc_static: - // size_t __tlsdesc_dynamic(size_t *a) - // { - // struct {size_t modidx,off;} *p = (void*)a[1]; --// size_t *dtv = *(size_t**)(tp + 16 - 8); -+// size_t *dtv = *(size_t**)(tp - 8); - // if (p->modidx <= dtv[0]) - // return dtv[p->modidx] + p->off - tp; - // return __tls_get_new(p) - tp; -@@ -28,8 +28,7 @@ __tlsdesc_dynamic: - mrs x1,tpidr_el0 // tp - ldr x0,[x0,#8] // p - ldr x2,[x0] // p->modidx -- add x3,x1,#8 -- ldr x3,[x3] // dtv -+ ldr x3,[x1,#-8] // dtv - ldr x4,[x3] // dtv[0] - cmp x2,x4 - b.hi 1f -diff --git a/src/ldso/m68k/dlsym.s b/src/ldso/m68k/dlsym.s -new file mode 100644 -index 00000000..5209ae1b ---- /dev/null -+++ b/src/ldso/m68k/dlsym.s -@@ -0,0 +1,12 @@ -+.text -+.global dlsym -+.hidden __dlsym -+.type dlsym,@function -+dlsym: -+ move.l (%sp),-(%sp) -+ move.l 12(%sp),-(%sp) -+ move.l 12(%sp),-(%sp) -+ lea __dlsym-.-8,%a1 -+ jsr (%pc,%a1) -+ add.l #12,%sp -+ rts -diff --git a/src/linux/getrandom.c b/src/linux/getrandom.c -new file mode 100644 -index 00000000..6cc6f6b0 ---- /dev/null -+++ b/src/linux/getrandom.c -@@ -0,0 +1,7 @@ -+#include <sys/random.h> -+#include "syscall.h" -+ -+ssize_t getrandom(void *buf, size_t buflen, unsigned flags) -+{ -+ return syscall_cp(SYS_getrandom, buf, buflen, flags); -+} -diff --git a/src/linux/memfd_create.c b/src/linux/memfd_create.c -new file mode 100644 -index 00000000..1649fe55 ---- /dev/null -+++ b/src/linux/memfd_create.c -@@ -0,0 +1,8 @@ -+#define _GNU_SOURCE 1 -+#include <sys/mman.h> -+#include "syscall.h" -+ -+int memfd_create(const char *name, unsigned flags) -+{ -+ return syscall(SYS_memfd_create, name, flags); -+} -diff --git a/src/linux/mlock2.c b/src/linux/mlock2.c -new file mode 100644 -index 00000000..10132742 ---- /dev/null -+++ b/src/linux/mlock2.c -@@ -0,0 +1,10 @@ -+#define _GNU_SOURCE 1 -+#include <sys/mman.h> -+#include "syscall.h" -+ -+int mlock2(const void *addr, size_t len, unsigned flags) -+{ -+ if (flags == 0) -+ return mlock(addr, len); -+ return syscall(SYS_mlock2, addr, len, flags); -+} -diff --git a/src/locale/iconv.c b/src/locale/iconv.c -index d469856c..3047c27b 100644 ---- a/src/locale/iconv.c -+++ b/src/locale/iconv.c -@@ -458,16 +458,24 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri - * range in the hkscs table then hard-coded - * here. Ugly, yes. */ - if (c/256 == 0xdc) { -- if (totype-0300U > 8) k = 2; -- else k = "\10\4\4\10\4\4\10\2\4"[totype-0300]; -- if (k > *outb) goto toobig; -- x += iconv(combine_to_from(to, 0), -+ union { -+ char c[8]; -+ wchar_t wc[2]; -+ } tmp; -+ char *ptmp = tmp.c; -+ size_t tmpx = iconv(combine_to_from(to, find_charmap("utf8")), - &(char *){"\303\212\314\204" - "\303\212\314\214" - "\303\252\314\204" - "\303\252\314\214" - +c%256}, &(size_t){4}, -- out, outb); -+ &ptmp, &(size_t){sizeof tmp}); -+ size_t tmplen = ptmp - tmp.c; -+ if (tmplen > *outb) goto toobig; -+ if (tmpx) x++; -+ memcpy(*out, &tmp, tmplen); -+ *out += tmplen; -+ *outb -= tmplen; - continue; - } - if (!c) goto ilseq; -@@ -539,6 +547,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri - if (*outb < 1) goto toobig; - if (c<256 && c==legacy_map(tomap, c)) { - revout: -+ if (*outb < 1) goto toobig; - *(*out)++ = c; - *outb -= 1; - break; -@@ -645,6 +654,8 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri - *out += 4; - *outb -= 4; - break; -+ case UTF_32: -+ totype = UTF_32BE; - case UTF_32BE: - case UTF_32LE: - if (*outb < 4) goto toobig; -diff --git a/src/locale/langinfo.c b/src/locale/langinfo.c -index b16caf44..83be6433 100644 ---- a/src/locale/langinfo.c -+++ b/src/locale/langinfo.c -@@ -33,7 +33,7 @@ char *__nl_langinfo_l(nl_item item, locale_t loc) - int idx = item & 65535; - const char *str; - -- if (item == CODESET) return MB_CUR_MAX==1 ? "ASCII" : "UTF-8"; -+ if (item == CODESET) return loc->cat[LC_CTYPE] ? "UTF-8" : "ASCII"; - - /* _NL_LOCALE_NAME extension */ - if (idx == 65535 && cat < LC_ALL) diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c index 40bc7ece..4d51cdfe 100644 --- a/src/locale/setlocale.c @@ -4415,675 +150,6 @@ index 40bc7ece..4d51cdfe 100644 LOCK(lock); /* For LC_ALL, setlocale is required to return a string which -diff --git a/src/malloc/__brk.c b/src/malloc/__brk.c -deleted file mode 100644 -index 4c9119b4..00000000 ---- a/src/malloc/__brk.c -+++ /dev/null -@@ -1,7 +0,0 @@ --#include <stdint.h> --#include "syscall.h" -- --uintptr_t __brk(uintptr_t newbrk) --{ -- return __syscall(SYS_brk, newbrk); --} -diff --git a/src/malloc/calloc.c b/src/malloc/calloc.c -deleted file mode 100644 -index 436c0b03..00000000 ---- a/src/malloc/calloc.c -+++ /dev/null -@@ -1,13 +0,0 @@ --#include <stdlib.h> --#include <errno.h> -- --void *__malloc0(size_t); -- --void *calloc(size_t m, size_t n) --{ -- if (n && m > (size_t)-1/n) { -- errno = ENOMEM; -- return 0; -- } -- return __malloc0(n * m); --} -diff --git a/src/malloc/lite_malloc.c b/src/malloc/lite_malloc.c -index 701f60b4..96c4feac 100644 ---- a/src/malloc/lite_malloc.c -+++ b/src/malloc/lite_malloc.c -@@ -47,4 +47,14 @@ static void *__simple_malloc(size_t n) - } - - weak_alias(__simple_malloc, malloc); --weak_alias(__simple_malloc, __malloc0); -+ -+static void *__simple_calloc(size_t m, size_t n) -+{ -+ if (n && m > (size_t)-1/n) { -+ errno = ENOMEM; -+ return 0; -+ } -+ return __simple_malloc(n * m); -+} -+ -+weak_alias(__simple_calloc, calloc); -diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c -index 9e05e1d6..d72883e1 100644 ---- a/src/malloc/malloc.c -+++ b/src/malloc/malloc.c -@@ -8,53 +8,19 @@ - #include "libc.h" - #include "atomic.h" - #include "pthread_impl.h" -+#include "malloc_impl.h" - - #if defined(__GNUC__) && defined(__PIC__) - #define inline inline __attribute__((always_inline)) - #endif - --void *__mmap(void *, size_t, int, int, int, off_t); --int __munmap(void *, size_t); --void *__mremap(void *, size_t, size_t, int, ...); --int __madvise(void *, size_t, int); -- --struct chunk { -- size_t psize, csize; -- struct chunk *next, *prev; --}; -- --struct bin { -- volatile int lock[2]; -- struct chunk *head; -- struct chunk *tail; --}; -- - static struct { - volatile uint64_t binmap; - struct bin bins[64]; - volatile int free_lock[2]; - } mal; - -- --#define SIZE_ALIGN (4*sizeof(size_t)) --#define SIZE_MASK (-SIZE_ALIGN) --#define OVERHEAD (2*sizeof(size_t)) --#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN) --#define DONTCARE 16 --#define RECLAIM 163840 -- --#define CHUNK_SIZE(c) ((c)->csize & -2) --#define CHUNK_PSIZE(c) ((c)->psize & -2) --#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c))) --#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c))) --#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD) --#define CHUNK_TO_MEM(c) (void *)((char *)(c) + OVERHEAD) --#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head)) -- --#define C_INUSE ((size_t)1) -- --#define IS_MMAPPED(c) !((c)->csize & (C_INUSE)) -- -+int __malloc_replaced; - - /* Synchronization tools */ - -@@ -314,7 +280,7 @@ static void trim(struct chunk *self, size_t n) - next->psize = n1-n | C_INUSE; - self->csize = n | C_INUSE; - -- free(CHUNK_TO_MEM(split)); -+ __bin_chunk(split); - } - - void *malloc(size_t n) -@@ -366,15 +332,40 @@ void *malloc(size_t n) - return CHUNK_TO_MEM(c); - } - --void *__malloc0(size_t n) -+static size_t mal0_clear(char *p, size_t pagesz, size_t n) - { -+#ifdef __GNUC__ -+ typedef uint64_t __attribute__((__may_alias__)) T; -+#else -+ typedef unsigned char T; -+#endif -+ char *pp = p + n; -+ size_t i = (uintptr_t)pp & (pagesz - 1); -+ for (;;) { -+ pp = memset(pp - i, 0, i); -+ if (pp - p < pagesz) return pp - p; -+ for (i = pagesz; i; i -= 2*sizeof(T), pp -= 2*sizeof(T)) -+ if (((T *)pp)[-1] | ((T *)pp)[-2]) -+ break; -+ } -+} -+ -+void *calloc(size_t m, size_t n) -+{ -+ if (n && m > (size_t)-1/n) { -+ errno = ENOMEM; -+ return 0; -+ } -+ n *= m; - void *p = malloc(n); -- if (p && !IS_MMAPPED(MEM_TO_CHUNK(p))) { -- size_t *z; -- n = (n + sizeof *z - 1)/sizeof *z; -- for (z=p; n; n--, z++) if (*z) *z=0; -+ if (!p) return p; -+ if (!__malloc_replaced) { -+ if (IS_MMAPPED(MEM_TO_CHUNK(p))) -+ return p; -+ if (n >= PAGE_SIZE) -+ n = mal0_clear(p, PAGE_SIZE, n); - } -- return p; -+ return memset(p, 0, n); - } - - void *realloc(void *p, size_t n) -@@ -397,10 +388,9 @@ void *realloc(void *p, size_t n) - size_t newlen = n + extra; - /* Crash on realloc of freed chunk */ - if (extra & 1) a_crash(); -- if (newlen < PAGE_SIZE && (new = malloc(n))) { -- memcpy(new, p, n-OVERHEAD); -- free(p); -- return new; -+ if (newlen < PAGE_SIZE && (new = malloc(n-OVERHEAD))) { -+ n0 = n; -+ goto copy_free_ret; - } - newlen = (newlen + PAGE_SIZE-1) & -PAGE_SIZE; - if (oldlen == newlen) return p; -@@ -443,34 +433,20 @@ copy_realloc: - /* As a last resort, allocate a new chunk and copy to it. */ - new = malloc(n-OVERHEAD); - if (!new) return 0; -+copy_free_ret: - memcpy(new, p, n0-OVERHEAD); - free(CHUNK_TO_MEM(self)); - return new; - } - --void free(void *p) -+void __bin_chunk(struct chunk *self) - { -- struct chunk *self, *next; -+ struct chunk *next = NEXT_CHUNK(self); - size_t final_size, new_size, size; - int reclaim=0; - int i; - -- if (!p) return; -- -- self = MEM_TO_CHUNK(p); -- -- if (IS_MMAPPED(self)) { -- size_t extra = self->psize; -- char *base = (char *)self - extra; -- size_t len = CHUNK_SIZE(self) + extra; -- /* Crash on double free */ -- if (extra & 1) a_crash(); -- __munmap(base, len); -- return; -- } -- - final_size = new_size = CHUNK_SIZE(self); -- next = NEXT_CHUNK(self); - - /* Crash on corrupted footer (likely from buffer overflow) */ - if (next->psize != self->csize) a_crash(); -@@ -531,3 +507,44 @@ void free(void *p) - - unlock_bin(i); - } -+ -+static void unmap_chunk(struct chunk *self) -+{ -+ size_t extra = self->psize; -+ char *base = (char *)self - extra; -+ size_t len = CHUNK_SIZE(self) + extra; -+ /* Crash on double free */ -+ if (extra & 1) a_crash(); -+ __munmap(base, len); -+} -+ -+void free(void *p) -+{ -+ if (!p) return; -+ -+ struct chunk *self = MEM_TO_CHUNK(p); -+ -+ if (IS_MMAPPED(self)) -+ unmap_chunk(self); -+ else -+ __bin_chunk(self); -+} -+ -+void __malloc_donate(char *start, char *end) -+{ -+ size_t align_start_up = (SIZE_ALIGN-1) & (-(uintptr_t)start - OVERHEAD); -+ size_t align_end_down = (SIZE_ALIGN-1) & (uintptr_t)end; -+ -+ /* Getting past this condition ensures that the padding for alignment -+ * and header overhead will not overflow and will leave a nonzero -+ * multiple of SIZE_ALIGN bytes between start and end. */ -+ if (end - start <= OVERHEAD + align_start_up + align_end_down) -+ return; -+ start += align_start_up + OVERHEAD; -+ end -= align_end_down; -+ -+ struct chunk *c = MEM_TO_CHUNK(start), *n = MEM_TO_CHUNK(end); -+ c->psize = n->csize = C_INUSE; -+ c->csize = n->psize = C_INUSE | (end-start); -+ __bin_chunk(c); -+} -diff --git a/src/malloc/memalign.c b/src/malloc/memalign.c -index 006bd21c..8a6152f4 100644 ---- a/src/malloc/memalign.c -+++ b/src/malloc/memalign.c -@@ -2,55 +2,53 @@ - #include <stdint.h> - #include <errno.h> - #include "libc.h" -- --/* This function should work with most dlmalloc-like chunk bookkeeping -- * systems, but it's only guaranteed to work with the native implementation -- * used in this library. */ -+#include "malloc_impl.h" - - void *__memalign(size_t align, size_t len) - { -- unsigned char *mem, *new, *end; -- size_t header, footer; -+ unsigned char *mem, *new; - - if ((align & -align) != align) { - errno = EINVAL; -- return NULL; -+ return 0; - } - -- if (len > SIZE_MAX - align) { -+ if (len > SIZE_MAX - align || __malloc_replaced) { - errno = ENOMEM; -- return NULL; -+ return 0; - } - -- if (align <= 4*sizeof(size_t)) { -- if (!(mem = malloc(len))) -- return NULL; -- return mem; -- } -+ if (align <= SIZE_ALIGN) -+ return malloc(len); - - if (!(mem = malloc(len + align-1))) -- return NULL; -+ return 0; - - new = (void *)((uintptr_t)mem + align-1 & -align); - if (new == mem) return mem; - -- header = ((size_t *)mem)[-1]; -+ struct chunk *c = MEM_TO_CHUNK(mem); -+ struct chunk *n = MEM_TO_CHUNK(new); - -- if (!(header & 7)) { -- ((size_t *)new)[-2] = ((size_t *)mem)[-2] + (new-mem); -- ((size_t *)new)[-1] = ((size_t *)mem)[-1] - (new-mem); -+ if (IS_MMAPPED(c)) { -+ /* Apply difference between aligned and original -+ * address to the "extra" field of mmapped chunk. */ -+ n->psize = c->psize + (new-mem); -+ n->csize = c->csize - (new-mem); - return new; - } - -- end = mem + (header & -8); -- footer = ((size_t *)end)[-2]; -+ struct chunk *t = NEXT_CHUNK(c); - -- ((size_t *)mem)[-1] = header&7 | new-mem; -- ((size_t *)new)[-2] = footer&7 | new-mem; -- ((size_t *)new)[-1] = header&7 | end-new; -- ((size_t *)end)[-2] = footer&7 | end-new; -+ /* Split the allocated chunk into two chunks. The aligned part -+ * that will be used has the size in its footer reduced by the -+ * difference between the aligned and original addresses, and -+ * the resulting size copied to its header. A new header and -+ * footer are written for the split-off part to be freed. */ -+ n->psize = c->csize = C_INUSE | (new-mem); -+ n->csize = t->psize -= new-mem; - -- free(mem); -+ __bin_chunk(c); - return new; - } - -diff --git a/src/math/__fpclassifyl.c b/src/math/__fpclassifyl.c -index 481c0b94..e41781b6 100644 ---- a/src/math/__fpclassifyl.c -+++ b/src/math/__fpclassifyl.c -@@ -13,10 +13,18 @@ int __fpclassifyl(long double x) - int msb = u.i.m>>63; - if (!e && !msb) - return u.i.m ? FP_SUBNORMAL : FP_ZERO; -+ if (e == 0x7fff) { -+ /* The x86 variant of 80-bit extended precision only admits -+ * one representation of each infinity, with the mantissa msb -+ * necessarily set. The version with it clear is invalid/nan. -+ * The m68k variant, however, allows either, and tooling uses -+ * the version with it clear. */ -+ if (__BYTE_ORDER == __LITTLE_ENDIAN && !msb) -+ return FP_NAN; -+ return u.i.m << 1 ? FP_NAN : FP_INFINITE; -+ } - if (!msb) - return FP_NAN; -- if (e == 0x7fff) -- return u.i.m << 1 ? FP_NAN : FP_INFINITE; - return FP_NORMAL; - } - #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -diff --git a/src/math/fmaf.c b/src/math/fmaf.c -index aa57feb6..80f5cd8a 100644 ---- a/src/math/fmaf.c -+++ b/src/math/fmaf.c -@@ -50,7 +50,7 @@ float fmaf(float x, float y, float z) - /* Common case: The double precision result is fine. */ - if ((u.i & 0x1fffffff) != 0x10000000 || /* not a halfway case */ - e == 0x7ff || /* NaN */ -- result - xy == z || /* exact */ -+ (result - xy == z && result - z == xy) || /* exact */ - fegetround() != FE_TONEAREST) /* not round-to-nearest */ - { - /* -diff --git a/src/misc/getentropy.c b/src/misc/getentropy.c -new file mode 100644 -index 00000000..4c61ae26 ---- /dev/null -+++ b/src/misc/getentropy.c -@@ -0,0 +1,31 @@ -+#include <sys/random.h> -+#include <pthread.h> -+#include <errno.h> -+ -+int getentropy(void *buffer, size_t len) -+{ -+ int cs, ret; -+ char *pos = buffer; -+ -+ if (len > 256) { -+ errno = EIO; -+ return -1; -+ } -+ -+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); -+ -+ while (len) { -+ ret = getrandom(pos, len, 0); -+ if (ret < 0) { -+ if (errno == EINTR) continue; -+ else break; -+ } -+ pos += ret; -+ len -= ret; -+ ret = 0; -+ } -+ -+ pthread_setcancelstate(cs, 0); -+ -+ return ret; -+} -diff --git a/src/misc/gethostid.c b/src/misc/gethostid.c -index ea65611a..25bb35db 100644 ---- a/src/misc/gethostid.c -+++ b/src/misc/gethostid.c -@@ -1,3 +1,5 @@ -+#include <unistd.h> -+ - long gethostid() - { - return 0; -diff --git a/src/misc/getopt.c b/src/misc/getopt.c -index e9bab41c..cd1f292f 100644 ---- a/src/misc/getopt.c -+++ b/src/misc/getopt.c -@@ -77,15 +77,19 @@ int getopt(int argc, char * const argv[], const char *optstring) - if (l>0) i+=l; else i++; - } while (l && d != c); - -- if (d != c) { -+ if (d != c || c == ':') { - optopt = c; - if (optstring[0] != ':' && opterr) - __getopt_msg(argv[0], ": unrecognized option: ", optchar, k); - return '?'; - } - if (optstring[i] == ':') { -- if (optstring[i+1] == ':') optarg = 0; -- else if (optind >= argc) { -+ optarg = 0; -+ if (optstring[i+1] != ':' || optpos) { -+ optarg = argv[optind++] + optpos; -+ optpos = 0; -+ } -+ if (optind > argc) { - optopt = c; - if (optstring[0] == ':') return ':'; - if (opterr) __getopt_msg(argv[0], -@@ -93,10 +97,6 @@ int getopt(int argc, char * const argv[], const char *optstring) - optchar, k); - return '?'; - } -- if (optstring[i+1] != ':' || optpos) { -- optarg = argv[optind++] + optpos; -- optpos = 0; -- } - } - return c; - } -diff --git a/src/misc/getopt_long.c b/src/misc/getopt_long.c -index 008b747c..ddcef949 100644 ---- a/src/misc/getopt_long.c -+++ b/src/misc/getopt_long.c -@@ -1,5 +1,7 @@ - #define _GNU_SOURCE - #include <stddef.h> -+#include <stdlib.h> -+#include <limits.h> - #include <getopt.h> - #include <stdio.h> - #include <string.h> -@@ -58,10 +60,10 @@ static int __getopt_long_core(int argc, char *const *argv, const char *optstring - { - int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':'; - int i, cnt, match; -- char *arg, *opt; -+ char *arg, *opt, *start = argv[optind]+1; - for (cnt=i=0; longopts[i].name; i++) { - const char *name = longopts[i].name; -- opt = argv[optind]+1; -+ opt = start; - if (*opt == '-') opt++; - while (*opt && *opt != '=' && *opt == *name) - name++, opt++; -@@ -74,6 +76,17 @@ static int __getopt_long_core(int argc, char *const *argv, const char *optstring - } - cnt++; - } -+ if (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) { -+ int l = arg-start; -+ for (i=0; optstring[i]; i++) { -+ int j; -+ for (j=0; j<l && start[j]==optstring[i+j]; j++); -+ if (j==l) { -+ cnt++; -+ break; -+ } -+ } -+ } - if (cnt==1) { - i = match; - opt = arg; -diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c -index b9439f77..ba26847a 100644 ---- a/src/network/getaddrinfo.c -+++ b/src/network/getaddrinfo.c -@@ -3,6 +3,10 @@ - #include <netinet/in.h> - #include <netdb.h> - #include <string.h> -+#include <pthread.h> -+#include <unistd.h> -+#include <endian.h> -+#include <errno.h> - #include "lookup.h" - - int getaddrinfo(const char *restrict host, const char *restrict serv, const struct addrinfo *restrict hint, struct addrinfo **restrict res) -@@ -43,6 +47,41 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru - } - } - -+ if (flags & AI_ADDRCONFIG) { -+ /* Define the "an address is configured" condition for address -+ * families via ability to create a socket for the family plus -+ * routability of the loopback address for the family. */ -+ static const struct sockaddr_in lo4 = { -+ .sin_family = AF_INET, .sin_port = 65535, -+ .sin_addr.s_addr = __BYTE_ORDER == __BIG_ENDIAN -+ ? 0x7f000001 : 0x0100007f -+ }; -+ static const struct sockaddr_in6 lo6 = { -+ .sin6_family = AF_INET6, .sin6_port = 65535, -+ .sin6_addr = IN6ADDR_LOOPBACK_INIT -+ }; -+ int tf[2] = { AF_INET, AF_INET6 }; -+ const void *ta[2] = { &lo4, &lo6 }; -+ socklen_t tl[2] = { sizeof lo4, sizeof lo6 }; -+ for (i=0; i<2; i++) { -+ if (family==tf[1-i]) continue; -+ int s = socket(tf[i], SOCK_CLOEXEC|SOCK_DGRAM, -+ IPPROTO_UDP); -+ if (s>=0) { -+ int cs; -+ pthread_setcancelstate( -+ PTHREAD_CANCEL_DISABLE, &cs); -+ int r = connect(s, ta[i], tl[i]); -+ pthread_setcancelstate(cs, 0); -+ close(s); -+ if (!r) continue; -+ } -+ if (errno != EAFNOSUPPORT) return EAI_SYSTEM; -+ if (family == tf[i]) return EAI_NONAME; -+ family = tf[1-i]; -+ } -+ } -+ - nservs = __lookup_serv(ports, serv, proto, socktype, flags); - if (nservs < 0) return nservs; - -diff --git a/src/network/inet_ntop.c b/src/network/inet_ntop.c -index 14f9f4c4..4bfef2c5 100644 ---- a/src/network/inet_ntop.c -+++ b/src/network/inet_ntop.c -@@ -36,7 +36,7 @@ const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen - j = strspn(buf+i, ":0"); - if (j>max) best=i, max=j; - } -- if (max>2) { -+ if (max>3) { - buf[best] = buf[best+1] = ':'; - memmove(buf+best+2, buf+best+max, i-best-max+1); - } -diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c -index 209c20f0..0e6db9ef 100644 ---- a/src/network/lookup_name.c -+++ b/src/network/lookup_name.c -@@ -184,6 +184,10 @@ static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[ - for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++; - if (dots >= conf.ndots || name[l-1]=='.') *search = 0; - -+ /* Strip final dot for canon, fail if multiple trailing dots. */ -+ if (name[l-1]=='.') l--; -+ if (!l || name[l-1]=='.') return EAI_NONAME; -+ - /* This can never happen; the caller already checked length. */ - if (l >= 256) return EAI_NONAME; - -@@ -351,36 +355,53 @@ int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], c - * excessive runtime and code size cost and dubious benefit. - * So far the label/precedence table cannot be customized. */ - for (i=0; i<cnt; i++) { -+ int family = buf[i].family; - int key = 0; -- struct sockaddr_in6 sa, da = { -+ struct sockaddr_in6 sa6 = { 0 }, da6 = { - .sin6_family = AF_INET6, - .sin6_scope_id = buf[i].scopeid, - .sin6_port = 65535 - }; -- if (buf[i].family == AF_INET6) { -- memcpy(da.sin6_addr.s6_addr, buf[i].addr, 16); -+ struct sockaddr_in sa4 = { 0 }, da4 = { -+ .sin_family = AF_INET, -+ .sin_port = 65535 -+ }; -+ void *sa, *da; -+ socklen_t salen, dalen; -+ if (family == AF_INET6) { -+ memcpy(da6.sin6_addr.s6_addr, buf[i].addr, 16); -+ da = &da6; dalen = sizeof da6; -+ sa = &sa6; salen = sizeof sa6; - } else { -- memcpy(da.sin6_addr.s6_addr, -+ memcpy(sa6.sin6_addr.s6_addr, -+ "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); -+ memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4); -+ memcpy(da6.sin6_addr.s6_addr, - "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); -- memcpy(da.sin6_addr.s6_addr+12, buf[i].addr, 4); -+ memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4); -+ memcpy(&da4.sin_addr, buf[i].addr, 4); -+ da = &da4; dalen = sizeof da4; -+ sa = &sa4; salen = sizeof sa4; - } -- const struct policy *dpolicy = policyof(&da.sin6_addr); -- int dscope = scopeof(&da.sin6_addr); -+ const struct policy *dpolicy = policyof(&da6.sin6_addr); -+ int dscope = scopeof(&da6.sin6_addr); - int dlabel = dpolicy->label; - int dprec = dpolicy->prec; - int prefixlen = 0; -- int fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP); -+ int fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP); - if (fd >= 0) { -- if (!connect(fd, (void *)&da, sizeof da)) { -+ if (!connect(fd, da, dalen)) { - key |= DAS_USABLE; -- if (!getsockname(fd, (void *)&sa, -- &(socklen_t){sizeof sa})) { -- if (dscope == scopeof(&sa.sin6_addr)) -+ if (!getsockname(fd, sa, &salen)) { -+ if (family == AF_INET) memcpy( -+ &sa6.sin6_addr.s6_addr+12, -+ &sa4.sin_addr, 4); -+ if (dscope == scopeof(&sa6.sin6_addr)) - key |= DAS_MATCHINGSCOPE; -- if (dlabel == labelof(&sa.sin6_addr)) -+ if (dlabel == labelof(&sa6.sin6_addr)) - key |= DAS_MATCHINGLABEL; -- prefixlen = prefixmatch(&sa.sin6_addr, -- &da.sin6_addr); -+ prefixlen = prefixmatch(&sa6.sin6_addr, -+ &da6.sin6_addr); - } - } - close(fd); diff --git a/src/process/execlp.c b/src/process/execlp.c index 5eed886e..f6da398b 100644 --- a/src/process/execlp.c @@ -5162,16 +228,10 @@ index 2dddeddb..fdd0ca48 100644 weak_alias(__execvpe, execvpe); diff --git a/src/process/system.c b/src/process/system.c -index 8cbdda06..aa01e13b 100644 +index 9135b815..aa01e13b 100644 --- a/src/process/system.c +++ b/src/process/system.c -@@ -14,12 +14,14 @@ int system(const char *cmd) - pid_t pid; - sigset_t old, reset; - struct sigaction sa = { .sa_handler = SIG_IGN }, oldint, oldquit; -- int status = 0x7f00, ret; -+ int status = -1, ret; - posix_spawnattr_t attr; +@@ -19,7 +19,9 @@ int system(const char *cmd) pthread_testcancel(); @@ -5182,1098 +242,11 @@ index 8cbdda06..aa01e13b 100644 sigaction(SIGINT, &sa, &oldint); sigaction(SIGQUIT, &sa, &oldquit); -diff --git a/src/setjmp/m68k/longjmp.s b/src/setjmp/m68k/longjmp.s -new file mode 100644 -index 00000000..cdb05fb5 ---- /dev/null -+++ b/src/setjmp/m68k/longjmp.s -@@ -0,0 +1,14 @@ -+.global _longjmp -+.global longjmp -+.type _longjmp,@function -+.type longjmp,@function -+_longjmp: -+longjmp: -+ movea.l 4(%sp),%a0 -+ move.l 8(%sp),%d0 -+ bne 1f -+ move.l #1,%d0 -+1: movem.l (%a0),%d2-%d7/%a2-%a7 -+ fmovem.x 52(%a0),%fp2-%fp7 -+ move.l 48(%a0),(%sp) -+ rts -diff --git a/src/setjmp/m68k/setjmp.s b/src/setjmp/m68k/setjmp.s -new file mode 100644 -index 00000000..15e549b0 ---- /dev/null -+++ b/src/setjmp/m68k/setjmp.s -@@ -0,0 +1,18 @@ -+.global ___setjmp -+.hidden ___setjmp -+.global __setjmp -+.global _setjmp -+.global setjmp -+.type __setjmp,@function -+.type _setjmp,@function -+.type setjmp,@function -+___setjmp: -+__setjmp: -+_setjmp: -+setjmp: -+ movea.l 4(%sp),%a0 -+ movem.l %d2-%d7/%a2-%a7,(%a0) -+ move.l (%sp),48(%a0) -+ fmovem.x %fp2-%fp7,52(%a0) -+ clr.l %d0 -+ rts -diff --git a/src/signal/m68k/sigsetjmp.s b/src/signal/m68k/sigsetjmp.s -new file mode 100644 -index 00000000..09bfa646 ---- /dev/null -+++ b/src/signal/m68k/sigsetjmp.s -@@ -0,0 +1,29 @@ -+.global sigsetjmp -+.global __sigsetjmp -+.type sigsetjmp,@function -+.type __sigsetjmp,@function -+sigsetjmp: -+__sigsetjmp: -+ move.l 8(%sp),%d0 -+ beq 1f -+ -+ movea.l 4(%sp),%a1 -+ move.l (%sp)+,156(%a1) -+ move.l %a2,156+4+8(%a1) -+ movea.l %a1,%a2 -+ -+.hidden ___setjmp -+ lea ___setjmp-.-8,%a1 -+ jsr (%pc,%a1) -+ -+ move.l 156(%a2),-(%sp) -+ move.l %a2,4(%sp) -+ move.l %d0,8(%sp) -+ movea.l 156+4+8(%a2),%a2 -+ -+.hidden __sigsetjmp_tail -+ lea __sigsetjmp_tail-.-8,%a1 -+ jmp (%pc,%a1) -+ -+1: lea ___setjmp-.-8,%a1 -+ jmp (%pc,%a1) -diff --git a/src/signal/psiginfo.c b/src/signal/psiginfo.c -index 57be34cd..2b15982b 100644 ---- a/src/signal/psiginfo.c -+++ b/src/signal/psiginfo.c -@@ -1,10 +1,6 @@ --#include <stdio.h> --#include <string.h> - #include <signal.h> - - void psiginfo(const siginfo_t *si, const char *msg) - { -- char *s = strsignal(si->si_signo); -- if (msg) fprintf(stderr, "%s: %s\n", msg, s); -- else fprintf(stderr, "%s\n", s); -+ psignal(si->si_signo, msg); - } -diff --git a/src/signal/psignal.c b/src/signal/psignal.c -index 02f1c760..138dbe00 100644 ---- a/src/signal/psignal.c -+++ b/src/signal/psignal.c -@@ -1,10 +1,27 @@ --#include <stdio.h> -+#include "stdio_impl.h" - #include <string.h> - #include <signal.h> -+#include <errno.h> - - void psignal(int sig, const char *msg) - { -+ FILE *f = stderr; - char *s = strsignal(sig); -- if (msg) fprintf(stderr, "%s: %s\n", msg, s); -- else fprintf(stderr, "%s\n", s); -+ -+ FLOCK(f); -+ -+ /* Save stderr's orientation and encoding rule, since psignal is not -+ * permitted to change them. Save errno and restore it if there is no -+ * error since fprintf might change it even on success but psignal is -+ * not permitted to do so. */ -+ void *old_locale = f->locale; -+ int old_mode = f->mode; -+ int old_errno = errno; -+ -+ if (fprintf(f, "%s%s%s\n", msg?msg:"", msg?": ":"", s)>=0) -+ errno = old_errno; -+ f->mode = old_mode; -+ f->locale = old_locale; -+ -+ FUNLOCK(f); - } -diff --git a/src/signal/sigisemptyset.c b/src/signal/sigisemptyset.c -index 312c66cf..68b86624 100644 ---- a/src/signal/sigisemptyset.c -+++ b/src/signal/sigisemptyset.c -@@ -4,6 +4,7 @@ - - int sigisemptyset(const sigset_t *set) - { -- static const unsigned long zeroset[_NSIG/8/sizeof(long)]; -- return !memcmp(set, &zeroset, _NSIG/8); -+ for (size_t i=0; i<_NSIG/8/sizeof *set->__bits; i++) -+ if (set->__bits[i]) return 0; -+ return 1; - } -diff --git a/src/signal/sigrtmin.c b/src/signal/sigrtmin.c -index d0e769bb..c5a1fd92 100644 ---- a/src/signal/sigrtmin.c -+++ b/src/signal/sigrtmin.c -@@ -1,3 +1,5 @@ -+#include <signal.h> -+ - int __libc_current_sigrtmin() - { - return 35; -diff --git a/src/stdio/__lockfile.c b/src/stdio/__lockfile.c -index 9d967d6e..2ff75d8a 100644 ---- a/src/stdio/__lockfile.c -+++ b/src/stdio/__lockfile.c -@@ -1,28 +1,25 @@ - #include "stdio_impl.h" - #include "pthread_impl.h" - -+#define MAYBE_WAITERS 0x40000000 -+ - int __lockfile(FILE *f) - { -- int owner, tid = __pthread_self()->tid; -- if (f->lock == tid) -+ int owner = f->lock, tid = __pthread_self()->tid; -+ if ((owner & ~MAYBE_WAITERS) == tid) - return 0; -- while ((owner = a_cas(&f->lock, 0, tid))) -- __wait(&f->lock, &f->waiters, owner, 1); -+ for (;;) { -+ owner = a_cas(&f->lock, 0, tid); -+ if (!owner) return 1; -+ if (a_cas(&f->lock, owner, owner|MAYBE_WAITERS)==owner) break; -+ } -+ while ((owner = a_cas(&f->lock, 0, tid|MAYBE_WAITERS))) -+ __futexwait(&f->lock, owner, 1); - return 1; - } - - void __unlockfile(FILE *f) - { -- a_store(&f->lock, 0); -- -- /* The following read is technically invalid under situations -- * of self-synchronized destruction. Another thread may have -- * called fclose as soon as the above store has completed. -- * Nonetheless, since FILE objects always live in memory -- * obtained by malloc from the heap, it's safe to assume -- * the dereferences below will not fault. In the worst case, -- * a spurious syscall will be made. If the implementation of -- * malloc changes, this assumption needs revisiting. */ -- -- if (f->waiters) __wake(&f->lock, 1, 1); -+ if (a_swap(&f->lock, 0) & MAYBE_WAITERS) -+ __wake(&f->lock, 1, 1); - } -diff --git a/src/stdio/__stdio_exit.c b/src/stdio/__stdio_exit.c -index 191b4454..5741070f 100644 ---- a/src/stdio/__stdio_exit.c -+++ b/src/stdio/__stdio_exit.c -@@ -19,6 +19,7 @@ void __stdio_exit(void) - for (f=*__ofl_lock(); f; f=f->next) close_file(f); - close_file(__stdin_used); - close_file(__stdout_used); -+ close_file(__stderr_used); - } - - weak_alias(__stdio_exit, __stdio_exit_needed); -diff --git a/src/stdio/__stdio_read.c b/src/stdio/__stdio_read.c -index f8fa6d3b..ea675da3 100644 ---- a/src/stdio/__stdio_read.c -+++ b/src/stdio/__stdio_read.c -@@ -9,10 +9,11 @@ size_t __stdio_read(FILE *f, unsigned char *buf, size_t len) - }; - ssize_t cnt; - -- cnt = syscall(SYS_readv, f->fd, iov, 2); -+ cnt = iov[0].iov_len ? syscall(SYS_readv, f->fd, iov, 2) -+ : syscall(SYS_read, f->fd, iov[1].iov_base, iov[1].iov_len); - if (cnt <= 0) { -- f->flags |= F_EOF ^ ((F_ERR^F_EOF) & cnt); -- return cnt; -+ f->flags |= cnt ? F_ERR : F_EOF; -+ return 0; - } - if (cnt <= iov[0].iov_len) return cnt; - cnt -= iov[0].iov_len; -diff --git a/src/stdio/__towrite.c b/src/stdio/__towrite.c -index 0a69d926..b022cbca 100644 ---- a/src/stdio/__towrite.c -+++ b/src/stdio/__towrite.c -@@ -3,7 +3,7 @@ - int __towrite(FILE *f) - { - f->mode |= f->mode-1; -- if (f->flags & (F_NOWR)) { -+ if (f->flags & F_NOWR) { - f->flags |= F_ERR; - return EOF; - } -diff --git a/src/stdio/fclose.c b/src/stdio/fclose.c -index d687a877..c675413d 100644 ---- a/src/stdio/fclose.c -+++ b/src/stdio/fclose.c -@@ -24,7 +24,7 @@ int fclose(FILE *f) - r = fflush(f); - r |= f->close(f); - -- if (f->getln_buf) free(f->getln_buf); -+ free(f->getln_buf); - if (!perm) free(f); - else FUNLOCK(f); - -diff --git a/src/stdio/fgetpos.c b/src/stdio/fgetpos.c -index c3fa0eb0..6eb361e1 100644 ---- a/src/stdio/fgetpos.c -+++ b/src/stdio/fgetpos.c -@@ -4,7 +4,7 @@ int fgetpos(FILE *restrict f, fpos_t *restrict pos) - { - off_t off = __ftello(f); - if (off < 0) return -1; -- *(off_t *)pos = off; -+ *(long long *)pos = off; - return 0; - } - -diff --git a/src/stdio/fileno.c b/src/stdio/fileno.c -index ba7f9391..0bd0e988 100644 ---- a/src/stdio/fileno.c -+++ b/src/stdio/fileno.c -@@ -1,13 +1,16 @@ - #include "stdio_impl.h" -+#include <errno.h> - - int fileno(FILE *f) - { -- /* f->fd never changes, but the lock must be obtained and released -- * anyway since this function cannot return while another thread -- * holds the lock. */ - FLOCK(f); -+ int fd = f->fd; - FUNLOCK(f); -- return f->fd; -+ if (fd < 0) { -+ errno = EBADF; -+ return -1; -+ } -+ return fd; - } - - weak_alias(fileno, fileno_unlocked); -diff --git a/src/stdio/flockfile.c b/src/stdio/flockfile.c -index a196c1ef..6806cf8b 100644 ---- a/src/stdio/flockfile.c -+++ b/src/stdio/flockfile.c -@@ -1,10 +1,11 @@ - #include "stdio_impl.h" - #include "pthread_impl.h" - -+void __register_locked_file(FILE *, pthread_t); -+ - void flockfile(FILE *f) - { -- while (ftrylockfile(f)) { -- int owner = f->lock; -- if (owner) __wait(&f->lock, &f->waiters, owner, 1); -- } -+ if (!ftrylockfile(f)) return; -+ __lockfile(f); -+ __register_locked_file(f, __pthread_self()); - } -diff --git a/src/stdio/fmemopen.c b/src/stdio/fmemopen.c -index 2ce43d32..5e0eeb50 100644 ---- a/src/stdio/fmemopen.c -+++ b/src/stdio/fmemopen.c -@@ -9,6 +9,12 @@ struct cookie { - int mode; - }; - -+struct mem_FILE { -+ FILE f; -+ struct cookie c; -+ unsigned char buf[UNGET+BUFSIZ], buf2[]; -+}; -+ - static off_t mseek(FILE *f, off_t off, int whence) - { - ssize_t base; -@@ -72,8 +78,7 @@ static int mclose(FILE *m) - - FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode) - { -- FILE *f; -- struct cookie *c; -+ struct mem_FILE *f; - int plus = !!strchr(mode, '+'); - - if (!size || !strchr("rwa", *mode)) { -@@ -86,29 +91,35 @@ FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode) - return 0; - } - -- f = calloc(sizeof *f + sizeof *c + UNGET + BUFSIZ + (buf?0:size), 1); -+ f = malloc(sizeof *f + (buf?0:size)); - if (!f) return 0; -- f->cookie = c = (void *)(f+1); -- f->fd = -1; -- f->lbf = EOF; -- f->buf = (unsigned char *)(c+1) + UNGET; -- f->buf_size = BUFSIZ; -- if (!buf) buf = f->buf + BUFSIZ; -+ memset(&f->f, 0, sizeof f->f); -+ f->f.cookie = &f->c; -+ f->f.fd = -1; -+ f->f.lbf = EOF; -+ f->f.buf = f->buf + UNGET; -+ f->f.buf_size = sizeof f->buf - UNGET; -+ if (!buf) { -+ buf = f->buf2;; -+ memset(buf, 0, size); -+ } - -- c->buf = buf; -- c->size = size; -- c->mode = *mode; -+ memset(&f->c, 0, sizeof f->c); -+ f->c.buf = buf; -+ f->c.size = size; -+ f->c.mode = *mode; - -- if (!plus) f->flags = (*mode == 'r') ? F_NOWR : F_NORD; -- if (*mode == 'r') c->len = size; -- else if (*mode == 'a') c->len = c->pos = strnlen(buf, size); -+ if (!plus) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD; -+ if (*mode == 'r') f->c.len = size; -+ else if (*mode == 'a') f->c.len = f->c.pos = strnlen(buf, size); -+ else if (plus) *f->c.buf = 0; - -- f->read = mread; -- f->write = mwrite; -- f->seek = mseek; -- f->close = mclose; -+ f->f.read = mread; -+ f->f.write = mwrite; -+ f->f.seek = mseek; -+ f->f.close = mclose; - -- if (!libc.threaded) f->lock = -1; -+ if (!libc.threaded) f->f.lock = -1; - -- return __ofl_add(f); -+ return __ofl_add(&f->f); - } -diff --git a/src/stdio/fopencookie.c b/src/stdio/fopencookie.c -index 2f46dd53..da042fe8 100644 ---- a/src/stdio/fopencookie.c -+++ b/src/stdio/fopencookie.c -@@ -116,15 +116,12 @@ FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t iofuncs) - - /* Set up our fcookie */ - f->fc.cookie = cookie; -- f->fc.iofuncs.read = iofuncs.read; -- f->fc.iofuncs.write = iofuncs.write; -- f->fc.iofuncs.seek = iofuncs.seek; -- f->fc.iofuncs.close = iofuncs.close; -+ f->fc.iofuncs = iofuncs; - - f->f.fd = -1; - f->f.cookie = &f->fc; - f->f.buf = f->buf + UNGET; -- f->f.buf_size = BUFSIZ; -+ f->f.buf_size = sizeof f->buf - UNGET; - f->f.lbf = EOF; - - /* Initialize op ptrs. No problem if some are unneeded. */ -diff --git a/src/stdio/fread.c b/src/stdio/fread.c -index aef75f73..733d3716 100644 ---- a/src/stdio/fread.c -+++ b/src/stdio/fread.c -@@ -25,7 +25,7 @@ size_t fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f) - /* Read the remainder directly */ - for (; l; l-=k, dest+=k) { - k = __toread(f) ? 0 : f->read(f, dest, l); -- if (k+1<=1) { -+ if (!k) { - FUNLOCK(f); - return (len-l)/size; - } -diff --git a/src/stdio/fsetpos.c b/src/stdio/fsetpos.c -index 5d76c8cd..6310424e 100644 ---- a/src/stdio/fsetpos.c -+++ b/src/stdio/fsetpos.c -@@ -2,7 +2,7 @@ - - int fsetpos(FILE *f, const fpos_t *pos) - { -- return __fseeko(f, *(const off_t *)pos, SEEK_SET); -+ return __fseeko(f, *(const long long *)pos, SEEK_SET); - } - - LFS64(fsetpos); -diff --git a/src/stdio/ftrylockfile.c b/src/stdio/ftrylockfile.c -index eb13c839..3b97807a 100644 ---- a/src/stdio/ftrylockfile.c -+++ b/src/stdio/ftrylockfile.c -@@ -2,6 +2,8 @@ - #include "pthread_impl.h" - #include <limits.h> - -+#define MAYBE_WAITERS 0x40000000 -+ - void __do_orphaned_stdio_locks() - { - FILE *f; -@@ -18,23 +20,29 @@ void __unlist_locked_file(FILE *f) - } - } - -+void __register_locked_file(FILE *f, pthread_t self) -+{ -+ f->lockcount = 1; -+ f->prev_locked = 0; -+ f->next_locked = self->stdio_locks; -+ if (f->next_locked) f->next_locked->prev_locked = f; -+ self->stdio_locks = f; -+} -+ - int ftrylockfile(FILE *f) - { - pthread_t self = __pthread_self(); - int tid = self->tid; -- if (f->lock == tid) { -+ int owner = f->lock; -+ if ((owner & ~MAYBE_WAITERS) == tid) { - if (f->lockcount == LONG_MAX) - return -1; - f->lockcount++; - return 0; - } -- if (f->lock < 0) f->lock = 0; -- if (f->lock || a_cas(&f->lock, 0, tid)) -+ if (owner < 0) f->lock = owner = 0; -+ if (owner || a_cas(&f->lock, 0, tid)) - return -1; -- f->lockcount = 1; -- f->prev_locked = 0; -- f->next_locked = self->stdio_locks; -- if (f->next_locked) f->next_locked->prev_locked = f; -- self->stdio_locks = f; -+ __register_locked_file(f, self); - return 0; - } -diff --git a/src/stdio/getdelim.c b/src/stdio/getdelim.c -index 1ccd8029..d4b23882 100644 ---- a/src/stdio/getdelim.c -+++ b/src/stdio/getdelim.c -@@ -3,8 +3,6 @@ - #include <inttypes.h> - #include <errno.h> - --#define MIN(a,b) ((a)<(b) ? (a) : (b)) -- - ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restrict f) - { - char *tmp; -diff --git a/src/stdio/open_memstream.c b/src/stdio/open_memstream.c -index eab024da..40f5ad60 100644 ---- a/src/stdio/open_memstream.c -+++ b/src/stdio/open_memstream.c -@@ -12,6 +12,12 @@ struct cookie { - size_t space; - }; - -+struct ms_FILE { -+ FILE f; -+ struct cookie c; -+ unsigned char buf[BUFSIZ]; -+}; -+ - static off_t ms_seek(FILE *f, off_t off, int whence) - { - ssize_t base; -@@ -57,34 +63,35 @@ static int ms_close(FILE *f) - - FILE *open_memstream(char **bufp, size_t *sizep) - { -- FILE *f; -- struct cookie *c; -+ struct ms_FILE *f; - char *buf; - -- if (!(f=malloc(sizeof *f + sizeof *c + BUFSIZ))) return 0; -+ if (!(f=malloc(sizeof *f))) return 0; - if (!(buf=malloc(sizeof *buf))) { - free(f); - return 0; - } -- memset(f, 0, sizeof *f + sizeof *c); -- f->cookie = c = (void *)(f+1); -+ memset(&f->f, 0, sizeof f->f); -+ memset(&f->c, 0, sizeof f->c); -+ f->f.cookie = &f->c; - -- c->bufp = bufp; -- c->sizep = sizep; -- c->pos = c->len = c->space = *sizep = 0; -- c->buf = *bufp = buf; -+ f->c.bufp = bufp; -+ f->c.sizep = sizep; -+ f->c.pos = f->c.len = f->c.space = *sizep = 0; -+ f->c.buf = *bufp = buf; - *buf = 0; - -- f->flags = F_NORD; -- f->fd = -1; -- f->buf = (void *)(c+1); -- f->buf_size = BUFSIZ; -- f->lbf = EOF; -- f->write = ms_write; -- f->seek = ms_seek; -- f->close = ms_close; -+ f->f.flags = F_NORD; -+ f->f.fd = -1; -+ f->f.buf = f->buf; -+ f->f.buf_size = sizeof f->buf; -+ f->f.lbf = EOF; -+ f->f.write = ms_write; -+ f->f.seek = ms_seek; -+ f->f.close = ms_close; -+ f->f.mode = -1; - -- if (!libc.threaded) f->lock = -1; -+ if (!libc.threaded) f->f.lock = -1; - -- return __ofl_add(f); -+ return __ofl_add(&f->f); - } -diff --git a/src/stdio/open_wmemstream.c b/src/stdio/open_wmemstream.c -index 4d90cd97..a7c3a645 100644 ---- a/src/stdio/open_wmemstream.c -+++ b/src/stdio/open_wmemstream.c -@@ -14,6 +14,12 @@ struct cookie { - mbstate_t mbs; - }; - -+struct wms_FILE { -+ FILE f; -+ struct cookie c; -+ unsigned char buf[1]; -+}; -+ - static off_t wms_seek(FILE *f, off_t off, int whence) - { - ssize_t base; -@@ -59,34 +65,36 @@ static int wms_close(FILE *f) - - FILE *open_wmemstream(wchar_t **bufp, size_t *sizep) - { -- FILE *f; -- struct cookie *c; -+ struct wms_FILE *f; - wchar_t *buf; - -- if (!(f=malloc(sizeof *f + sizeof *c))) return 0; -+ if (!(f=malloc(sizeof *f))) return 0; - if (!(buf=malloc(sizeof *buf))) { - free(f); - return 0; - } -- memset(f, 0, sizeof *f + sizeof *c); -- f->cookie = c = (void *)(f+1); -+ memset(&f->f, 0, sizeof f->f); -+ memset(&f->c, 0, sizeof f->c); -+ f->f.cookie = &f->c; - -- c->bufp = bufp; -- c->sizep = sizep; -- c->pos = c->len = c->space = *sizep = 0; -- c->buf = *bufp = buf; -+ f->c.bufp = bufp; -+ f->c.sizep = sizep; -+ f->c.pos = f->c.len = f->c.space = *sizep = 0; -+ f->c.buf = *bufp = buf; - *buf = 0; - -- f->flags = F_NORD; -- f->fd = -1; -- f->buf = (void *)(c+1); -- f->buf_size = 0; -- f->lbf = EOF; -- f->write = wms_write; -- f->seek = wms_seek; -- f->close = wms_close; -+ f->f.flags = F_NORD; -+ f->f.fd = -1; -+ f->f.buf = f->buf; -+ f->f.buf_size = 0; -+ f->f.lbf = EOF; -+ f->f.write = wms_write; -+ f->f.seek = wms_seek; -+ f->f.close = wms_close; -+ -+ if (!libc.threaded) f->f.lock = -1; - -- if (!libc.threaded) f->lock = -1; -+ fwide(&f->f, 1); - -- return __ofl_add(f); -+ return __ofl_add(&f->f); - } -diff --git a/src/stdio/perror.c b/src/stdio/perror.c -index fdcb4d71..d0943f26 100644 ---- a/src/stdio/perror.c -+++ b/src/stdio/perror.c -@@ -9,6 +9,11 @@ void perror(const char *msg) - char *errstr = strerror(errno); - - FLOCK(f); -+ -+ /* Save stderr's orientation and encoding rule, since perror is not -+ * permitted to change them. */ -+ void *old_locale = f->locale; -+ int old_mode = f->mode; - - if (msg && *msg) { - fwrite(msg, strlen(msg), 1, f); -@@ -18,5 +23,8 @@ void perror(const char *msg) - fwrite(errstr, strlen(errstr), 1, f); - fputc('\n', f); - -+ f->mode = old_mode; -+ f->locale = old_locale; -+ - FUNLOCK(f); - } -diff --git a/src/stdio/setvbuf.c b/src/stdio/setvbuf.c -index 541a125f..06ea296c 100644 ---- a/src/stdio/setvbuf.c -+++ b/src/stdio/setvbuf.c -@@ -1,22 +1,25 @@ - #include "stdio_impl.h" - --/* This function makes no attempt to protect the user from his/her own -- * stupidity. If called any time but when then ISO C standard specifically -- * allows it, all hell can and will break loose, especially with threads! -- * -- * This implementation ignores all arguments except the buffering type, -- * and uses the existing buffer allocated alongside the FILE object. -- * In the case of stderr where the preexisting buffer is length 1, it -- * is not possible to set line buffering or full buffering. */ -+/* The behavior of this function is undefined except when it is the first -+ * operation on the stream, so the presence or absence of locking is not -+ * observable in a program whose behavior is defined. Thus no locking is -+ * performed here. No allocation of buffers is performed, but a buffer -+ * provided by the caller is used as long as it is suitably sized. */ - - int setvbuf(FILE *restrict f, char *restrict buf, int type, size_t size) - { - f->lbf = EOF; - -- if (type == _IONBF) -+ if (type == _IONBF) { - f->buf_size = 0; -- else if (type == _IOLBF) -- f->lbf = '\n'; -+ } else { -+ if (buf && size >= UNGET) { -+ f->buf = (void *)(buf + UNGET); -+ f->buf_size = size - UNGET; -+ } -+ if (type == _IOLBF && f->buf_size) -+ f->lbf = '\n'; -+ } - - f->flags |= F_SVB; - -diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c -index 50fb55c1..2100eb5e 100644 ---- a/src/stdio/vfprintf.c -+++ b/src/stdio/vfprintf.c -@@ -220,6 +220,7 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) - else re=LDBL_MANT_DIG/4-1-p; - - if (re) { -+ round *= 1<<(LDBL_MANT_DIG%4); - while (re--) round*=16; - if (*prefix=='-') { - y=-y; -@@ -673,11 +674,12 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) - if (f->mode < 1) f->flags &= ~F_ERR; - if (!f->buf_size) { - saved_buf = f->buf; -- f->wpos = f->wbase = f->buf = internal_buf; -+ f->buf = internal_buf; - f->buf_size = sizeof internal_buf; -- f->wend = internal_buf + sizeof internal_buf; -+ f->wpos = f->wbase = f->wend = 0; - } -- ret = printf_core(f, fmt, &ap2, nl_arg, nl_type); -+ if (!f->wend && __towrite(f)) ret = -1; -+ else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type); - if (saved_buf) { - f->write(f, 0, 0); - if (!f->wpos) ret = -1; -diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c -index e87ad42a..9d774fcc 100644 ---- a/src/stdio/vfwprintf.c -+++ b/src/stdio/vfwprintf.c -@@ -255,8 +255,11 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ - } - continue; - case 'c': -+ if (w<1) w=1; -+ if (w>1 && !(fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, ""); - fputwc(btowc(arg.i), f); -- l = 1; -+ if (w>1 && (fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, ""); -+ l = w; - continue; - case 'C': - fputwc(arg.i, f); -diff --git a/src/stdio/vswprintf.c b/src/stdio/vswprintf.c -index 6eb2f6ac..38efed65 100644 ---- a/src/stdio/vswprintf.c -+++ b/src/stdio/vswprintf.c -@@ -1,6 +1,5 @@ - #include "stdio_impl.h" - #include <limits.h> --#include <string.h> - #include <errno.h> - #include <stdint.h> - #include <wchar.h> -@@ -37,17 +36,17 @@ static size_t sw_write(FILE *f, const unsigned char *s, size_t l) - int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap) - { - int r; -- FILE f; - unsigned char buf[256]; - struct cookie c = { s, n-1 }; -+ FILE f = { -+ .lbf = EOF, -+ .write = sw_write, -+ .lock = -1, -+ .buf = buf, -+ .buf_size = sizeof buf, -+ .cookie = &c, -+ }; - -- memset(&f, 0, sizeof(FILE)); -- f.lbf = EOF; -- f.write = sw_write; -- f.buf_size = sizeof buf; -- f.buf = buf; -- f.lock = -1; -- f.cookie = &c; - if (!n) { - return -1; - } else if (n > INT_MAX) { -diff --git a/src/stdlib/abs.c b/src/stdlib/abs.c -index 4806d629..e721fdc2 100644 ---- a/src/stdlib/abs.c -+++ b/src/stdlib/abs.c -@@ -1,3 +1,5 @@ -+#include <stdlib.h> -+ - int abs(int a) - { - return a>0 ? a : -a; -diff --git a/src/stdlib/bsearch.c b/src/stdlib/bsearch.c -index 61d89367..fe050ea3 100644 ---- a/src/stdlib/bsearch.c -+++ b/src/stdlib/bsearch.c -@@ -7,13 +7,13 @@ void *bsearch(const void *key, const void *base, size_t nel, size_t width, int ( - while (nel > 0) { - try = (char *)base + width*(nel/2); - sign = cmp(key, try); -- if (!sign) return try; -- else if (nel == 1) break; -- else if (sign < 0) -+ if (sign < 0) { - nel /= 2; -- else { -- base = try; -- nel -= nel/2; -+ } else if (sign > 0) { -+ base = (char *)try + width; -+ nel -= nel/2+1; -+ } else { -+ return try; - } - } - return NULL; -diff --git a/src/stdlib/labs.c b/src/stdlib/labs.c -index 675b95b8..83ddb147 100644 ---- a/src/stdlib/labs.c -+++ b/src/stdlib/labs.c -@@ -1,3 +1,5 @@ -+#include <stdlib.h> -+ - long labs(long a) - { - return a>0 ? a : -a; -diff --git a/src/stdlib/llabs.c b/src/stdlib/llabs.c -index bec4a03d..9dfaf5cf 100644 ---- a/src/stdlib/llabs.c -+++ b/src/stdlib/llabs.c -@@ -1,3 +1,5 @@ -+#include <stdlib.h> -+ - long long llabs(long long a) - { - return a>0 ? a : -a; -diff --git a/src/string/explicit_bzero.c b/src/string/explicit_bzero.c -new file mode 100644 -index 00000000..f2e12f23 ---- /dev/null -+++ b/src/string/explicit_bzero.c -@@ -0,0 +1,8 @@ -+#define _BSD_SOURCE -+#include <string.h> -+ -+void explicit_bzero(void *d, size_t n) -+{ -+ d = memset(d, 0, n); -+ __asm__ __volatile__ ("" : : "r"(d) : "memory"); -+} -diff --git a/src/thread/arm/__aeabi_read_tp.s b/src/thread/arm/__aeabi_read_tp.s -index 9d0cd311..2585620c 100644 ---- a/src/thread/arm/__aeabi_read_tp.s -+++ b/src/thread/arm/__aeabi_read_tp.s -@@ -2,7 +2,9 @@ - .global __aeabi_read_tp - .type __aeabi_read_tp,%function - __aeabi_read_tp: -- push {r1,r2,r3,lr} -- bl __aeabi_read_tp_c -- pop {r1,r2,r3,lr} -- bx lr -+ ldr r0,1f -+ add r0,r0,pc -+ ldr r0,[r0] -+2: bx r0 -+ .align 2 -+1: .word __a_gettp_ptr - 2b -diff --git a/src/thread/arm/__aeabi_read_tp_c.c b/src/thread/arm/__aeabi_read_tp_c.c -deleted file mode 100644 -index 654bdc57..00000000 ---- a/src/thread/arm/__aeabi_read_tp_c.c -+++ /dev/null -@@ -1,8 +0,0 @@ --#include "pthread_impl.h" --#include <stdint.h> -- --__attribute__((__visibility__("hidden"))) --void *__aeabi_read_tp_c(void) --{ -- return (void *)((uintptr_t)__pthread_self()-8+sizeof(struct pthread)); --} -diff --git a/src/thread/default_attr.c b/src/thread/default_attr.c -new file mode 100644 -index 00000000..46fe98ee ---- /dev/null -+++ b/src/thread/default_attr.c -@@ -0,0 +1,4 @@ -+#include "pthread_impl.h" -+ -+size_t __default_stacksize = DEFAULT_STACK_SIZE; -+size_t __default_guardsize = DEFAULT_GUARD_SIZE; -diff --git a/src/thread/m68k/__m68k_read_tp.s b/src/thread/m68k/__m68k_read_tp.s -new file mode 100644 -index 00000000..86886da8 ---- /dev/null -+++ b/src/thread/m68k/__m68k_read_tp.s -@@ -0,0 +1,8 @@ -+.text -+.global __m68k_read_tp -+.type __m68k_read_tp,@function -+__m68k_read_tp: -+ move.l #333,%d0 -+ trap #0 -+ move.l %d0,%a0 -+ rts -diff --git a/src/thread/m68k/clone.s b/src/thread/m68k/clone.s -new file mode 100644 -index 00000000..5b61b6fa ---- /dev/null -+++ b/src/thread/m68k/clone.s -@@ -0,0 +1,24 @@ -+.text -+.global __clone -+.type __clone,@function -+__clone: -+ movem.l %d2-%d5,-(%sp) -+ move.l #120,%d0 -+ move.l 28(%sp),%d1 -+ move.l 24(%sp),%d2 -+ and.l #-16,%d2 -+ move.l 36(%sp),%d3 -+ move.l 44(%sp),%d4 -+ move.l 40(%sp),%d5 -+ move.l 20(%sp),%a0 -+ move.l 32(%sp),%a1 -+ trap #0 -+ tst.l %d0 -+ beq 1f -+ movem.l (%sp)+,%d2-%d5 -+ rts -+1: move.l %a1,-(%sp) -+ jsr (%a0) -+ move.l #1,%d0 -+ trap #0 -+ clr.b 0 -diff --git a/src/thread/m68k/syscall_cp.s b/src/thread/m68k/syscall_cp.s -new file mode 100644 -index 00000000..5628a896 ---- /dev/null -+++ b/src/thread/m68k/syscall_cp.s -@@ -0,0 +1,26 @@ -+.text -+.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: -+ movem.l %d2-%d5,-(%sp) -+ movea.l 20(%sp),%a0 -+__cp_begin: -+ move.l (%a0),%d0 -+ bne __cp_cancel -+ movem.l 24(%sp),%d0-%d5/%a0 -+ trap #0 -+__cp_end: -+ movem.l (%sp)+,%d2-%d5 -+ rts -+__cp_cancel: -+ movem.l (%sp)+,%d2-%d5 -+ move.l __cancel-.-8,%a1 -+ jmp (%pc,%a1) -diff --git a/src/thread/mips/clone.s b/src/thread/mips/clone.s -index 37dddf57..30a0146b 100644 ---- a/src/thread/mips/clone.s -+++ b/src/thread/mips/clone.s -@@ -28,5 +28,8 @@ __clone: - nop - 1: lw $25, 0($sp) - lw $4, 4($sp) -- jr $25 -+ jalr $25 - nop -+ move $4, $2 -+ li $2, 4001 -+ syscall -diff --git a/src/thread/mips64/clone.s b/src/thread/mips64/clone.s -index 229d2677..1b71e07c 100644 ---- a/src/thread/mips64/clone.s -+++ b/src/thread/mips64/clone.s -@@ -26,5 +26,8 @@ __clone: - nop - 1: ld $25, 0($sp) # function pointer - ld $4, 8($sp) # argument pointer -- jr $25 # call the user's function -+ jalr $25 # call the user's function - nop -+ move $4, $2 -+ li $2, 5058 -+ syscall -diff --git a/src/thread/mipsn32/clone.s b/src/thread/mipsn32/clone.s -index 51035852..ebf5dbea 100644 ---- a/src/thread/mipsn32/clone.s -+++ b/src/thread/mipsn32/clone.s -@@ -26,5 +26,8 @@ __clone: - nop - 1: lw $25, 0($sp) # function pointer - lw $4, 4($sp) # argument pointer -- jr $25 # call the user's function -+ jalr $25 # call the user's function - nop -+ move $4, $2 -+ li $2, 6058 -+ syscall -diff --git a/src/thread/powerpc64/syscall_cp.s b/src/thread/powerpc64/syscall_cp.s -index d420dbde..ef50ed00 100644 ---- a/src/thread/powerpc64/syscall_cp.s -+++ b/src/thread/powerpc64/syscall_cp.s -@@ -34,4 +34,11 @@ __cp_end: - blr - - __cp_cancel: -+ mflr 0 -+ bl 1f -+ .long .TOC.-. -+1: mflr 3 -+ lwa 2, 0(3) -+ add 2, 2, 3 -+ mtlr 0 - b __cancel -diff --git a/src/thread/pthread_attr_init.c b/src/thread/pthread_attr_init.c -index 8f6e3374..a962b460 100644 ---- a/src/thread/pthread_attr_init.c -+++ b/src/thread/pthread_attr_init.c -@@ -1,9 +1,12 @@ - #include "pthread_impl.h" - -+extern size_t __default_stacksize; -+extern size_t __default_guardsize; -+ - int pthread_attr_init(pthread_attr_t *a) - { - *a = (pthread_attr_t){0}; -- a->_a_stacksize = DEFAULT_STACK_SIZE; -- a->_a_guardsize = DEFAULT_GUARD_SIZE; -+ a->_a_stacksize = __default_stacksize; -+ a->_a_guardsize = __default_guardsize; - return 0; - } diff --git a/src/thread/pthread_attr_setinheritsched.c b/src/thread/pthread_attr_setinheritsched.c -index c91d8f83..4115e2fe 100644 +index e540e846..4115e2fe 100644 --- a/src/thread/pthread_attr_setinheritsched.c +++ b/src/thread/pthread_attr_setinheritsched.c -@@ -1,8 +1,29 @@ - #include "pthread_impl.h" -+#include "syscall.h" -+ -+__attribute__((__visibility__("hidden"))) -+void *__start_sched(void *p) -+{ -+ struct start_sched_args *ssa = p; -+ void *start_arg = ssa->start_arg; -+ void *(*start_fn)(void *) = ssa->start_fn; -+ pthread_t self = __pthread_self(); -+ -+ int ret = -__syscall(SYS_sched_setscheduler, self->tid, -+ ssa->attr->_a_policy, &ssa->attr->_a_prio); -+ if (!ret) __restore_sigs(&ssa->mask); -+ a_store(&ssa->futex, ret); -+ __wake(&ssa->futex, 1, 1); -+ if (ret) { -+ self->detach_state = DT_DYNAMIC; -+ return 0; -+ } -+ return start_fn(start_arg); -+} +@@ -23,7 +23,7 @@ void *__start_sched(void *p) int pthread_attr_setinheritsched(pthread_attr_t *a, int inherit) { @@ -6294,375 +267,6 @@ index 46b520c0..933bdb38 100644 + return ENOTSUP; } } -diff --git a/src/thread/pthread_barrierattr_setpshared.c b/src/thread/pthread_barrierattr_setpshared.c -index b391461e..c2d2929d 100644 ---- a/src/thread/pthread_barrierattr_setpshared.c -+++ b/src/thread/pthread_barrierattr_setpshared.c -@@ -2,6 +2,7 @@ - - int pthread_barrierattr_setpshared(pthread_barrierattr_t *a, int pshared) - { -+ if (pshared > 1U) return EINVAL; - a->__attr = pshared ? INT_MIN : 0; - return 0; - } -diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c -index 3d229223..5d458af2 100644 ---- a/src/thread/pthread_cancel.c -+++ b/src/thread/pthread_cancel.c -@@ -61,6 +61,9 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx) - - if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) { - uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel; -+#ifdef CANCEL_GOT -+ uc->uc_mcontext.MC_GOT = CANCEL_GOT; -+#endif - return; - } - -@@ -92,6 +95,10 @@ int pthread_cancel(pthread_t t) - init = 1; - } - a_store(&t->cancel, 1); -- if (t == pthread_self() && !t->cancelasync) return 0; -+ if (t == pthread_self()) { -+ if (t->canceldisable == PTHREAD_CANCEL_ENABLE && t->cancelasync) -+ pthread_exit(PTHREAD_CANCELED); -+ return 0; -+ } - return pthread_kill(t, SIGCANCEL); - } -diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c -index 439ee363..27ace2c6 100644 ---- a/src/thread/pthread_create.c -+++ b/src/thread/pthread_create.c -@@ -19,6 +19,12 @@ weak_alias(dummy_0, __pthread_tsd_run_dtors); - weak_alias(dummy_0, __do_orphaned_stdio_locks); - weak_alias(dummy_0, __dl_thread_cleanup); - -+static void *dummy_1(void *p) -+{ -+ return 0; -+} -+weak_alias(dummy_1, __start_sched); -+ - _Noreturn void __pthread_exit(void *result) - { - pthread_t self = __pthread_self(); -@@ -37,11 +43,11 @@ _Noreturn void __pthread_exit(void *result) - - __pthread_tsd_run_dtors(); - -- LOCK(self->exitlock); -- -- /* Mark this thread dead before decrementing count */ -+ /* Access to target the exiting thread with syscalls that use -+ * its kernel tid is controlled by killlock. For detached threads, -+ * any use past this point would have undefined behavior, but for -+ * joinable threads it's a valid usage that must be handled. */ - LOCK(self->killlock); -- self->dead = 1; - - /* Block all signals before decrementing the live thread count. - * This is important to ensure that dynamically allocated TLS -@@ -49,20 +55,14 @@ _Noreturn void __pthread_exit(void *result) - * reasons as well. */ - __block_all_sigs(&set); - -- /* Wait to unlock the kill lock, which governs functions like -- * pthread_kill which target a thread id, until signals have -- * been blocked. This precludes observation of the thread id -- * as a live thread (with application code running in it) after -- * the thread was reported dead by ESRCH being returned. */ -- UNLOCK(self->killlock); -- - /* It's impossible to determine whether this is "the last thread" - * until performing the atomic decrement, since multiple threads - * could exit at the same time. For the last thread, revert the -- * decrement and unblock signals to give the atexit handlers and -- * stdio cleanup code a consistent state. */ -+ * decrement, restore the tid, and unblock signals to give the -+ * atexit handlers and stdio cleanup code a consistent state. */ - if (a_fetch_add(&libc.threads_minus_1, -1)==0) { - libc.threads_minus_1 = 0; -+ UNLOCK(self->killlock); - __restore_sigs(&set); - exit(0); - } -@@ -89,15 +89,19 @@ _Noreturn void __pthread_exit(void *result) - __do_orphaned_stdio_locks(); - __dl_thread_cleanup(); - -- if (self->detached && self->map_base) { -+ /* This atomic potentially competes with a concurrent pthread_detach -+ * call; the loser is responsible for freeing thread resources. */ -+ int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING); -+ -+ if (state>=DT_DETACHED && self->map_base) { - /* Detached threads must avoid the kernel clear_child_tid - * feature, since the virtual address will have been - * unmapped and possibly already reused by a new mapping - * at the time the kernel would perform the write. In - * the case of threads that started out detached, the - * initial clone flags are correct, but if the thread was -- * detached later (== 2), we need to clear it here. */ -- if (self->detached == 2) __syscall(SYS_set_tid_address, 0); -+ * detached later, we need to clear it here. */ -+ if (state == DT_DYNAMIC) __syscall(SYS_set_tid_address, 0); - - /* Robust list will no longer be valid, and was already - * processed above, so unregister it with the kernel. */ -@@ -113,6 +117,12 @@ _Noreturn void __pthread_exit(void *result) - __unmapself(self->map_base, self->map_size); - } - -+ /* After the kernel thread exits, its tid may be reused. Clear it -+ * to prevent inadvertent use and inform functions that would use -+ * it that it's no longer available. */ -+ self->tid = 0; -+ UNLOCK(self->killlock); -+ - for (;;) __syscall(SYS_exit, 0); - } - -@@ -131,19 +141,6 @@ void __do_cleanup_pop(struct __ptcb *cb) - static int start(void *p) - { - pthread_t self = p; -- /* States for startlock: -- * 0 = no need for start sync -- * 1 = waiting for parent to do work -- * 2 = failure in parent, child must abort -- * 3 = success in parent, child must restore sigmask */ -- if (self->startlock[0]) { -- __wait(self->startlock, 0, 1, 1); -- if (self->startlock[0] == 2) { -- self->detached = 2; -- pthread_exit(0); -- } -- __restore_sigs(self->sigmask); -- } - if (self->unblock_cancel) - __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, - SIGPT_SET, 0, _NSIG/8); -@@ -168,8 +165,8 @@ static void *dummy_tsd[1] = { 0 }; - weak_alias(dummy_tsd, __pthread_tsd_main); - - volatile int __block_new_threads = 0; --size_t __default_stacksize = DEFAULT_STACK_SIZE; --size_t __default_guardsize = DEFAULT_GUARD_SIZE; -+extern size_t __default_stacksize; -+extern size_t __default_guardsize; - - static FILE *volatile dummy_file = 0; - weak_alias(dummy_file, __stdin_used); -@@ -194,6 +191,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att - | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_DETACHED; - int do_sched = 0; - pthread_attr_t attr = { 0 }; -+ struct start_sched_args ssa; - - if (!libc.can_do_threads) return ENOSYS; - self = __pthread_self(); -@@ -272,24 +270,32 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att - new->tsd = (void *)tsd; - new->locale = &libc.global_locale; - if (attr._a_detach) { -- new->detached = 1; -+ new->detach_state = DT_DETACHED; - flags -= CLONE_CHILD_CLEARTID; -+ } else { -+ new->detach_state = DT_JOINABLE; - } - if (attr._a_sched) { -- do_sched = new->startlock[0] = 1; -- __block_app_sigs(new->sigmask); -+ do_sched = 1; -+ ssa.futex = -1; -+ ssa.start_fn = new->start; -+ ssa.start_arg = new->start_arg; -+ ssa.attr = &attr; -+ new->start = __start_sched; -+ new->start_arg = &ssa; -+ __block_app_sigs(&ssa.mask); - } - new->robust_list.head = &new->robust_list.head; - new->unblock_cancel = self->cancel; - new->CANARY = self->CANARY; - - a_inc(&libc.threads_minus_1); -- ret = __clone((c11 ? start_c11 : start), stack, flags, new, &new->tid, TP_ADJ(new), &new->tid); -+ ret = __clone((c11 ? start_c11 : start), stack, flags, new, &new->tid, TP_ADJ(new), &new->detach_state); - - __release_ptc(); - - if (do_sched) { -- __restore_sigs(new->sigmask); -+ __restore_sigs(&ssa.mask); - } - - if (ret < 0) { -@@ -299,11 +305,9 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att - } - - if (do_sched) { -- ret = __syscall(SYS_sched_setscheduler, new->tid, -- attr._a_policy, &attr._a_prio); -- a_store(new->startlock, ret<0 ? 2 : 3); -- __wake(new->startlock, 1, 1); -- if (ret < 0) return -ret; -+ __futexwait(&ssa.futex, -1, 1); -+ ret = ssa.futex; -+ if (ret) return ret; - } - - *res = new; -diff --git a/src/thread/pthread_detach.c b/src/thread/pthread_detach.c -index 692bbaf9..9cee7a89 100644 ---- a/src/thread/pthread_detach.c -+++ b/src/thread/pthread_detach.c -@@ -5,11 +5,10 @@ int __pthread_join(pthread_t, void **); - - static int __pthread_detach(pthread_t t) - { -- /* Cannot detach a thread that's already exiting */ -- if (a_cas(t->exitlock, 0, INT_MIN + 1)) -+ /* If the cas fails, detach state is either already-detached -+ * or exiting/exited, and pthread_join will trap or cleanup. */ -+ if (a_cas(&t->detach_state, DT_JOINABLE, DT_DYNAMIC) != DT_JOINABLE) - return __pthread_join(t, 0); -- t->detached = 2; -- UNLOCK(t->exitlock); - return 0; - } - -diff --git a/src/thread/pthread_getattr_np.c b/src/thread/pthread_getattr_np.c -index 29a209bd..2881831f 100644 ---- a/src/thread/pthread_getattr_np.c -+++ b/src/thread/pthread_getattr_np.c -@@ -6,7 +6,7 @@ - int pthread_getattr_np(pthread_t t, pthread_attr_t *a) - { - *a = (pthread_attr_t){0}; -- a->_a_detach = !!t->detached; -+ a->_a_detach = t->detach_state>=DT_DETACHED; - a->_a_guardsize = t->guard_size; - if (t->stack) { - a->_a_stackaddr = (uintptr_t)t->stack; -diff --git a/src/thread/pthread_getschedparam.c b/src/thread/pthread_getschedparam.c -index a994b637..05be4242 100644 ---- a/src/thread/pthread_getschedparam.c -+++ b/src/thread/pthread_getschedparam.c -@@ -4,7 +4,7 @@ int pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param - { - int r; - LOCK(t->killlock); -- if (t->dead) { -+ if (!t->tid) { - r = ESRCH; - } else { - r = -__syscall(SYS_sched_getparam, t->tid, param); -diff --git a/src/thread/pthread_join.c b/src/thread/pthread_join.c -index b7175c09..18264da6 100644 ---- a/src/thread/pthread_join.c -+++ b/src/thread/pthread_join.c -@@ -7,13 +7,14 @@ int __pthread_setcancelstate(int, int *); - - int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec *at) - { -- int tmp, cs, r = 0; -+ int state, cs, r = 0; - __pthread_testcancel(); - __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); - if (cs == PTHREAD_CANCEL_ENABLE) __pthread_setcancelstate(cs, 0); -- if (t->detached) a_crash(); -- while ((tmp = t->tid) && r != ETIMEDOUT && r != EINVAL) -- r = __timedwait_cp(&t->tid, tmp, CLOCK_REALTIME, at, 0); -+ while ((state = t->detach_state) && r != ETIMEDOUT && r != EINVAL) { -+ if (state >= DT_DETACHED) a_crash(); -+ r = __timedwait_cp(&t->detach_state, state, CLOCK_REALTIME, at, 0); -+ } - __pthread_setcancelstate(cs, 0); - if (r == ETIMEDOUT || r == EINVAL) return r; - a_barrier(); -@@ -29,7 +30,7 @@ int __pthread_join(pthread_t t, void **res) - - int __pthread_tryjoin_np(pthread_t t, void **res) - { -- return t->tid ? EBUSY : __pthread_join(t, res); -+ return t->detach_state==DT_JOINABLE ? EBUSY : __pthread_join(t, res); - } - - weak_alias(__pthread_tryjoin_np, pthread_tryjoin_np); -diff --git a/src/thread/pthread_kill.c b/src/thread/pthread_kill.c -index f0903420..6d70e626 100644 ---- a/src/thread/pthread_kill.c -+++ b/src/thread/pthread_kill.c -@@ -4,7 +4,8 @@ int pthread_kill(pthread_t t, int sig) - { - int r; - LOCK(t->killlock); -- r = t->dead ? ESRCH : -__syscall(SYS_tkill, t->tid, sig); -+ r = t->tid ? -__syscall(SYS_tkill, t->tid, sig) -+ : (sig+0U >= _NSIG ? EINVAL : 0); - UNLOCK(t->killlock); - return r; - } -diff --git a/src/thread/pthread_setschedparam.c b/src/thread/pthread_setschedparam.c -index 9e2fa456..ab45f2ff 100644 ---- a/src/thread/pthread_setschedparam.c -+++ b/src/thread/pthread_setschedparam.c -@@ -4,7 +4,7 @@ int pthread_setschedparam(pthread_t t, int policy, const struct sched_param *par - { - int r; - LOCK(t->killlock); -- r = t->dead ? ESRCH : -__syscall(SYS_sched_setscheduler, t->tid, policy, param); -+ r = !t->tid ? ESRCH : -__syscall(SYS_sched_setscheduler, t->tid, policy, param); - UNLOCK(t->killlock); - return r; - } -diff --git a/src/thread/pthread_setschedprio.c b/src/thread/pthread_setschedprio.c -index dc745b42..c353f6b5 100644 ---- a/src/thread/pthread_setschedprio.c -+++ b/src/thread/pthread_setschedprio.c -@@ -4,7 +4,7 @@ int pthread_setschedprio(pthread_t t, int prio) - { - int r; - LOCK(t->killlock); -- r = t->dead ? ESRCH : -__syscall(SYS_sched_setparam, t->tid, &prio); -+ r = !t->tid ? ESRCH : -__syscall(SYS_sched_setparam, t->tid, &prio); - UNLOCK(t->killlock); - return r; - } -diff --git a/src/time/__tz.c b/src/time/__tz.c -index 1dbb0b8f..814edcdf 100644 ---- a/src/time/__tz.c -+++ b/src/time/__tz.c -@@ -230,7 +230,7 @@ static void do_tzset() - dst_off = __timezone - 3600; - } else { - __daylight = 0; -- dst_off = 0; -+ dst_off = __timezone; - } - - if (*s == ',') s++, getrule(&s, r0); -diff --git a/src/time/strftime.c b/src/time/strftime.c -index 708875ee..d3f2add9 100644 ---- a/src/time/strftime.c -+++ b/src/time/strftime.c -@@ -181,9 +181,8 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm * - *l = 0; - return ""; - } -- *l = snprintf(*s, sizeof *s, "%+.2d%.2d", -- (tm->__tm_gmtoff)/3600, -- abs(tm->__tm_gmtoff%3600)/60); -+ *l = snprintf(*s, sizeof *s, "%+.4ld", -+ tm->__tm_gmtoff/3600*100 + tm->__tm_gmtoff%3600/60); - return *s; - case 'Z': - if (tm->tm_isdst < 0) { diff --git a/src/time/timespec_get.c b/src/time/timespec_get.c index 03c5a77b..c423b825 100644 --- a/src/time/timespec_get.c @@ -6676,115 +280,3 @@ index 03c5a77b..c423b825 100644 int ret = __clock_gettime(CLOCK_REALTIME, ts); return ret < 0 ? 0 : base; } -diff --git a/src/time/wcsftime.c b/src/time/wcsftime.c -index 638e64f6..23500cc8 100644 ---- a/src/time/wcsftime.c -+++ b/src/time/wcsftime.c -@@ -4,7 +4,7 @@ - #include "locale_impl.h" - #include "libc.h" - --const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc); -+const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc, int pad); - - size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, const struct tm *restrict tm, locale_t loc) - { -@@ -14,7 +14,7 @@ size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, co - wchar_t *p; - const char *t_mb; - const wchar_t *t; -- int plus; -+ int pad, plus; - unsigned long width; - for (l=0; l<n; f++) { - if (!*f) { -@@ -26,6 +26,8 @@ size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, co - continue; - } - f++; -+ pad = 0; -+ if (*f == '-' || *f == '_' || *f == '0') pad = *f++; - if ((plus = (*f == '+'))) f++; - width = wcstoul(f, &p, 10); - if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') { -@@ -35,7 +37,7 @@ size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, co - } - f = p; - if (*f == 'E' || *f == 'O') f++; -- t_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc); -+ t_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad); - if (!t_mb) break; - k = mbstowcs(wbuf, t_mb, sizeof wbuf / sizeof *wbuf); - if (k == (size_t)-1) return 0; -diff --git a/src/unistd/getcwd.c b/src/unistd/getcwd.c -index 103fbbb5..f407ffe0 100644 ---- a/src/unistd/getcwd.c -+++ b/src/unistd/getcwd.c -@@ -6,10 +6,10 @@ - - char *getcwd(char *buf, size_t size) - { -- char tmp[PATH_MAX]; -+ char tmp[buf ? 1 : PATH_MAX]; - if (!buf) { - buf = tmp; -- size = PATH_MAX; -+ size = sizeof tmp; - } else if (!size) { - errno = EINVAL; - return 0; -diff --git a/src/unistd/gethostname.c b/src/unistd/gethostname.c -index f984b7dd..633ef571 100644 ---- a/src/unistd/gethostname.c -+++ b/src/unistd/gethostname.c -@@ -8,6 +8,6 @@ int gethostname(char *name, size_t len) - if (uname(&uts)) return -1; - if (len > sizeof uts.nodename) len = sizeof uts.nodename; - for (i=0; i<len && (name[i] = uts.nodename[i]); i++); -- if (i==len) name[i-1] = 0; -+ if (i && i==len) name[i-1] = 0; - return 0; - } -diff --git a/src/unistd/nice.c b/src/unistd/nice.c -index da569967..6c25c8c3 100644 ---- a/src/unistd/nice.c -+++ b/src/unistd/nice.c -@@ -1,12 +1,16 @@ - #include <unistd.h> - #include <sys/resource.h> -+#include <limits.h> - #include "syscall.h" - - int nice(int inc) - { --#ifdef SYS_nice -- return syscall(SYS_nice, inc); --#else -- return setpriority(PRIO_PROCESS, 0, getpriority(PRIO_PROCESS, 0)+inc); --#endif -+ int prio = inc; -+ // Only query old priority if it can affect the result. -+ // This also avoids issues with integer overflow. -+ if (inc > -2*NZERO && inc < 2*NZERO) -+ prio += getpriority(PRIO_PROCESS, 0); -+ if (prio > NZERO-1) prio = NZERO-1; -+ if (prio < -NZERO) prio = -NZERO; -+ return setpriority(PRIO_PROCESS, 0, prio) ? -1 : prio; - } -diff --git a/tools/musl-gcc.specs.sh b/tools/musl-gcc.specs.sh -index 294e24f7..30492574 100644 ---- a/tools/musl-gcc.specs.sh -+++ b/tools/musl-gcc.specs.sh -@@ -17,10 +17,10 @@ cat <<EOF - libgcc.a%s %:if-exists(libgcc_eh.a%s) - - *startfile: --%{!shared: $libdir/%{pie:S}crt1.o} $libdir/crti.o %{shared|pie:crtbeginS.o%s;:crtbegin.o%s} -+%{!shared: $libdir/Scrt1.o} $libdir/crti.o crtbeginS.o%s - - *endfile: --%{shared|pie:crtendS.o%s;:crtend.o%s} $libdir/crtn.o -+crtendS.o%s $libdir/crtn.o - - *link: - -dynamic-linker $ldso -nostdlib %{shared:-shared} %{static:-static} %{rdynamic:-export-dynamic} |