diff options
Diffstat (limited to 'toolchain/musl/patches/000-git-2015-01-09.patch')
-rw-r--r-- | toolchain/musl/patches/000-git-2015-01-09.patch | 3440 |
1 files changed, 0 insertions, 3440 deletions
diff --git a/toolchain/musl/patches/000-git-2015-01-09.patch b/toolchain/musl/patches/000-git-2015-01-09.patch deleted file mode 100644 index c710fe0ef2..0000000000 --- a/toolchain/musl/patches/000-git-2015-01-09.patch +++ /dev/null @@ -1,3440 +0,0 @@ ---- a/arch/arm/atomic.h -+++ b/arch/arm/atomic.h -@@ -22,37 +22,150 @@ static inline int a_ctz_64(uint64_t x) - return a_ctz_l(y); - } - --#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__) && !__thumb__) \ -- || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 -- - #if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 --#define MEM_BARRIER "dmb ish" --#else --#define MEM_BARRIER "mcr p15,0,r0,c7,c10,5" --#endif - --static inline int __k_cas(int t, int s, volatile int *p) -+static inline void a_barrier() - { -- int ret; -- __asm__( -- " " MEM_BARRIER "\n" -+ __asm__ __volatile__("dmb ish"); -+} -+ -+static inline int a_cas(volatile int *p, int t, int s) -+{ -+ int old; -+ __asm__ __volatile__( -+ " dmb ish\n" - "1: ldrex %0,%3\n" -- " subs %0,%0,%1\n" --#ifdef __thumb__ -- " itt eq\n" --#endif -- " strexeq %0,%2,%3\n" -- " teqeq %0,#1\n" -- " beq 1b\n" -- " " MEM_BARRIER "\n" -- : "=&r"(ret) -+ " cmp %0,%1\n" -+ " bne 1f\n" -+ " strex %0,%2,%3\n" -+ " cmp %0, #0\n" -+ " bne 1b\n" -+ " mov %0, %1\n" -+ "1: dmb ish\n" -+ : "=&r"(old) - : "r"(t), "r"(s), "Q"(*p) - : "memory", "cc" ); -- return ret; -+ return old; -+} -+ -+static inline int a_swap(volatile int *x, int v) -+{ -+ int old, tmp; -+ __asm__ __volatile__( -+ " dmb ish\n" -+ "1: ldrex %0,%3\n" -+ " strex %1,%2,%3\n" -+ " cmp %1, #0\n" -+ " bne 1b\n" -+ " dmb ish\n" -+ : "=&r"(old), "=&r"(tmp) -+ : "r"(v), "Q"(*x) -+ : "memory", "cc" ); -+ return old; -+} -+ -+static inline int a_fetch_add(volatile int *x, int v) -+{ -+ int old, tmp; -+ __asm__ __volatile__( -+ " dmb ish\n" -+ "1: ldrex %0,%3\n" -+ " add %0,%0,%2\n" -+ " strex %1,%0,%3\n" -+ " cmp %1, #0\n" -+ " bne 1b\n" -+ " dmb ish\n" -+ : "=&r"(old), "=&r"(tmp) -+ : "r"(v), "Q"(*x) -+ : "memory", "cc" ); -+ return old-v; -+} -+ -+static inline void a_inc(volatile int *x) -+{ -+ int tmp, tmp2; -+ __asm__ __volatile__( -+ " dmb ish\n" -+ "1: ldrex %0,%2\n" -+ " add %0,%0,#1\n" -+ " strex %1,%0,%2\n" -+ " cmp %1, #0\n" -+ " bne 1b\n" -+ " dmb ish\n" -+ : "=&r"(tmp), "=&r"(tmp2) -+ : "Q"(*x) -+ : "memory", "cc" ); -+} -+ -+static inline void a_dec(volatile int *x) -+{ -+ int tmp, tmp2; -+ __asm__ __volatile__( -+ " dmb ish\n" -+ "1: ldrex %0,%2\n" -+ " sub %0,%0,#1\n" -+ " strex %1,%0,%2\n" -+ " cmp %1, #0\n" -+ " bne 1b\n" -+ " dmb ish\n" -+ : "=&r"(tmp), "=&r"(tmp2) -+ : "Q"(*x) -+ : "memory", "cc" ); -+} -+ -+static inline void a_and(volatile int *x, int v) -+{ -+ int tmp, tmp2; -+ __asm__ __volatile__( -+ " dmb ish\n" -+ "1: ldrex %0,%3\n" -+ " and %0,%0,%2\n" -+ " strex %1,%0,%3\n" -+ " cmp %1, #0\n" -+ " bne 1b\n" -+ " dmb ish\n" -+ : "=&r"(tmp), "=&r"(tmp2) -+ : "r"(v), "Q"(*x) -+ : "memory", "cc" ); -+} -+ -+static inline void a_or(volatile int *x, int v) -+{ -+ int tmp, tmp2; -+ __asm__ __volatile__( -+ " dmb ish\n" -+ "1: ldrex %0,%3\n" -+ " orr %0,%0,%2\n" -+ " strex %1,%0,%3\n" -+ " cmp %1, #0\n" -+ " bne 1b\n" -+ " dmb ish\n" -+ : "=&r"(tmp), "=&r"(tmp2) -+ : "r"(v), "Q"(*x) -+ : "memory", "cc" ); -+} -+ -+static inline void a_store(volatile int *p, int x) -+{ -+ __asm__ __volatile__( -+ " dmb ish\n" -+ " str %1,%0\n" -+ " dmb ish\n" -+ : "=m"(*p) -+ : "r"(x) -+ : "memory", "cc" ); - } -+ - #else --#define __k_cas ((int (*)(int, int, volatile int *))0xffff0fc0) --#endif -+ -+int __a_cas(int, int, volatile int *) __attribute__((__visibility__("hidden"))); -+#define __k_cas __a_cas -+ -+static inline void a_barrier() -+{ -+ __asm__ __volatile__("bl __a_barrier" -+ : : : "memory", "cc", "ip", "lr" ); -+} - - static inline int a_cas(volatile int *p, int t, int s) - { -@@ -65,11 +178,6 @@ static inline int a_cas(volatile int *p, - } - } - --static inline void *a_cas_p(volatile void *p, void *t, void *s) --{ -- return (void *)a_cas(p, (int)t, (int)s); --} -- - static inline int a_swap(volatile int *x, int v) - { - int old; -@@ -98,19 +206,9 @@ static inline void a_dec(volatile int *x - - static inline void a_store(volatile int *p, int x) - { -- while (__k_cas(*p, x, p)); --} -- --#define a_spin a_barrier -- --static inline void a_barrier() --{ -- __k_cas(0, 0, &(int){0}); --} -- --static inline void a_crash() --{ -- *(volatile char *)0=0; -+ a_barrier(); -+ *p = x; -+ a_barrier(); - } - - static inline void a_and(volatile int *p, int v) -@@ -127,6 +225,20 @@ static inline void a_or(volatile int *p, - while (__k_cas(old, old|v, p)); - } - -+#endif -+ -+static inline void *a_cas_p(volatile void *p, void *t, void *s) -+{ -+ return (void *)a_cas(p, (int)t, (int)s); -+} -+ -+#define a_spin a_barrier -+ -+static inline void a_crash() -+{ -+ *(volatile char *)0=0; -+} -+ - static inline void a_or_l(volatile void *p, long v) - { - a_or(p, v); ---- a/arch/arm/bits/alltypes.h.in -+++ b/arch/arm/bits/alltypes.h.in -@@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list - #ifndef __cplusplus - TYPEDEF unsigned wchar_t; - #endif --TYPEDEF unsigned wint_t; - - TYPEDEF float float_t; - TYPEDEF double double_t; ---- a/arch/arm/bits/syscall.h -+++ b/arch/arm/bits/syscall.h -@@ -339,7 +339,13 @@ - #define __NR_seccomp 383 - #define __NR_getrandom 384 - #define __NR_memfd_create 385 -+#define __NR_bpf 386 - -+#define __ARM_NR_breakpoint 0x0f0001 -+#define __ARM_NR_cacheflush 0x0f0002 -+#define __ARM_NR_usr26 0x0f0003 -+#define __ARM_NR_usr32 0x0f0004 -+#define __ARM_NR_set_tls 0x0f0005 - - /* Repeated with SYS_ prefix */ - -@@ -684,3 +690,4 @@ - #define SYS_seccomp 383 - #define SYS_getrandom 384 - #define SYS_memfd_create 385 -+#define SYS_bpf 386 ---- a/arch/arm/pthread_arch.h -+++ b/arch/arm/pthread_arch.h -@@ -10,9 +10,17 @@ static inline __attribute__((const)) pth - - #else - --typedef char *(*__ptr_func_t)(void) __attribute__((const)); --#define __pthread_self() \ -- ((pthread_t)(((__ptr_func_t)0xffff0fe0)()+8-sizeof(struct pthread))) -+static inline __attribute__((const)) pthread_t __pthread_self() -+{ -+#ifdef __clang__ -+ char *p; -+ __asm__( "bl __a_gettp\n\tmov %0,r0" : "=r"(p) : : "cc", "r0", "lr" ); -+#else -+ register char *p __asm__("r0"); -+ __asm__( "bl __a_gettp" : "=r"(p) : : "cc", "lr" ); -+#endif -+ return (void *)(p+8-sizeof(struct pthread)); -+} - - #endif - ---- /dev/null -+++ b/arch/arm/src/__set_thread_area.c -@@ -0,0 +1,49 @@ -+#include <stdint.h> -+#include <elf.h> -+#include "pthread_impl.h" -+#include "libc.h" -+ -+#define HWCAP_TLS (1 << 15) -+ -+extern const unsigned char __attribute__((__visibility__("hidden"))) -+ __a_barrier_dummy[], __a_barrier_oldkuser[], -+ __a_barrier_v6[], __a_barrier_v7[], -+ __a_cas_dummy[], __a_cas_v6[], __a_cas_v7[], -+ __a_gettp_dummy[]; -+ -+#define __a_barrier_kuser 0xffff0fa0 -+#define __a_cas_kuser 0xffff0fc0 -+#define __a_gettp_kuser 0xffff0fe0 -+ -+extern uintptr_t __attribute__((__visibility__("hidden"))) -+ __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr; -+ -+#define SET(op,ver) (__a_##op##_ptr = \ -+ (uintptr_t)__a_##op##_##ver - (uintptr_t)__a_##op##_dummy) -+ -+int __set_thread_area(void *p) -+{ -+#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7 -+ if (__hwcap & HWCAP_TLS) { -+ size_t *aux; -+ SET(cas, v7); -+ SET(barrier, v7); -+ for (aux=libc.auxv; *aux; aux+=2) { -+ if (*aux != AT_PLATFORM) continue; -+ const char *s = (void *)aux[1]; -+ if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break; -+ SET(cas, v6); -+ SET(barrier, v6); -+ break; -+ } -+ } else { -+ int ver = *(int *)0xffff0ffc; -+ SET(gettp, kuser); -+ SET(cas, kuser); -+ SET(barrier, kuser); -+ if (ver < 2) a_crash(); -+ if (ver < 3) SET(barrier, oldkuser); -+ } -+#endif -+ return __syscall(0xf0005, p); -+} ---- /dev/null -+++ b/arch/arm/src/arm/atomics.s -@@ -0,0 +1,116 @@ -+.text -+ -+.global __a_barrier -+.hidden __a_barrier -+.type __a_barrier,%function -+__a_barrier: -+ ldr ip,1f -+ ldr ip,[pc,ip] -+ add pc,pc,ip -+1: .word __a_barrier_ptr-1b -+.global __a_barrier_dummy -+.hidden __a_barrier_dummy -+__a_barrier_dummy: -+ tst lr,#1 -+ moveq pc,lr -+ bx lr -+.global __a_barrier_oldkuser -+.hidden __a_barrier_oldkuser -+__a_barrier_oldkuser: -+ push {r0,r1,r2,r3,ip,lr} -+ mov r1,r0 -+ mov r2,sp -+ ldr ip,=0xffff0fc0 -+ mov lr,pc -+ mov pc,ip -+ pop {r0,r1,r2,r3,ip,lr} -+ tst lr,#1 -+ moveq pc,lr -+ bx lr -+.global __a_barrier_v6 -+.hidden __a_barrier_v6 -+__a_barrier_v6: -+ mcr p15,0,r0,c7,c10,5 -+ bx lr -+.global __a_barrier_v7 -+.hidden __a_barrier_v7 -+__a_barrier_v7: -+ .word 0xf57ff05b /* dmb ish */ -+ bx lr -+ -+.global __a_cas -+.hidden __a_cas -+.type __a_cas,%function -+__a_cas: -+ ldr ip,1f -+ ldr ip,[pc,ip] -+ add pc,pc,ip -+1: .word __a_cas_ptr-1b -+.global __a_cas_dummy -+.hidden __a_cas_dummy -+__a_cas_dummy: -+ mov r3,r0 -+ ldr r0,[r2] -+ subs r0,r3,r0 -+ streq r1,[r2] -+ tst lr,#1 -+ moveq pc,lr -+ bx lr -+.global __a_cas_v6 -+.hidden __a_cas_v6 -+__a_cas_v6: -+ mov r3,r0 -+ mcr p15,0,r0,c7,c10,5 -+1: .word 0xe1920f9f /* ldrex r0,[r2] */ -+ subs r0,r3,r0 -+ .word 0x01820f91 /* strexeq r0,r1,[r2] */ -+ teqeq r0,#1 -+ beq 1b -+ mcr p15,0,r0,c7,c10,5 -+ bx lr -+.global __a_cas_v7 -+.hidden __a_cas_v7 -+__a_cas_v7: -+ mov r3,r0 -+ .word 0xf57ff05b /* dmb ish */ -+1: .word 0xe1920f9f /* ldrex r0,[r2] */ -+ subs r0,r3,r0 -+ .word 0x01820f91 /* strexeq r0,r1,[r2] */ -+ teqeq r0,#1 -+ beq 1b -+ .word 0xf57ff05b /* dmb ish */ -+ bx lr -+ -+.global __aeabi_read_tp -+.type __aeabi_read_tp,%function -+__aeabi_read_tp: -+ -+.global __a_gettp -+.hidden __a_gettp -+.type __a_gettp,%function -+__a_gettp: -+ ldr r0,1f -+ ldr r0,[pc,r0] -+ add pc,pc,r0 -+1: .word __a_gettp_ptr-1b -+.global __a_gettp_dummy -+.hidden __a_gettp_dummy -+__a_gettp_dummy: -+ mrc p15,0,r0,c13,c0,3 -+ bx lr -+ -+.data -+.global __a_barrier_ptr -+.hidden __a_barrier_ptr -+__a_barrier_ptr: -+ .word 0 -+ -+.global __a_cas_ptr -+.hidden __a_cas_ptr -+__a_cas_ptr: -+ .word 0 -+ -+.global __a_gettp_ptr -+.hidden __a_gettp_ptr -+__a_gettp_ptr: -+ .word 0 ---- a/arch/arm/syscall_arch.h -+++ b/arch/arm/syscall_arch.h -@@ -5,8 +5,6 @@ - - long (__syscall)(long, ...); - --#ifndef __clang__ -- - #define __asm_syscall(...) do { \ - __asm__ __volatile__ ( "svc 0" \ - : "=r"(r0) : __VA_ARGS__ : "memory"); \ -@@ -54,41 +52,25 @@ static inline long __syscall4(long n, lo - __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3)); - } - --#else -- --static inline long __syscall0(long n) --{ -- return (__syscall)(n); --} -- --static inline long __syscall1(long n, long a) --{ -- return (__syscall)(n, a); --} -- --static inline long __syscall2(long n, long a, long b) --{ -- return (__syscall)(n, a, b); --} -- --static inline long __syscall3(long n, long a, long b, long c) --{ -- return (__syscall)(n, a, b, c); --} -- --static inline long __syscall4(long n, long a, long b, long c, long d) --{ -- return (__syscall)(n, a, b, c, d); --} -- --#endif -- - static inline long __syscall5(long n, long a, long b, long c, long d, long e) - { -- return (__syscall)(n, a, b, c, d, e); -+ 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)); - } - - static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f) - { -- return (__syscall)(n, a, b, c, d, e, f); -+ 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)); - } ---- a/arch/i386/bits/alltypes.h.in -+++ b/arch/i386/bits/alltypes.h.in -@@ -17,7 +17,6 @@ TYPEDEF __WCHAR_TYPE__ wchar_t; - TYPEDEF long wchar_t; - #endif - #endif --TYPEDEF unsigned wint_t; - - #if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 0 - TYPEDEF float float_t; ---- a/arch/i386/bits/syscall.h -+++ b/arch/i386/bits/syscall.h -@@ -355,6 +355,7 @@ - #define __NR_seccomp 354 - #define __NR_getrandom 355 - #define __NR_memfd_create 356 -+#define __NR_bpf 357 - - - /* Repeated with SYS_ prefix */ -@@ -716,3 +717,4 @@ - #define SYS_seccomp 354 - #define SYS_getrandom 355 - #define SYS_memfd_create 356 -+#define SYS_bpf 357 ---- a/arch/microblaze/bits/alltypes.h.in -+++ b/arch/microblaze/bits/alltypes.h.in -@@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list - #ifndef __cplusplus - TYPEDEF int wchar_t; - #endif --TYPEDEF unsigned wint_t; - - TYPEDEF float float_t; - TYPEDEF double double_t; ---- a/arch/microblaze/bits/syscall.h -+++ b/arch/microblaze/bits/syscall.h -@@ -381,6 +381,7 @@ - #define __NR_seccomp 384 - #define __NR_getrandom 385 - #define __NR_memfd_create 386 -+#define __NR_bpf 387 - - /* Repeated with SYS_ prefix */ - -@@ -768,3 +769,4 @@ - #define SYS_seccomp 384 - #define SYS_getrandom 385 - #define SYS_memfd_create 386 -+#define SYS_bpf 387 ---- a/arch/microblaze/syscall_arch.h -+++ b/arch/microblaze/syscall_arch.h -@@ -100,39 +100,7 @@ static inline long __syscall6(long n, lo - - #else - --static inline long __syscall0(long n) --{ -- return (__syscall)(n); --} -- --static inline long __syscall1(long n, long a) --{ -- return (__syscall)(n, a); --} -- --static inline long __syscall2(long n, long a, long b) --{ -- return (__syscall)(n, a, b); --} -- --static inline long __syscall3(long n, long a, long b, long c) --{ -- return (__syscall)(n, a, b, c); --} -- --static inline long __syscall4(long n, long a, long b, long c, long d) --{ -- return (__syscall)(n, a, b, c, d); --} -- --static inline long __syscall5(long n, long a, long b, long c, long d, long e) --{ -- return (__syscall)(n, a, b, c, d, e); --} -- --static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f) --{ -- return (__syscall)(n, a, b, c, d, e, f); --} -+#undef SYSCALL_NO_INLINE -+#define SYSCALL_NO_INLINE - - #endif ---- a/arch/mips/bits/alltypes.h.in -+++ b/arch/mips/bits/alltypes.h.in -@@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list - #ifndef __cplusplus - TYPEDEF int wchar_t; - #endif --TYPEDEF unsigned wint_t; - - TYPEDEF float float_t; - TYPEDEF double double_t; ---- a/arch/mips/bits/syscall.h -+++ b/arch/mips/bits/syscall.h -@@ -352,6 +352,7 @@ - #define __NR_seccomp 4352 - #define __NR_getrandom 4353 - #define __NR_memfd_create 4354 -+#define __NR_bpf 4355 - - - /* Repeated with SYS_ prefix */ -@@ -709,3 +710,4 @@ - #define SYS_seccomp 4352 - #define SYS_getrandom 4353 - #define SYS_memfd_create 4354 -+#define SYS_bpf 4355 ---- a/arch/or1k/bits/alltypes.h.in -+++ b/arch/or1k/bits/alltypes.h.in -@@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list - #ifndef __cplusplus - TYPEDEF unsigned wchar_t; - #endif --TYPEDEF unsigned wint_t; - - TYPEDEF float float_t; - TYPEDEF double double_t; ---- a/arch/or1k/bits/syscall.h -+++ b/arch/or1k/bits/syscall.h -@@ -263,6 +263,7 @@ - #define __NR_seccomp 277 - #define __NR_getrandom 278 - #define __NR_memfd_create 279 -+#define __NR_bpf 280 - - #define SYS_io_setup __NR_io_setup - #define SYS_io_destroy __NR_io_destroy -@@ -529,3 +530,4 @@ - #define SYS_seccomp __NR_seccomp - #define SYS_getrandom __NR_getrandom - #define SYS_memfd_create __NR_memfd_create -+#define SYS_bpf __NR_bpf ---- a/arch/or1k/syscall_arch.h -+++ b/arch/or1k/syscall_arch.h -@@ -1,7 +1,7 @@ - #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) 0, __SYSCALL_LL_E((x)) -+#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x)) - - #define SYSCALL_MMAP2_UNIT 8192ULL - -@@ -118,39 +118,7 @@ static inline long __syscall6(long n, lo - - #else - --static inline long __syscall0(long n) --{ -- return (__syscall)(n); --} -- --static inline long __syscall1(long n, long a) --{ -- return (__syscall)(n, a); --} -- --static inline long __syscall2(long n, long a, long b) --{ -- return (__syscall)(n, a, b); --} -- --static inline long __syscall3(long n, long a, long b, long c) --{ -- return (__syscall)(n, a, b, c); --} -- --static inline long __syscall4(long n, long a, long b, long c, long d) --{ -- return (__syscall)(n, a, b, c, d); --} -- --static inline long __syscall5(long n, long a, long b, long c, long d, long e) --{ -- return (__syscall)(n, a, b, c, d, e); --} -- --static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f) --{ -- return (__syscall)(n, a, b, c, d, e, f); --} -+#undef SYSCALL_NO_INLINE -+#define SYSCALL_NO_INLINE - - #endif ---- a/arch/powerpc/bits/alltypes.h.in -+++ b/arch/powerpc/bits/alltypes.h.in -@@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list - #ifndef __cplusplus - TYPEDEF long wchar_t; - #endif --TYPEDEF unsigned wint_t; - - TYPEDEF float float_t; - TYPEDEF double double_t; ---- a/arch/powerpc/bits/syscall.h -+++ b/arch/powerpc/bits/syscall.h -@@ -374,6 +374,7 @@ - #define __NR_seccomp 358 - #define __NR_getrandom 359 - #define __NR_memfd_create 360 -+#define __NR_bpf 361 - - /* - * repeated with SYS prefix -@@ -754,3 +755,4 @@ - #define SYS_seccomp 358 - #define SYS_getrandom 359 - #define SYS_memfd_create 360 -+#define SYS_bpf 361 ---- a/arch/powerpc/syscall_arch.h -+++ b/arch/powerpc/syscall_arch.h -@@ -3,39 +3,5 @@ - ((union { long long ll; long l[2]; }){ .ll = x }).l[1] - #define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x)) - --long (__syscall)(long, ...); -- --static inline long __syscall0(long n) --{ -- return (__syscall)(n, 0, 0, 0, 0, 0, 0); --} -- --static inline long __syscall1(long n, long a) --{ -- return (__syscall)(n, a, 0, 0, 0, 0, 0); --} -- --static inline long __syscall2(long n, long a, long b) --{ -- return (__syscall)(n, a, b, 0, 0, 0, 0); --} -- --static inline long __syscall3(long n, long a, long b, long c) --{ -- return (__syscall)(n, a, b, c, 0, 0, 0); --} -- --static inline long __syscall4(long n, long a, long b, long c, long d) --{ -- return (__syscall)(n, a, b, c, d, 0, 0); --} -- --static inline long __syscall5(long n, long a, long b, long c, long d, long e) --{ -- return (__syscall)(n, a, b, c, d, e, 0); --} -- --static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f) --{ -- return (__syscall)(n, a, b, c, d, e, f); --} -+#undef SYSCALL_NO_INLINE -+#define SYSCALL_NO_INLINE ---- a/arch/sh/bits/alltypes.h.in -+++ b/arch/sh/bits/alltypes.h.in -@@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list - #ifndef __cplusplus - TYPEDEF long wchar_t; - #endif --TYPEDEF unsigned wint_t; - - TYPEDEF float float_t; - TYPEDEF double double_t; ---- a/arch/x32/bits/alltypes.h.in -+++ b/arch/x32/bits/alltypes.h.in -@@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list - #ifndef __cplusplus - TYPEDEF long wchar_t; - #endif --TYPEDEF unsigned wint_t; - - #if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2 - TYPEDEF long double float_t; ---- a/arch/x32/bits/syscall.h -+++ b/arch/x32/bits/syscall.h -@@ -277,6 +277,8 @@ - #define __NR_seccomp (__X32_SYSCALL_BIT + 317) - #define __NR_getrandom (__X32_SYSCALL_BIT + 318) - #define __NR_memfd_create (__X32_SYSCALL_BIT + 319) -+#define __NR_kexec_file_load (__X32_SYSCALL_BIT + 320) -+#define __NR_bpf (__X32_SYSCALL_BIT + 321) - - #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) - #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) -@@ -604,6 +606,8 @@ - #define SYS_seccomp __NR_seccomp - #define SYS_getrandom __NR_getrandom - #define SYS_memfd_create __NR_memfd_create -+#define SYS_kexec_file_load __NR_kexec_file_load -+#define SYS_bpf __NR_bpf - - #define SYS_rt_sigaction __NR_rt_sigaction - #define SYS_rt_sigreturn __NR_rt_sigreturn ---- a/arch/x86_64/bits/alltypes.h.in -+++ b/arch/x86_64/bits/alltypes.h.in -@@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list - #ifndef __cplusplus - TYPEDEF int wchar_t; - #endif --TYPEDEF unsigned wint_t; - - #if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2 - TYPEDEF long double float_t; ---- a/arch/x86_64/bits/syscall.h -+++ b/arch/x86_64/bits/syscall.h -@@ -318,6 +318,8 @@ - #define __NR_seccomp 317 - #define __NR_getrandom 318 - #define __NR_memfd_create 319 -+#define __NR_kexec_file_load 320 -+#define __NR_bpf 321 - - - #undef __NR_fstatat -@@ -654,6 +656,8 @@ - #define SYS_seccomp 317 - #define SYS_getrandom 318 - #define SYS_memfd_create 319 -+#define SYS_kexec_file_load 320 -+#define SYS_bpf 321 - - #undef SYS_fstatat - #undef SYS_pread ---- a/include/alltypes.h.in -+++ b/include/alltypes.h.in -@@ -28,6 +28,7 @@ TYPEDEF _Int64 blkcnt_t; - TYPEDEF unsigned _Int64 fsblkcnt_t; - TYPEDEF unsigned _Int64 fsfilcnt_t; - -+TYPEDEF unsigned wint_t; - TYPEDEF unsigned long wctype_t; - - TYPEDEF void * timer_t; ---- a/include/arpa/nameser.h -+++ b/include/arpa/nameser.h -@@ -1,6 +1,11 @@ - #ifndef _ARPA_NAMESER_H - #define _ARPA_NAMESER_H - -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#include <stddef.h> - #include <stdint.h> - - #define __NAMESER 19991006 -@@ -48,6 +53,8 @@ extern const struct _ns_flagdata _ns_fla - #define ns_msg_end(handle) ((handle)._eom + 0) - #define ns_msg_size(handle) ((handle)._eom - (handle)._msg) - #define ns_msg_count(handle, section) ((handle)._counts[section] + 0) -+#define ns_msg_getflag(handle, flag) \ -+ (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift) - - typedef struct __ns_rr { - char name[NS_MAXDNAME]; -@@ -296,43 +303,20 @@ typedef enum __ns_cert_types { - #define NS_OPT_DNSSEC_OK 0x8000U - #define NS_OPT_NSID 3 - --#define NS_GET16(s, cp) do { \ -- register const unsigned char *t_cp = (const unsigned char *)(cp); \ -- (s) = ((uint16_t)t_cp[0] << 8) \ -- | ((uint16_t)t_cp[1]) \ -- ; \ -- (cp) += NS_INT16SZ; \ --} while (0) -- --#define NS_GET32(l, cp) do { \ -- register const unsigned char *t_cp = (const unsigned char *)(cp); \ -- (l) = ((uint32_t)t_cp[0] << 24) \ -- | ((uint32_t)t_cp[1] << 16) \ -- | ((uint32_t)t_cp[2] << 8) \ -- | ((uint32_t)t_cp[3]) \ -- ; \ -- (cp) += NS_INT32SZ; \ --} while (0) -- --#define NS_PUT16(s, cp) do { \ -- register uint16_t t_s = (uint16_t)(s); \ -- register unsigned char *t_cp = (unsigned char *)(cp); \ -- *t_cp++ = t_s >> 8; \ -- *t_cp = t_s; \ -- (cp) += NS_INT16SZ; \ --} while (0) -- --#define NS_PUT32(l, cp) do { \ -- register uint32_t t_l = (uint32_t)(l); \ -- register unsigned char *t_cp = (unsigned char *)(cp); \ -- *t_cp++ = t_l >> 24; \ -- *t_cp++ = t_l >> 16; \ -- *t_cp++ = t_l >> 8; \ -- *t_cp = t_l; \ -- (cp) += NS_INT32SZ; \ --} while (0) -- -- -+#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp)+=2)-2)) -+#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp)+=4)-4)) -+#define NS_PUT16(s, cp) ns_put16((s), ((cp)+=2)-2) -+#define NS_PUT32(l, cp) ns_put32((l), ((cp)+=4)-4) -+ -+unsigned ns_get16(const unsigned char *); -+unsigned long ns_get32(const unsigned char *); -+void ns_put16(unsigned, unsigned char *); -+void ns_put32(unsigned long, unsigned char *); -+ -+int ns_initparse(const unsigned char *, int, ns_msg *); -+int ns_parserr(ns_msg *, ns_sect, int, ns_rr *); -+int ns_skiprr(const unsigned char *, const unsigned char *, ns_sect, int); -+int ns_name_uncompress(const unsigned char *, const unsigned char *, const unsigned char *, char *, size_t); - - - #define __BIND 19950621 -@@ -464,4 +448,8 @@ typedef struct { - #define PUTSHORT NS_PUT16 - #define PUTLONG NS_PUT32 - -+#ifdef __cplusplus -+} -+#endif -+ - #endif ---- a/include/complex.h -+++ b/include/complex.h -@@ -7,9 +7,9 @@ extern "C" { - - #define complex _Complex - #ifdef __GNUC__ --#define _Complex_I (__extension__ 1.0fi) -+#define _Complex_I (__extension__ (0.0f+1.0fi)) - #else --#define _Complex_I 1.0fi -+#define _Complex_I (0.0f+1.0fi) - #endif - #define I _Complex_I - -@@ -101,8 +101,9 @@ double creal(double complex); - float crealf(float complex); - long double creall(long double complex); - -+#ifndef __cplusplus - #define __CIMAG(x, t) \ -- ((union { _Complex t __z; t __xy[2]; }){(_Complex t)(x)}.__xy[1]) -+ (+(union { _Complex t __z; t __xy[2]; }){(_Complex t)(x)}.__xy[1]) - - #define creal(x) ((double)(x)) - #define crealf(x) ((float)(x)) -@@ -111,13 +112,20 @@ long double creall(long double complex); - #define cimag(x) __CIMAG(x, double) - #define cimagf(x) __CIMAG(x, float) - #define cimagl(x) __CIMAG(x, long double) -+#endif - --#define __CMPLX(x, y, t) \ -- ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z) -- -+#if __STDC_VERSION__ >= 201112L -+#if defined(_Imaginary_I) -+#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y))) -+#elif defined(__clang__) -+#define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) }) -+#else -+#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y))) -+#endif - #define CMPLX(x, y) __CMPLX(x, y, double) - #define CMPLXF(x, y) __CMPLX(x, y, float) - #define CMPLXL(x, y) __CMPLX(x, y, long double) -+#endif - - #ifdef __cplusplus - } ---- a/include/pthread.h -+++ b/include/pthread.h -@@ -84,7 +84,9 @@ __attribute__((const)) - pthread_t pthread_self(void); - - int pthread_equal(pthread_t, pthread_t); -+#ifndef __cplusplus - #define pthread_equal(x,y) ((x)==(y)) -+#endif - - int pthread_setcancelstate(int, int *); - int pthread_setcanceltype(int, int *); ---- a/include/stdint.h -+++ b/include/stdint.h -@@ -47,8 +47,8 @@ typedef uint64_t uint_least64_t; - - #define UINT8_MAX (0xff) - #define UINT16_MAX (0xffff) --#define UINT32_MAX (0xffffffff) --#define UINT64_MAX (0xffffffffffffffff) -+#define UINT32_MAX (0xffffffffu) -+#define UINT64_MAX (0xffffffffffffffffu) - - #define INT_FAST8_MIN INT8_MIN - #define INT_FAST64_MIN INT64_MIN -@@ -78,7 +78,7 @@ typedef uint64_t uint_least64_t; - #define INTMAX_MAX INT64_MAX - #define UINTMAX_MAX UINT64_MAX - --#define WINT_MIN 0 -+#define WINT_MIN 0U - #define WINT_MAX UINT32_MAX - - #if L'\0'-1 > 0 ---- a/include/sys/prctl.h -+++ b/include/sys/prctl.h -@@ -5,6 +5,8 @@ - extern "C" { - #endif - -+#include <stdint.h> -+ - #define PR_SET_PDEATHSIG 1 - #define PR_GET_PDEATHSIG 2 - #define PR_GET_DUMPABLE 3 -@@ -80,6 +82,25 @@ extern "C" { - #define PR_SET_MM_ENV_END 11 - #define PR_SET_MM_AUXV 12 - #define PR_SET_MM_EXE_FILE 13 -+#define PR_SET_MM_MAP 14 -+#define PR_SET_MM_MAP_SIZE 15 -+ -+struct prctl_mm_map { -+ uint64_t start_code; -+ uint64_t end_code; -+ uint64_t start_data; -+ uint64_t end_data; -+ uint64_t start_brk; -+ uint64_t brk; -+ uint64_t start_stack; -+ uint64_t arg_start; -+ uint64_t arg_end; -+ uint64_t env_start; -+ uint64_t env_end; -+ uint64_t *auxv; -+ uint32_t auxv_size; -+ uint32_t exe_fd; -+}; - - #define PR_SET_PTRACER 0x59616d61 - #define PR_SET_PTRACER_ANY (-1UL) ---- a/include/threads.h -+++ b/include/threads.h -@@ -51,7 +51,9 @@ void thrd_yield(void); - - thrd_t thrd_current(void); - int thrd_equal(thrd_t, thrd_t); -+#ifndef __cplusplus - #define thrd_equal(A, B) ((A) == (B)) -+#endif - - void call_once(once_flag *, void (*)(void)); - ---- a/include/utmp.h -+++ b/include/utmp.h -@@ -35,6 +35,8 @@ void setutent(void); - - void updwtmp(const char *, const struct utmp *); - -+int login_tty(int); -+ - #define _PATH_UTMP "/dev/null/utmp" - #define _PATH_WTMP "/dev/null/wtmp" - ---- a/src/fcntl/open.c -+++ b/src/fcntl/open.c -@@ -7,7 +7,7 @@ int open(const char *filename, int flags - { - mode_t mode = 0; - -- if (flags & O_CREAT) { -+ if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) { - va_list ap; - va_start(ap, flags); - mode = va_arg(ap, mode_t); ---- a/src/fcntl/openat.c -+++ b/src/fcntl/openat.c -@@ -5,11 +5,15 @@ - - int openat(int fd, const char *filename, int flags, ...) - { -- mode_t mode; -- va_list ap; -- va_start(ap, flags); -- mode = va_arg(ap, mode_t); -- va_end(ap); -+ mode_t mode = 0; -+ -+ if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) { -+ va_list ap; -+ va_start(ap, flags); -+ mode = va_arg(ap, mode_t); -+ va_end(ap); -+ } -+ - return syscall_cp(SYS_openat, fd, filename, flags|O_LARGEFILE, mode); - } - ---- a/src/internal/libm.h -+++ b/src/internal/libm.h -@@ -128,6 +128,18 @@ do { - (d) = __u.f; \ - } while (0) - -+#undef __CMPLX -+#undef CMPLX -+#undef CMPLXF -+#undef CMPLXL -+ -+#define __CMPLX(x, y, t) \ -+ ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z) -+ -+#define CMPLX(x, y) __CMPLX(x, y, double) -+#define CMPLXF(x, y) __CMPLX(x, y, float) -+#define CMPLXL(x, y) __CMPLX(x, y, long double) -+ - /* fdlibm kernel functions */ - - int __rem_pio2_large(double*,double*,int,int,int); ---- a/src/internal/syscall.h -+++ b/src/internal/syscall.h -@@ -24,12 +24,22 @@ long __syscall_ret(unsigned long), __sys - __syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, - syscall_arg_t, syscall_arg_t, syscall_arg_t); - -+#ifdef SYSCALL_NO_INLINE -+#define __syscall0(n) (__syscall)(n) -+#define __syscall1(n,a) (__syscall)(n,__scc(a)) -+#define __syscall2(n,a,b) (__syscall)(n,__scc(a),__scc(b)) -+#define __syscall3(n,a,b,c) (__syscall)(n,__scc(a),__scc(b),__scc(c)) -+#define __syscall4(n,a,b,c,d) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d)) -+#define __syscall5(n,a,b,c,d,e) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) -+#define __syscall6(n,a,b,c,d,e,f) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) -+#else - #define __syscall1(n,a) __syscall1(n,__scc(a)) - #define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b)) - #define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c)) - #define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d)) - #define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) - #define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) -+#endif - #define __syscall7(n,a,b,c,d,e,f,g) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g)) - - #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n ---- a/src/ldso/dynlink.c -+++ b/src/ldso/dynlink.c -@@ -645,6 +645,8 @@ static void decode_dyn(struct dso *p) - p->hashtab = (void *)(p->base + dyn[DT_HASH]); - if (dyn[0]&(1<<DT_RPATH)) - p->rpath_orig = (void *)(p->strings + dyn[DT_RPATH]); -+ if (dyn[0]&(1<<DT_RUNPATH)) -+ p->rpath_orig = (void *)(p->strings + dyn[DT_RUNPATH]); - if (search_vec(p->dynv, dyn, DT_GNU_HASH)) - p->ghashtab = (void *)(p->base + *dyn); - if (search_vec(p->dynv, dyn, DT_VERSYM)) -@@ -1126,6 +1128,7 @@ void *__dynlink(int argc, char **argv) - libc.secure = 1; - } - libc.page_size = aux[AT_PAGESZ]; -+ libc.auxv = auxv; - - /* If the dynamic linker was invoked as a program itself, AT_BASE - * will not be set. In that case, we assume the base address is ---- a/src/math/__rem_pio2.c -+++ b/src/math/__rem_pio2.c -@@ -19,6 +19,12 @@ - - #include "libm.h" - -+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -+#define EPS DBL_EPSILON -+#elif FLT_EVAL_METHOD==2 -+#define EPS LDBL_EPSILON -+#endif -+ - /* - * invpio2: 53 bits of 2/pi - * pio2_1: first 33 bit of pi/2 -@@ -29,6 +35,7 @@ - * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) - */ - static const double -+toint = 1.5/EPS, - invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ - pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ - pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ -@@ -41,8 +48,8 @@ pio2_3t = 8.47842766036889956997e-32; /* - int __rem_pio2(double x, double *y) - { - union {double f; uint64_t i;} u = {x}; -- double_t z,w,t,r; -- double tx[3],ty[2],fn; -+ double_t z,w,t,r,fn; -+ double tx[3],ty[2]; - uint32_t ix; - int sign, n, ex, ey, i; - -@@ -111,8 +118,7 @@ int __rem_pio2(double x, double *y) - if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */ - medium: - /* rint(x/(pi/2)), Assume round-to-nearest. */ -- fn = x*invpio2 + 0x1.8p52; -- fn = fn - 0x1.8p52; -+ fn = x*invpio2 + toint - toint; - n = (int32_t)fn; - r = x - fn*pio2_1; - w = fn*pio2_1t; /* 1st round, good to 85 bits */ ---- a/src/math/__rem_pio2f.c -+++ b/src/math/__rem_pio2f.c -@@ -22,12 +22,19 @@ - - #include "libm.h" - -+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -+#define EPS DBL_EPSILON -+#elif FLT_EVAL_METHOD==2 -+#define EPS LDBL_EPSILON -+#endif -+ - /* - * invpio2: 53 bits of 2/pi - * pio2_1: first 25 bits of pi/2 - * pio2_1t: pi/2 - pio2_1 - */ - static const double -+toint = 1.5/EPS, - invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ - pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */ - pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */ -@@ -35,7 +42,8 @@ pio2_1t = 1.58932547735281966916e-08; /* - int __rem_pio2f(float x, double *y) - { - union {float f; uint32_t i;} u = {x}; -- double tx[1],ty[1],fn; -+ double tx[1],ty[1]; -+ double_t fn; - uint32_t ix; - int n, sign, e0; - -@@ -43,8 +51,7 @@ int __rem_pio2f(float x, double *y) - /* 25+53 bit pi is good enough for medium size */ - if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */ - /* Use a specialized rint() to get fn. Assume round-to-nearest. */ -- fn = x*invpio2 + 0x1.8p52; -- fn = fn - 0x1.8p52; -+ fn = x*invpio2 + toint - toint; - n = (int32_t)fn; - *y = x - fn*pio2_1 - fn*pio2_1t; - return n; ---- a/src/math/__rem_pio2l.c -+++ b/src/math/__rem_pio2l.c -@@ -20,10 +20,11 @@ - * use __rem_pio2_large() for large x - */ - -+static const long double toint = 1.5/LDBL_EPSILON; -+ - #if LDBL_MANT_DIG == 64 - /* u ~< 0x1p25*pi/2 */ - #define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.m>>48) < ((0x3fff + 25)<<16 | 0x921f>>1 | 0x8000)) --#define TOINT 0x1.8p63 - #define QUOBITS(x) ((uint32_t)(int32_t)x & 0x7fffffff) - #define ROUND1 22 - #define ROUND2 61 -@@ -50,7 +51,6 @@ pio2_3t = -2.75299651904407171810e-37L; - #elif LDBL_MANT_DIG == 113 - /* u ~< 0x1p45*pi/2 */ - #define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.top) < ((0x3fff + 45)<<16 | 0x921f)) --#define TOINT 0x1.8p112 - #define QUOBITS(x) ((uint32_t)(int64_t)x & 0x7fffffff) - #define ROUND1 51 - #define ROUND2 119 -@@ -77,7 +77,7 @@ int __rem_pio2l(long double x, long doub - ex = u.i.se & 0x7fff; - if (SMALL(u)) { - /* rint(x/(pi/2)), Assume round-to-nearest. */ -- fn = x*invpio2 + TOINT - TOINT; -+ fn = x*invpio2 + toint - toint; - n = QUOBITS(fn); - r = x-fn*pio2_1; - w = fn*pio2_1t; /* 1st round good to 102/180 bits (ld80/ld128) */ ---- a/src/math/ceil.c -+++ b/src/math/ceil.c -@@ -1,5 +1,12 @@ - #include "libm.h" - -+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -+#define EPS DBL_EPSILON -+#elif FLT_EVAL_METHOD==2 -+#define EPS LDBL_EPSILON -+#endif -+static const double_t toint = 1/EPS; -+ - double ceil(double x) - { - union {double f; uint64_t i;} u = {x}; -@@ -10,9 +17,9 @@ double ceil(double x) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i >> 63) -- y = (double)(x - 0x1p52) + 0x1p52 - x; -+ y = x - toint + toint - x; - else -- y = (double)(x + 0x1p52) - 0x1p52 - x; -+ y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3ff-1) { - FORCE_EVAL(y); ---- a/src/math/ceill.c -+++ b/src/math/ceill.c -@@ -6,11 +6,9 @@ long double ceill(long double x) - return ceil(x); - } - #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 --#if LDBL_MANT_DIG == 64 --#define TOINT 0x1p63 --#elif LDBL_MANT_DIG == 113 --#define TOINT 0x1p112 --#endif -+ -+static const long double toint = 1/LDBL_EPSILON; -+ - long double ceill(long double x) - { - union ldshape u = {x}; -@@ -21,9 +19,9 @@ long double ceill(long double x) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i.se >> 15) -- y = x - TOINT + TOINT - x; -+ y = x - toint + toint - x; - else -- y = x + TOINT - TOINT - x; -+ y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3fff-1) { - FORCE_EVAL(y); ---- a/src/math/floor.c -+++ b/src/math/floor.c -@@ -1,5 +1,12 @@ - #include "libm.h" - -+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -+#define EPS DBL_EPSILON -+#elif FLT_EVAL_METHOD==2 -+#define EPS LDBL_EPSILON -+#endif -+static const double_t toint = 1/EPS; -+ - double floor(double x) - { - union {double f; uint64_t i;} u = {x}; -@@ -10,9 +17,9 @@ double floor(double x) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i >> 63) -- y = (double)(x - 0x1p52) + 0x1p52 - x; -+ y = x - toint + toint - x; - else -- y = (double)(x + 0x1p52) - 0x1p52 - x; -+ y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3ff-1) { - FORCE_EVAL(y); ---- a/src/math/floorl.c -+++ b/src/math/floorl.c -@@ -6,11 +6,9 @@ long double floorl(long double x) - return floor(x); - } - #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 --#if LDBL_MANT_DIG == 64 --#define TOINT 0x1p63 --#elif LDBL_MANT_DIG == 113 --#define TOINT 0x1p112 --#endif -+ -+static const long double toint = 1/LDBL_EPSILON; -+ - long double floorl(long double x) - { - union ldshape u = {x}; -@@ -21,9 +19,9 @@ long double floorl(long double x) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i.se >> 15) -- y = x - TOINT + TOINT - x; -+ y = x - toint + toint - x; - else -- y = x + TOINT - TOINT - x; -+ y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3fff-1) { - FORCE_EVAL(y); ---- a/src/math/i386/fmod.s -+++ b/src/math/i386/fmod.s -@@ -4,7 +4,7 @@ fmod: - fldl 12(%esp) - fldl 4(%esp) - 1: fprem -- fstsw %ax -+ fnstsw %ax - sahf - jp 1b - fstp %st(1) ---- a/src/math/i386/fmodf.s -+++ b/src/math/i386/fmodf.s -@@ -4,7 +4,7 @@ fmodf: - flds 8(%esp) - flds 4(%esp) - 1: fprem -- fstsw %ax -+ fnstsw %ax - sahf - jp 1b - fstp %st(1) ---- a/src/math/i386/fmodl.s -+++ b/src/math/i386/fmodl.s -@@ -4,7 +4,7 @@ fmodl: - fldt 16(%esp) - fldt 4(%esp) - 1: fprem -- fstsw %ax -+ fnstsw %ax - sahf - jp 1b - fstp %st(1) ---- a/src/math/i386/remainder.s -+++ b/src/math/i386/remainder.s -@@ -7,7 +7,7 @@ drem: - fldl 12(%esp) - fldl 4(%esp) - 1: fprem1 -- fstsw %ax -+ fnstsw %ax - sahf - jp 1b - fstp %st(1) ---- a/src/math/i386/remainderf.s -+++ b/src/math/i386/remainderf.s -@@ -7,7 +7,7 @@ dremf: - flds 8(%esp) - flds 4(%esp) - 1: fprem1 -- fstsw %ax -+ fnstsw %ax - sahf - jp 1b - fstp %st(1) ---- a/src/math/i386/remainderl.s -+++ b/src/math/i386/remainderl.s -@@ -4,7 +4,7 @@ remainderl: - fldt 16(%esp) - fldt 4(%esp) - 1: fprem1 -- fstsw %ax -+ fnstsw %ax - sahf - jp 1b - fstp %st(1) ---- a/src/math/i386/sqrt.s -+++ b/src/math/i386/sqrt.s -@@ -2,7 +2,7 @@ - .type sqrt,@function - sqrt: fldl 4(%esp) - fsqrt -- fstsw %ax -+ fnstsw %ax - sub $12,%esp - fld %st(0) - fstpt (%esp) ---- a/src/math/modfl.c -+++ b/src/math/modfl.c -@@ -11,11 +11,9 @@ long double modfl(long double x, long do - return r; - } - #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 --#if LDBL_MANT_DIG == 64 --#define TOINT 0x1p63 --#elif LDBL_MANT_DIG == 113 --#define TOINT 0x1p112 --#endif -+ -+static const long double toint = 1/LDBL_EPSILON; -+ - long double modfl(long double x, long double *iptr) - { - union ldshape u = {x}; -@@ -40,7 +38,7 @@ long double modfl(long double x, long do - - /* raises spurious inexact */ - absx = s ? -x : x; -- y = absx + TOINT - TOINT - absx; -+ y = absx + toint - toint - absx; - if (y == 0) { - *iptr = x; - return s ? -0.0 : 0.0; ---- a/src/math/rint.c -+++ b/src/math/rint.c -@@ -1,6 +1,14 @@ -+#include <float.h> - #include <math.h> - #include <stdint.h> - -+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -+#define EPS DBL_EPSILON -+#elif FLT_EVAL_METHOD==2 -+#define EPS LDBL_EPSILON -+#endif -+static const double_t toint = 1/EPS; -+ - double rint(double x) - { - union {double f; uint64_t i;} u = {x}; -@@ -11,9 +19,9 @@ double rint(double x) - if (e >= 0x3ff+52) - return x; - if (s) -- y = (double)(x - 0x1p52) + 0x1p52; -+ y = x - toint + toint; - else -- y = (double)(x + 0x1p52) - 0x1p52; -+ y = x + toint - toint; - if (y == 0) - return s ? -0.0 : 0; - return y; ---- a/src/math/rintf.c -+++ b/src/math/rintf.c -@@ -1,6 +1,16 @@ -+#include <float.h> - #include <math.h> - #include <stdint.h> - -+#if FLT_EVAL_METHOD==0 -+#define EPS FLT_EPSILON -+#elif FLT_EVAL_METHOD==1 -+#define EPS DBL_EPSILON -+#elif FLT_EVAL_METHOD==2 -+#define EPS LDBL_EPSILON -+#endif -+static const float_t toint = 1/EPS; -+ - float rintf(float x) - { - union {float f; uint32_t i;} u = {x}; -@@ -11,9 +21,9 @@ float rintf(float x) - if (e >= 0x7f+23) - return x; - if (s) -- y = (float)(x - 0x1p23f) + 0x1p23f; -+ y = x - toint + toint; - else -- y = (float)(x + 0x1p23f) - 0x1p23f; -+ y = x + toint - toint; - if (y == 0) - return s ? -0.0f : 0.0f; - return y; ---- a/src/math/rintl.c -+++ b/src/math/rintl.c -@@ -6,11 +6,9 @@ long double rintl(long double x) - return rint(x); - } - #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 --#if LDBL_MANT_DIG == 64 --#define TOINT 0x1p63 --#elif LDBL_MANT_DIG == 113 --#define TOINT 0x1p112 --#endif -+ -+static const long double toint = 1/LDBL_EPSILON; -+ - long double rintl(long double x) - { - union ldshape u = {x}; -@@ -21,9 +19,9 @@ long double rintl(long double x) - if (e >= 0x3fff+LDBL_MANT_DIG-1) - return x; - if (s) -- y = x - TOINT + TOINT; -+ y = x - toint + toint; - else -- y = x + TOINT - TOINT; -+ y = x + toint - toint; - if (y == 0) - return 0*x; - return y; ---- a/src/math/round.c -+++ b/src/math/round.c -@@ -1,5 +1,12 @@ - #include "libm.h" - -+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -+#define EPS DBL_EPSILON -+#elif FLT_EVAL_METHOD==2 -+#define EPS LDBL_EPSILON -+#endif -+static const double_t toint = 1/EPS; -+ - double round(double x) - { - union {double f; uint64_t i;} u = {x}; -@@ -12,10 +19,10 @@ double round(double x) - x = -x; - if (e < 0x3ff-1) { - /* raise inexact if x!=0 */ -- FORCE_EVAL(x + 0x1p52); -+ FORCE_EVAL(x + toint); - return 0*u.f; - } -- y = (double)(x + 0x1p52) - 0x1p52 - x; -+ y = x + toint - toint - x; - if (y > 0.5) - y = y + x - 1; - else if (y <= -0.5) ---- a/src/math/roundf.c -+++ b/src/math/roundf.c -@@ -1,5 +1,14 @@ - #include "libm.h" - -+#if FLT_EVAL_METHOD==0 -+#define EPS FLT_EPSILON -+#elif FLT_EVAL_METHOD==1 -+#define EPS DBL_EPSILON -+#elif FLT_EVAL_METHOD==2 -+#define EPS LDBL_EPSILON -+#endif -+static const float_t toint = 1/EPS; -+ - float roundf(float x) - { - union {float f; uint32_t i;} u = {x}; -@@ -11,10 +20,10 @@ float roundf(float x) - if (u.i >> 31) - x = -x; - if (e < 0x7f-1) { -- FORCE_EVAL(x + 0x1p23f); -+ FORCE_EVAL(x + toint); - return 0*u.f; - } -- y = (float)(x + 0x1p23f) - 0x1p23f - x; -+ y = x + toint - toint - x; - if (y > 0.5f) - y = y + x - 1; - else if (y <= -0.5f) ---- a/src/math/roundl.c -+++ b/src/math/roundl.c -@@ -6,11 +6,9 @@ long double roundl(long double x) - return round(x); - } - #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 --#if LDBL_MANT_DIG == 64 --#define TOINT 0x1p63 --#elif LDBL_MANT_DIG == 113 --#define TOINT 0x1p112 --#endif -+ -+static const long double toint = 1/LDBL_EPSILON; -+ - long double roundl(long double x) - { - union ldshape u = {x}; -@@ -22,10 +20,10 @@ long double roundl(long double x) - if (u.i.se >> 15) - x = -x; - if (e < 0x3fff-1) { -- FORCE_EVAL(x + TOINT); -+ FORCE_EVAL(x + toint); - return 0*u.f; - } -- y = x + TOINT - TOINT - x; -+ y = x + toint - toint - x; - if (y > 0.5) - y = y + x - 1; - else if (y <= -0.5) ---- a/src/math/truncl.c -+++ b/src/math/truncl.c -@@ -6,11 +6,9 @@ long double truncl(long double x) - return trunc(x); - } - #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 --#if LDBL_MANT_DIG == 64 --#define TOINT 0x1p63 --#elif LDBL_MANT_DIG == 113 --#define TOINT 0x1p112 --#endif -+ -+static const long double toint = 1/LDBL_EPSILON; -+ - long double truncl(long double x) - { - union ldshape u = {x}; -@@ -27,7 +25,7 @@ long double truncl(long double x) - /* y = int(|x|) - |x|, where int(|x|) is an integer neighbor of |x| */ - if (s) - x = -x; -- y = x + TOINT - TOINT - x; -+ y = x + toint - toint - x; - if (y > 0) - y -= 1; - x += y; ---- a/src/math/x32/exp2l.s -+++ b/src/math/x32/exp2l.s -@@ -6,9 +6,7 @@ expm1l: - fmulp - movl $0xc2820000,-4(%esp) - flds -4(%esp) -- fucomp %st(1) -- fnstsw %ax -- sahf -+ fucomip %st(1) - fld1 - jb 1f - # x*log2e <= -65, return -1 without underflow -@@ -17,11 +15,8 @@ expm1l: - ret - 1: fld %st(1) - fabs -- fucom %st(1) -- fnstsw %ax -+ fucomip %st(1) - fstp %st(0) -- fstp %st(0) -- sahf - ja 1f - f2xm1 - ret -@@ -53,9 +48,7 @@ exp2l: - fld %st(1) - fsub %st(1) - faddp -- fucomp %st(1) -- fnstsw -- sahf -+ fucomip %st(1) - je 2f # x - 0x1p63 + 0x1p63 == x - movl $1,(%esp) - flds (%esp) # 0x1p-149 ---- a/src/math/x32/fmodl.s -+++ b/src/math/x32/fmodl.s -@@ -4,8 +4,8 @@ fmodl: - fldt 24(%esp) - fldt 8(%esp) - 1: fprem -- fstsw %ax -- sahf -- jp 1b -+ fnstsw %ax -+ testb $4,%ah -+ jnz 1b - fstp %st(1) - ret ---- a/src/math/x32/remainderl.s -+++ b/src/math/x32/remainderl.s -@@ -4,8 +4,8 @@ remainderl: - fldt 24(%esp) - fldt 8(%esp) - 1: fprem1 -- fstsw %ax -- sahf -- jp 1b -+ fnstsw %ax -+ testb $4,%ah -+ jnz 1b - fstp %st(1) - ret ---- a/src/math/x86_64/exp2l.s -+++ b/src/math/x86_64/exp2l.s -@@ -6,9 +6,7 @@ expm1l: - fmulp - movl $0xc2820000,-4(%rsp) - flds -4(%rsp) -- fucomp %st(1) -- fnstsw %ax -- sahf -+ fucomip %st(1) - fld1 - jb 1f - # x*log2e <= -65, return -1 without underflow -@@ -17,11 +15,8 @@ expm1l: - ret - 1: fld %st(1) - fabs -- fucom %st(1) -- fnstsw %ax -+ fucomip %st(1) - fstp %st(0) -- fstp %st(0) -- sahf - ja 1f - f2xm1 - ret -@@ -53,9 +48,7 @@ exp2l: - fld %st(1) - fsub %st(1) - faddp -- fucomp %st(1) -- fnstsw -- sahf -+ fucomip %st(1) - je 2f # x - 0x1p63 + 0x1p63 == x - movl $1,(%rsp) - flds (%rsp) # 0x1p-149 ---- a/src/math/x86_64/fmodl.s -+++ b/src/math/x86_64/fmodl.s -@@ -4,8 +4,8 @@ fmodl: - fldt 24(%rsp) - fldt 8(%rsp) - 1: fprem -- fstsw %ax -- sahf -- jp 1b -+ fnstsw %ax -+ testb $4,%ah -+ jnz 1b - fstp %st(1) - ret ---- a/src/math/x86_64/remainderl.s -+++ b/src/math/x86_64/remainderl.s -@@ -4,8 +4,8 @@ remainderl: - fldt 24(%rsp) - fldt 8(%rsp) - 1: fprem1 -- fstsw %ax -- sahf -- jp 1b -+ fnstsw %ax -+ testb $4,%ah -+ jnz 1b - fstp %st(1) - ret ---- a/src/misc/forkpty.c -+++ b/src/misc/forkpty.c -@@ -1,38 +1,57 @@ - #include <pty.h> -+#include <utmp.h> - #include <unistd.h> --#include <sys/ioctl.h> -+#include <errno.h> - #include <fcntl.h> -+#include <sys/wait.h> -+#include <pthread.h> - --int forkpty(int *m, char *name, const struct termios *tio, const struct winsize *ws) -+int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws) - { -- int s, t, i, istmp[3]={0}; -- pid_t pid; -+ int m, s, ec=0, p[2], cs; -+ pid_t pid=-1; -+ sigset_t set, oldset; - -- if (openpty(m, &s, name, tio, ws) < 0) return -1; -+ if (openpty(&m, &s, name, tio, ws) < 0) return -1; - -- /* Ensure before forking that we don't exceed fd limit */ -- for (i=0; i<3; i++) { -- if (fcntl(i, F_GETFL) < 0) { -- t = fcntl(s, F_DUPFD, i); -- if (t<0) break; -- else if (t!=i) close(t); -- else istmp[i] = 1; -- } -+ sigfillset(&set); -+ pthread_sigmask(SIG_BLOCK, &set, &oldset); -+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); -+ -+ if (pipe2(p, O_CLOEXEC)) { -+ close(s); -+ goto out; - } -- pid = i==3 ? fork() : -1; -+ -+ pid = fork(); - if (!pid) { -- close(*m); -- setsid(); -- ioctl(s, TIOCSCTTY, (char *)0); -- dup2(s, 0); -- dup2(s, 1); -- dup2(s, 2); -- if (s>2) close(s); -+ close(m); -+ close(p[0]); -+ if (login_tty(s)) { -+ write(p[1], &errno, sizeof errno); -+ _exit(127); -+ } -+ close(p[1]); -+ pthread_setcancelstate(cs, 0); -+ pthread_sigmask(SIG_SETMASK, &oldset, 0); - return 0; - } -- for (i=0; i<3; i++) -- if (istmp[i]) close(i); - close(s); -- if (pid < 0) close(*m); -+ close(p[1]); -+ if (read(p[0], &ec, sizeof ec) > 0) { -+ int status; -+ waitpid(pid, &status, 0); -+ pid = -1; -+ errno = ec; -+ } -+ close(p[0]); -+ -+out: -+ if (pid > 0) *pm = m; -+ else close(m); -+ -+ pthread_setcancelstate(cs, 0); -+ pthread_sigmask(SIG_SETMASK, &oldset, 0); -+ - return pid; - } ---- a/src/misc/getopt.c -+++ b/src/misc/getopt.c -@@ -4,6 +4,7 @@ - #include <limits.h> - #include <stdlib.h> - #include "libc.h" -+#include "locale_impl.h" - - char *optarg; - int optind=1, opterr=1, optopt, __optpos, __optreset=0; -@@ -11,6 +12,18 @@ int optind=1, opterr=1, optopt, __optpos - #define optpos __optpos - weak_alias(__optreset, optreset); - -+void __getopt_msg(const char *a, const char *b, const char *c, size_t l) -+{ -+ FILE *f = stderr; -+ b = __lctrans_cur(b); -+ flockfile(f); -+ fwrite(a, strlen(a), 1, f) -+ && fwrite(b, strlen(b), 1, f) -+ && fwrite(c, l, 1, f) -+ && putc('\n', f); -+ funlockfile(f); -+} -+ - int getopt(int argc, char * const argv[], const char *optstring) - { - int i; -@@ -24,8 +37,20 @@ int getopt(int argc, char * const argv[] - optind = 1; - } - -- if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1]) -+ if (optind >= argc || !argv[optind]) -+ return -1; -+ -+ if (argv[optind][0] != '-') { -+ if (optstring[0] == '-') { -+ optarg = argv[optind++]; -+ return 1; -+ } -+ return -1; -+ } -+ -+ if (!argv[optind][1]) - return -1; -+ - if (argv[optind][1] == '-' && !argv[optind][2]) - return optind++, -1; - -@@ -43,30 +68,31 @@ int getopt(int argc, char * const argv[] - optpos = 0; - } - -- for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1); -+ if (optstring[0] == '-' || optstring[0] == '+') -+ optstring++; -+ -+ i = 0; -+ d = 0; -+ do { -+ l = mbtowc(&d, optstring+i, MB_LEN_MAX); -+ if (l>0) i+=l; else i++; -+ } while (l && d != c); - - if (d != c) { -- if (optstring[0] != ':' && opterr) { -- write(2, argv[0], strlen(argv[0])); -- write(2, ": illegal option: ", 18); -- write(2, optchar, k); -- write(2, "\n", 1); -- } -+ if (optstring[0] != ':' && opterr) -+ __getopt_msg(argv[0], ": unrecognized option: ", optchar, k); - return '?'; - } -- if (optstring[i+1] == ':') { -- if (optind >= argc) { -+ if (optstring[i] == ':') { -+ if (optstring[i+1] == ':') optarg = 0; -+ else if (optind >= argc) { - if (optstring[0] == ':') return ':'; -- if (opterr) { -- write(2, argv[0], strlen(argv[0])); -- write(2, ": option requires an argument: ", 31); -- write(2, optchar, k); -- write(2, "\n", 1); -- } -+ if (opterr) __getopt_msg(argv[0], -+ ": option requires an argument: ", -+ optchar, k); - return '?'; - } -- if (optstring[i+2] == ':') optarg = 0; -- if (optstring[i+2] != ':' || optpos) { -+ if (optstring[i+1] != ':' || optpos) { - optarg = argv[optind++] + optpos; - optpos = 0; - } ---- a/src/misc/getopt_long.c -+++ b/src/misc/getopt_long.c -@@ -2,37 +2,106 @@ - #include <stddef.h> - #include <getopt.h> - #include <stdio.h> -+#include <string.h> - - extern int __optpos, __optreset; - -+static void permute(char *const *argv, int dest, int src) -+{ -+ char **av = (char **)argv; -+ char *tmp = av[src]; -+ int i; -+ for (i=src; i>dest; i--) -+ av[i] = av[i-1]; -+ av[dest] = tmp; -+} -+ -+void __getopt_msg(const char *, const char *, const char *, size_t); -+ -+static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly); -+ - static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) - { -+ int ret, skipped, resumed; -+ const char *optstring2 = optstring + 1; - if (!optind || __optreset) { - __optreset = 0; - __optpos = 0; - optind = 1; - } -- if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1; -- if ((longonly && argv[optind][1]) || -- (argv[optind][1] == '-' && argv[optind][2])) -- { -+ if (optind >= argc || !argv[optind]) return -1; -+ skipped = optind; -+ if (optstring[0] != '+' && optstring[0] != '-') { - int i; -- for (i=0; longopts[i].name; i++) { -+ for (i=optind; ; i++) { -+ if (i >= argc || !argv[i]) return -1; -+ if (argv[i][0] == '-' && argv[i][1]) break; -+ } -+ optind = i; -+ optstring2 = optstring; -+ } -+ resumed = optind; -+ ret = __getopt_long_core(argc, argv, optstring2, longopts, idx, longonly); -+ if (resumed > skipped) { -+ int i, cnt = optind-resumed; -+ for (i=0; i<cnt; i++) -+ permute(argv, skipped, optind-1); -+ optind = skipped + cnt; -+ } -+ return ret; -+} -+ -+static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) -+{ -+ -+ if (longopts && argv[optind][0] == '-' && -+ ((longonly && argv[optind][1]) || -+ (argv[optind][1] == '-' && argv[optind][2]))) -+ { -+ int i, cnt, match; -+ char *opt; -+ for (cnt=i=0; longopts[i].name; i++) { - const char *name = longopts[i].name; -- char *opt = argv[optind]+1; -+ opt = argv[optind]+1; - if (*opt == '-') opt++; - for (; *name && *name == *opt; name++, opt++); -- if (*name || (*opt && *opt != '=')) continue; -+ if (*opt && *opt != '=') continue; -+ match = i; -+ if (!*name) { -+ cnt = 1; -+ break; -+ } -+ cnt++; -+ } -+ if (cnt==1) { -+ i = match; -+ optind++; -+ optopt = longopts[i].val; - if (*opt == '=') { -- if (!longopts[i].has_arg) continue; -+ if (!longopts[i].has_arg) { -+ if (optstring[0] == ':' || !opterr) -+ return '?'; -+ __getopt_msg(argv[0], -+ ": option does not take an argument: ", -+ longopts[i].name, -+ strlen(longopts[i].name)); -+ return '?'; -+ } - optarg = opt+1; - } else { - if (longopts[i].has_arg == required_argument) { -- if (!(optarg = argv[++optind])) -- return ':'; -+ if (!(optarg = argv[optind])) { -+ if (optstring[0] == ':' || !opterr) -+ return ':'; -+ __getopt_msg(argv[0], -+ ": option requires an argument: ", -+ longopts[i].name, -+ strlen(longopts[i].name)); -+ return '?'; -+ } -+ optind++; - } else optarg = NULL; - } -- optind++; - if (idx) *idx = i; - if (longopts[i].flag) { - *longopts[i].flag = longopts[i].val; -@@ -41,6 +110,12 @@ static int __getopt_long(int argc, char - return longopts[i].val; - } - if (argv[optind][1] == '-') { -+ if (optstring[0] != ':' && opterr) -+ __getopt_msg(argv[0], cnt ? -+ ": option is ambiguous: " : -+ ": unrecognized option: ", -+ argv[optind]+2, -+ strlen(argv[optind]+2)); - optind++; - return '?'; - } ---- /dev/null -+++ b/src/misc/login_tty.c -@@ -0,0 +1,14 @@ -+#include <utmp.h> -+#include <sys/ioctl.h> -+#include <unistd.h> -+ -+int login_tty(int fd) -+{ -+ setsid(); -+ if (ioctl(fd, TIOCSCTTY, (char *)0)) return -1; -+ dup2(fd, 0); -+ dup2(fd, 1); -+ dup2(fd, 2); -+ if (fd>2) close(fd); -+ return 0; -+} ---- a/src/misc/openpty.c -+++ b/src/misc/openpty.c -@@ -3,31 +3,38 @@ - #include <unistd.h> - #include <pty.h> - #include <stdio.h> -+#include <pthread.h> - - /* Nonstandard, but vastly superior to the standard functions */ - --int openpty(int *m, int *s, char *name, const struct termios *tio, const struct winsize *ws) -+int openpty(int *pm, int *ps, char *name, const struct termios *tio, const struct winsize *ws) - { -- int n=0; -+ int m, s, n=0, cs; - char buf[20]; - -- *m = open("/dev/ptmx", O_RDWR|O_NOCTTY); -- if (*m < 0) return -1; -+ m = open("/dev/ptmx", O_RDWR|O_NOCTTY); -+ if (m < 0) return -1; - -- if (ioctl(*m, TIOCSPTLCK, &n) || ioctl (*m, TIOCGPTN, &n)) { -- close(*m); -- return -1; -- } -+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); -+ -+ if (ioctl(m, TIOCSPTLCK, &n) || ioctl (m, TIOCGPTN, &n)) -+ goto fail; - - if (!name) name = buf; - snprintf(name, sizeof buf, "/dev/pts/%d", n); -- if ((*s = open(name, O_RDWR|O_NOCTTY)) < 0) { -- close(*m); -- return -1; -- } -+ if ((s = open(name, O_RDWR|O_NOCTTY)) < 0) -+ goto fail; -+ -+ if (tio) tcsetattr(s, TCSANOW, tio); -+ if (ws) ioctl(s, TIOCSWINSZ, ws); - -- if (tio) tcsetattr(*s, TCSANOW, tio); -- if (ws) ioctl(*s, TIOCSWINSZ, ws); -+ *pm = m; -+ *ps = s; - -+ pthread_setcancelstate(cs, 0); - return 0; -+fail: -+ close(m); -+ pthread_setcancelstate(cs, 0); -+ return -1; - } ---- a/src/misc/syslog.c -+++ b/src/misc/syslog.c -@@ -46,8 +46,12 @@ void closelog(void) - - static void __openlog() - { -- log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); -- if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr); -+ int fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); -+ if (fd < 0) return; -+ if (connect(fd, (void *)&log_addr, sizeof log_addr) < 0) -+ close(fd); -+ else -+ log_fd = fd; - } - - void openlog(const char *ident, int opt, int facility) ---- a/src/multibyte/c16rtomb.c -+++ b/src/multibyte/c16rtomb.c -@@ -4,6 +4,8 @@ - - size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps) - { -+ static unsigned internal_state; -+ if (!ps) ps = (void *)&internal_state; - unsigned *x = (unsigned *)ps; - wchar_t wc; - ---- a/src/multibyte/mbrtoc16.c -+++ b/src/multibyte/mbrtoc16.c -@@ -3,6 +3,8 @@ - - size_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps) - { -+ static unsigned internal_state; -+ if (!ps) ps = (void *)&internal_state; - unsigned *pending = (unsigned *)ps; - - if (!s) return mbrtoc16(0, "", 1, ps); ---- a/src/multibyte/mbrtoc32.c -+++ b/src/multibyte/mbrtoc32.c -@@ -3,6 +3,8 @@ - - size_t mbrtoc32(char32_t *restrict pc32, const char *restrict s, size_t n, mbstate_t *restrict ps) - { -+ static unsigned internal_state; -+ if (!ps) ps = (void *)&internal_state; - if (!s) return mbrtoc32(0, "", 1, ps); - wchar_t wc; - size_t ret = mbrtowc(&wc, s, n, ps); ---- a/src/multibyte/wcsnrtombs.c -+++ b/src/multibyte/wcsnrtombs.c -@@ -40,7 +40,7 @@ size_t wcsnrtombs(char *restrict dst, co - ws++; wn--; - /* safe - this loop runs fewer than sizeof(buf) times */ - s+=l; n-=l; -- cnt++; -+ cnt += l; - } - if (dst) *wcs = ws; - return cnt; ---- /dev/null -+++ b/src/network/ns_parse.c -@@ -0,0 +1,171 @@ -+#define _BSD_SOURCE -+#include <errno.h> -+#include <stddef.h> -+#include <resolv.h> -+#include <arpa/nameser.h> -+ -+const struct _ns_flagdata _ns_flagdata[16] = { -+ { 0x8000, 15 }, -+ { 0x7800, 11 }, -+ { 0x0400, 10 }, -+ { 0x0200, 9 }, -+ { 0x0100, 8 }, -+ { 0x0080, 7 }, -+ { 0x0040, 6 }, -+ { 0x0020, 5 }, -+ { 0x0010, 4 }, -+ { 0x000f, 0 }, -+ { 0x0000, 0 }, -+ { 0x0000, 0 }, -+ { 0x0000, 0 }, -+ { 0x0000, 0 }, -+ { 0x0000, 0 }, -+ { 0x0000, 0 }, -+}; -+ -+unsigned ns_get16(const unsigned char *cp) -+{ -+ return cp[0]<<8 | cp[1]; -+} -+ -+unsigned long ns_get32(const unsigned char *cp) -+{ -+ return (unsigned)cp[0]<<24 | cp[1]<<16 | cp[2]<<8 | cp[3]; -+} -+ -+void ns_put16(unsigned s, unsigned char *cp) -+{ -+ *cp++ = s>>8; -+ *cp++ = s; -+} -+ -+void ns_put32(unsigned long l, unsigned char *cp) -+{ -+ *cp++ = l>>24; -+ *cp++ = l>>16; -+ *cp++ = l>>8; -+ *cp++ = l; -+} -+ -+int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle) -+{ -+ int i, r; -+ -+ handle->_msg = msg; -+ handle->_eom = msg + msglen; -+ if (msglen < (2 + ns_s_max) * NS_INT16SZ) goto bad; -+ NS_GET16(handle->_id, msg); -+ NS_GET16(handle->_flags, msg); -+ for (i = 0; i < ns_s_max; i++) NS_GET16(handle->_counts[i], msg); -+ for (i = 0; i < ns_s_max; i++) { -+ if (handle->_counts[i]) { -+ handle->_sections[i] = msg; -+ r = ns_skiprr(msg, handle->_eom, i, handle->_counts[i]); -+ if (r < 0) return -1; -+ msg += r; -+ } else { -+ handle->_sections[i] = NULL; -+ } -+ } -+ if (msg != handle->_eom) goto bad; -+ handle->_sect = ns_s_max; -+ handle->_rrnum = -1; -+ handle->_msg_ptr = NULL; -+ return 0; -+bad: -+ errno = EMSGSIZE; -+ return -1; -+} -+ -+int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count) -+{ -+ const unsigned char *p = ptr; -+ int r; -+ -+ while (count--) { -+ r = dn_skipname(p, eom); -+ if (r < 0) goto bad; -+ if (r + 2 * NS_INT16SZ > eom - p) goto bad; -+ p += r + 2 * NS_INT16SZ; -+ if (section != ns_s_qd) { -+ if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad; -+ p += NS_INT32SZ; -+ NS_GET16(r, p); -+ if (r > eom - p) goto bad; -+ p += r; -+ } -+ } -+ return ptr - p; -+bad: -+ errno = EMSGSIZE; -+ return -1; -+} -+ -+int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) -+{ -+ int r; -+ -+ if (section < 0 || section >= ns_s_max) goto bad; -+ if (section != handle->_sect) { -+ handle->_sect = section; -+ handle->_rrnum = 0; -+ handle->_msg_ptr = handle->_sections[section]; -+ } -+ if (rrnum == -1) rrnum = handle->_rrnum; -+ if (rrnum < 0 || rrnum >= handle->_counts[section]) goto bad; -+ if (rrnum < handle->_rrnum) { -+ handle->_rrnum = 0; -+ handle->_msg_ptr = handle->_sections[section]; -+ } -+ if (rrnum > handle->_rrnum) { -+ r = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum); -+ if (r < 0) return -1; -+ handle->_msg_ptr += r; -+ handle->_rrnum = rrnum; -+ } -+ r = ns_name_uncompress(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME); -+ if (r < 0) return -1; -+ handle->_msg_ptr += r; -+ if (2 * NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size; -+ NS_GET16(rr->type, handle->_msg_ptr); -+ NS_GET16(rr->rr_class, handle->_msg_ptr); -+ if (section != ns_s_qd) { -+ if (NS_INT32SZ + NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size; -+ NS_GET32(rr->ttl, handle->_msg_ptr); -+ NS_GET16(rr->rdlength, handle->_msg_ptr); -+ if (rr->rdlength > handle->_eom - handle->_msg_ptr) goto size; -+ rr->rdata = handle->_msg_ptr; -+ handle->_msg_ptr += rr->rdlength; -+ } else { -+ rr->ttl = 0; -+ rr->rdlength = 0; -+ rr->rdata = NULL; -+ } -+ handle->_rrnum++; -+ if (handle->_rrnum > handle->_counts[section]) { -+ handle->_sect = section + 1; -+ if (handle->_sect == ns_s_max) { -+ handle->_rrnum = -1; -+ handle->_msg_ptr = NULL; -+ } else { -+ handle->_rrnum = 0; -+ } -+ } -+ return 0; -+bad: -+ errno = ENODEV; -+ return -1; -+size: -+ errno = EMSGSIZE; -+ return -1; -+} -+ -+int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom, -+ const unsigned char *src, char *dst, size_t dstsiz) -+{ -+ int r; -+ r = dn_expand(msg, eom, src, dst, dstsiz); -+ if (r < 0) errno = EMSGSIZE; -+ return r; -+} -+ ---- a/src/process/posix_spawn.c -+++ b/src/process/posix_spawn.c -@@ -102,8 +102,7 @@ static int child(void *args_vp) - } - switch(op->cmd) { - case FDOP_CLOSE: -- if ((ret=__syscall(SYS_close, op->fd))) -- goto fail; -+ __syscall(SYS_close, op->fd); - break; - case FDOP_DUP2: - if ((ret=__sys_dup2(op->srcfd, op->fd))<0) -@@ -137,7 +136,7 @@ static int child(void *args_vp) - fail: - /* Since sizeof errno < PIPE_BUF, the write is atomic. */ - ret = -ret; -- if (ret) while (write(p, &ret, sizeof ret) < 0); -+ if (ret) while (__syscall(SYS_write, p, &ret, sizeof ret) < 0); - _exit(127); - } - ---- a/src/regex/fnmatch.c -+++ b/src/regex/fnmatch.c -@@ -97,7 +97,13 @@ escaped: - return pat[0]; - } - --static int match_bracket(const char *p, int k) -+static int casefold(int k) -+{ -+ int c = towupper(k); -+ return c == k ? towlower(k) : c; -+} -+ -+static int match_bracket(const char *p, int k, int kfold) - { - wchar_t wc; - int inv = 0; -@@ -119,7 +125,10 @@ static int match_bracket(const char *p, - wchar_t wc2; - int l = mbtowc(&wc2, p+1, 4); - if (l < 0) return 0; -- if (wc<=wc2 && (unsigned)k-wc <= wc2-wc) return !inv; -+ if (wc <= wc2) -+ if ((unsigned)k-wc <= wc2-wc || -+ (unsigned)kfold-wc <= wc2-wc) -+ return !inv; - p += l-1; - continue; - } -@@ -132,7 +141,9 @@ static int match_bracket(const char *p, - char buf[16]; - memcpy(buf, p0, p-1-p0); - buf[p-1-p0] = 0; -- if (iswctype(k, wctype(buf))) return !inv; -+ if (iswctype(k, wctype(buf)) || -+ iswctype(kfold, wctype(buf))) -+ return !inv; - } - continue; - } -@@ -143,7 +154,7 @@ static int match_bracket(const char *p, - if (l < 0) return 0; - p += l-1; - } -- if (wc==k) return !inv; -+ if (wc==k || wc==kfold) return !inv; - } - return inv; - } -@@ -153,7 +164,7 @@ static int fnmatch_internal(const char * - const char *p, *ptail, *endpat; - const char *s, *stail, *endstr; - size_t pinc, sinc, tailcnt=0; -- int c, k; -+ int c, k, kfold; - - if (flags & FNM_PERIOD) { - if (*str == '.' && *pat != '.') -@@ -173,10 +184,11 @@ static int fnmatch_internal(const char * - return (c==END) ? 0 : FNM_NOMATCH; - str += sinc; - n -= sinc; -+ kfold = flags & FNM_CASEFOLD ? casefold(k) : k; - if (c == BRACKET) { -- if (!match_bracket(pat, k)) -+ if (!match_bracket(pat, k, kfold)) - return FNM_NOMATCH; -- } else if (c != QUESTION && k != c) { -+ } else if (c != QUESTION && k != c && kfold != c) { - return FNM_NOMATCH; - } - pat+=pinc; -@@ -233,10 +245,11 @@ static int fnmatch_internal(const char * - break; - } - s += sinc; -+ kfold = flags & FNM_CASEFOLD ? casefold(k) : k; - if (c == BRACKET) { -- if (!match_bracket(p-pinc, k)) -+ if (!match_bracket(p-pinc, k, kfold)) - return FNM_NOMATCH; -- } else if (c != QUESTION && k != c) { -+ } else if (c != QUESTION && k != c && kfold != c) { - return FNM_NOMATCH; - } - } -@@ -261,10 +274,11 @@ static int fnmatch_internal(const char * - k = str_next(s, endstr-s, &sinc); - if (!k) - return FNM_NOMATCH; -+ kfold = flags & FNM_CASEFOLD ? casefold(k) : k; - if (c == BRACKET) { -- if (!match_bracket(p-pinc, k)) -+ if (!match_bracket(p-pinc, k, kfold)) - break; -- } else if (c != QUESTION && k != c) { -+ } else if (c != QUESTION && k != c && kfold != c) { - break; - } - s += sinc; ---- a/src/sched/affinity.c -+++ b/src/sched/affinity.c -@@ -1,5 +1,6 @@ - #define _GNU_SOURCE - #include <sched.h> -+#include <string.h> - #include "pthread_impl.h" - #include "syscall.h" - -@@ -10,17 +11,23 @@ int sched_setaffinity(pid_t tid, size_t - - int pthread_setaffinity_np(pthread_t td, size_t size, const cpu_set_t *set) - { -- return syscall(SYS_sched_setaffinity, td->tid, size, set); -+ return -__syscall(SYS_sched_setaffinity, td->tid, size, set); - } - --int sched_getaffinity(pid_t tid, size_t size, cpu_set_t *set) -+static int do_getaffinity(pid_t tid, size_t size, cpu_set_t *set) - { - long ret = __syscall(SYS_sched_getaffinity, tid, size, set); -- if (ret > 0) ret = 0; -- return __syscall_ret(ret); -+ if (ret < 0) return ret; -+ if (ret < size) memset((char *)set+ret, 0, size-ret); -+ return 0; -+} -+ -+int sched_getaffinity(pid_t tid, size_t size, cpu_set_t *set) -+{ -+ return __syscall_ret(do_getaffinity(tid, size, set)); - } - - int pthread_getaffinity_np(pthread_t td, size_t size, cpu_set_t *set) - { -- return sched_getaffinity(td->tid, size, set); -+ return -do_getaffinity(td->tid, size, set); - } ---- a/src/setjmp/arm/longjmp.s -+++ b/src/setjmp/arm/longjmp.s -@@ -20,7 +20,7 @@ longjmp: - ldc p2, cr4, [ip], #48 - 2: tst r1,#0x40 - beq 2f -- ldc p11, cr8, [ip], #64 -+ .word 0xecbc8b10 /* vldmia ip!, {d8-d15} */ - 2: tst r1,#0x200 - beq 3f - ldcl p1, cr10, [ip], #8 ---- a/src/setjmp/arm/setjmp.s -+++ b/src/setjmp/arm/setjmp.s -@@ -22,7 +22,7 @@ setjmp: - stc p2, cr4, [ip], #48 - 2: tst r1,#0x40 - beq 2f -- stc p11, cr8, [ip], #64 -+ .word 0xecac8b10 /* vstmia ip!, {d8-d15} */ - 2: tst r1,#0x200 - beq 3f - stcl p1, cr10, [ip], #8 ---- a/src/signal/raise.c -+++ b/src/signal/raise.c -@@ -5,12 +5,11 @@ - - int raise(int sig) - { -- int pid, tid, ret; -+ int tid, ret; - sigset_t set; - __block_app_sigs(&set); - tid = __syscall(SYS_gettid); -- pid = __syscall(SYS_getpid); -- ret = syscall(SYS_tgkill, pid, tid, sig); -+ ret = syscall(SYS_tkill, tid, sig); - __restore_sigs(&set); - return ret; - } ---- a/src/stdio/vfprintf.c -+++ b/src/stdio/vfprintf.c -@@ -158,7 +158,7 @@ static void pop_arg(union arg *arg, int - - static void out(FILE *f, const char *s, size_t l) - { -- __fwritex((void *)s, l, f); -+ if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f); - } - - static void pad(FILE *f, char c, int w, int l, int fl) -@@ -225,7 +225,7 @@ static int fmt_fp(FILE *f, long double y - - if (!isfinite(y)) { - char *s = (t&32)?"inf":"INF"; -- if (y!=y) s=(t&32)?"nan":"NAN", pl=0; -+ if (y!=y) s=(t&32)?"nan":"NAN"; - pad(f, ' ', w, 3+pl, fl&~ZERO_PAD); - out(f, prefix, pl); - out(f, s, 3); -@@ -570,7 +570,7 @@ static int printf_core(FILE *f, const ch - if (0) { - case 'o': - a = fmt_o(arg.i, z); -- if ((fl&ALT_FORM) && arg.i) prefix+=5, pl=1; -+ if ((fl&ALT_FORM) && p<z-a+1) p=z-a+1; - } if (0) { - case 'd': case 'i': - pl=1; -@@ -656,6 +656,7 @@ int vfprintf(FILE *restrict f, const cha - int nl_type[NL_ARGMAX+1] = {0}; - union arg nl_arg[NL_ARGMAX+1]; - unsigned char internal_buf[80], *saved_buf = 0; -+ int olderr; - int ret; - - /* the copy allows passing va_list* even if va_list is an array */ -@@ -666,6 +667,8 @@ int vfprintf(FILE *restrict f, const cha - } - - FLOCK(f); -+ olderr = f->flags & F_ERR; -+ if (f->mode < 1) f->flags &= ~F_ERR; - if (!f->buf_size) { - saved_buf = f->buf; - f->wpos = f->wbase = f->buf = internal_buf; -@@ -680,6 +683,8 @@ int vfprintf(FILE *restrict f, const cha - f->buf_size = 0; - f->wpos = f->wbase = f->wend = 0; - } -+ if (f->flags & F_ERR) ret = -1; -+ f->flags |= olderr; - FUNLOCK(f); - va_end(ap2); - return ret; ---- a/src/stdio/vfwprintf.c -+++ b/src/stdio/vfwprintf.c -@@ -149,7 +149,7 @@ static void pop_arg(union arg *arg, int - - static void out(FILE *f, const wchar_t *s, size_t l) - { -- while (l--) fputwc(*s++, f); -+ while (l-- && !(f->flags & F_ERR)) fputwc(*s++, f); - } - - static int getint(wchar_t **s) { -@@ -345,6 +345,7 @@ int vfwprintf(FILE *restrict f, const wc - va_list ap2; - int nl_type[NL_ARGMAX] = {0}; - union arg nl_arg[NL_ARGMAX]; -+ int olderr; - int ret; - - /* the copy allows passing va_list* even if va_list is an array */ -@@ -356,7 +357,11 @@ int vfwprintf(FILE *restrict f, const wc - - FLOCK(f); - f->mode |= f->mode+1; -+ olderr = f->flags & F_ERR; -+ f->flags &= ~F_ERR; - ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type); -+ if (f->flags & F_ERR) ret = -1; -+ f->flags |= olderr; - FUNLOCK(f); - va_end(ap2); - return ret; ---- a/src/string/armel/memcpy.s -+++ b/src/string/armel/memcpy.s -@@ -49,113 +49,113 @@ memcpy: - * ARM ABI. Since we have to save R0, we might as well save R4 - * which we can use for better pipelining of the reads below - */ -- .fnstart -- .save {r0, r4, lr} -- stmfd sp!, {r0, r4, lr} -- /* Making room for r5-r11 which will be spilled later */ -- .pad #28 -- sub sp, sp, #28 -- -- /* it simplifies things to take care of len<4 early */ -- cmp r2, #4 -- blo copy_last_3_and_return -- -- /* compute the offset to align the source -- * offset = (4-(src&3))&3 = -src & 3 -- */ -- rsb r3, r1, #0 -- ands r3, r3, #3 -- beq src_aligned -- -- /* align source to 32 bits. We need to insert 2 instructions between -- * a ldr[b|h] and str[b|h] because byte and half-word instructions -- * stall 2 cycles. -- */ -- movs r12, r3, lsl #31 -- sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */ -- ldrmib r3, [r1], #1 -- ldrcsb r4, [r1], #1 -- ldrcsb r12,[r1], #1 -- strmib r3, [r0], #1 -- strcsb r4, [r0], #1 -- strcsb r12,[r0], #1 -+ .fnstart -+ .save {r0, r4, lr} -+ stmfd sp!, {r0, r4, lr} -+ /* Making room for r5-r11 which will be spilled later */ -+ .pad #28 -+ sub sp, sp, #28 -+ -+ /* it simplifies things to take care of len<4 early */ -+ cmp r2, #4 -+ blo copy_last_3_and_return -+ -+ /* compute the offset to align the source -+ * offset = (4-(src&3))&3 = -src & 3 -+ */ -+ rsb r3, r1, #0 -+ ands r3, r3, #3 -+ beq src_aligned -+ -+ /* align source to 32 bits. We need to insert 2 instructions between -+ * a ldr[b|h] and str[b|h] because byte and half-word instructions -+ * stall 2 cycles. -+ */ -+ movs r12, r3, lsl #31 -+ sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */ -+ .word 0x44d13001 /* ldrbmi r3, [r1], #1 */ -+ .word 0x24d14001 /* ldrbcs r4, [r1], #1 */ -+ .word 0x24d1c001 /* ldrbcs r12,[r1], #1 */ -+ .word 0x44c03001 /* strbmi r3, [r0], #1 */ -+ .word 0x24c04001 /* strbcs r4, [r0], #1 */ -+ .word 0x24c0c001 /* strbcs r12,[r0], #1 */ - - src_aligned: - - /* see if src and dst are aligned together (congruent) */ -- eor r12, r0, r1 -- tst r12, #3 -- bne non_congruent -- -- /* Use post-incriment mode for stm to spill r5-r11 to reserved stack -- * frame. Don't update sp. -- */ -- stmea sp, {r5-r11} -- -- /* align the destination to a cache-line */ -- rsb r3, r0, #0 -- ands r3, r3, #0x1C -- beq congruent_aligned32 -- cmp r3, r2 -- andhi r3, r2, #0x1C -- -- /* conditionnaly copies 0 to 7 words (length in r3) */ -- movs r12, r3, lsl #28 -- ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */ -- ldmmiia r1!, {r8, r9} /* 8 bytes */ -- stmcsia r0!, {r4, r5, r6, r7} -- stmmiia r0!, {r8, r9} -- tst r3, #0x4 -- ldrne r10,[r1], #4 /* 4 bytes */ -- strne r10,[r0], #4 -- sub r2, r2, r3 -+ eor r12, r0, r1 -+ tst r12, #3 -+ bne non_congruent -+ -+ /* Use post-incriment mode for stm to spill r5-r11 to reserved stack -+ * frame. Don't update sp. -+ */ -+ stmea sp, {r5-r11} -+ -+ /* align the destination to a cache-line */ -+ rsb r3, r0, #0 -+ ands r3, r3, #0x1C -+ beq congruent_aligned32 -+ cmp r3, r2 -+ andhi r3, r2, #0x1C -+ -+ /* conditionnaly copies 0 to 7 words (length in r3) */ -+ movs r12, r3, lsl #28 -+ ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */ -+ ldmmi r1!, {r8, r9} /* 8 bytes */ -+ stmcs r0!, {r4, r5, r6, r7} -+ stmmi r0!, {r8, r9} -+ tst r3, #0x4 -+ ldrne r10,[r1], #4 /* 4 bytes */ -+ strne r10,[r0], #4 -+ sub r2, r2, r3 - - congruent_aligned32: - /* -- * here source is aligned to 32 bytes. -- */ -+ * here source is aligned to 32 bytes. -+ */ - - cached_aligned32: -- subs r2, r2, #32 -- blo less_than_32_left -+ subs r2, r2, #32 -+ blo less_than_32_left - -- /* -- * We preload a cache-line up to 64 bytes ahead. On the 926, this will -- * stall only until the requested world is fetched, but the linefill -- * continues in the the background. -- * While the linefill is going, we write our previous cache-line -- * into the write-buffer (which should have some free space). -- * When the linefill is done, the writebuffer will -- * start dumping its content into memory -- * -- * While all this is going, we then load a full cache line into -- * 8 registers, this cache line should be in the cache by now -- * (or partly in the cache). -- * -- * This code should work well regardless of the source/dest alignment. -- * -- */ -- -- /* Align the preload register to a cache-line because the cpu does -- * "critical word first" (the first word requested is loaded first). -- */ -- @ bic r12, r1, #0x1F -- @ add r12, r12, #64 -- --1: ldmia r1!, { r4-r11 } -- subs r2, r2, #32 -- -- /* -- * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi -- * for ARM9 preload will not be safely guarded by the preceding subs. -- * When it is safely guarded the only possibility to have SIGSEGV here -- * is because the caller overstates the length. -- */ -- @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */ -- stmia r0!, { r4-r11 } -- bhs 1b -+ /* -+ * We preload a cache-line up to 64 bytes ahead. On the 926, this will -+ * stall only until the requested world is fetched, but the linefill -+ * continues in the the background. -+ * While the linefill is going, we write our previous cache-line -+ * into the write-buffer (which should have some free space). -+ * When the linefill is done, the writebuffer will -+ * start dumping its content into memory -+ * -+ * While all this is going, we then load a full cache line into -+ * 8 registers, this cache line should be in the cache by now -+ * (or partly in the cache). -+ * -+ * This code should work well regardless of the source/dest alignment. -+ * -+ */ - -- add r2, r2, #32 -+ /* Align the preload register to a cache-line because the cpu does -+ * "critical word first" (the first word requested is loaded first). -+ */ -+ @ bic r12, r1, #0x1F -+ @ add r12, r12, #64 -+ -+1: ldmia r1!, { r4-r11 } -+ subs r2, r2, #32 -+ -+ /* -+ * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi -+ * for ARM9 preload will not be safely guarded by the preceding subs. -+ * When it is safely guarded the only possibility to have SIGSEGV here -+ * is because the caller overstates the length. -+ */ -+ @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */ -+ stmia r0!, { r4-r11 } -+ bhs 1b -+ -+ add r2, r2, #32 - - less_than_32_left: - /* -@@ -166,30 +166,30 @@ less_than_32_left: - * be a common case (if not executed the code below takes - * about 16 cycles) - */ -- tst r2, #0x1F -- beq 1f -+ tst r2, #0x1F -+ beq 1f - -- /* conditionnaly copies 0 to 31 bytes */ -- movs r12, r2, lsl #28 -- ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */ -- ldmmiia r1!, {r8, r9} /* 8 bytes */ -- stmcsia r0!, {r4, r5, r6, r7} -- stmmiia r0!, {r8, r9} -- movs r12, r2, lsl #30 -- ldrcs r3, [r1], #4 /* 4 bytes */ -- ldrmih r4, [r1], #2 /* 2 bytes */ -- strcs r3, [r0], #4 -- strmih r4, [r0], #2 -- tst r2, #0x1 -- ldrneb r3, [r1] /* last byte */ -- strneb r3, [r0] -- -- /* we're done! restore everything and return */ --1: ldmfd sp!, {r5-r11} -- ldmfd sp!, {r0, r4, lr} -- tst lr, #1 -- moveq pc, lr -- bx lr -+ /* conditionnaly copies 0 to 31 bytes */ -+ movs r12, r2, lsl #28 -+ ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */ -+ ldmmi r1!, {r8, r9} /* 8 bytes */ -+ stmcs r0!, {r4, r5, r6, r7} -+ stmmi r0!, {r8, r9} -+ movs r12, r2, lsl #30 -+ ldrcs r3, [r1], #4 /* 4 bytes */ -+ .word 0x40d140b2 /* ldrhmi r4, [r1], #2 */ /* 2 bytes */ -+ strcs r3, [r0], #4 -+ .word 0x40c040b2 /* strhmi r4, [r0], #2 */ -+ tst r2, #0x1 -+ .word 0x15d13000 /* ldrbne r3, [r1] */ /* last byte */ -+ .word 0x15c03000 /* strbne r3, [r0] */ -+ -+ /* we're done! restore everything and return */ -+1: ldmfd sp!, {r5-r11} -+ ldmfd sp!, {r0, r4, lr} -+ tst lr, #1 -+ moveq pc, lr -+ bx lr - - /********************************************************************/ - -@@ -202,180 +202,180 @@ non_congruent: - * (the number of bytes written is always smaller, because we have - * partial words in the shift queue) - */ -- cmp r2, #4 -- blo copy_last_3_and_return -+ cmp r2, #4 -+ blo copy_last_3_and_return - -- /* Use post-incriment mode for stm to spill r5-r11 to reserved stack -- * frame. Don't update sp. -- */ -- stmea sp, {r5-r11} -- -- /* compute shifts needed to align src to dest */ -- rsb r5, r0, #0 -- and r5, r5, #3 /* r5 = # bytes in partial words */ -- mov r12, r5, lsl #3 /* r12 = right */ -- rsb lr, r12, #32 /* lr = left */ -- -- /* read the first word */ -- ldr r3, [r1], #4 -- sub r2, r2, #4 -- -- /* write a partial word (0 to 3 bytes), such that destination -- * becomes aligned to 32 bits (r5 = nb of words to copy for alignment) -- */ -- movs r5, r5, lsl #31 -- strmib r3, [r0], #1 -- movmi r3, r3, lsr #8 -- strcsb r3, [r0], #1 -- movcs r3, r3, lsr #8 -- strcsb r3, [r0], #1 -- movcs r3, r3, lsr #8 -- -- cmp r2, #4 -- blo partial_word_tail -- -- /* Align destination to 32 bytes (cache line boundary) */ --1: tst r0, #0x1c -- beq 2f -- ldr r5, [r1], #4 -- sub r2, r2, #4 -- orr r4, r3, r5, lsl lr -- mov r3, r5, lsr r12 -- str r4, [r0], #4 -- cmp r2, #4 -- bhs 1b -- blo partial_word_tail -+ /* Use post-incriment mode for stm to spill r5-r11 to reserved stack -+ * frame. Don't update sp. -+ */ -+ stmea sp, {r5-r11} -+ -+ /* compute shifts needed to align src to dest */ -+ rsb r5, r0, #0 -+ and r5, r5, #3 /* r5 = # bytes in partial words */ -+ mov r12, r5, lsl #3 /* r12 = right */ -+ rsb lr, r12, #32 /* lr = left */ -+ -+ /* read the first word */ -+ ldr r3, [r1], #4 -+ sub r2, r2, #4 -+ -+ /* write a partial word (0 to 3 bytes), such that destination -+ * becomes aligned to 32 bits (r5 = nb of words to copy for alignment) -+ */ -+ movs r5, r5, lsl #31 -+ .word 0x44c03001 /* strbmi r3, [r0], #1 */ -+ movmi r3, r3, lsr #8 -+ .word 0x24c03001 /* strbcs r3, [r0], #1 */ -+ movcs r3, r3, lsr #8 -+ .word 0x24c03001 /* strbcs r3, [r0], #1 */ -+ movcs r3, r3, lsr #8 -+ -+ cmp r2, #4 -+ blo partial_word_tail -+ -+ /* Align destination to 32 bytes (cache line boundary) */ -+1: tst r0, #0x1c -+ beq 2f -+ ldr r5, [r1], #4 -+ sub r2, r2, #4 -+ orr r4, r3, r5, lsl lr -+ mov r3, r5, lsr r12 -+ str r4, [r0], #4 -+ cmp r2, #4 -+ bhs 1b -+ blo partial_word_tail - - /* copy 32 bytes at a time */ --2: subs r2, r2, #32 -- blo less_than_thirtytwo -+2: subs r2, r2, #32 -+ blo less_than_thirtytwo -+ -+ /* Use immediate mode for the shifts, because there is an extra cycle -+ * for register shifts, which could account for up to 50% of -+ * performance hit. -+ */ - -- /* Use immediate mode for the shifts, because there is an extra cycle -- * for register shifts, which could account for up to 50% of -- * performance hit. -- */ -- -- cmp r12, #24 -- beq loop24 -- cmp r12, #8 -- beq loop8 -+ cmp r12, #24 -+ beq loop24 -+ cmp r12, #8 -+ beq loop8 - - loop16: -- ldr r12, [r1], #4 --1: mov r4, r12 -- ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} -- subs r2, r2, #32 -- ldrhs r12, [r1], #4 -- orr r3, r3, r4, lsl #16 -- mov r4, r4, lsr #16 -- orr r4, r4, r5, lsl #16 -- mov r5, r5, lsr #16 -- orr r5, r5, r6, lsl #16 -- mov r6, r6, lsr #16 -- orr r6, r6, r7, lsl #16 -- mov r7, r7, lsr #16 -- orr r7, r7, r8, lsl #16 -- mov r8, r8, lsr #16 -- orr r8, r8, r9, lsl #16 -- mov r9, r9, lsr #16 -- orr r9, r9, r10, lsl #16 -- mov r10, r10, lsr #16 -- orr r10, r10, r11, lsl #16 -- stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} -- mov r3, r11, lsr #16 -- bhs 1b -- b less_than_thirtytwo -+ ldr r12, [r1], #4 -+1: mov r4, r12 -+ ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} -+ subs r2, r2, #32 -+ ldrhs r12, [r1], #4 -+ orr r3, r3, r4, lsl #16 -+ mov r4, r4, lsr #16 -+ orr r4, r4, r5, lsl #16 -+ mov r5, r5, lsr #16 -+ orr r5, r5, r6, lsl #16 -+ mov r6, r6, lsr #16 -+ orr r6, r6, r7, lsl #16 -+ mov r7, r7, lsr #16 -+ orr r7, r7, r8, lsl #16 -+ mov r8, r8, lsr #16 -+ orr r8, r8, r9, lsl #16 -+ mov r9, r9, lsr #16 -+ orr r9, r9, r10, lsl #16 -+ mov r10, r10, lsr #16 -+ orr r10, r10, r11, lsl #16 -+ stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} -+ mov r3, r11, lsr #16 -+ bhs 1b -+ b less_than_thirtytwo - - loop8: -- ldr r12, [r1], #4 --1: mov r4, r12 -- ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} -- subs r2, r2, #32 -- ldrhs r12, [r1], #4 -- orr r3, r3, r4, lsl #24 -- mov r4, r4, lsr #8 -- orr r4, r4, r5, lsl #24 -- mov r5, r5, lsr #8 -- orr r5, r5, r6, lsl #24 -- mov r6, r6, lsr #8 -- orr r6, r6, r7, lsl #24 -- mov r7, r7, lsr #8 -- orr r7, r7, r8, lsl #24 -- mov r8, r8, lsr #8 -- orr r8, r8, r9, lsl #24 -- mov r9, r9, lsr #8 -- orr r9, r9, r10, lsl #24 -- mov r10, r10, lsr #8 -- orr r10, r10, r11, lsl #24 -- stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} -- mov r3, r11, lsr #8 -- bhs 1b -- b less_than_thirtytwo -+ ldr r12, [r1], #4 -+1: mov r4, r12 -+ ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} -+ subs r2, r2, #32 -+ ldrhs r12, [r1], #4 -+ orr r3, r3, r4, lsl #24 -+ mov r4, r4, lsr #8 -+ orr r4, r4, r5, lsl #24 -+ mov r5, r5, lsr #8 -+ orr r5, r5, r6, lsl #24 -+ mov r6, r6, lsr #8 -+ orr r6, r6, r7, lsl #24 -+ mov r7, r7, lsr #8 -+ orr r7, r7, r8, lsl #24 -+ mov r8, r8, lsr #8 -+ orr r8, r8, r9, lsl #24 -+ mov r9, r9, lsr #8 -+ orr r9, r9, r10, lsl #24 -+ mov r10, r10, lsr #8 -+ orr r10, r10, r11, lsl #24 -+ stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} -+ mov r3, r11, lsr #8 -+ bhs 1b -+ b less_than_thirtytwo - - loop24: -- ldr r12, [r1], #4 --1: mov r4, r12 -- ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} -- subs r2, r2, #32 -- ldrhs r12, [r1], #4 -- orr r3, r3, r4, lsl #8 -- mov r4, r4, lsr #24 -- orr r4, r4, r5, lsl #8 -- mov r5, r5, lsr #24 -- orr r5, r5, r6, lsl #8 -- mov r6, r6, lsr #24 -- orr r6, r6, r7, lsl #8 -- mov r7, r7, lsr #24 -- orr r7, r7, r8, lsl #8 -- mov r8, r8, lsr #24 -- orr r8, r8, r9, lsl #8 -- mov r9, r9, lsr #24 -- orr r9, r9, r10, lsl #8 -- mov r10, r10, lsr #24 -- orr r10, r10, r11, lsl #8 -- stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} -- mov r3, r11, lsr #24 -- bhs 1b -+ ldr r12, [r1], #4 -+1: mov r4, r12 -+ ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} -+ subs r2, r2, #32 -+ ldrhs r12, [r1], #4 -+ orr r3, r3, r4, lsl #8 -+ mov r4, r4, lsr #24 -+ orr r4, r4, r5, lsl #8 -+ mov r5, r5, lsr #24 -+ orr r5, r5, r6, lsl #8 -+ mov r6, r6, lsr #24 -+ orr r6, r6, r7, lsl #8 -+ mov r7, r7, lsr #24 -+ orr r7, r7, r8, lsl #8 -+ mov r8, r8, lsr #24 -+ orr r8, r8, r9, lsl #8 -+ mov r9, r9, lsr #24 -+ orr r9, r9, r10, lsl #8 -+ mov r10, r10, lsr #24 -+ orr r10, r10, r11, lsl #8 -+ stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} -+ mov r3, r11, lsr #24 -+ bhs 1b - - less_than_thirtytwo: - /* copy the last 0 to 31 bytes of the source */ -- rsb r12, lr, #32 /* we corrupted r12, recompute it */ -- add r2, r2, #32 -- cmp r2, #4 -- blo partial_word_tail -- --1: ldr r5, [r1], #4 -- sub r2, r2, #4 -- orr r4, r3, r5, lsl lr -- mov r3, r5, lsr r12 -- str r4, [r0], #4 -- cmp r2, #4 -- bhs 1b -+ rsb r12, lr, #32 /* we corrupted r12, recompute it */ -+ add r2, r2, #32 -+ cmp r2, #4 -+ blo partial_word_tail -+ -+1: ldr r5, [r1], #4 -+ sub r2, r2, #4 -+ orr r4, r3, r5, lsl lr -+ mov r3, r5, lsr r12 -+ str r4, [r0], #4 -+ cmp r2, #4 -+ bhs 1b - - partial_word_tail: - /* we have a partial word in the input buffer */ -- movs r5, lr, lsl #(31-3) -- strmib r3, [r0], #1 -- movmi r3, r3, lsr #8 -- strcsb r3, [r0], #1 -- movcs r3, r3, lsr #8 -- strcsb r3, [r0], #1 -+ movs r5, lr, lsl #(31-3) -+ .word 0x44c03001 /* strbmi r3, [r0], #1 */ -+ movmi r3, r3, lsr #8 -+ .word 0x24c03001 /* strbcs r3, [r0], #1 */ -+ movcs r3, r3, lsr #8 -+ .word 0x24c03001 /* strbcs r3, [r0], #1 */ - -- /* Refill spilled registers from the stack. Don't update sp. */ -- ldmfd sp, {r5-r11} -+ /* Refill spilled registers from the stack. Don't update sp. */ -+ ldmfd sp, {r5-r11} - - copy_last_3_and_return: -- movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */ -- ldrmib r2, [r1], #1 -- ldrcsb r3, [r1], #1 -- ldrcsb r12,[r1] -- strmib r2, [r0], #1 -- strcsb r3, [r0], #1 -- strcsb r12,[r0] -- -- /* we're done! restore sp and spilled registers and return */ -- add sp, sp, #28 -- ldmfd sp!, {r0, r4, lr} -- tst lr, #1 -- moveq pc, lr -- bx lr -+ movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */ -+ .word 0x44d12001 /* ldrbmi r2, [r1], #1 */ -+ .word 0x24d13001 /* ldrbcs r3, [r1], #1 */ -+ .word 0x25d1c000 /* ldrbcs r12,[r1] */ -+ .word 0x44c02001 /* strbmi r2, [r0], #1 */ -+ .word 0x24c03001 /* strbcs r3, [r0], #1 */ -+ .word 0x25c0c000 /* strbcs r12,[r0] */ -+ -+ /* we're done! restore sp and spilled registers and return */ -+ add sp, sp, #28 -+ ldmfd sp!, {r0, r4, lr} -+ tst lr, #1 -+ moveq pc, lr -+ bx lr ---- a/src/thread/arm/__set_thread_area.s -+++ b/src/thread/arm/__set_thread_area.s -@@ -1,12 +1 @@ --.text --.global __set_thread_area --.type __set_thread_area,%function --__set_thread_area: -- mov r1,r7 -- mov r7,#0x0f0000 -- add r7,r7,#5 -- svc 0 -- mov r7,r1 -- tst lr,#1 -- moveq pc,lr -- bx lr -+/* Replaced by C code in arch/arm/src */ ---- a/src/thread/arm/tls.s -+++ /dev/null -@@ -1,4 +0,0 @@ --.global __aeabi_read_tp --.type __aeabi_read_tp,%function --__aeabi_read_tp: -- ldr pc,=0xffff0fe0 ---- a/src/thread/pthread_once.c -+++ b/src/thread/pthread_once.c -@@ -8,15 +8,8 @@ static void undo(void *control) - __wake(control, -1, 1); - } - --int __pthread_once(pthread_once_t *control, void (*init)(void)) -+int __pthread_once_full(pthread_once_t *control, void (*init)(void)) - { -- /* Return immediately if init finished before, but ensure that -- * effects of the init routine are visible to the caller. */ -- if (*control == 2) { -- a_barrier(); -- return 0; -- } -- - /* Try to enter initializing state. Four possibilities: - * 0 - we're the first or the other cancelled; run init - * 1 - another thread is running init; wait -@@ -43,4 +36,15 @@ int __pthread_once(pthread_once_t *contr - } - } - -+int __pthread_once(pthread_once_t *control, void (*init)(void)) -+{ -+ /* Return immediately if init finished before, but ensure that -+ * effects of the init routine are visible to the caller. */ -+ if (*control == 2) { -+ a_barrier(); -+ return 0; -+ } -+ return __pthread_once_full(control, init); -+} -+ - weak_alias(__pthread_once, pthread_once); |