musl: merge changes from git, includes further getopt fixes
[openwrt.git] / toolchain / musl / patches / 000-git-2015-01-09.patch
1 --- a/arch/arm/atomic.h
2 +++ b/arch/arm/atomic.h
3 @@ -22,37 +22,150 @@ static inline int a_ctz_64(uint64_t x)
4         return a_ctz_l(y);
5  }
6  
7 -#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__) && !__thumb__) \
8 - || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
9 -
10  #if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ ||  __ARM_ARCH >= 7
11 -#define MEM_BARRIER "dmb ish"
12 -#else
13 -#define MEM_BARRIER "mcr p15,0,r0,c7,c10,5"
14 -#endif
15  
16 -static inline int __k_cas(int t, int s, volatile int *p)
17 +static inline void a_barrier()
18  {
19 -       int ret;
20 -       __asm__(
21 -               "       " MEM_BARRIER "\n"
22 +       __asm__ __volatile__("dmb ish");
23 +}
24 +
25 +static inline int a_cas(volatile int *p, int t, int s)
26 +{
27 +       int old;
28 +       __asm__ __volatile__(
29 +               "       dmb ish\n"
30                 "1:     ldrex %0,%3\n"
31 -               "       subs %0,%0,%1\n"
32 -#ifdef __thumb__
33 -               "       itt eq\n"
34 -#endif
35 -               "       strexeq %0,%2,%3\n"
36 -               "       teqeq %0,#1\n"
37 -               "       beq 1b\n"
38 -               "       " MEM_BARRIER "\n"
39 -               : "=&r"(ret)
40 +               "       cmp %0,%1\n"
41 +               "       bne 1f\n"
42 +               "       strex %0,%2,%3\n"
43 +               "       cmp %0, #0\n"
44 +               "       bne 1b\n"
45 +               "       mov %0, %1\n"
46 +               "1:     dmb ish\n"
47 +               : "=&r"(old)
48                 : "r"(t), "r"(s), "Q"(*p)
49                 : "memory", "cc" );
50 -       return ret;
51 +       return old;
52 +}
53 +
54 +static inline int a_swap(volatile int *x, int v)
55 +{
56 +       int old, tmp;
57 +       __asm__ __volatile__(
58 +               "       dmb ish\n"
59 +               "1:     ldrex %0,%3\n"
60 +               "       strex %1,%2,%3\n"
61 +               "       cmp %1, #0\n"
62 +               "       bne 1b\n"
63 +               "       dmb ish\n"
64 +               : "=&r"(old), "=&r"(tmp)
65 +               : "r"(v), "Q"(*x)
66 +               : "memory", "cc" );
67 +       return old;
68 +}
69 +
70 +static inline int a_fetch_add(volatile int *x, int v)
71 +{
72 +       int old, tmp;
73 +       __asm__ __volatile__(
74 +               "       dmb ish\n"
75 +               "1:     ldrex %0,%3\n"
76 +               "       add %0,%0,%2\n"
77 +               "       strex %1,%0,%3\n"
78 +               "       cmp %1, #0\n"
79 +               "       bne 1b\n"
80 +               "       dmb ish\n"
81 +               : "=&r"(old), "=&r"(tmp)
82 +               : "r"(v), "Q"(*x)
83 +               : "memory", "cc" );
84 +       return old-v;
85 +}
86 +
87 +static inline void a_inc(volatile int *x)
88 +{
89 +       int tmp, tmp2;
90 +       __asm__ __volatile__(
91 +               "       dmb ish\n"
92 +               "1:     ldrex %0,%2\n"
93 +               "       add %0,%0,#1\n"
94 +               "       strex %1,%0,%2\n"
95 +               "       cmp %1, #0\n"
96 +               "       bne 1b\n"
97 +               "       dmb ish\n"
98 +               : "=&r"(tmp), "=&r"(tmp2)
99 +               : "Q"(*x)
100 +               : "memory", "cc" );
101 +}
102 +
103 +static inline void a_dec(volatile int *x)
104 +{
105 +       int tmp, tmp2;
106 +       __asm__ __volatile__(
107 +               "       dmb ish\n"
108 +               "1:     ldrex %0,%2\n"
109 +               "       sub %0,%0,#1\n"
110 +               "       strex %1,%0,%2\n"
111 +               "       cmp %1, #0\n"
112 +               "       bne 1b\n"
113 +               "       dmb ish\n"
114 +               : "=&r"(tmp), "=&r"(tmp2)
115 +               : "Q"(*x)
116 +               : "memory", "cc" );
117 +}
118 +
119 +static inline void a_and(volatile int *x, int v)
120 +{
121 +       int tmp, tmp2;
122 +       __asm__ __volatile__(
123 +               "       dmb ish\n"
124 +               "1:     ldrex %0,%3\n"
125 +               "       and %0,%0,%2\n"
126 +               "       strex %1,%0,%3\n"
127 +               "       cmp %1, #0\n"
128 +               "       bne 1b\n"
129 +               "       dmb ish\n"
130 +               : "=&r"(tmp), "=&r"(tmp2)
131 +               : "r"(v), "Q"(*x)
132 +               : "memory", "cc" );
133 +}
134 +
135 +static inline void a_or(volatile int *x, int v)
136 +{
137 +       int tmp, tmp2;
138 +       __asm__ __volatile__(
139 +               "       dmb ish\n"
140 +               "1:     ldrex %0,%3\n"
141 +               "       orr %0,%0,%2\n"
142 +               "       strex %1,%0,%3\n"
143 +               "       cmp %1, #0\n"
144 +               "       bne 1b\n"
145 +               "       dmb ish\n"
146 +               : "=&r"(tmp), "=&r"(tmp2)
147 +               : "r"(v), "Q"(*x)
148 +               : "memory", "cc" );
149 +}
150 +
151 +static inline void a_store(volatile int *p, int x)
152 +{
153 +       __asm__ __volatile__(
154 +               "       dmb ish\n"
155 +               "       str %1,%0\n"
156 +               "       dmb ish\n"
157 +               : "=m"(*p)
158 +               : "r"(x)
159 +               : "memory", "cc" );
160  }
161 +
162  #else
163 -#define __k_cas ((int (*)(int, int, volatile int *))0xffff0fc0)
164 -#endif
165 +
166 +int __a_cas(int, int, volatile int *) __attribute__((__visibility__("hidden")));
167 +#define __k_cas __a_cas
168 +
169 +static inline void a_barrier()
170 +{
171 +       __asm__ __volatile__("bl __a_barrier"
172 +               : : : "memory", "cc", "ip", "lr" );
173 +}
174  
175  static inline int a_cas(volatile int *p, int t, int s)
176  {
177 @@ -65,11 +178,6 @@ static inline int a_cas(volatile int *p,
178         }
179  }
180  
181 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
182 -{
183 -       return (void *)a_cas(p, (int)t, (int)s);
184 -}
185 -
186  static inline int a_swap(volatile int *x, int v)
187  {
188         int old;
189 @@ -98,19 +206,9 @@ static inline void a_dec(volatile int *x
190  
191  static inline void a_store(volatile int *p, int x)
192  {
193 -       while (__k_cas(*p, x, p));
194 -}
195 -
196 -#define a_spin a_barrier
197 -
198 -static inline void a_barrier()
199 -{
200 -       __k_cas(0, 0, &(int){0});
201 -}
202 -
203 -static inline void a_crash()
204 -{
205 -       *(volatile char *)0=0;
206 +       a_barrier();
207 +       *p = x;
208 +       a_barrier();
209  }
210  
211  static inline void a_and(volatile int *p, int v)
212 @@ -127,6 +225,20 @@ static inline void a_or(volatile int *p,
213         while (__k_cas(old, old|v, p));
214  }
215  
216 +#endif
217 +
218 +static inline void *a_cas_p(volatile void *p, void *t, void *s)
219 +{
220 +       return (void *)a_cas(p, (int)t, (int)s);
221 +}
222 +
223 +#define a_spin a_barrier
224 +
225 +static inline void a_crash()
226 +{
227 +       *(volatile char *)0=0;
228 +}
229 +
230  static inline void a_or_l(volatile void *p, long v)
231  {
232         a_or(p, v);
233 --- a/arch/arm/bits/alltypes.h.in
234 +++ b/arch/arm/bits/alltypes.h.in
235 @@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list
236  #ifndef __cplusplus
237  TYPEDEF unsigned wchar_t;
238  #endif
239 -TYPEDEF unsigned wint_t;
240  
241  TYPEDEF float float_t;
242  TYPEDEF double double_t;
243 --- a/arch/arm/bits/syscall.h
244 +++ b/arch/arm/bits/syscall.h
245 @@ -339,7 +339,13 @@
246  #define __NR_seccomp   383
247  #define __NR_getrandom 384
248  #define __NR_memfd_create      385
249 +#define __NR_bpf       386
250  
251 +#define __ARM_NR_breakpoint    0x0f0001
252 +#define __ARM_NR_cacheflush    0x0f0002
253 +#define __ARM_NR_usr26         0x0f0003
254 +#define __ARM_NR_usr32         0x0f0004
255 +#define __ARM_NR_set_tls       0x0f0005
256  
257  /* Repeated with SYS_ prefix */
258  
259 @@ -684,3 +690,4 @@
260  #define SYS_seccomp    383
261  #define SYS_getrandom  384
262  #define SYS_memfd_create       385
263 +#define SYS_bpf        386
264 --- a/arch/arm/pthread_arch.h
265 +++ b/arch/arm/pthread_arch.h
266 @@ -10,9 +10,17 @@ static inline __attribute__((const)) pth
267  
268  #else
269  
270 -typedef char *(*__ptr_func_t)(void) __attribute__((const));
271 -#define __pthread_self() \
272 -       ((pthread_t)(((__ptr_func_t)0xffff0fe0)()+8-sizeof(struct pthread)))
273 +static inline __attribute__((const)) pthread_t __pthread_self()
274 +{
275 +#ifdef __clang__
276 +       char *p;
277 +       __asm__( "bl __a_gettp\n\tmov %0,r0" : "=r"(p) : : "cc", "r0", "lr" );
278 +#else
279 +       register char *p __asm__("r0");
280 +       __asm__( "bl __a_gettp" : "=r"(p) : : "cc", "lr" );
281 +#endif
282 +       return (void *)(p+8-sizeof(struct pthread));
283 +}
284  
285  #endif
286  
287 --- /dev/null
288 +++ b/arch/arm/src/__set_thread_area.c
289 @@ -0,0 +1,49 @@
290 +#include <stdint.h>
291 +#include <elf.h>
292 +#include "pthread_impl.h"
293 +#include "libc.h"
294 +
295 +#define HWCAP_TLS (1 << 15)
296 +
297 +extern const unsigned char __attribute__((__visibility__("hidden")))
298 +       __a_barrier_dummy[], __a_barrier_oldkuser[],
299 +       __a_barrier_v6[], __a_barrier_v7[],
300 +       __a_cas_dummy[], __a_cas_v6[], __a_cas_v7[],
301 +       __a_gettp_dummy[];
302 +
303 +#define __a_barrier_kuser 0xffff0fa0
304 +#define __a_cas_kuser 0xffff0fc0
305 +#define __a_gettp_kuser 0xffff0fe0
306 +
307 +extern uintptr_t __attribute__((__visibility__("hidden")))
308 +       __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;
309 +
310 +#define SET(op,ver) (__a_##op##_ptr = \
311 +       (uintptr_t)__a_##op##_##ver - (uintptr_t)__a_##op##_dummy)
312 +
313 +int __set_thread_area(void *p)
314 +{
315 +#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
316 +       if (__hwcap & HWCAP_TLS) {
317 +               size_t *aux;
318 +               SET(cas, v7);
319 +               SET(barrier, v7);
320 +               for (aux=libc.auxv; *aux; aux+=2) {
321 +                       if (*aux != AT_PLATFORM) continue;
322 +                       const char *s = (void *)aux[1];
323 +                       if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;
324 +                       SET(cas, v6);
325 +                       SET(barrier, v6);
326 +                       break;
327 +               }
328 +       } else {
329 +               int ver = *(int *)0xffff0ffc;
330 +               SET(gettp, kuser);
331 +               SET(cas, kuser);
332 +               SET(barrier, kuser);
333 +               if (ver < 2) a_crash();
334 +               if (ver < 3) SET(barrier, oldkuser);
335 +       }
336 +#endif
337 +       return __syscall(0xf0005, p);
338 +}
339 --- /dev/null
340 +++ b/arch/arm/src/arm/atomics.s
341 @@ -0,0 +1,116 @@
342 +.text
343 +
344 +.global __a_barrier
345 +.hidden __a_barrier
346 +.type __a_barrier,%function
347 +__a_barrier:
348 +       ldr ip,1f
349 +       ldr ip,[pc,ip]
350 +       add pc,pc,ip
351 +1:     .word __a_barrier_ptr-1b
352 +.global __a_barrier_dummy
353 +.hidden __a_barrier_dummy
354 +__a_barrier_dummy:
355 +       tst lr,#1
356 +       moveq pc,lr
357 +       bx lr
358 +.global __a_barrier_oldkuser
359 +.hidden __a_barrier_oldkuser
360 +__a_barrier_oldkuser:
361 +       push {r0,r1,r2,r3,ip,lr}
362 +       mov r1,r0
363 +       mov r2,sp
364 +       ldr ip,=0xffff0fc0
365 +       mov lr,pc
366 +       mov pc,ip
367 +       pop {r0,r1,r2,r3,ip,lr}
368 +       tst lr,#1
369 +       moveq pc,lr
370 +       bx lr
371 +.global __a_barrier_v6
372 +.hidden __a_barrier_v6
373 +__a_barrier_v6:
374 +       mcr p15,0,r0,c7,c10,5
375 +       bx lr
376 +.global __a_barrier_v7
377 +.hidden __a_barrier_v7
378 +__a_barrier_v7:
379 +       .word 0xf57ff05b        /* dmb ish */
380 +       bx lr
381 +
382 +.global __a_cas
383 +.hidden __a_cas
384 +.type __a_cas,%function
385 +__a_cas:
386 +       ldr ip,1f
387 +       ldr ip,[pc,ip]
388 +       add pc,pc,ip
389 +1:     .word __a_cas_ptr-1b
390 +.global __a_cas_dummy
391 +.hidden __a_cas_dummy
392 +__a_cas_dummy:
393 +       mov r3,r0
394 +       ldr r0,[r2]
395 +       subs r0,r3,r0
396 +       streq r1,[r2]
397 +       tst lr,#1
398 +       moveq pc,lr
399 +       bx lr
400 +.global __a_cas_v6
401 +.hidden __a_cas_v6
402 +__a_cas_v6:
403 +       mov r3,r0
404 +       mcr p15,0,r0,c7,c10,5
405 +1:     .word 0xe1920f9f        /* ldrex r0,[r2] */
406 +       subs r0,r3,r0
407 +       .word 0x01820f91        /* strexeq r0,r1,[r2] */
408 +       teqeq r0,#1
409 +       beq 1b
410 +       mcr p15,0,r0,c7,c10,5
411 +       bx lr
412 +.global __a_cas_v7
413 +.hidden __a_cas_v7
414 +__a_cas_v7:
415 +       mov r3,r0
416 +       .word 0xf57ff05b        /* dmb ish */
417 +1:     .word 0xe1920f9f        /* ldrex r0,[r2] */
418 +       subs r0,r3,r0
419 +       .word 0x01820f91        /* strexeq r0,r1,[r2] */
420 +       teqeq r0,#1
421 +       beq 1b
422 +       .word 0xf57ff05b        /* dmb ish */
423 +       bx lr
424 +
425 +.global __aeabi_read_tp
426 +.type __aeabi_read_tp,%function
427 +__aeabi_read_tp:
428 +
429 +.global __a_gettp
430 +.hidden __a_gettp
431 +.type __a_gettp,%function
432 +__a_gettp:
433 +       ldr r0,1f
434 +       ldr r0,[pc,r0]
435 +       add pc,pc,r0
436 +1:     .word __a_gettp_ptr-1b
437 +.global __a_gettp_dummy
438 +.hidden __a_gettp_dummy
439 +__a_gettp_dummy:
440 +       mrc p15,0,r0,c13,c0,3
441 +       bx lr
442 +
443 +.data
444 +.global __a_barrier_ptr
445 +.hidden __a_barrier_ptr
446 +__a_barrier_ptr:
447 +       .word 0
448 +
449 +.global __a_cas_ptr
450 +.hidden __a_cas_ptr
451 +__a_cas_ptr:
452 +       .word 0
453 +
454 +.global __a_gettp_ptr
455 +.hidden __a_gettp_ptr
456 +__a_gettp_ptr:
457 +       .word 0
458 --- a/arch/arm/syscall_arch.h
459 +++ b/arch/arm/syscall_arch.h
460 @@ -5,8 +5,6 @@
461  
462  long (__syscall)(long, ...);
463  
464 -#ifndef __clang__
465 -
466  #define __asm_syscall(...) do { \
467         __asm__ __volatile__ ( "svc 0" \
468         : "=r"(r0) : __VA_ARGS__ : "memory"); \
469 @@ -54,41 +52,25 @@ static inline long __syscall4(long n, lo
470         __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3));
471  }
472  
473 -#else
474 -
475 -static inline long __syscall0(long n)
476 -{
477 -       return (__syscall)(n);
478 -}
479 -
480 -static inline long __syscall1(long n, long a)
481 -{
482 -       return (__syscall)(n, a);
483 -}
484 -
485 -static inline long __syscall2(long n, long a, long b)
486 -{
487 -       return (__syscall)(n, a, b);
488 -}
489 -
490 -static inline long __syscall3(long n, long a, long b, long c)
491 -{
492 -       return (__syscall)(n, a, b, c);
493 -}
494 -
495 -static inline long __syscall4(long n, long a, long b, long c, long d)
496 -{
497 -       return (__syscall)(n, a, b, c, d);
498 -}
499 -
500 -#endif
501 -
502  static inline long __syscall5(long n, long a, long b, long c, long d, long e)
503  {
504 -       return (__syscall)(n, a, b, c, d, e);
505 +       register long r7 __asm__("r7") = n;
506 +       register long r0 __asm__("r0") = a;
507 +       register long r1 __asm__("r1") = b;
508 +       register long r2 __asm__("r2") = c;
509 +       register long r3 __asm__("r3") = d;
510 +       register long r4 __asm__("r4") = e;
511 +       __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4));
512  }
513  
514  static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
515  {
516 -       return (__syscall)(n, a, b, c, d, e, f);
517 +       register long r7 __asm__("r7") = n;
518 +       register long r0 __asm__("r0") = a;
519 +       register long r1 __asm__("r1") = b;
520 +       register long r2 __asm__("r2") = c;
521 +       register long r3 __asm__("r3") = d;
522 +       register long r4 __asm__("r4") = e;
523 +       register long r5 __asm__("r5") = f;
524 +       __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
525  }
526 --- a/arch/i386/bits/alltypes.h.in
527 +++ b/arch/i386/bits/alltypes.h.in
528 @@ -17,7 +17,6 @@ TYPEDEF __WCHAR_TYPE__ wchar_t;
529  TYPEDEF long wchar_t;
530  #endif
531  #endif
532 -TYPEDEF unsigned wint_t;
533  
534  #if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 0
535  TYPEDEF float float_t;
536 --- a/arch/i386/bits/syscall.h
537 +++ b/arch/i386/bits/syscall.h
538 @@ -355,6 +355,7 @@
539  #define __NR_seccomp           354
540  #define __NR_getrandom         355
541  #define __NR_memfd_create      356
542 +#define __NR_bpf               357
543  
544  
545  /* Repeated with SYS_ prefix */
546 @@ -716,3 +717,4 @@
547  #define SYS_seccomp            354
548  #define SYS_getrandom          355
549  #define SYS_memfd_create       356
550 +#define SYS_bpf                        357
551 --- a/arch/microblaze/bits/alltypes.h.in
552 +++ b/arch/microblaze/bits/alltypes.h.in
553 @@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list
554  #ifndef __cplusplus
555  TYPEDEF int wchar_t;
556  #endif
557 -TYPEDEF unsigned wint_t;
558  
559  TYPEDEF float float_t;
560  TYPEDEF double double_t;
561 --- a/arch/microblaze/bits/syscall.h
562 +++ b/arch/microblaze/bits/syscall.h
563 @@ -381,6 +381,7 @@
564  #define __NR_seccomp 384
565  #define __NR_getrandom 385
566  #define __NR_memfd_create 386
567 +#define __NR_bpf 387
568  
569  /* Repeated with SYS_ prefix */
570  
571 @@ -768,3 +769,4 @@
572  #define SYS_seccomp 384
573  #define SYS_getrandom 385
574  #define SYS_memfd_create 386
575 +#define SYS_bpf 387
576 --- a/arch/microblaze/syscall_arch.h
577 +++ b/arch/microblaze/syscall_arch.h
578 @@ -100,39 +100,7 @@ static inline long __syscall6(long n, lo
579  
580  #else
581  
582 -static inline long __syscall0(long n)
583 -{
584 -       return (__syscall)(n);
585 -}
586 -
587 -static inline long __syscall1(long n, long a)
588 -{
589 -       return (__syscall)(n, a);
590 -}
591 -
592 -static inline long __syscall2(long n, long a, long b)
593 -{
594 -       return (__syscall)(n, a, b);
595 -}
596 -
597 -static inline long __syscall3(long n, long a, long b, long c)
598 -{
599 -       return (__syscall)(n, a, b, c);
600 -}
601 -
602 -static inline long __syscall4(long n, long a, long b, long c, long d)
603 -{
604 -       return (__syscall)(n, a, b, c, d);
605 -}
606 -
607 -static inline long __syscall5(long n, long a, long b, long c, long d, long e)
608 -{
609 -       return (__syscall)(n, a, b, c, d, e);
610 -}
611 -
612 -static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
613 -{
614 -       return (__syscall)(n, a, b, c, d, e, f);
615 -}
616 +#undef SYSCALL_NO_INLINE
617 +#define SYSCALL_NO_INLINE
618  
619  #endif
620 --- a/arch/mips/bits/alltypes.h.in
621 +++ b/arch/mips/bits/alltypes.h.in
622 @@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list
623  #ifndef __cplusplus
624  TYPEDEF int wchar_t;
625  #endif
626 -TYPEDEF unsigned wint_t;
627  
628  TYPEDEF float float_t;
629  TYPEDEF double double_t;
630 --- a/arch/mips/bits/syscall.h
631 +++ b/arch/mips/bits/syscall.h
632 @@ -352,6 +352,7 @@
633  #define __NR_seccomp                 4352
634  #define __NR_getrandom               4353
635  #define __NR_memfd_create            4354
636 +#define __NR_bpf                     4355
637  
638  
639  /* Repeated with SYS_ prefix */
640 @@ -709,3 +710,4 @@
641  #define SYS_seccomp                 4352
642  #define SYS_getrandom               4353
643  #define SYS_memfd_create            4354
644 +#define SYS_bpf                     4355
645 --- a/arch/or1k/bits/alltypes.h.in
646 +++ b/arch/or1k/bits/alltypes.h.in
647 @@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list
648  #ifndef __cplusplus
649  TYPEDEF unsigned wchar_t;
650  #endif
651 -TYPEDEF unsigned wint_t;
652  
653  TYPEDEF float float_t;
654  TYPEDEF double double_t;
655 --- a/arch/or1k/bits/syscall.h
656 +++ b/arch/or1k/bits/syscall.h
657 @@ -263,6 +263,7 @@
658  #define __NR_seccomp 277
659  #define __NR_getrandom 278
660  #define __NR_memfd_create 279
661 +#define __NR_bpf 280
662  
663  #define SYS_io_setup __NR_io_setup
664  #define SYS_io_destroy __NR_io_destroy
665 @@ -529,3 +530,4 @@
666  #define SYS_seccomp __NR_seccomp
667  #define SYS_getrandom __NR_getrandom
668  #define SYS_memfd_create __NR_memfd_create
669 +#define SYS_bpf __NR_bpf
670 --- a/arch/or1k/syscall_arch.h
671 +++ b/arch/or1k/syscall_arch.h
672 @@ -1,7 +1,7 @@
673  #define __SYSCALL_LL_E(x) \
674  ((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
675  ((union { long long ll; long l[2]; }){ .ll = x }).l[1]
676 -#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
677 +#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))
678  
679  #define SYSCALL_MMAP2_UNIT 8192ULL
680  
681 @@ -118,39 +118,7 @@ static inline long __syscall6(long n, lo
682  
683  #else
684  
685 -static inline long __syscall0(long n)
686 -{
687 -       return (__syscall)(n);
688 -}
689 -
690 -static inline long __syscall1(long n, long a)
691 -{
692 -       return (__syscall)(n, a);
693 -}
694 -
695 -static inline long __syscall2(long n, long a, long b)
696 -{
697 -       return (__syscall)(n, a, b);
698 -}
699 -
700 -static inline long __syscall3(long n, long a, long b, long c)
701 -{
702 -       return (__syscall)(n, a, b, c);
703 -}
704 -
705 -static inline long __syscall4(long n, long a, long b, long c, long d)
706 -{
707 -       return (__syscall)(n, a, b, c, d);
708 -}
709 -
710 -static inline long __syscall5(long n, long a, long b, long c, long d, long e)
711 -{
712 -       return (__syscall)(n, a, b, c, d, e);
713 -}
714 -
715 -static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
716 -{
717 -       return (__syscall)(n, a, b, c, d, e, f);
718 -}
719 +#undef SYSCALL_NO_INLINE
720 +#define SYSCALL_NO_INLINE
721  
722  #endif
723 --- a/arch/powerpc/bits/alltypes.h.in
724 +++ b/arch/powerpc/bits/alltypes.h.in
725 @@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list
726  #ifndef __cplusplus
727  TYPEDEF long wchar_t;
728  #endif
729 -TYPEDEF unsigned wint_t;
730  
731  TYPEDEF float float_t;
732  TYPEDEF double double_t;
733 --- a/arch/powerpc/bits/syscall.h
734 +++ b/arch/powerpc/bits/syscall.h
735 @@ -374,6 +374,7 @@
736  #define __NR_seccomp               358
737  #define __NR_getrandom             359
738  #define __NR_memfd_create          360
739 +#define __NR_bpf                   361
740  
741  /*
742   * repeated with SYS prefix
743 @@ -754,3 +755,4 @@
744  #define SYS_seccomp               358
745  #define SYS_getrandom             359
746  #define SYS_memfd_create          360
747 +#define SYS_bpf                   361
748 --- a/arch/powerpc/syscall_arch.h
749 +++ b/arch/powerpc/syscall_arch.h
750 @@ -3,39 +3,5 @@
751  ((union { long long ll; long l[2]; }){ .ll = x }).l[1]
752  #define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
753  
754 -long (__syscall)(long, ...);
755 -
756 -static inline long __syscall0(long n)
757 -{
758 -       return (__syscall)(n, 0, 0, 0, 0, 0, 0);
759 -}
760 -
761 -static inline long __syscall1(long n, long a)
762 -{
763 -       return (__syscall)(n, a, 0, 0, 0, 0, 0);
764 -}
765 -
766 -static inline long __syscall2(long n, long a, long b)
767 -{
768 -       return (__syscall)(n, a, b, 0, 0, 0, 0);
769 -}
770 -
771 -static inline long __syscall3(long n, long a, long b, long c)
772 -{
773 -       return (__syscall)(n, a, b, c, 0, 0, 0);
774 -}
775 -
776 -static inline long __syscall4(long n, long a, long b, long c, long d)
777 -{
778 -       return (__syscall)(n, a, b, c, d, 0, 0);
779 -}
780 -
781 -static inline long __syscall5(long n, long a, long b, long c, long d, long e)
782 -{
783 -       return (__syscall)(n, a, b, c, d, e, 0);
784 -}
785 -
786 -static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
787 -{
788 -       return (__syscall)(n, a, b, c, d, e, f);
789 -}
790 +#undef SYSCALL_NO_INLINE
791 +#define SYSCALL_NO_INLINE
792 --- a/arch/sh/bits/alltypes.h.in
793 +++ b/arch/sh/bits/alltypes.h.in
794 @@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list
795  #ifndef __cplusplus
796  TYPEDEF long wchar_t;
797  #endif
798 -TYPEDEF unsigned wint_t;
799  
800  TYPEDEF float float_t;
801  TYPEDEF double double_t;
802 --- a/arch/x32/bits/alltypes.h.in
803 +++ b/arch/x32/bits/alltypes.h.in
804 @@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list
805  #ifndef __cplusplus
806  TYPEDEF long wchar_t;
807  #endif
808 -TYPEDEF unsigned wint_t;
809  
810  #if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2
811  TYPEDEF long double float_t;
812 --- a/arch/x32/bits/syscall.h
813 +++ b/arch/x32/bits/syscall.h
814 @@ -277,6 +277,8 @@
815  #define __NR_seccomp (__X32_SYSCALL_BIT + 317)
816  #define __NR_getrandom (__X32_SYSCALL_BIT + 318)
817  #define __NR_memfd_create (__X32_SYSCALL_BIT + 319)
818 +#define __NR_kexec_file_load (__X32_SYSCALL_BIT + 320)
819 +#define __NR_bpf (__X32_SYSCALL_BIT + 321)
820  
821  #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
822  #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
823 @@ -604,6 +606,8 @@
824  #define SYS_seccomp __NR_seccomp
825  #define SYS_getrandom __NR_getrandom
826  #define SYS_memfd_create __NR_memfd_create
827 +#define SYS_kexec_file_load __NR_kexec_file_load
828 +#define SYS_bpf __NR_bpf
829  
830  #define SYS_rt_sigaction __NR_rt_sigaction
831  #define SYS_rt_sigreturn __NR_rt_sigreturn
832 --- a/arch/x86_64/bits/alltypes.h.in
833 +++ b/arch/x86_64/bits/alltypes.h.in
834 @@ -8,7 +8,6 @@ TYPEDEF __builtin_va_list __isoc_va_list
835  #ifndef __cplusplus
836  TYPEDEF int wchar_t;
837  #endif
838 -TYPEDEF unsigned wint_t;
839  
840  #if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2
841  TYPEDEF long double float_t;
842 --- a/arch/x86_64/bits/syscall.h
843 +++ b/arch/x86_64/bits/syscall.h
844 @@ -318,6 +318,8 @@
845  #define __NR_seccomp                           317
846  #define __NR_getrandom                         318
847  #define __NR_memfd_create                      319
848 +#define __NR_kexec_file_load                   320
849 +#define __NR_bpf                               321
850  
851  
852  #undef __NR_fstatat
853 @@ -654,6 +656,8 @@
854  #define SYS_seccomp                            317
855  #define SYS_getrandom                          318
856  #define SYS_memfd_create                       319
857 +#define SYS_kexec_file_load                    320
858 +#define SYS_bpf                                        321
859  
860  #undef SYS_fstatat
861  #undef SYS_pread
862 --- a/include/alltypes.h.in
863 +++ b/include/alltypes.h.in
864 @@ -28,6 +28,7 @@ TYPEDEF _Int64 blkcnt_t;
865  TYPEDEF unsigned _Int64 fsblkcnt_t;
866  TYPEDEF unsigned _Int64 fsfilcnt_t;
867  
868 +TYPEDEF unsigned wint_t;
869  TYPEDEF unsigned long wctype_t;
870  
871  TYPEDEF void * timer_t;
872 --- a/include/arpa/nameser.h
873 +++ b/include/arpa/nameser.h
874 @@ -1,6 +1,11 @@
875  #ifndef _ARPA_NAMESER_H
876  #define _ARPA_NAMESER_H
877  
878 +#ifdef __cplusplus
879 +extern "C" {
880 +#endif
881 +
882 +#include <stddef.h>
883  #include <stdint.h>
884  
885  #define __NAMESER      19991006
886 @@ -48,6 +53,8 @@ extern const struct _ns_flagdata _ns_fla
887  #define ns_msg_end(handle) ((handle)._eom + 0)
888  #define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
889  #define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
890 +#define ns_msg_getflag(handle, flag) \
891 +       (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
892  
893  typedef        struct __ns_rr {
894         char            name[NS_MAXDNAME];
895 @@ -296,43 +303,20 @@ typedef enum __ns_cert_types {
896  #define NS_OPT_DNSSEC_OK        0x8000U
897  #define NS_OPT_NSID            3
898  
899 -#define NS_GET16(s, cp) do { \
900 -       register const unsigned char *t_cp = (const unsigned char *)(cp); \
901 -       (s) = ((uint16_t)t_cp[0] << 8) \
902 -           | ((uint16_t)t_cp[1]) \
903 -           ; \
904 -       (cp) += NS_INT16SZ; \
905 -} while (0)
906 -
907 -#define NS_GET32(l, cp) do { \
908 -       register const unsigned char *t_cp = (const unsigned char *)(cp); \
909 -       (l) = ((uint32_t)t_cp[0] << 24) \
910 -           | ((uint32_t)t_cp[1] << 16) \
911 -           | ((uint32_t)t_cp[2] << 8) \
912 -           | ((uint32_t)t_cp[3]) \
913 -           ; \
914 -       (cp) += NS_INT32SZ; \
915 -} while (0)
916 -
917 -#define NS_PUT16(s, cp) do { \
918 -       register uint16_t t_s = (uint16_t)(s); \
919 -       register unsigned char *t_cp = (unsigned char *)(cp); \
920 -       *t_cp++ = t_s >> 8; \
921 -       *t_cp   = t_s; \
922 -       (cp) += NS_INT16SZ; \
923 -} while (0)
924 -
925 -#define NS_PUT32(l, cp) do { \
926 -       register uint32_t t_l = (uint32_t)(l); \
927 -       register unsigned char *t_cp = (unsigned char *)(cp); \
928 -       *t_cp++ = t_l >> 24; \
929 -       *t_cp++ = t_l >> 16; \
930 -       *t_cp++ = t_l >> 8; \
931 -       *t_cp   = t_l; \
932 -       (cp) += NS_INT32SZ; \
933 -} while (0)
934 -
935 -
936 +#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp)+=2)-2))
937 +#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp)+=4)-4))
938 +#define NS_PUT16(s, cp) ns_put16((s), ((cp)+=2)-2)
939 +#define NS_PUT32(l, cp) ns_put32((l), ((cp)+=4)-4)
940 +
941 +unsigned ns_get16(const unsigned char *);
942 +unsigned long ns_get32(const unsigned char *);
943 +void ns_put16(unsigned, unsigned char *);
944 +void ns_put32(unsigned long, unsigned char *);
945 +
946 +int ns_initparse(const unsigned char *, int, ns_msg *);
947 +int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
948 +int ns_skiprr(const unsigned char *, const unsigned char *, ns_sect, int);
949 +int ns_name_uncompress(const unsigned char *, const unsigned char *, const unsigned char *, char *, size_t);
950  
951  
952  #define        __BIND          19950621
953 @@ -464,4 +448,8 @@ typedef struct {
954  #define        PUTSHORT                NS_PUT16
955  #define        PUTLONG                 NS_PUT32
956  
957 +#ifdef __cplusplus
958 +}
959 +#endif
960 +
961  #endif
962 --- a/include/complex.h
963 +++ b/include/complex.h
964 @@ -7,9 +7,9 @@ extern "C" {
965  
966  #define complex _Complex
967  #ifdef __GNUC__
968 -#define _Complex_I (__extension__ 1.0fi)
969 +#define _Complex_I (__extension__ (0.0f+1.0fi))
970  #else
971 -#define _Complex_I 1.0fi
972 +#define _Complex_I (0.0f+1.0fi)
973  #endif
974  #define I _Complex_I
975  
976 @@ -101,8 +101,9 @@ double creal(double complex);
977  float crealf(float complex);
978  long double creall(long double complex);
979  
980 +#ifndef __cplusplus
981  #define __CIMAG(x, t) \
982 -       ((union { _Complex t __z; t __xy[2]; }){(_Complex t)(x)}.__xy[1])
983 +       (+(union { _Complex t __z; t __xy[2]; }){(_Complex t)(x)}.__xy[1])
984  
985  #define creal(x) ((double)(x))
986  #define crealf(x) ((float)(x))
987 @@ -111,13 +112,20 @@ long double creall(long double complex);
988  #define cimag(x) __CIMAG(x, double)
989  #define cimagf(x) __CIMAG(x, float)
990  #define cimagl(x) __CIMAG(x, long double)
991 +#endif
992  
993 -#define __CMPLX(x, y, t) \
994 -       ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)
995 -
996 +#if __STDC_VERSION__ >= 201112L
997 +#if defined(_Imaginary_I)
998 +#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y)))
999 +#elif defined(__clang__)
1000 +#define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) })
1001 +#else
1002 +#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y)))
1003 +#endif
1004  #define CMPLX(x, y) __CMPLX(x, y, double)
1005  #define CMPLXF(x, y) __CMPLX(x, y, float)
1006  #define CMPLXL(x, y) __CMPLX(x, y, long double)
1007 +#endif
1008  
1009  #ifdef __cplusplus
1010  }
1011 --- a/include/pthread.h
1012 +++ b/include/pthread.h
1013 @@ -84,7 +84,9 @@ __attribute__((const))
1014  pthread_t pthread_self(void);
1015  
1016  int pthread_equal(pthread_t, pthread_t);
1017 +#ifndef __cplusplus
1018  #define pthread_equal(x,y) ((x)==(y))
1019 +#endif
1020  
1021  int pthread_setcancelstate(int, int *);
1022  int pthread_setcanceltype(int, int *);
1023 --- a/include/stdint.h
1024 +++ b/include/stdint.h
1025 @@ -47,8 +47,8 @@ typedef uint64_t uint_least64_t;
1026  
1027  #define UINT8_MAX  (0xff)
1028  #define UINT16_MAX (0xffff)
1029 -#define UINT32_MAX (0xffffffff)
1030 -#define UINT64_MAX (0xffffffffffffffff)
1031 +#define UINT32_MAX (0xffffffffu)
1032 +#define UINT64_MAX (0xffffffffffffffffu)
1033  
1034  #define INT_FAST8_MIN   INT8_MIN
1035  #define INT_FAST64_MIN  INT64_MIN
1036 @@ -78,7 +78,7 @@ typedef uint64_t uint_least64_t;
1037  #define INTMAX_MAX  INT64_MAX
1038  #define UINTMAX_MAX UINT64_MAX
1039  
1040 -#define WINT_MIN 0
1041 +#define WINT_MIN 0U
1042  #define WINT_MAX UINT32_MAX
1043  
1044  #if L'\0'-1 > 0
1045 --- a/include/sys/prctl.h
1046 +++ b/include/sys/prctl.h
1047 @@ -5,6 +5,8 @@
1048  extern "C" {
1049  #endif
1050  
1051 +#include <stdint.h>
1052 +
1053  #define PR_SET_PDEATHSIG  1
1054  #define PR_GET_PDEATHSIG  2
1055  #define PR_GET_DUMPABLE   3
1056 @@ -80,6 +82,25 @@ extern "C" {
1057  #define PR_SET_MM_ENV_END              11
1058  #define PR_SET_MM_AUXV                 12
1059  #define PR_SET_MM_EXE_FILE             13
1060 +#define PR_SET_MM_MAP                  14
1061 +#define PR_SET_MM_MAP_SIZE             15
1062 +
1063 +struct prctl_mm_map {
1064 +       uint64_t start_code;
1065 +       uint64_t end_code;
1066 +       uint64_t start_data;
1067 +       uint64_t end_data;
1068 +       uint64_t start_brk;
1069 +       uint64_t brk;
1070 +       uint64_t start_stack;
1071 +       uint64_t arg_start;
1072 +       uint64_t arg_end;
1073 +       uint64_t env_start;
1074 +       uint64_t env_end;
1075 +       uint64_t *auxv;
1076 +       uint32_t auxv_size;
1077 +       uint32_t exe_fd;
1078 +};
1079  
1080  #define PR_SET_PTRACER 0x59616d61
1081  #define PR_SET_PTRACER_ANY (-1UL)
1082 --- a/include/threads.h
1083 +++ b/include/threads.h
1084 @@ -51,7 +51,9 @@ void thrd_yield(void);
1085  
1086  thrd_t thrd_current(void);
1087  int thrd_equal(thrd_t, thrd_t);
1088 +#ifndef __cplusplus
1089  #define thrd_equal(A, B) ((A) == (B))
1090 +#endif
1091  
1092  void call_once(once_flag *, void (*)(void));
1093  
1094 --- a/include/utmp.h
1095 +++ b/include/utmp.h
1096 @@ -35,6 +35,8 @@ void         setutent(void);
1097  
1098  void updwtmp(const char *, const struct utmp *);
1099  
1100 +int login_tty(int);
1101 +
1102  #define _PATH_UTMP "/dev/null/utmp"
1103  #define _PATH_WTMP "/dev/null/wtmp"
1104  
1105 --- a/src/fcntl/open.c
1106 +++ b/src/fcntl/open.c
1107 @@ -7,7 +7,7 @@ int open(const char *filename, int flags
1108  {
1109         mode_t mode = 0;
1110  
1111 -       if (flags & O_CREAT) {
1112 +       if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
1113                 va_list ap;
1114                 va_start(ap, flags);
1115                 mode = va_arg(ap, mode_t);
1116 --- a/src/fcntl/openat.c
1117 +++ b/src/fcntl/openat.c
1118 @@ -5,11 +5,15 @@
1119  
1120  int openat(int fd, const char *filename, int flags, ...)
1121  {
1122 -       mode_t mode;
1123 -       va_list ap;
1124 -       va_start(ap, flags);
1125 -       mode = va_arg(ap, mode_t);
1126 -       va_end(ap);
1127 +       mode_t mode = 0;
1128 +
1129 +       if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
1130 +               va_list ap;
1131 +               va_start(ap, flags);
1132 +               mode = va_arg(ap, mode_t);
1133 +               va_end(ap);
1134 +       }
1135 +
1136         return syscall_cp(SYS_openat, fd, filename, flags|O_LARGEFILE, mode);
1137  }
1138  
1139 --- a/src/internal/libm.h
1140 +++ b/src/internal/libm.h
1141 @@ -128,6 +128,18 @@ do {                                    
1142    (d) = __u.f;                                    \
1143  } while (0)
1144  
1145 +#undef __CMPLX
1146 +#undef CMPLX
1147 +#undef CMPLXF
1148 +#undef CMPLXL
1149 +
1150 +#define __CMPLX(x, y, t) \
1151 +       ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)
1152 +
1153 +#define CMPLX(x, y) __CMPLX(x, y, double)
1154 +#define CMPLXF(x, y) __CMPLX(x, y, float)
1155 +#define CMPLXL(x, y) __CMPLX(x, y, long double)
1156 +
1157  /* fdlibm kernel functions */
1158  
1159  int    __rem_pio2_large(double*,double*,int,int,int);
1160 --- a/src/internal/syscall.h
1161 +++ b/src/internal/syscall.h
1162 @@ -24,12 +24,22 @@ long __syscall_ret(unsigned long), __sys
1163         __syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t,
1164                      syscall_arg_t, syscall_arg_t, syscall_arg_t);
1165  
1166 +#ifdef SYSCALL_NO_INLINE
1167 +#define __syscall0(n) (__syscall)(n)
1168 +#define __syscall1(n,a) (__syscall)(n,__scc(a))
1169 +#define __syscall2(n,a,b) (__syscall)(n,__scc(a),__scc(b))
1170 +#define __syscall3(n,a,b,c) (__syscall)(n,__scc(a),__scc(b),__scc(c))
1171 +#define __syscall4(n,a,b,c,d) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d))
1172 +#define __syscall5(n,a,b,c,d,e) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
1173 +#define __syscall6(n,a,b,c,d,e,f) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
1174 +#else
1175  #define __syscall1(n,a) __syscall1(n,__scc(a))
1176  #define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b))
1177  #define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c))
1178  #define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d))
1179  #define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
1180  #define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
1181 +#endif
1182  #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))
1183  
1184  #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
1185 --- a/src/ldso/dynlink.c
1186 +++ b/src/ldso/dynlink.c
1187 @@ -645,6 +645,8 @@ static void decode_dyn(struct dso *p)
1188                 p->hashtab = (void *)(p->base + dyn[DT_HASH]);
1189         if (dyn[0]&(1<<DT_RPATH))
1190                 p->rpath_orig = (void *)(p->strings + dyn[DT_RPATH]);
1191 +       if (dyn[0]&(1<<DT_RUNPATH))
1192 +               p->rpath_orig = (void *)(p->strings + dyn[DT_RUNPATH]);
1193         if (search_vec(p->dynv, dyn, DT_GNU_HASH))
1194                 p->ghashtab = (void *)(p->base + *dyn);
1195         if (search_vec(p->dynv, dyn, DT_VERSYM))
1196 @@ -1126,6 +1128,7 @@ void *__dynlink(int argc, char **argv)
1197                 libc.secure = 1;
1198         }
1199         libc.page_size = aux[AT_PAGESZ];
1200 +       libc.auxv = auxv;
1201  
1202         /* If the dynamic linker was invoked as a program itself, AT_BASE
1203          * will not be set. In that case, we assume the base address is
1204 --- a/src/math/__rem_pio2.c
1205 +++ b/src/math/__rem_pio2.c
1206 @@ -19,6 +19,12 @@
1207  
1208  #include "libm.h"
1209  
1210 +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
1211 +#define EPS DBL_EPSILON
1212 +#elif FLT_EVAL_METHOD==2
1213 +#define EPS LDBL_EPSILON
1214 +#endif
1215 +
1216  /*
1217   * invpio2:  53 bits of 2/pi
1218   * pio2_1:   first  33 bit of pi/2
1219 @@ -29,6 +35,7 @@
1220   * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
1221   */
1222  static const double
1223 +toint   = 1.5/EPS,
1224  invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
1225  pio2_1  = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
1226  pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
1227 @@ -41,8 +48,8 @@ pio2_3t = 8.47842766036889956997e-32; /*
1228  int __rem_pio2(double x, double *y)
1229  {
1230         union {double f; uint64_t i;} u = {x};
1231 -       double_t z,w,t,r;
1232 -       double tx[3],ty[2],fn;
1233 +       double_t z,w,t,r,fn;
1234 +       double tx[3],ty[2];
1235         uint32_t ix;
1236         int sign, n, ex, ey, i;
1237  
1238 @@ -111,8 +118,7 @@ int __rem_pio2(double x, double *y)
1239         if (ix < 0x413921fb) {  /* |x| ~< 2^20*(pi/2), medium size */
1240  medium:
1241                 /* rint(x/(pi/2)), Assume round-to-nearest. */
1242 -               fn = x*invpio2 + 0x1.8p52;
1243 -               fn = fn - 0x1.8p52;
1244 +               fn = x*invpio2 + toint - toint;
1245                 n = (int32_t)fn;
1246                 r = x - fn*pio2_1;
1247                 w = fn*pio2_1t;  /* 1st round, good to 85 bits */
1248 --- a/src/math/__rem_pio2f.c
1249 +++ b/src/math/__rem_pio2f.c
1250 @@ -22,12 +22,19 @@
1251  
1252  #include "libm.h"
1253  
1254 +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
1255 +#define EPS DBL_EPSILON
1256 +#elif FLT_EVAL_METHOD==2
1257 +#define EPS LDBL_EPSILON
1258 +#endif
1259 +
1260  /*
1261   * invpio2:  53 bits of 2/pi
1262   * pio2_1:   first 25 bits of pi/2
1263   * pio2_1t:  pi/2 - pio2_1
1264   */
1265  static const double
1266 +toint   = 1.5/EPS,
1267  invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
1268  pio2_1  = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */
1269  pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
1270 @@ -35,7 +42,8 @@ pio2_1t = 1.58932547735281966916e-08; /*
1271  int __rem_pio2f(float x, double *y)
1272  {
1273         union {float f; uint32_t i;} u = {x};
1274 -       double tx[1],ty[1],fn;
1275 +       double tx[1],ty[1];
1276 +       double_t fn;
1277         uint32_t ix;
1278         int n, sign, e0;
1279  
1280 @@ -43,8 +51,7 @@ int __rem_pio2f(float x, double *y)
1281         /* 25+53 bit pi is good enough for medium size */
1282         if (ix < 0x4dc90fdb) {  /* |x| ~< 2^28*(pi/2), medium size */
1283                 /* Use a specialized rint() to get fn.  Assume round-to-nearest. */
1284 -               fn = x*invpio2 + 0x1.8p52;
1285 -               fn = fn - 0x1.8p52;
1286 +               fn = x*invpio2 + toint - toint;
1287                 n  = (int32_t)fn;
1288                 *y = x - fn*pio2_1 - fn*pio2_1t;
1289                 return n;
1290 --- a/src/math/__rem_pio2l.c
1291 +++ b/src/math/__rem_pio2l.c
1292 @@ -20,10 +20,11 @@
1293   * use __rem_pio2_large() for large x
1294   */
1295  
1296 +static const long double toint = 1.5/LDBL_EPSILON;
1297 +
1298  #if LDBL_MANT_DIG == 64
1299  /* u ~< 0x1p25*pi/2 */
1300  #define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.m>>48) < ((0x3fff + 25)<<16 | 0x921f>>1 | 0x8000))
1301 -#define TOINT 0x1.8p63
1302  #define QUOBITS(x) ((uint32_t)(int32_t)x & 0x7fffffff)
1303  #define ROUND1 22
1304  #define ROUND2 61
1305 @@ -50,7 +51,6 @@ pio2_3t = -2.75299651904407171810e-37L; 
1306  #elif LDBL_MANT_DIG == 113
1307  /* u ~< 0x1p45*pi/2 */
1308  #define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.top) < ((0x3fff + 45)<<16 | 0x921f))
1309 -#define TOINT 0x1.8p112
1310  #define QUOBITS(x) ((uint32_t)(int64_t)x & 0x7fffffff)
1311  #define ROUND1 51
1312  #define ROUND2 119
1313 @@ -77,7 +77,7 @@ int __rem_pio2l(long double x, long doub
1314         ex = u.i.se & 0x7fff;
1315         if (SMALL(u)) {
1316                 /* rint(x/(pi/2)), Assume round-to-nearest. */
1317 -               fn = x*invpio2 + TOINT - TOINT;
1318 +               fn = x*invpio2 + toint - toint;
1319                 n = QUOBITS(fn);
1320                 r = x-fn*pio2_1;
1321                 w = fn*pio2_1t;  /* 1st round good to 102/180 bits (ld80/ld128) */
1322 --- a/src/math/ceil.c
1323 +++ b/src/math/ceil.c
1324 @@ -1,5 +1,12 @@
1325  #include "libm.h"
1326  
1327 +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
1328 +#define EPS DBL_EPSILON
1329 +#elif FLT_EVAL_METHOD==2
1330 +#define EPS LDBL_EPSILON
1331 +#endif
1332 +static const double_t toint = 1/EPS;
1333 +
1334  double ceil(double x)
1335  {
1336         union {double f; uint64_t i;} u = {x};
1337 @@ -10,9 +17,9 @@ double ceil(double x)
1338                 return x;
1339         /* y = int(x) - x, where int(x) is an integer neighbor of x */
1340         if (u.i >> 63)
1341 -               y = (double)(x - 0x1p52) + 0x1p52 - x;
1342 +               y = x - toint + toint - x;
1343         else
1344 -               y = (double)(x + 0x1p52) - 0x1p52 - x;
1345 +               y = x + toint - toint - x;
1346         /* special case because of non-nearest rounding modes */
1347         if (e <= 0x3ff-1) {
1348                 FORCE_EVAL(y);
1349 --- a/src/math/ceill.c
1350 +++ b/src/math/ceill.c
1351 @@ -6,11 +6,9 @@ long double ceill(long double x)
1352         return ceil(x);
1353  }
1354  #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
1355 -#if LDBL_MANT_DIG == 64
1356 -#define TOINT 0x1p63
1357 -#elif LDBL_MANT_DIG == 113
1358 -#define TOINT 0x1p112
1359 -#endif
1360 +
1361 +static const long double toint = 1/LDBL_EPSILON;
1362 +
1363  long double ceill(long double x)
1364  {
1365         union ldshape u = {x};
1366 @@ -21,9 +19,9 @@ long double ceill(long double x)
1367                 return x;
1368         /* y = int(x) - x, where int(x) is an integer neighbor of x */
1369         if (u.i.se >> 15)
1370 -               y = x - TOINT + TOINT - x;
1371 +               y = x - toint + toint - x;
1372         else
1373 -               y = x + TOINT - TOINT - x;
1374 +               y = x + toint - toint - x;
1375         /* special case because of non-nearest rounding modes */
1376         if (e <= 0x3fff-1) {
1377                 FORCE_EVAL(y);
1378 --- a/src/math/floor.c
1379 +++ b/src/math/floor.c
1380 @@ -1,5 +1,12 @@
1381  #include "libm.h"
1382  
1383 +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
1384 +#define EPS DBL_EPSILON
1385 +#elif FLT_EVAL_METHOD==2
1386 +#define EPS LDBL_EPSILON
1387 +#endif
1388 +static const double_t toint = 1/EPS;
1389 +
1390  double floor(double x)
1391  {
1392         union {double f; uint64_t i;} u = {x};
1393 @@ -10,9 +17,9 @@ double floor(double x)
1394                 return x;
1395         /* y = int(x) - x, where int(x) is an integer neighbor of x */
1396         if (u.i >> 63)
1397 -               y = (double)(x - 0x1p52) + 0x1p52 - x;
1398 +               y = x - toint + toint - x;
1399         else
1400 -               y = (double)(x + 0x1p52) - 0x1p52 - x;
1401 +               y = x + toint - toint - x;
1402         /* special case because of non-nearest rounding modes */
1403         if (e <= 0x3ff-1) {
1404                 FORCE_EVAL(y);
1405 --- a/src/math/floorl.c
1406 +++ b/src/math/floorl.c
1407 @@ -6,11 +6,9 @@ long double floorl(long double x)
1408         return floor(x);
1409  }
1410  #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
1411 -#if LDBL_MANT_DIG == 64
1412 -#define TOINT 0x1p63
1413 -#elif LDBL_MANT_DIG == 113
1414 -#define TOINT 0x1p112
1415 -#endif
1416 +
1417 +static const long double toint = 1/LDBL_EPSILON;
1418 +
1419  long double floorl(long double x)
1420  {
1421         union ldshape u = {x};
1422 @@ -21,9 +19,9 @@ long double floorl(long double x)
1423                 return x;
1424         /* y = int(x) - x, where int(x) is an integer neighbor of x */
1425         if (u.i.se >> 15)
1426 -               y = x - TOINT + TOINT - x;
1427 +               y = x - toint + toint - x;
1428         else
1429 -               y = x + TOINT - TOINT - x;
1430 +               y = x + toint - toint - x;
1431         /* special case because of non-nearest rounding modes */
1432         if (e <= 0x3fff-1) {
1433                 FORCE_EVAL(y);
1434 --- a/src/math/i386/fmod.s
1435 +++ b/src/math/i386/fmod.s
1436 @@ -4,7 +4,7 @@ fmod:
1437         fldl 12(%esp)
1438         fldl 4(%esp)
1439  1:     fprem
1440 -       fstsw %ax
1441 +       fnstsw %ax
1442         sahf
1443         jp 1b
1444         fstp %st(1)
1445 --- a/src/math/i386/fmodf.s
1446 +++ b/src/math/i386/fmodf.s
1447 @@ -4,7 +4,7 @@ fmodf:
1448         flds 8(%esp)
1449         flds 4(%esp)
1450  1:     fprem
1451 -       fstsw %ax
1452 +       fnstsw %ax
1453         sahf
1454         jp 1b
1455         fstp %st(1)
1456 --- a/src/math/i386/fmodl.s
1457 +++ b/src/math/i386/fmodl.s
1458 @@ -4,7 +4,7 @@ fmodl:
1459         fldt 16(%esp)
1460         fldt 4(%esp)
1461  1:     fprem
1462 -       fstsw %ax
1463 +       fnstsw %ax
1464         sahf
1465         jp 1b
1466         fstp %st(1)
1467 --- a/src/math/i386/remainder.s
1468 +++ b/src/math/i386/remainder.s
1469 @@ -7,7 +7,7 @@ drem:
1470         fldl 12(%esp)
1471         fldl 4(%esp)
1472  1:     fprem1
1473 -       fstsw %ax
1474 +       fnstsw %ax
1475         sahf
1476         jp 1b
1477         fstp %st(1)
1478 --- a/src/math/i386/remainderf.s
1479 +++ b/src/math/i386/remainderf.s
1480 @@ -7,7 +7,7 @@ dremf:
1481         flds 8(%esp)
1482         flds 4(%esp)
1483  1:     fprem1
1484 -       fstsw %ax
1485 +       fnstsw %ax
1486         sahf
1487         jp 1b
1488         fstp %st(1)
1489 --- a/src/math/i386/remainderl.s
1490 +++ b/src/math/i386/remainderl.s
1491 @@ -4,7 +4,7 @@ remainderl:
1492         fldt 16(%esp)
1493         fldt 4(%esp)
1494  1:     fprem1
1495 -       fstsw %ax
1496 +       fnstsw %ax
1497         sahf
1498         jp 1b
1499         fstp %st(1)
1500 --- a/src/math/i386/sqrt.s
1501 +++ b/src/math/i386/sqrt.s
1502 @@ -2,7 +2,7 @@
1503  .type sqrt,@function
1504  sqrt:  fldl 4(%esp)
1505         fsqrt
1506 -       fstsw %ax
1507 +       fnstsw %ax
1508         sub $12,%esp
1509         fld %st(0)
1510         fstpt (%esp)
1511 --- a/src/math/modfl.c
1512 +++ b/src/math/modfl.c
1513 @@ -11,11 +11,9 @@ long double modfl(long double x, long do
1514         return r;
1515  }
1516  #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
1517 -#if LDBL_MANT_DIG == 64
1518 -#define TOINT 0x1p63
1519 -#elif LDBL_MANT_DIG == 113
1520 -#define TOINT 0x1p112
1521 -#endif
1522 +
1523 +static const long double toint = 1/LDBL_EPSILON;
1524 +
1525  long double modfl(long double x, long double *iptr)
1526  {
1527         union ldshape u = {x};
1528 @@ -40,7 +38,7 @@ long double modfl(long double x, long do
1529  
1530         /* raises spurious inexact */
1531         absx = s ? -x : x;
1532 -       y = absx + TOINT - TOINT - absx;
1533 +       y = absx + toint - toint - absx;
1534         if (y == 0) {
1535                 *iptr = x;
1536                 return s ? -0.0 : 0.0;
1537 --- a/src/math/rint.c
1538 +++ b/src/math/rint.c
1539 @@ -1,6 +1,14 @@
1540 +#include <float.h>
1541  #include <math.h>
1542  #include <stdint.h>
1543  
1544 +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
1545 +#define EPS DBL_EPSILON
1546 +#elif FLT_EVAL_METHOD==2
1547 +#define EPS LDBL_EPSILON
1548 +#endif
1549 +static const double_t toint = 1/EPS;
1550 +
1551  double rint(double x)
1552  {
1553         union {double f; uint64_t i;} u = {x};
1554 @@ -11,9 +19,9 @@ double rint(double x)
1555         if (e >= 0x3ff+52)
1556                 return x;
1557         if (s)
1558 -               y = (double)(x - 0x1p52) + 0x1p52;
1559 +               y = x - toint + toint;
1560         else
1561 -               y = (double)(x + 0x1p52) - 0x1p52;
1562 +               y = x + toint - toint;
1563         if (y == 0)
1564                 return s ? -0.0 : 0;
1565         return y;
1566 --- a/src/math/rintf.c
1567 +++ b/src/math/rintf.c
1568 @@ -1,6 +1,16 @@
1569 +#include <float.h>
1570  #include <math.h>
1571  #include <stdint.h>
1572  
1573 +#if FLT_EVAL_METHOD==0
1574 +#define EPS FLT_EPSILON
1575 +#elif FLT_EVAL_METHOD==1
1576 +#define EPS DBL_EPSILON
1577 +#elif FLT_EVAL_METHOD==2
1578 +#define EPS LDBL_EPSILON
1579 +#endif
1580 +static const float_t toint = 1/EPS;
1581 +
1582  float rintf(float x)
1583  {
1584         union {float f; uint32_t i;} u = {x};
1585 @@ -11,9 +21,9 @@ float rintf(float x)
1586         if (e >= 0x7f+23)
1587                 return x;
1588         if (s)
1589 -               y = (float)(x - 0x1p23f) + 0x1p23f;
1590 +               y = x - toint + toint;
1591         else
1592 -               y = (float)(x + 0x1p23f) - 0x1p23f;
1593 +               y = x + toint - toint;
1594         if (y == 0)
1595                 return s ? -0.0f : 0.0f;
1596         return y;
1597 --- a/src/math/rintl.c
1598 +++ b/src/math/rintl.c
1599 @@ -6,11 +6,9 @@ long double rintl(long double x)
1600         return rint(x);
1601  }
1602  #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
1603 -#if LDBL_MANT_DIG == 64
1604 -#define TOINT 0x1p63
1605 -#elif LDBL_MANT_DIG == 113
1606 -#define TOINT 0x1p112
1607 -#endif
1608 +
1609 +static const long double toint = 1/LDBL_EPSILON;
1610 +
1611  long double rintl(long double x)
1612  {
1613         union ldshape u = {x};
1614 @@ -21,9 +19,9 @@ long double rintl(long double x)
1615         if (e >= 0x3fff+LDBL_MANT_DIG-1)
1616                 return x;
1617         if (s)
1618 -               y = x - TOINT + TOINT;
1619 +               y = x - toint + toint;
1620         else
1621 -               y = x + TOINT - TOINT;
1622 +               y = x + toint - toint;
1623         if (y == 0)
1624                 return 0*x;
1625         return y;
1626 --- a/src/math/round.c
1627 +++ b/src/math/round.c
1628 @@ -1,5 +1,12 @@
1629  #include "libm.h"
1630  
1631 +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
1632 +#define EPS DBL_EPSILON
1633 +#elif FLT_EVAL_METHOD==2
1634 +#define EPS LDBL_EPSILON
1635 +#endif
1636 +static const double_t toint = 1/EPS;
1637 +
1638  double round(double x)
1639  {
1640         union {double f; uint64_t i;} u = {x};
1641 @@ -12,10 +19,10 @@ double round(double x)
1642                 x = -x;
1643         if (e < 0x3ff-1) {
1644                 /* raise inexact if x!=0 */
1645 -               FORCE_EVAL(x + 0x1p52);
1646 +               FORCE_EVAL(x + toint);
1647                 return 0*u.f;
1648         }
1649 -       y = (double)(x + 0x1p52) - 0x1p52 - x;
1650 +       y = x + toint - toint - x;
1651         if (y > 0.5)
1652                 y = y + x - 1;
1653         else if (y <= -0.5)
1654 --- a/src/math/roundf.c
1655 +++ b/src/math/roundf.c
1656 @@ -1,5 +1,14 @@
1657  #include "libm.h"
1658  
1659 +#if FLT_EVAL_METHOD==0
1660 +#define EPS FLT_EPSILON
1661 +#elif FLT_EVAL_METHOD==1
1662 +#define EPS DBL_EPSILON
1663 +#elif FLT_EVAL_METHOD==2
1664 +#define EPS LDBL_EPSILON
1665 +#endif
1666 +static const float_t toint = 1/EPS;
1667 +
1668  float roundf(float x)
1669  {
1670         union {float f; uint32_t i;} u = {x};
1671 @@ -11,10 +20,10 @@ float roundf(float x)
1672         if (u.i >> 31)
1673                 x = -x;
1674         if (e < 0x7f-1) {
1675 -               FORCE_EVAL(x + 0x1p23f);
1676 +               FORCE_EVAL(x + toint);
1677                 return 0*u.f;
1678         }
1679 -       y = (float)(x + 0x1p23f) - 0x1p23f - x;
1680 +       y = x + toint - toint - x;
1681         if (y > 0.5f)
1682                 y = y + x - 1;
1683         else if (y <= -0.5f)
1684 --- a/src/math/roundl.c
1685 +++ b/src/math/roundl.c
1686 @@ -6,11 +6,9 @@ long double roundl(long double x)
1687         return round(x);
1688  }
1689  #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
1690 -#if LDBL_MANT_DIG == 64
1691 -#define TOINT 0x1p63
1692 -#elif LDBL_MANT_DIG == 113
1693 -#define TOINT 0x1p112
1694 -#endif
1695 +
1696 +static const long double toint = 1/LDBL_EPSILON;
1697 +
1698  long double roundl(long double x)
1699  {
1700         union ldshape u = {x};
1701 @@ -22,10 +20,10 @@ long double roundl(long double x)
1702         if (u.i.se >> 15)
1703                 x = -x;
1704         if (e < 0x3fff-1) {
1705 -               FORCE_EVAL(x + TOINT);
1706 +               FORCE_EVAL(x + toint);
1707                 return 0*u.f;
1708         }
1709 -       y = x + TOINT - TOINT - x;
1710 +       y = x + toint - toint - x;
1711         if (y > 0.5)
1712                 y = y + x - 1;
1713         else if (y <= -0.5)
1714 --- a/src/math/truncl.c
1715 +++ b/src/math/truncl.c
1716 @@ -6,11 +6,9 @@ long double truncl(long double x)
1717         return trunc(x);
1718  }
1719  #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
1720 -#if LDBL_MANT_DIG == 64
1721 -#define TOINT 0x1p63
1722 -#elif LDBL_MANT_DIG == 113
1723 -#define TOINT 0x1p112
1724 -#endif
1725 +
1726 +static const long double toint = 1/LDBL_EPSILON;
1727 +
1728  long double truncl(long double x)
1729  {
1730         union ldshape u = {x};
1731 @@ -27,7 +25,7 @@ long double truncl(long double x)
1732         /* y = int(|x|) - |x|, where int(|x|) is an integer neighbor of |x| */
1733         if (s)
1734                 x = -x;
1735 -       y = x + TOINT - TOINT - x;
1736 +       y = x + toint - toint - x;
1737         if (y > 0)
1738                 y -= 1;
1739         x += y;
1740 --- a/src/math/x32/exp2l.s
1741 +++ b/src/math/x32/exp2l.s
1742 @@ -6,9 +6,7 @@ expm1l:
1743         fmulp
1744         movl $0xc2820000,-4(%esp)
1745         flds -4(%esp)
1746 -       fucomp %st(1)
1747 -       fnstsw %ax
1748 -       sahf
1749 +       fucomip %st(1)
1750         fld1
1751         jb 1f
1752                 # x*log2e <= -65, return -1 without underflow
1753 @@ -17,11 +15,8 @@ expm1l:
1754         ret
1755  1:     fld %st(1)
1756         fabs
1757 -       fucom %st(1)
1758 -       fnstsw %ax
1759 +       fucomip %st(1)
1760         fstp %st(0)
1761 -       fstp %st(0)
1762 -       sahf
1763         ja 1f
1764         f2xm1
1765         ret
1766 @@ -53,9 +48,7 @@ exp2l:
1767         fld %st(1)
1768         fsub %st(1)
1769         faddp
1770 -       fucomp %st(1)
1771 -       fnstsw
1772 -       sahf
1773 +       fucomip %st(1)
1774         je 2f             # x - 0x1p63 + 0x1p63 == x
1775         movl $1,(%esp)
1776         flds (%esp)       # 0x1p-149
1777 --- a/src/math/x32/fmodl.s
1778 +++ b/src/math/x32/fmodl.s
1779 @@ -4,8 +4,8 @@ fmodl:
1780         fldt 24(%esp)
1781         fldt 8(%esp)
1782  1:     fprem
1783 -       fstsw %ax
1784 -       sahf
1785 -       jp 1b
1786 +       fnstsw %ax
1787 +       testb $4,%ah
1788 +       jnz 1b
1789         fstp %st(1)
1790         ret
1791 --- a/src/math/x32/remainderl.s
1792 +++ b/src/math/x32/remainderl.s
1793 @@ -4,8 +4,8 @@ remainderl:
1794         fldt 24(%esp)
1795         fldt 8(%esp)
1796  1:     fprem1
1797 -       fstsw %ax
1798 -       sahf
1799 -       jp 1b
1800 +       fnstsw %ax
1801 +       testb $4,%ah
1802 +       jnz 1b
1803         fstp %st(1)
1804         ret
1805 --- a/src/math/x86_64/exp2l.s
1806 +++ b/src/math/x86_64/exp2l.s
1807 @@ -6,9 +6,7 @@ expm1l:
1808         fmulp
1809         movl $0xc2820000,-4(%rsp)
1810         flds -4(%rsp)
1811 -       fucomp %st(1)
1812 -       fnstsw %ax
1813 -       sahf
1814 +       fucomip %st(1)
1815         fld1
1816         jb 1f
1817                 # x*log2e <= -65, return -1 without underflow
1818 @@ -17,11 +15,8 @@ expm1l:
1819         ret
1820  1:     fld %st(1)
1821         fabs
1822 -       fucom %st(1)
1823 -       fnstsw %ax
1824 +       fucomip %st(1)
1825         fstp %st(0)
1826 -       fstp %st(0)
1827 -       sahf
1828         ja 1f
1829         f2xm1
1830         ret
1831 @@ -53,9 +48,7 @@ exp2l:
1832         fld %st(1)
1833         fsub %st(1)
1834         faddp
1835 -       fucomp %st(1)
1836 -       fnstsw
1837 -       sahf
1838 +       fucomip %st(1)
1839         je 2f             # x - 0x1p63 + 0x1p63 == x
1840         movl $1,(%rsp)
1841         flds (%rsp)       # 0x1p-149
1842 --- a/src/math/x86_64/fmodl.s
1843 +++ b/src/math/x86_64/fmodl.s
1844 @@ -4,8 +4,8 @@ fmodl:
1845         fldt 24(%rsp)
1846         fldt 8(%rsp)
1847  1:     fprem
1848 -       fstsw %ax
1849 -       sahf
1850 -       jp 1b
1851 +       fnstsw %ax
1852 +       testb $4,%ah
1853 +       jnz 1b
1854         fstp %st(1)
1855         ret
1856 --- a/src/math/x86_64/remainderl.s
1857 +++ b/src/math/x86_64/remainderl.s
1858 @@ -4,8 +4,8 @@ remainderl:
1859         fldt 24(%rsp)
1860         fldt 8(%rsp)
1861  1:     fprem1
1862 -       fstsw %ax
1863 -       sahf
1864 -       jp 1b
1865 +       fnstsw %ax
1866 +       testb $4,%ah
1867 +       jnz 1b
1868         fstp %st(1)
1869         ret
1870 --- a/src/misc/forkpty.c
1871 +++ b/src/misc/forkpty.c
1872 @@ -1,38 +1,57 @@
1873  #include <pty.h>
1874 +#include <utmp.h>
1875  #include <unistd.h>
1876 -#include <sys/ioctl.h>
1877 +#include <errno.h>
1878  #include <fcntl.h>
1879 +#include <sys/wait.h>
1880 +#include <pthread.h>
1881  
1882 -int forkpty(int *m, char *name, const struct termios *tio, const struct winsize *ws)
1883 +int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws)
1884  {
1885 -       int s, t, i, istmp[3]={0};
1886 -       pid_t pid;
1887 +       int m, s, ec=0, p[2], cs;
1888 +       pid_t pid=-1;
1889 +       sigset_t set, oldset;
1890  
1891 -       if (openpty(m, &s, name, tio, ws) < 0) return -1;
1892 +       if (openpty(&m, &s, name, tio, ws) < 0) return -1;
1893  
1894 -       /* Ensure before forking that we don't exceed fd limit */
1895 -       for (i=0; i<3; i++) {
1896 -               if (fcntl(i, F_GETFL) < 0) {
1897 -                       t = fcntl(s, F_DUPFD, i);
1898 -                       if (t<0) break;
1899 -                       else if (t!=i) close(t);
1900 -                       else istmp[i] = 1;
1901 -               }
1902 +       sigfillset(&set);
1903 +       pthread_sigmask(SIG_BLOCK, &set, &oldset);
1904 +       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
1905 +
1906 +       if (pipe2(p, O_CLOEXEC)) {
1907 +               close(s);
1908 +               goto out;
1909         }
1910 -       pid = i==3 ? fork() : -1;
1911 +
1912 +       pid = fork();
1913         if (!pid) {
1914 -               close(*m);
1915 -               setsid();
1916 -               ioctl(s, TIOCSCTTY, (char *)0);
1917 -               dup2(s, 0);
1918 -               dup2(s, 1);
1919 -               dup2(s, 2);
1920 -               if (s>2) close(s);
1921 +               close(m);
1922 +               close(p[0]);
1923 +               if (login_tty(s)) {
1924 +                       write(p[1], &errno, sizeof errno);
1925 +                       _exit(127);
1926 +               }
1927 +               close(p[1]);
1928 +               pthread_setcancelstate(cs, 0);
1929 +               pthread_sigmask(SIG_SETMASK, &oldset, 0);
1930                 return 0;
1931         }
1932 -       for (i=0; i<3; i++)
1933 -               if (istmp[i]) close(i);
1934         close(s);
1935 -       if (pid < 0) close(*m);
1936 +       close(p[1]);
1937 +       if (read(p[0], &ec, sizeof ec) > 0) {
1938 +               int status;
1939 +               waitpid(pid, &status, 0);
1940 +               pid = -1;
1941 +               errno = ec;
1942 +       }
1943 +       close(p[0]);
1944 +
1945 +out:
1946 +       if (pid > 0) *pm = m;
1947 +       else close(m);
1948 +
1949 +       pthread_setcancelstate(cs, 0);
1950 +       pthread_sigmask(SIG_SETMASK, &oldset, 0);
1951 +
1952         return pid;
1953  }
1954 --- a/src/misc/getopt.c
1955 +++ b/src/misc/getopt.c
1956 @@ -4,6 +4,7 @@
1957  #include <limits.h>
1958  #include <stdlib.h>
1959  #include "libc.h"
1960 +#include "locale_impl.h"
1961  
1962  char *optarg;
1963  int optind=1, opterr=1, optopt, __optpos, __optreset=0;
1964 @@ -11,6 +12,18 @@ int optind=1, opterr=1, optopt, __optpos
1965  #define optpos __optpos
1966  weak_alias(__optreset, optreset);
1967  
1968 +void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
1969 +{
1970 +       FILE *f = stderr;
1971 +       b = __lctrans_cur(b);
1972 +       flockfile(f);
1973 +       fwrite(a, strlen(a), 1, f)
1974 +       && fwrite(b, strlen(b), 1, f)
1975 +       && fwrite(c, l, 1, f)
1976 +       && putc('\n', f);
1977 +       funlockfile(f);
1978 +}
1979 +
1980  int getopt(int argc, char * const argv[], const char *optstring)
1981  {
1982         int i;
1983 @@ -24,8 +37,20 @@ int getopt(int argc, char * const argv[]
1984                 optind = 1;
1985         }
1986  
1987 -       if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1])
1988 +       if (optind >= argc || !argv[optind])
1989 +               return -1;
1990 +
1991 +       if (argv[optind][0] != '-') {
1992 +               if (optstring[0] == '-') {
1993 +                       optarg = argv[optind++];
1994 +                       return 1;
1995 +               }
1996 +               return -1;
1997 +       }
1998 +
1999 +       if (!argv[optind][1])
2000                 return -1;
2001 +
2002         if (argv[optind][1] == '-' && !argv[optind][2])
2003                 return optind++, -1;
2004  
2005 @@ -43,30 +68,31 @@ int getopt(int argc, char * const argv[]
2006                 optpos = 0;
2007         }
2008  
2009 -       for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1);
2010 +       if (optstring[0] == '-' || optstring[0] == '+')
2011 +               optstring++;
2012 +
2013 +       i = 0;
2014 +       d = 0;
2015 +       do {
2016 +               l = mbtowc(&d, optstring+i, MB_LEN_MAX);
2017 +               if (l>0) i+=l; else i++;
2018 +       } while (l && d != c);
2019  
2020         if (d != c) {
2021 -               if (optstring[0] != ':' && opterr) {
2022 -                       write(2, argv[0], strlen(argv[0]));
2023 -                       write(2, ": illegal option: ", 18);
2024 -                       write(2, optchar, k);
2025 -                       write(2, "\n", 1);
2026 -               }
2027 +               if (optstring[0] != ':' && opterr)
2028 +                       __getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
2029                 return '?';
2030         }
2031 -       if (optstring[i+1] == ':') {
2032 -               if (optind >= argc) {
2033 +       if (optstring[i] == ':') {
2034 +               if (optstring[i+1] == ':') optarg = 0;
2035 +               else if (optind >= argc) {
2036                         if (optstring[0] == ':') return ':';
2037 -                       if (opterr) {
2038 -                               write(2, argv[0], strlen(argv[0]));
2039 -                               write(2, ": option requires an argument: ", 31);
2040 -                               write(2, optchar, k);
2041 -                               write(2, "\n", 1);
2042 -                       }
2043 +                       if (opterr) __getopt_msg(argv[0],
2044 +                               ": option requires an argument: ",
2045 +                               optchar, k);
2046                         return '?';
2047                 }
2048 -               if (optstring[i+2] == ':') optarg = 0;
2049 -               if (optstring[i+2] != ':' || optpos) {
2050 +               if (optstring[i+1] != ':' || optpos) {
2051                         optarg = argv[optind++] + optpos;
2052                         optpos = 0;
2053                 }
2054 --- a/src/misc/getopt_long.c
2055 +++ b/src/misc/getopt_long.c
2056 @@ -2,37 +2,106 @@
2057  #include <stddef.h>
2058  #include <getopt.h>
2059  #include <stdio.h>
2060 +#include <string.h>
2061  
2062  extern int __optpos, __optreset;
2063  
2064 +static void permute(char *const *argv, int dest, int src)
2065 +{
2066 +       char **av = (char **)argv;
2067 +       char *tmp = av[src];
2068 +       int i;
2069 +       for (i=src; i>dest; i--)
2070 +               av[i] = av[i-1];
2071 +       av[dest] = tmp;
2072 +}
2073 +
2074 +void __getopt_msg(const char *, const char *, const char *, size_t);
2075 +
2076 +static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly);
2077 +
2078  static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
2079  {
2080 +       int ret, skipped, resumed;
2081 +       const char *optstring2 = optstring + 1;
2082         if (!optind || __optreset) {
2083                 __optreset = 0;
2084                 __optpos = 0;
2085                 optind = 1;
2086         }
2087 -       if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1;
2088 -       if ((longonly && argv[optind][1]) ||
2089 -               (argv[optind][1] == '-' && argv[optind][2]))
2090 -       {
2091 +       if (optind >= argc || !argv[optind]) return -1;
2092 +       skipped = optind;
2093 +       if (optstring[0] != '+' && optstring[0] != '-') {
2094                 int i;
2095 -               for (i=0; longopts[i].name; i++) {
2096 +               for (i=optind; ; i++) {
2097 +                       if (i >= argc || !argv[i]) return -1;
2098 +                       if (argv[i][0] == '-' && argv[i][1]) break;
2099 +               }
2100 +               optind = i;
2101 +               optstring2 = optstring;
2102 +       }
2103 +       resumed = optind;
2104 +       ret = __getopt_long_core(argc, argv, optstring2, longopts, idx, longonly);
2105 +       if (resumed > skipped) {
2106 +               int i, cnt = optind-resumed;
2107 +               for (i=0; i<cnt; i++)
2108 +                       permute(argv, skipped, optind-1);
2109 +               optind = skipped + cnt;
2110 +       }
2111 +       return ret;
2112 +}
2113 +
2114 +static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
2115 +{
2116 +
2117 +       if (longopts && argv[optind][0] == '-' &&
2118 +               ((longonly && argv[optind][1]) ||
2119 +                (argv[optind][1] == '-' && argv[optind][2])))
2120 +       {
2121 +               int i, cnt, match;
2122 +               char *opt;
2123 +               for (cnt=i=0; longopts[i].name; i++) {
2124                         const char *name = longopts[i].name;
2125 -                       char *opt = argv[optind]+1;
2126 +                       opt = argv[optind]+1;
2127                         if (*opt == '-') opt++;
2128                         for (; *name && *name == *opt; name++, opt++);
2129 -                       if (*name || (*opt && *opt != '=')) continue;
2130 +                       if (*opt && *opt != '=') continue;
2131 +                       match = i;
2132 +                       if (!*name) {
2133 +                               cnt = 1;
2134 +                               break;
2135 +                       }
2136 +                       cnt++;
2137 +               }
2138 +               if (cnt==1) {
2139 +                       i = match;
2140 +                       optind++;
2141 +                       optopt = longopts[i].val;
2142                         if (*opt == '=') {
2143 -                               if (!longopts[i].has_arg) continue;
2144 +                               if (!longopts[i].has_arg) {
2145 +                                       if (optstring[0] == ':' || !opterr)
2146 +                                               return '?';
2147 +                                       __getopt_msg(argv[0],
2148 +                                               ": option does not take an argument: ",
2149 +                                               longopts[i].name,
2150 +                                               strlen(longopts[i].name));
2151 +                                       return '?';
2152 +                               }
2153                                 optarg = opt+1;
2154                         } else {
2155                                 if (longopts[i].has_arg == required_argument) {
2156 -                                       if (!(optarg = argv[++optind]))
2157 -                                               return ':';
2158 +                                       if (!(optarg = argv[optind])) {
2159 +                                               if (optstring[0] == ':' || !opterr)
2160 +                                                       return ':';
2161 +                                               __getopt_msg(argv[0],
2162 +                                                       ": option requires an argument: ",
2163 +                                                       longopts[i].name,
2164 +                                                       strlen(longopts[i].name));
2165 +                                               return '?';
2166 +                                       }
2167 +                                       optind++;
2168                                 } else optarg = NULL;
2169                         }
2170 -                       optind++;
2171                         if (idx) *idx = i;
2172                         if (longopts[i].flag) {
2173                                 *longopts[i].flag = longopts[i].val;
2174 @@ -41,6 +110,12 @@ static int __getopt_long(int argc, char 
2175                         return longopts[i].val;
2176                 }
2177                 if (argv[optind][1] == '-') {
2178 +                       if (optstring[0] != ':' && opterr)
2179 +                               __getopt_msg(argv[0], cnt ?
2180 +                                       ": option is ambiguous: " :
2181 +                                       ": unrecognized option: ",
2182 +                                       argv[optind]+2,
2183 +                                       strlen(argv[optind]+2));
2184                         optind++;
2185                         return '?';
2186                 }
2187 --- /dev/null
2188 +++ b/src/misc/login_tty.c
2189 @@ -0,0 +1,14 @@
2190 +#include <utmp.h>
2191 +#include <sys/ioctl.h>
2192 +#include <unistd.h>
2193 +
2194 +int login_tty(int fd)
2195 +{
2196 +       setsid();
2197 +       if (ioctl(fd, TIOCSCTTY, (char *)0)) return -1;
2198 +       dup2(fd, 0);
2199 +       dup2(fd, 1);
2200 +       dup2(fd, 2);
2201 +       if (fd>2) close(fd);
2202 +       return 0;
2203 +}
2204 --- a/src/misc/openpty.c
2205 +++ b/src/misc/openpty.c
2206 @@ -3,31 +3,38 @@
2207  #include <unistd.h>
2208  #include <pty.h>
2209  #include <stdio.h>
2210 +#include <pthread.h>
2211  
2212  /* Nonstandard, but vastly superior to the standard functions */
2213  
2214 -int openpty(int *m, int *s, char *name, const struct termios *tio, const struct winsize *ws)
2215 +int openpty(int *pm, int *ps, char *name, const struct termios *tio, const struct winsize *ws)
2216  {
2217 -       int n=0;
2218 +       int m, s, n=0, cs;
2219         char buf[20];
2220  
2221 -       *m = open("/dev/ptmx", O_RDWR|O_NOCTTY);
2222 -       if (*m < 0) return -1;
2223 +       m = open("/dev/ptmx", O_RDWR|O_NOCTTY);
2224 +       if (m < 0) return -1;
2225  
2226 -       if (ioctl(*m, TIOCSPTLCK, &n) || ioctl (*m, TIOCGPTN, &n)) {
2227 -               close(*m);
2228 -               return -1;
2229 -       }
2230 +       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
2231 +
2232 +       if (ioctl(m, TIOCSPTLCK, &n) || ioctl (m, TIOCGPTN, &n))
2233 +               goto fail;
2234  
2235         if (!name) name = buf;
2236         snprintf(name, sizeof buf, "/dev/pts/%d", n);
2237 -       if ((*s = open(name, O_RDWR|O_NOCTTY)) < 0) {
2238 -               close(*m);
2239 -               return -1;
2240 -       }
2241 +       if ((s = open(name, O_RDWR|O_NOCTTY)) < 0)
2242 +               goto fail;
2243 +
2244 +       if (tio) tcsetattr(s, TCSANOW, tio);
2245 +       if (ws) ioctl(s, TIOCSWINSZ, ws);
2246  
2247 -       if (tio) tcsetattr(*s, TCSANOW, tio);
2248 -       if (ws) ioctl(*s, TIOCSWINSZ, ws);
2249 +       *pm = m;
2250 +       *ps = s;
2251  
2252 +       pthread_setcancelstate(cs, 0);
2253         return 0;
2254 +fail:
2255 +       close(m);
2256 +       pthread_setcancelstate(cs, 0);
2257 +       return -1;
2258  }
2259 --- a/src/misc/syslog.c
2260 +++ b/src/misc/syslog.c
2261 @@ -46,8 +46,12 @@ void closelog(void)
2262  
2263  static void __openlog()
2264  {
2265 -       log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
2266 -       if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr);
2267 +       int fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
2268 +       if (fd < 0) return;
2269 +       if (connect(fd, (void *)&log_addr, sizeof log_addr) < 0)
2270 +               close(fd);
2271 +       else
2272 +               log_fd = fd;
2273  }
2274  
2275  void openlog(const char *ident, int opt, int facility)
2276 --- a/src/multibyte/c16rtomb.c
2277 +++ b/src/multibyte/c16rtomb.c
2278 @@ -4,6 +4,8 @@
2279  
2280  size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps)
2281  {
2282 +       static unsigned internal_state;
2283 +       if (!ps) ps = (void *)&internal_state;
2284         unsigned *x = (unsigned *)ps;
2285         wchar_t wc;
2286  
2287 --- a/src/multibyte/mbrtoc16.c
2288 +++ b/src/multibyte/mbrtoc16.c
2289 @@ -3,6 +3,8 @@
2290  
2291  size_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps)
2292  {
2293 +       static unsigned internal_state;
2294 +       if (!ps) ps = (void *)&internal_state;
2295         unsigned *pending = (unsigned *)ps;
2296  
2297         if (!s) return mbrtoc16(0, "", 1, ps);
2298 --- a/src/multibyte/mbrtoc32.c
2299 +++ b/src/multibyte/mbrtoc32.c
2300 @@ -3,6 +3,8 @@
2301  
2302  size_t mbrtoc32(char32_t *restrict pc32, const char *restrict s, size_t n, mbstate_t *restrict ps)
2303  {
2304 +       static unsigned internal_state;
2305 +       if (!ps) ps = (void *)&internal_state;
2306         if (!s) return mbrtoc32(0, "", 1, ps);
2307         wchar_t wc;
2308         size_t ret = mbrtowc(&wc, s, n, ps);
2309 --- a/src/multibyte/wcsnrtombs.c
2310 +++ b/src/multibyte/wcsnrtombs.c
2311 @@ -40,7 +40,7 @@ size_t wcsnrtombs(char *restrict dst, co
2312                 ws++; wn--;
2313                 /* safe - this loop runs fewer than sizeof(buf) times */
2314                 s+=l; n-=l;
2315 -               cnt++;
2316 +               cnt += l;
2317         }
2318         if (dst) *wcs = ws;
2319         return cnt;
2320 --- /dev/null
2321 +++ b/src/network/ns_parse.c
2322 @@ -0,0 +1,171 @@
2323 +#define _BSD_SOURCE
2324 +#include <errno.h>
2325 +#include <stddef.h>
2326 +#include <resolv.h>
2327 +#include <arpa/nameser.h>
2328 +
2329 +const struct _ns_flagdata _ns_flagdata[16] = {
2330 +       { 0x8000, 15 },
2331 +       { 0x7800, 11 },
2332 +       { 0x0400, 10 },
2333 +       { 0x0200, 9 },
2334 +       { 0x0100, 8 },
2335 +       { 0x0080, 7 },
2336 +       { 0x0040, 6 },
2337 +       { 0x0020, 5 },
2338 +       { 0x0010, 4 },
2339 +       { 0x000f, 0 },
2340 +       { 0x0000, 0 },
2341 +       { 0x0000, 0 },
2342 +       { 0x0000, 0 },
2343 +       { 0x0000, 0 },
2344 +       { 0x0000, 0 },
2345 +       { 0x0000, 0 },
2346 +};
2347 +
2348 +unsigned ns_get16(const unsigned char *cp)
2349 +{
2350 +       return cp[0]<<8 | cp[1];
2351 +}
2352 +
2353 +unsigned long ns_get32(const unsigned char *cp)
2354 +{
2355 +       return (unsigned)cp[0]<<24 | cp[1]<<16 | cp[2]<<8 | cp[3];
2356 +}
2357 +
2358 +void ns_put16(unsigned s, unsigned char *cp)
2359 +{
2360 +       *cp++ = s>>8;
2361 +       *cp++ = s;
2362 +}
2363 +
2364 +void ns_put32(unsigned long l, unsigned char *cp)
2365 +{
2366 +       *cp++ = l>>24;
2367 +       *cp++ = l>>16;
2368 +       *cp++ = l>>8;
2369 +       *cp++ = l;
2370 +}
2371 +
2372 +int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
2373 +{
2374 +       int i, r;
2375 +
2376 +       handle->_msg = msg;
2377 +       handle->_eom = msg + msglen;
2378 +       if (msglen < (2 + ns_s_max) * NS_INT16SZ) goto bad;
2379 +       NS_GET16(handle->_id, msg);
2380 +       NS_GET16(handle->_flags, msg);
2381 +       for (i = 0; i < ns_s_max; i++) NS_GET16(handle->_counts[i], msg);
2382 +       for (i = 0; i < ns_s_max; i++) {
2383 +               if (handle->_counts[i]) {
2384 +                       handle->_sections[i] = msg;
2385 +                       r = ns_skiprr(msg, handle->_eom, i, handle->_counts[i]);
2386 +                       if (r < 0) return -1;
2387 +                       msg += r;
2388 +               } else {
2389 +                       handle->_sections[i] = NULL;
2390 +               }
2391 +       }
2392 +       if (msg != handle->_eom) goto bad;
2393 +       handle->_sect = ns_s_max;
2394 +       handle->_rrnum = -1;
2395 +       handle->_msg_ptr = NULL;
2396 +       return 0;
2397 +bad:
2398 +       errno = EMSGSIZE;
2399 +       return -1;
2400 +}
2401 +
2402 +int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count)
2403 +{
2404 +       const unsigned char *p = ptr;
2405 +       int r;
2406 +
2407 +       while (count--) {
2408 +               r = dn_skipname(p, eom);
2409 +               if (r < 0) goto bad;
2410 +               if (r + 2 * NS_INT16SZ > eom - p) goto bad;
2411 +               p += r + 2 * NS_INT16SZ;
2412 +               if (section != ns_s_qd) {
2413 +                       if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad;
2414 +                       p += NS_INT32SZ;
2415 +                       NS_GET16(r, p);
2416 +                       if (r > eom - p) goto bad;
2417 +                       p += r;
2418 +               }
2419 +       }
2420 +       return ptr - p;
2421 +bad:
2422 +       errno = EMSGSIZE;
2423 +       return -1;
2424 +}
2425 +
2426 +int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
2427 +{
2428 +       int r;
2429 +
2430 +       if (section < 0 || section >= ns_s_max) goto bad;
2431 +       if (section != handle->_sect) {
2432 +               handle->_sect = section;
2433 +               handle->_rrnum = 0;
2434 +               handle->_msg_ptr = handle->_sections[section];
2435 +       }
2436 +       if (rrnum == -1) rrnum = handle->_rrnum;
2437 +       if (rrnum < 0 || rrnum >= handle->_counts[section]) goto bad;
2438 +       if (rrnum < handle->_rrnum) {
2439 +               handle->_rrnum = 0;
2440 +               handle->_msg_ptr = handle->_sections[section];
2441 +       }
2442 +       if (rrnum > handle->_rrnum) {
2443 +               r = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum);
2444 +               if (r < 0) return -1;
2445 +               handle->_msg_ptr += r;
2446 +               handle->_rrnum = rrnum;
2447 +       }
2448 +       r = ns_name_uncompress(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME);
2449 +       if (r < 0) return -1;
2450 +       handle->_msg_ptr += r;
2451 +       if (2 * NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
2452 +       NS_GET16(rr->type, handle->_msg_ptr);
2453 +       NS_GET16(rr->rr_class, handle->_msg_ptr);
2454 +       if (section != ns_s_qd) {
2455 +               if (NS_INT32SZ + NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
2456 +               NS_GET32(rr->ttl, handle->_msg_ptr);
2457 +               NS_GET16(rr->rdlength, handle->_msg_ptr);
2458 +               if (rr->rdlength > handle->_eom - handle->_msg_ptr) goto size;
2459 +               rr->rdata = handle->_msg_ptr;
2460 +               handle->_msg_ptr += rr->rdlength;
2461 +       } else {
2462 +               rr->ttl = 0;
2463 +               rr->rdlength = 0;
2464 +               rr->rdata = NULL;
2465 +       }
2466 +       handle->_rrnum++;
2467 +       if (handle->_rrnum > handle->_counts[section]) {
2468 +               handle->_sect = section + 1;
2469 +               if (handle->_sect == ns_s_max) {
2470 +                       handle->_rrnum = -1;
2471 +                       handle->_msg_ptr = NULL;
2472 +               } else {
2473 +                       handle->_rrnum = 0;
2474 +               }
2475 +       }
2476 +       return 0;
2477 +bad:
2478 +       errno = ENODEV;
2479 +       return -1;
2480 +size:
2481 +       errno = EMSGSIZE;
2482 +       return -1;
2483 +}
2484 +
2485 +int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom,
2486 +                       const unsigned char *src, char *dst, size_t dstsiz)
2487 +{
2488 +       int r;
2489 +       r = dn_expand(msg, eom, src, dst, dstsiz);
2490 +       if (r < 0) errno = EMSGSIZE;
2491 +       return r;
2492 +}
2493 +
2494 --- a/src/process/posix_spawn.c
2495 +++ b/src/process/posix_spawn.c
2496 @@ -102,8 +102,7 @@ static int child(void *args_vp)
2497                         }
2498                         switch(op->cmd) {
2499                         case FDOP_CLOSE:
2500 -                               if ((ret=__syscall(SYS_close, op->fd)))
2501 -                                       goto fail;
2502 +                               __syscall(SYS_close, op->fd);
2503                                 break;
2504                         case FDOP_DUP2:
2505                                 if ((ret=__sys_dup2(op->srcfd, op->fd))<0)
2506 @@ -137,7 +136,7 @@ static int child(void *args_vp)
2507  fail:
2508         /* Since sizeof errno < PIPE_BUF, the write is atomic. */
2509         ret = -ret;
2510 -       if (ret) while (write(p, &ret, sizeof ret) < 0);
2511 +       if (ret) while (__syscall(SYS_write, p, &ret, sizeof ret) < 0);
2512         _exit(127);
2513  }
2514  
2515 --- a/src/regex/fnmatch.c
2516 +++ b/src/regex/fnmatch.c
2517 @@ -97,7 +97,13 @@ escaped:
2518         return pat[0];
2519  }
2520  
2521 -static int match_bracket(const char *p, int k)
2522 +static int casefold(int k)
2523 +{
2524 +       int c = towupper(k);
2525 +       return c == k ? towlower(k) : c;
2526 +}
2527 +
2528 +static int match_bracket(const char *p, int k, int kfold)
2529  {
2530         wchar_t wc;
2531         int inv = 0;
2532 @@ -119,7 +125,10 @@ static int match_bracket(const char *p, 
2533                         wchar_t wc2;
2534                         int l = mbtowc(&wc2, p+1, 4);
2535                         if (l < 0) return 0;
2536 -                       if (wc<=wc2 && (unsigned)k-wc <= wc2-wc) return !inv;
2537 +                       if (wc <= wc2)
2538 +                               if ((unsigned)k-wc <= wc2-wc ||
2539 +                                   (unsigned)kfold-wc <= wc2-wc)
2540 +                                       return !inv;
2541                         p += l-1;
2542                         continue;
2543                 }
2544 @@ -132,7 +141,9 @@ static int match_bracket(const char *p, 
2545                                 char buf[16];
2546                                 memcpy(buf, p0, p-1-p0);
2547                                 buf[p-1-p0] = 0;
2548 -                               if (iswctype(k, wctype(buf))) return !inv;
2549 +                               if (iswctype(k, wctype(buf)) ||
2550 +                                   iswctype(kfold, wctype(buf)))
2551 +                                       return !inv;
2552                         }
2553                         continue;
2554                 }
2555 @@ -143,7 +154,7 @@ static int match_bracket(const char *p, 
2556                         if (l < 0) return 0;
2557                         p += l-1;
2558                 }
2559 -               if (wc==k) return !inv;
2560 +               if (wc==k || wc==kfold) return !inv;
2561         }
2562         return inv;
2563  }
2564 @@ -153,7 +164,7 @@ static int fnmatch_internal(const char *
2565         const char *p, *ptail, *endpat;
2566         const char *s, *stail, *endstr;
2567         size_t pinc, sinc, tailcnt=0;
2568 -       int c, k;
2569 +       int c, k, kfold;
2570  
2571         if (flags & FNM_PERIOD) {
2572                 if (*str == '.' && *pat != '.')
2573 @@ -173,10 +184,11 @@ static int fnmatch_internal(const char *
2574                                 return (c==END) ? 0 : FNM_NOMATCH;
2575                         str += sinc;
2576                         n -= sinc;
2577 +                       kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
2578                         if (c == BRACKET) {
2579 -                               if (!match_bracket(pat, k))
2580 +                               if (!match_bracket(pat, k, kfold))
2581                                         return FNM_NOMATCH;
2582 -                       } else if (c != QUESTION && k != c) {
2583 +                       } else if (c != QUESTION && k != c && kfold != c) {
2584                                 return FNM_NOMATCH;
2585                         }
2586                         pat+=pinc;
2587 @@ -233,10 +245,11 @@ static int fnmatch_internal(const char *
2588                         break;
2589                 }
2590                 s += sinc;
2591 +               kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
2592                 if (c == BRACKET) {
2593 -                       if (!match_bracket(p-pinc, k))
2594 +                       if (!match_bracket(p-pinc, k, kfold))
2595                                 return FNM_NOMATCH;
2596 -               } else if (c != QUESTION && k != c) {
2597 +               } else if (c != QUESTION && k != c && kfold != c) {
2598                         return FNM_NOMATCH;
2599                 }
2600         }
2601 @@ -261,10 +274,11 @@ static int fnmatch_internal(const char *
2602                         k = str_next(s, endstr-s, &sinc);
2603                         if (!k)
2604                                 return FNM_NOMATCH;
2605 +                       kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
2606                         if (c == BRACKET) {
2607 -                               if (!match_bracket(p-pinc, k))
2608 +                               if (!match_bracket(p-pinc, k, kfold))
2609                                         break;
2610 -                       } else if (c != QUESTION && k != c) {
2611 +                       } else if (c != QUESTION && k != c && kfold != c) {
2612                                 break;
2613                         }
2614                         s += sinc;
2615 --- a/src/sched/affinity.c
2616 +++ b/src/sched/affinity.c
2617 @@ -1,5 +1,6 @@
2618  #define _GNU_SOURCE
2619  #include <sched.h>
2620 +#include <string.h>
2621  #include "pthread_impl.h"
2622  #include "syscall.h"
2623  
2624 @@ -10,17 +11,23 @@ int sched_setaffinity(pid_t tid, size_t 
2625  
2626  int pthread_setaffinity_np(pthread_t td, size_t size, const cpu_set_t *set)
2627  {
2628 -       return syscall(SYS_sched_setaffinity, td->tid, size, set);
2629 +       return -__syscall(SYS_sched_setaffinity, td->tid, size, set);
2630  }
2631  
2632 -int sched_getaffinity(pid_t tid, size_t size, cpu_set_t *set)
2633 +static int do_getaffinity(pid_t tid, size_t size, cpu_set_t *set)
2634  {
2635         long ret = __syscall(SYS_sched_getaffinity, tid, size, set);
2636 -       if (ret > 0) ret = 0;
2637 -       return __syscall_ret(ret);
2638 +       if (ret < 0) return ret;
2639 +       if (ret < size) memset((char *)set+ret, 0, size-ret);
2640 +       return 0;
2641 +}
2642 +
2643 +int sched_getaffinity(pid_t tid, size_t size, cpu_set_t *set)
2644 +{
2645 +       return __syscall_ret(do_getaffinity(tid, size, set));
2646  }
2647  
2648  int pthread_getaffinity_np(pthread_t td, size_t size, cpu_set_t *set)
2649  {
2650 -       return sched_getaffinity(td->tid, size, set);
2651 +       return -do_getaffinity(td->tid, size, set);
2652  }
2653 --- a/src/setjmp/arm/longjmp.s
2654 +++ b/src/setjmp/arm/longjmp.s
2655 @@ -20,7 +20,7 @@ longjmp:
2656         ldc p2, cr4, [ip], #48
2657  2:     tst r1,#0x40
2658         beq 2f
2659 -       ldc p11, cr8, [ip], #64
2660 +       .word 0xecbc8b10 /* vldmia ip!, {d8-d15} */
2661  2:     tst r1,#0x200
2662         beq 3f
2663         ldcl p1, cr10, [ip], #8
2664 --- a/src/setjmp/arm/setjmp.s
2665 +++ b/src/setjmp/arm/setjmp.s
2666 @@ -22,7 +22,7 @@ setjmp:
2667         stc p2, cr4, [ip], #48
2668  2:     tst r1,#0x40
2669         beq 2f
2670 -       stc p11, cr8, [ip], #64
2671 +       .word 0xecac8b10 /* vstmia ip!, {d8-d15} */
2672  2:     tst r1,#0x200
2673         beq 3f
2674         stcl p1, cr10, [ip], #8
2675 --- a/src/signal/raise.c
2676 +++ b/src/signal/raise.c
2677 @@ -5,12 +5,11 @@
2678  
2679  int raise(int sig)
2680  {
2681 -       int pid, tid, ret;
2682 +       int tid, ret;
2683         sigset_t set;
2684         __block_app_sigs(&set);
2685         tid = __syscall(SYS_gettid);
2686 -       pid = __syscall(SYS_getpid);
2687 -       ret = syscall(SYS_tgkill, pid, tid, sig);
2688 +       ret = syscall(SYS_tkill, tid, sig);
2689         __restore_sigs(&set);
2690         return ret;
2691  }
2692 --- a/src/stdio/vfprintf.c
2693 +++ b/src/stdio/vfprintf.c
2694 @@ -158,7 +158,7 @@ static void pop_arg(union arg *arg, int 
2695  
2696  static void out(FILE *f, const char *s, size_t l)
2697  {
2698 -       __fwritex((void *)s, l, f);
2699 +       if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f);
2700  }
2701  
2702  static void pad(FILE *f, char c, int w, int l, int fl)
2703 @@ -225,7 +225,7 @@ static int fmt_fp(FILE *f, long double y
2704  
2705         if (!isfinite(y)) {
2706                 char *s = (t&32)?"inf":"INF";
2707 -               if (y!=y) s=(t&32)?"nan":"NAN", pl=0;
2708 +               if (y!=y) s=(t&32)?"nan":"NAN";
2709                 pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
2710                 out(f, prefix, pl);
2711                 out(f, s, 3);
2712 @@ -570,7 +570,7 @@ static int printf_core(FILE *f, const ch
2713                         if (0) {
2714                 case 'o':
2715                         a = fmt_o(arg.i, z);
2716 -                       if ((fl&ALT_FORM) && arg.i) prefix+=5, pl=1;
2717 +                       if ((fl&ALT_FORM) && p<z-a+1) p=z-a+1;
2718                         } if (0) {
2719                 case 'd': case 'i':
2720                         pl=1;
2721 @@ -656,6 +656,7 @@ int vfprintf(FILE *restrict f, const cha
2722         int nl_type[NL_ARGMAX+1] = {0};
2723         union arg nl_arg[NL_ARGMAX+1];
2724         unsigned char internal_buf[80], *saved_buf = 0;
2725 +       int olderr;
2726         int ret;
2727  
2728         /* the copy allows passing va_list* even if va_list is an array */
2729 @@ -666,6 +667,8 @@ int vfprintf(FILE *restrict f, const cha
2730         }
2731  
2732         FLOCK(f);
2733 +       olderr = f->flags & F_ERR;
2734 +       if (f->mode < 1) f->flags &= ~F_ERR;
2735         if (!f->buf_size) {
2736                 saved_buf = f->buf;
2737                 f->wpos = f->wbase = f->buf = internal_buf;
2738 @@ -680,6 +683,8 @@ int vfprintf(FILE *restrict f, const cha
2739                 f->buf_size = 0;
2740                 f->wpos = f->wbase = f->wend = 0;
2741         }
2742 +       if (f->flags & F_ERR) ret = -1;
2743 +       f->flags |= olderr;
2744         FUNLOCK(f);
2745         va_end(ap2);
2746         return ret;
2747 --- a/src/stdio/vfwprintf.c
2748 +++ b/src/stdio/vfwprintf.c
2749 @@ -149,7 +149,7 @@ static void pop_arg(union arg *arg, int 
2750  
2751  static void out(FILE *f, const wchar_t *s, size_t l)
2752  {
2753 -       while (l--) fputwc(*s++, f);
2754 +       while (l-- && !(f->flags & F_ERR)) fputwc(*s++, f);
2755  }
2756  
2757  static int getint(wchar_t **s) {
2758 @@ -345,6 +345,7 @@ int vfwprintf(FILE *restrict f, const wc
2759         va_list ap2;
2760         int nl_type[NL_ARGMAX] = {0};
2761         union arg nl_arg[NL_ARGMAX];
2762 +       int olderr;
2763         int ret;
2764  
2765         /* the copy allows passing va_list* even if va_list is an array */
2766 @@ -356,7 +357,11 @@ int vfwprintf(FILE *restrict f, const wc
2767  
2768         FLOCK(f);
2769         f->mode |= f->mode+1;
2770 +       olderr = f->flags & F_ERR;
2771 +       f->flags &= ~F_ERR;
2772         ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
2773 +       if (f->flags & F_ERR) ret = -1;
2774 +       f->flags |= olderr;
2775         FUNLOCK(f);
2776         va_end(ap2);
2777         return ret;
2778 --- a/src/string/armel/memcpy.s
2779 +++ b/src/string/armel/memcpy.s
2780 @@ -49,113 +49,113 @@ memcpy:
2781          * ARM ABI. Since we have to save R0, we might as well save R4
2782          * which we can use for better pipelining of the reads below
2783          */
2784 -        .fnstart
2785 -        .save       {r0, r4, lr}
2786 -        stmfd       sp!, {r0, r4, lr}
2787 -        /* Making room for r5-r11 which will be spilled later */
2788 -        .pad        #28
2789 -        sub         sp, sp, #28
2790 -
2791 -        /* it simplifies things to take care of len<4 early */
2792 -        cmp    r2, #4
2793 -        blo    copy_last_3_and_return
2794 -
2795 -        /* compute the offset to align the source
2796 -         * offset = (4-(src&3))&3 = -src & 3
2797 -         */
2798 -        rsb    r3, r1, #0
2799 -        ands   r3, r3, #3
2800 -        beq    src_aligned
2801 -
2802 -        /* align source to 32 bits. We need to insert 2 instructions between
2803 -         * a ldr[b|h] and str[b|h] because byte and half-word instructions
2804 -         * stall 2 cycles.
2805 -         */
2806 -        movs   r12, r3, lsl #31
2807 -        sub    r2, r2, r3              /* we know that r3 <= r2 because r2 >= 4 */
2808 -        ldrmib r3, [r1], #1
2809 -        ldrcsb r4, [r1], #1
2810 -        ldrcsb r12,[r1], #1
2811 -        strmib r3, [r0], #1
2812 -        strcsb r4, [r0], #1
2813 -        strcsb r12,[r0], #1
2814 +       .fnstart
2815 +       .save       {r0, r4, lr}
2816 +       stmfd       sp!, {r0, r4, lr}
2817 +       /* Making room for r5-r11 which will be spilled later */
2818 +       .pad        #28
2819 +       sub         sp, sp, #28
2820 +
2821 +       /* it simplifies things to take care of len<4 early */
2822 +       cmp     r2, #4
2823 +       blo     copy_last_3_and_return
2824 +
2825 +       /* compute the offset to align the source
2826 +        * offset = (4-(src&3))&3 = -src & 3
2827 +        */
2828 +       rsb     r3, r1, #0
2829 +       ands    r3, r3, #3
2830 +       beq     src_aligned
2831 +
2832 +       /* align source to 32 bits. We need to insert 2 instructions between
2833 +        * a ldr[b|h] and str[b|h] because byte and half-word instructions
2834 +        * stall 2 cycles.
2835 +        */
2836 +       movs    r12, r3, lsl #31
2837 +       sub     r2, r2, r3              /* we know that r3 <= r2 because r2 >= 4 */
2838 +       .word 0x44d13001 /* ldrbmi r3, [r1], #1 */
2839 +       .word 0x24d14001 /* ldrbcs r4, [r1], #1 */
2840 +       .word 0x24d1c001 /* ldrbcs r12,[r1], #1 */
2841 +       .word 0x44c03001 /* strbmi r3, [r0], #1 */
2842 +       .word 0x24c04001 /* strbcs r4, [r0], #1 */
2843 +       .word 0x24c0c001 /* strbcs r12,[r0], #1 */
2844  
2845  src_aligned:
2846  
2847         /* see if src and dst are aligned together (congruent) */
2848 -       eor     r12, r0, r1
2849 -        tst    r12, #3
2850 -        bne    non_congruent
2851 -
2852 -        /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
2853 -         * frame. Don't update sp.
2854 -         */
2855 -        stmea  sp, {r5-r11}
2856 -
2857 -        /* align the destination to a cache-line */
2858 -        rsb    r3, r0, #0
2859 -        ands   r3, r3, #0x1C
2860 -        beq            congruent_aligned32
2861 -        cmp            r3, r2
2862 -        andhi  r3, r2, #0x1C
2863 -
2864 -        /* conditionnaly copies 0 to 7 words (length in r3) */
2865 -        movs   r12, r3, lsl #28
2866 -        ldmcsia        r1!, {r4, r5, r6, r7}   /* 16 bytes */
2867 -        ldmmiia        r1!, {r8, r9}                   /*  8 bytes */
2868 -        stmcsia        r0!, {r4, r5, r6, r7}
2869 -        stmmiia        r0!, {r8, r9}
2870 -        tst            r3, #0x4
2871 -        ldrne  r10,[r1], #4                    /*  4 bytes */
2872 -        strne  r10,[r0], #4
2873 -        sub            r2, r2, r3
2874 +       eor     r12, r0, r1
2875 +       tst     r12, #3
2876 +       bne     non_congruent
2877 +
2878 +       /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
2879 +        * frame. Don't update sp.
2880 +        */
2881 +       stmea   sp, {r5-r11}
2882 +
2883 +       /* align the destination to a cache-line */
2884 +       rsb     r3, r0, #0
2885 +       ands    r3, r3, #0x1C
2886 +       beq     congruent_aligned32
2887 +       cmp     r3, r2
2888 +       andhi   r3, r2, #0x1C
2889 +
2890 +       /* conditionnaly copies 0 to 7 words (length in r3) */
2891 +       movs    r12, r3, lsl #28
2892 +       ldmcs   r1!, {r4, r5, r6, r7}           /* 16 bytes */
2893 +       ldmmi   r1!, {r8, r9}                   /*  8 bytes */
2894 +       stmcs   r0!, {r4, r5, r6, r7}
2895 +       stmmi   r0!, {r8, r9}
2896 +       tst     r3, #0x4
2897 +       ldrne   r10,[r1], #4                    /*  4 bytes */
2898 +       strne   r10,[r0], #4
2899 +       sub     r2, r2, r3
2900  
2901  congruent_aligned32:
2902         /*
2903 -        * here source is aligned to 32 bytes.
2904 -        */
2905 +        * here source is aligned to 32 bytes.
2906 +        */
2907  
2908  cached_aligned32:
2909 -        subs           r2, r2, #32
2910 -        blo            less_than_32_left
2911 +       subs    r2, r2, #32
2912 +       blo     less_than_32_left
2913  
2914 -        /*
2915 -         * We preload a cache-line up to 64 bytes ahead. On the 926, this will
2916 -         * stall only until the requested world is fetched, but the linefill
2917 -         * continues in the the background.
2918 -         * While the linefill is going, we write our previous cache-line
2919 -         * into the write-buffer (which should have some free space).
2920 -         * When the linefill is done, the writebuffer will
2921 -         * start dumping its content into memory
2922 -         *
2923 -         * While all this is going, we then load a full cache line into
2924 -         * 8 registers, this cache line should be in the cache by now
2925 -         * (or partly in the cache).
2926 -         *
2927 -         * This code should work well regardless of the source/dest alignment.
2928 -         *
2929 -         */
2930 -
2931 -        /* Align the preload register to a cache-line because the cpu does
2932 -         * "critical word first" (the first word requested is loaded first).
2933 -         */
2934 -        @ bic          r12, r1, #0x1F
2935 -        @ add          r12, r12, #64
2936 -
2937 -1:      ldmia          r1!, { r4-r11 }
2938 -        subs           r2, r2, #32
2939 -
2940 -        /* 
2941 -         * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
2942 -         * for ARM9 preload will not be safely guarded by the preceding subs.
2943 -         * When it is safely guarded the only possibility to have SIGSEGV here
2944 -         * is because the caller overstates the length.
2945 -         */
2946 -        @ ldrhi        r3, [r12], #32      /* cheap ARM9 preload */
2947 -        stmia          r0!, { r4-r11 }
2948 -       bhs     1b
2949 +       /*
2950 +        * We preload a cache-line up to 64 bytes ahead. On the 926, this will
2951 +        * stall only until the requested world is fetched, but the linefill
2952 +        * continues in the the background.
2953 +        * While the linefill is going, we write our previous cache-line
2954 +        * into the write-buffer (which should have some free space).
2955 +        * When the linefill is done, the writebuffer will
2956 +        * start dumping its content into memory
2957 +        *
2958 +        * While all this is going, we then load a full cache line into
2959 +        * 8 registers, this cache line should be in the cache by now
2960 +        * (or partly in the cache).
2961 +        *
2962 +        * This code should work well regardless of the source/dest alignment.
2963 +        *
2964 +        */
2965  
2966 -        add    r2, r2, #32
2967 +       /* Align the preload register to a cache-line because the cpu does
2968 +        * "critical word first" (the first word requested is loaded first).
2969 +        */
2970 +       @ bic           r12, r1, #0x1F
2971 +       @ add           r12, r12, #64
2972 +
2973 +1:      ldmia   r1!, { r4-r11 }
2974 +       subs    r2, r2, #32
2975 +
2976 +       /* 
2977 +        * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
2978 +        * for ARM9 preload will not be safely guarded by the preceding subs.
2979 +        * When it is safely guarded the only possibility to have SIGSEGV here
2980 +        * is because the caller overstates the length.
2981 +        */
2982 +       @ ldrhi         r3, [r12], #32      /* cheap ARM9 preload */
2983 +       stmia   r0!, { r4-r11 }
2984 +       bhs     1b
2985 +
2986 +       add     r2, r2, #32
2987  
2988  less_than_32_left:
2989         /*
2990 @@ -166,30 +166,30 @@ less_than_32_left:
2991          * be a common case (if not executed the code below takes
2992          * about 16 cycles)
2993          */
2994 -       tst     r2, #0x1F
2995 -        beq    1f
2996 +       tst     r2, #0x1F
2997 +       beq     1f
2998  
2999 -        /* conditionnaly copies 0 to 31 bytes */
3000 -        movs   r12, r2, lsl #28
3001 -        ldmcsia        r1!, {r4, r5, r6, r7}   /* 16 bytes */
3002 -        ldmmiia        r1!, {r8, r9}                   /*  8 bytes */
3003 -        stmcsia        r0!, {r4, r5, r6, r7}
3004 -        stmmiia        r0!, {r8, r9}
3005 -        movs   r12, r2, lsl #30
3006 -        ldrcs  r3, [r1], #4                    /*  4 bytes */
3007 -        ldrmih r4, [r1], #2                    /*  2 bytes */
3008 -        strcs  r3, [r0], #4
3009 -        strmih r4, [r0], #2
3010 -        tst            r2, #0x1
3011 -        ldrneb r3, [r1]                                /*  last byte  */
3012 -        strneb r3, [r0]
3013 -
3014 -        /* we're done! restore everything and return */
3015 -1:     ldmfd   sp!, {r5-r11}
3016 -        ldmfd  sp!, {r0, r4, lr}
3017 -        tst    lr, #1
3018 -        moveq  pc, lr
3019 -        bx     lr
3020 +       /* conditionnaly copies 0 to 31 bytes */
3021 +       movs    r12, r2, lsl #28
3022 +       ldmcs   r1!, {r4, r5, r6, r7}           /* 16 bytes */
3023 +       ldmmi   r1!, {r8, r9}                   /*  8 bytes */
3024 +       stmcs   r0!, {r4, r5, r6, r7}
3025 +       stmmi   r0!, {r8, r9}
3026 +       movs    r12, r2, lsl #30
3027 +       ldrcs   r3, [r1], #4                    /*  4 bytes */
3028 +       .word 0x40d140b2 /* ldrhmi r4, [r1], #2 */ /*  2 bytes */
3029 +       strcs   r3, [r0], #4
3030 +       .word 0x40c040b2 /* strhmi r4, [r0], #2 */
3031 +       tst     r2, #0x1
3032 +       .word 0x15d13000 /* ldrbne r3, [r1] */  /*  last byte  */
3033 +       .word 0x15c03000 /* strbne r3, [r0] */
3034 +
3035 +       /* we're done! restore everything and return */
3036 +1:      ldmfd   sp!, {r5-r11}
3037 +       ldmfd   sp!, {r0, r4, lr}
3038 +       tst     lr, #1
3039 +       moveq   pc, lr
3040 +       bx      lr
3041  
3042         /********************************************************************/
3043  
3044 @@ -202,180 +202,180 @@ non_congruent:
3045          * (the number of bytes written is always smaller, because we have
3046          * partial words in the shift queue)
3047          */
3048 -       cmp     r2, #4
3049 -       blo     copy_last_3_and_return
3050 +       cmp     r2, #4
3051 +       blo     copy_last_3_and_return
3052  
3053 -        /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
3054 -         * frame. Don't update sp.
3055 -         */
3056 -        stmea  sp, {r5-r11}
3057 -
3058 -        /* compute shifts needed to align src to dest */
3059 -        rsb    r5, r0, #0
3060 -        and    r5, r5, #3                      /* r5 = # bytes in partial words */
3061 -        mov    r12, r5, lsl #3         /* r12 = right */
3062 -        rsb    lr, r12, #32            /* lr = left  */
3063 -
3064 -        /* read the first word */
3065 -        ldr    r3, [r1], #4
3066 -        sub    r2, r2, #4
3067 -
3068 -        /* write a partial word (0 to 3 bytes), such that destination
3069 -         * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
3070 -         */
3071 -        movs   r5, r5, lsl #31
3072 -        strmib r3, [r0], #1
3073 -        movmi  r3, r3, lsr #8
3074 -        strcsb r3, [r0], #1
3075 -        movcs  r3, r3, lsr #8
3076 -        strcsb r3, [r0], #1
3077 -        movcs  r3, r3, lsr #8
3078 -
3079 -        cmp    r2, #4
3080 -        blo    partial_word_tail
3081 -
3082 -        /* Align destination to 32 bytes (cache line boundary) */
3083 -1:     tst     r0, #0x1c
3084 -        beq    2f
3085 -        ldr    r5, [r1], #4
3086 -        sub            r2, r2, #4
3087 -        orr    r4, r3, r5,             lsl lr
3088 -        mov    r3, r5,                 lsr r12
3089 -        str    r4, [r0], #4
3090 -        cmp            r2, #4
3091 -        bhs    1b
3092 -        blo    partial_word_tail
3093 +       /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
3094 +        * frame. Don't update sp.
3095 +        */
3096 +       stmea   sp, {r5-r11}
3097 +
3098 +       /* compute shifts needed to align src to dest */
3099 +       rsb     r5, r0, #0
3100 +       and     r5, r5, #3                      /* r5 = # bytes in partial words */
3101 +       mov     r12, r5, lsl #3         /* r12 = right */
3102 +       rsb     lr, r12, #32            /* lr = left  */
3103 +
3104 +       /* read the first word */
3105 +       ldr     r3, [r1], #4
3106 +       sub     r2, r2, #4
3107 +
3108 +       /* write a partial word (0 to 3 bytes), such that destination
3109 +        * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
3110 +        */
3111 +       movs    r5, r5, lsl #31
3112 +       .word 0x44c03001 /* strbmi r3, [r0], #1 */
3113 +       movmi   r3, r3, lsr #8
3114 +       .word 0x24c03001 /* strbcs r3, [r0], #1 */
3115 +       movcs   r3, r3, lsr #8
3116 +       .word 0x24c03001 /* strbcs r3, [r0], #1 */
3117 +       movcs   r3, r3, lsr #8
3118 +
3119 +       cmp     r2, #4
3120 +       blo     partial_word_tail
3121 +
3122 +       /* Align destination to 32 bytes (cache line boundary) */
3123 +1:      tst     r0, #0x1c
3124 +       beq     2f
3125 +       ldr     r5, [r1], #4
3126 +       sub     r2, r2, #4
3127 +       orr     r4, r3, r5,             lsl lr
3128 +       mov     r3, r5,                 lsr r12
3129 +       str     r4, [r0], #4
3130 +       cmp     r2, #4
3131 +       bhs     1b
3132 +       blo     partial_word_tail
3133  
3134         /* copy 32 bytes at a time */
3135 -2:     subs    r2, r2, #32
3136 -       blo     less_than_thirtytwo
3137 +2:      subs    r2, r2, #32
3138 +       blo     less_than_thirtytwo
3139 +
3140 +       /* Use immediate mode for the shifts, because there is an extra cycle
3141 +        * for register shifts, which could account for up to 50% of
3142 +        * performance hit.
3143 +        */
3144  
3145 -        /* Use immediate mode for the shifts, because there is an extra cycle
3146 -         * for register shifts, which could account for up to 50% of
3147 -         * performance hit.
3148 -         */
3149 -
3150 -        cmp    r12, #24
3151 -        beq    loop24
3152 -        cmp    r12, #8
3153 -        beq    loop8
3154 +       cmp     r12, #24
3155 +       beq     loop24
3156 +       cmp     r12, #8
3157 +       beq     loop8
3158  
3159  loop16:
3160 -        ldr            r12, [r1], #4
3161 -1:      mov            r4, r12
3162 -       ldmia   r1!, {   r5,r6,r7,  r8,r9,r10,r11}
3163 -        subs           r2, r2, #32
3164 -        ldrhs          r12, [r1], #4
3165 -       orr     r3, r3, r4, lsl #16
3166 -        mov    r4, r4, lsr #16
3167 -        orr    r4, r4, r5, lsl #16
3168 -        mov    r5, r5, lsr #16
3169 -        orr    r5, r5, r6, lsl #16
3170 -        mov    r6, r6, lsr #16
3171 -        orr    r6, r6, r7, lsl #16
3172 -        mov    r7, r7, lsr #16
3173 -        orr    r7, r7, r8, lsl #16
3174 -        mov    r8, r8, lsr #16
3175 -        orr    r8, r8, r9, lsl #16
3176 -        mov    r9, r9, lsr #16
3177 -        orr    r9, r9, r10, lsl #16
3178 -        mov    r10, r10,               lsr #16
3179 -        orr    r10, r10, r11, lsl #16
3180 -        stmia  r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
3181 -        mov    r3, r11, lsr #16
3182 -        bhs    1b
3183 -        b      less_than_thirtytwo
3184 +       ldr     r12, [r1], #4
3185 +1:      mov     r4, r12
3186 +       ldmia   r1!, {   r5,r6,r7,  r8,r9,r10,r11}
3187 +       subs    r2, r2, #32
3188 +       ldrhs   r12, [r1], #4
3189 +       orr     r3, r3, r4, lsl #16
3190 +       mov     r4, r4, lsr #16
3191 +       orr     r4, r4, r5, lsl #16
3192 +       mov     r5, r5, lsr #16
3193 +       orr     r5, r5, r6, lsl #16
3194 +       mov     r6, r6, lsr #16
3195 +       orr     r6, r6, r7, lsl #16
3196 +       mov     r7, r7, lsr #16
3197 +       orr     r7, r7, r8, lsl #16
3198 +       mov     r8, r8, lsr #16
3199 +       orr     r8, r8, r9, lsl #16
3200 +       mov     r9, r9, lsr #16
3201 +       orr     r9, r9, r10, lsl #16
3202 +       mov     r10, r10,               lsr #16
3203 +       orr     r10, r10, r11, lsl #16
3204 +       stmia   r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
3205 +       mov     r3, r11, lsr #16
3206 +       bhs     1b
3207 +       b       less_than_thirtytwo
3208  
3209  loop8:
3210 -        ldr            r12, [r1], #4
3211 -1:      mov            r4, r12
3212 -       ldmia   r1!, {   r5,r6,r7,  r8,r9,r10,r11}
3213 -       subs    r2, r2, #32
3214 -        ldrhs          r12, [r1], #4
3215 -        orr    r3, r3, r4, lsl #24
3216 -        mov    r4, r4, lsr #8
3217 -        orr    r4, r4, r5, lsl #24
3218 -        mov    r5, r5, lsr #8
3219 -        orr    r5, r5, r6, lsl #24
3220 -        mov    r6, r6,  lsr #8
3221 -        orr    r6, r6, r7, lsl #24
3222 -        mov    r7, r7,  lsr #8
3223 -        orr    r7, r7, r8,             lsl #24
3224 -        mov    r8, r8,  lsr #8
3225 -        orr    r8, r8, r9,             lsl #24
3226 -        mov    r9, r9,  lsr #8
3227 -        orr    r9, r9, r10,    lsl #24
3228 -        mov    r10, r10, lsr #8
3229 -        orr    r10, r10, r11,  lsl #24
3230 -        stmia  r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
3231 -        mov    r3, r11, lsr #8
3232 -        bhs    1b
3233 -        b      less_than_thirtytwo
3234 +       ldr     r12, [r1], #4
3235 +1:      mov     r4, r12
3236 +       ldmia   r1!, {   r5,r6,r7,  r8,r9,r10,r11}
3237 +       subs    r2, r2, #32
3238 +       ldrhs   r12, [r1], #4
3239 +       orr     r3, r3, r4, lsl #24
3240 +       mov     r4, r4, lsr #8
3241 +       orr     r4, r4, r5, lsl #24
3242 +       mov     r5, r5, lsr #8
3243 +       orr     r5, r5, r6, lsl #24
3244 +       mov     r6, r6,  lsr #8
3245 +       orr     r6, r6, r7, lsl #24
3246 +       mov     r7, r7,  lsr #8
3247 +       orr     r7, r7, r8,             lsl #24
3248 +       mov     r8, r8,  lsr #8
3249 +       orr     r8, r8, r9,             lsl #24
3250 +       mov     r9, r9,  lsr #8
3251 +       orr     r9, r9, r10,    lsl #24
3252 +       mov     r10, r10, lsr #8
3253 +       orr     r10, r10, r11,  lsl #24
3254 +       stmia   r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
3255 +       mov     r3, r11, lsr #8
3256 +       bhs     1b
3257 +       b       less_than_thirtytwo
3258  
3259  loop24:
3260 -        ldr            r12, [r1], #4
3261 -1:      mov            r4, r12
3262 -       ldmia   r1!, {   r5,r6,r7,  r8,r9,r10,r11}
3263 -        subs   r2, r2, #32
3264 -        ldrhs          r12, [r1], #4
3265 -        orr    r3, r3, r4, lsl #8
3266 -        mov    r4, r4, lsr #24
3267 -        orr    r4, r4, r5, lsl #8
3268 -        mov    r5, r5, lsr #24
3269 -        orr    r5, r5, r6, lsl #8
3270 -        mov    r6, r6, lsr #24
3271 -        orr    r6, r6, r7, lsl #8
3272 -        mov    r7, r7, lsr #24
3273 -        orr    r7, r7, r8, lsl #8
3274 -        mov    r8, r8, lsr #24
3275 -        orr    r8, r8, r9, lsl #8
3276 -        mov    r9, r9, lsr #24
3277 -        orr    r9, r9, r10, lsl #8
3278 -        mov    r10, r10, lsr #24
3279 -        orr    r10, r10, r11, lsl #8
3280 -        stmia  r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
3281 -        mov    r3, r11, lsr #24
3282 -        bhs    1b
3283 +       ldr     r12, [r1], #4
3284 +1:      mov     r4, r12
3285 +       ldmia   r1!, {   r5,r6,r7,  r8,r9,r10,r11}
3286 +       subs    r2, r2, #32
3287 +       ldrhs   r12, [r1], #4
3288 +       orr     r3, r3, r4, lsl #8
3289 +       mov     r4, r4, lsr #24
3290 +       orr     r4, r4, r5, lsl #8
3291 +       mov     r5, r5, lsr #24
3292 +       orr     r5, r5, r6, lsl #8
3293 +       mov     r6, r6, lsr #24
3294 +       orr     r6, r6, r7, lsl #8
3295 +       mov     r7, r7, lsr #24
3296 +       orr     r7, r7, r8, lsl #8
3297 +       mov     r8, r8, lsr #24
3298 +       orr     r8, r8, r9, lsl #8
3299 +       mov     r9, r9, lsr #24
3300 +       orr     r9, r9, r10, lsl #8
3301 +       mov     r10, r10, lsr #24
3302 +       orr     r10, r10, r11, lsl #8
3303 +       stmia   r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
3304 +       mov     r3, r11, lsr #24
3305 +       bhs     1b
3306  
3307  less_than_thirtytwo:
3308         /* copy the last 0 to 31 bytes of the source */
3309 -       rsb     r12, lr, #32            /* we corrupted r12, recompute it  */
3310 -        add    r2, r2, #32
3311 -        cmp    r2, #4
3312 -        blo    partial_word_tail
3313 -
3314 -1:     ldr     r5, [r1], #4
3315 -        sub            r2, r2, #4
3316 -        orr    r4, r3, r5,             lsl lr
3317 -        mov    r3,     r5,                     lsr r12
3318 -        str    r4, [r0], #4
3319 -        cmp            r2, #4
3320 -        bhs    1b
3321 +       rsb     r12, lr, #32            /* we corrupted r12, recompute it  */
3322 +       add     r2, r2, #32
3323 +       cmp     r2, #4
3324 +       blo     partial_word_tail
3325 +
3326 +1:      ldr     r5, [r1], #4
3327 +       sub     r2, r2, #4
3328 +       orr     r4, r3, r5,             lsl lr
3329 +       mov     r3,     r5,                     lsr r12
3330 +       str     r4, [r0], #4
3331 +       cmp     r2, #4
3332 +       bhs     1b
3333  
3334  partial_word_tail:
3335         /* we have a partial word in the input buffer */
3336 -       movs    r5, lr, lsl #(31-3)
3337 -       strmib  r3, [r0], #1
3338 -        movmi  r3, r3, lsr #8
3339 -        strcsb r3, [r0], #1
3340 -        movcs  r3, r3, lsr #8
3341 -        strcsb r3, [r0], #1
3342 +       movs    r5, lr, lsl #(31-3)
3343 +       .word 0x44c03001 /* strbmi r3, [r0], #1 */
3344 +       movmi   r3, r3, lsr #8
3345 +       .word 0x24c03001 /* strbcs r3, [r0], #1 */
3346 +       movcs   r3, r3, lsr #8
3347 +       .word 0x24c03001 /* strbcs r3, [r0], #1 */
3348  
3349 -        /* Refill spilled registers from the stack. Don't update sp. */
3350 -        ldmfd  sp, {r5-r11}
3351 +       /* Refill spilled registers from the stack. Don't update sp. */
3352 +       ldmfd   sp, {r5-r11}
3353  
3354  copy_last_3_and_return:
3355 -       movs    r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
3356 -        ldrmib r2, [r1], #1
3357 -        ldrcsb r3, [r1], #1
3358 -        ldrcsb r12,[r1]
3359 -        strmib r2, [r0], #1
3360 -        strcsb r3, [r0], #1
3361 -        strcsb r12,[r0]
3362 -
3363 -        /* we're done! restore sp and spilled registers and return */
3364 -        add            sp,  sp, #28
3365 -        ldmfd  sp!, {r0, r4, lr}
3366 -        tst    lr, #1
3367 -        moveq  pc, lr
3368 -        bx     lr
3369 +       movs    r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
3370 +       .word 0x44d12001 /* ldrbmi r2, [r1], #1 */
3371 +       .word 0x24d13001 /* ldrbcs r3, [r1], #1 */
3372 +       .word 0x25d1c000 /* ldrbcs r12,[r1] */
3373 +       .word 0x44c02001 /* strbmi r2, [r0], #1 */
3374 +       .word 0x24c03001 /* strbcs r3, [r0], #1 */
3375 +       .word 0x25c0c000 /* strbcs r12,[r0] */
3376 +
3377 +       /* we're done! restore sp and spilled registers and return */
3378 +       add     sp,  sp, #28
3379 +       ldmfd   sp!, {r0, r4, lr}
3380 +       tst     lr, #1
3381 +       moveq   pc, lr
3382 +       bx      lr
3383 --- a/src/thread/arm/__set_thread_area.s
3384 +++ b/src/thread/arm/__set_thread_area.s
3385 @@ -1,12 +1 @@
3386 -.text
3387 -.global __set_thread_area
3388 -.type   __set_thread_area,%function
3389 -__set_thread_area:
3390 -       mov r1,r7
3391 -       mov r7,#0x0f0000
3392 -       add r7,r7,#5
3393 -       svc 0
3394 -       mov r7,r1
3395 -       tst lr,#1
3396 -       moveq pc,lr
3397 -       bx lr
3398 +/* Replaced by C code in arch/arm/src */
3399 --- a/src/thread/arm/tls.s
3400 +++ /dev/null
3401 @@ -1,4 +0,0 @@
3402 -.global __aeabi_read_tp
3403 -.type __aeabi_read_tp,%function
3404 -__aeabi_read_tp:
3405 -       ldr pc,=0xffff0fe0
3406 --- a/src/thread/pthread_once.c
3407 +++ b/src/thread/pthread_once.c
3408 @@ -8,15 +8,8 @@ static void undo(void *control)
3409                 __wake(control, -1, 1);
3410  }
3411  
3412 -int __pthread_once(pthread_once_t *control, void (*init)(void))
3413 +int __pthread_once_full(pthread_once_t *control, void (*init)(void))
3414  {
3415 -       /* Return immediately if init finished before, but ensure that
3416 -        * effects of the init routine are visible to the caller. */
3417 -       if (*control == 2) {
3418 -               a_barrier();
3419 -               return 0;
3420 -       }
3421 -
3422         /* Try to enter initializing state. Four possibilities:
3423          *  0 - we're the first or the other cancelled; run init
3424          *  1 - another thread is running init; wait
3425 @@ -43,4 +36,15 @@ int __pthread_once(pthread_once_t *contr
3426         }
3427  }
3428  
3429 +int __pthread_once(pthread_once_t *control, void (*init)(void))
3430 +{
3431 +       /* Return immediately if init finished before, but ensure that
3432 +        * effects of the init routine are visible to the caller. */
3433 +       if (*control == 2) {
3434 +               a_barrier();
3435 +               return 0;
3436 +       }
3437 +       return __pthread_once_full(control, init);
3438 +}
3439 +
3440  weak_alias(__pthread_once, pthread_once);