939de6bcd62dc1e2d8c6984196fcfa95019f93ac
[openwrt.git] / toolchain / musl / patches / 001-git-2015-07-22.patch
1 commit 3975577922aedab7d60788dd320a2c8e4e94bc6e
2 Author: Roman Yeryomin <roman@ubnt.com>
3 Date:   Thu Jul 2 12:29:00 2015 +0300
4
5     socket.h: cleanup/reorder mips and powerpc bits/socket.h
6     
7     ....to be somewhat consistent and easily comparable with asm/socket.h
8     
9     Signed-off-by: Roman Yeryomin <roman@ubnt.com>
10
11 commit 29ec7677a73a5227badbb1064205be09e707e466
12 Author: Roman Yeryomin <roman@ubnt.com>
13 Date:   Thu Jul 2 12:28:41 2015 +0300
14
15     socket.h: fix SO_* for mips
16     
17     Signed-off-by: Roman Yeryomin <roman@ubnt.com>
18
19 commit 3fffa7a658aa925b8f95d36aef7531c1827dbf28
20 Author: Felix Fietkau <nbd@openwrt.org>
21 Date:   Tue Jul 21 15:01:25 2015 +0200
22
23     mips: fix mcontext_t register array field name
24     
25     glibc and uclibc use gregs instead of regs
26     
27     Signed-off-by: Felix Fietkau <nbd@openwrt.org>
28
29 commit 0f9c2666aca95eb98eb0ef4f4d8d1473c8ce3fa0
30 Author: Rich Felker <dalias@aerifal.cx>
31 Date:   Thu Jul 9 18:36:02 2015 +0000
32
33     handle loss of syslog socket connection
34     
35     when traditional syslogd implementations are restarted, the old server
36     socket ceases to exist and a new unix socket with the same pathname is
37     created. when this happens, the default destination address associated
38     with the client socket via connect is no longer valid, and attempts to
39     send produce errors. this happens despite the socket being datagram
40     type, and is in contrast to the behavior that would be seen with an IP
41     datagram (UDP) socket.
42     
43     in order to avoid a situation where the application is unable to send
44     further syslog messages without calling closelog, this patch makes
45     syslog attempt to reconnect the socket when send returns an error
46     indicating a lost connection.
47     
48     additionally, initial failure to connect the socket no longer results
49     in the socket being closed. this ensures that an application which
50     calls openlog to reserve the socket file descriptor will not run into
51     a situation where transient connection failure (e.g. due to syslogd
52     restart) prevents fd reservation. however, applications which may be
53     unable to connect the socket later (e.g. due to chroot, restricted
54     permissions, seccomp, etc.) will still fail to log if the syslog
55     socket cannot be connected at openlog time or if it has to be
56     reconnected later.
57
58 commit 11894f6d3a80be950a490dc7dfab349f057a545f
59 Author: Rich Felker <dalias@aerifal.cx>
60 Date:   Thu Jul 9 17:07:35 2015 +0000
61
62     fix incorrect void return type for syncfs function
63     
64     being nonstandard, the closest thing to a specification for this
65     function is its man page, which documents it as returning int. it can
66     fail with EBADF if the file descriptor passed is invalid.
67
68 commit e8cbe0bad4284906230a53af4c91ad2b9713d03b
69 Author: Rich Felker <dalias@aerifal.cx>
70 Date:   Wed Jul 8 02:46:45 2015 +0000
71
72     fix negated return value of ns_skiprr, breakage in related functions
73     
74     due to a reversed pointer difference computation, ns_skiprr always
75     returned a negative value, which functions using it would interpret as
76     an error.
77     
78     patch by Yu Lu.
79
80 commit fb58545f8d1c5fa32122244caeaf3625c12ddc01
81 Author: Shiz <hi@shiz.me>
82 Date:   Sun Jun 28 23:08:21 2015 +0200
83
84     add musl-clang, a wrapper for system clang installs
85     
86     musl-clang allows the user to compile musl-powered programs using their
87     already existent clang install, without the need of a special cross compiler.
88     it achieves this by wrapping around both the system clang install and the
89     linker and passing them special flags to re-target musl at runtime.
90     it does only affect invocations done through the special musl-clang wrapper
91     script, so that the user setup remains fully intact otherwise.
92     
93     the clang wrapper consists of the compiler frontend wrapper script,
94     musl-clang, and the linker wrapper script, ld.musl-clang.
95     musl-clang makes sure clang invokes ld.musl-clang to link objects; neither
96     script needs to be in PATH for the wrapper to work.
97
98 commit f8db6f74b2c74a50c4dec7e30be5215f0e2c37a6
99 Author: Shiz <hi@shiz.me>
100 Date:   Sun Jun 28 23:08:20 2015 +0200
101
102     build: fix musl-targeting toolchain test
103     
104     the old test was broken in that it would never fail on a toolchains built
105     without dynamic linking support, leading to the wrapper script possibly being
106     installed on compilers that do not support it. in addition, the new test is
107     portable across compilers: the old test only worked on GCC.
108     
109     the new test works by testing whether the toolchain libc defines __GLIBC__:
110     most non-musl Linux libc's do define this for compatibility even when they
111     are not glibc, so this is a safe bet to check for musl. in addition, the
112     compiler runtime would need to have a somewhat glibc-compatible ABI in the
113     first place, so any non-glibc compatible libc's compiler runtime might not
114     work. it is safer to disable these cases by default and have the user enable
115     the wrappers manually there using --enable-wrapper if they certain it works.
116
117 commit b3cd7d13fe630ba1847326242525298e361018c1
118 Author: Shiz <hi@shiz.me>
119 Date:   Sun Jun 28 23:08:19 2015 +0200
120
121     build: overhaul wrapper script system for multiple wrapper support
122     
123     this overhauls part of the build system in order to support multiple
124     toolchain wrapper scripts, as opposed to solely the musl-gcc wrapper as
125     before. it thereby replaces --enable-gcc-wrapper with --enable-wrapper=...,
126     which has the options 'auto' (the default, detect whether to use wrappers),
127     'all' (build and install all wrappers), 'no' (don't build any) and finally
128     the options named after the individual compiler scripts (currently only
129     'gcc' is available) to build and install only that wrapper.
130     the old --enable-gcc-wrapper is removed from --help, but still available.
131     
132     it also modifies the wrappers to use the C compiler specified to the build
133     system as 'inner' compiler, when applicable. as wrapper detection works by
134     probing this compiler, it may not work with any other.
135
136 commit 2a780aa3050b86d888489361f04220bfb58890a1
137 Author: Rich Felker <dalias@aerifal.cx>
138 Date:   Mon Jul 6 22:13:11 2015 +0000
139
140     treat empty TZ environment variable as GMT rather than default
141     
142     this improves compatibility with the behavior of other systems and
143     with some applications which set an empty TZ var to disable use of
144     local time by mktime, etc.
145
146 commit 8f08a58c635bea5cdfae6bc0e323c80aa9ff82a7
147 Author: Alexander Monakov <amonakov@ispras.ru>
148 Date:   Sun Jun 28 02:48:33 2015 +0300
149
150     dynlink.c: pass gnu-hash table pointer to gnu_lookup
151     
152     The callers need to check the value of the pointer anyway, so make
153     them pass the pointer to gnu_lookup instead of reloading it there.
154     
155     Reorder gnu_lookup arguments so that always-used ones are listed
156     first. GCC can choose a calling convention with arguments in registers
157     (e.g. up to 3 arguments in eax, ecx, edx on x86), but cannot reorder
158     the arguments for static functions.
159
160 commit 5b4286e12cd6baac343b10a41dc17ac578832089
161 Author: Alexander Monakov <amonakov@ispras.ru>
162 Date:   Sun Jun 28 02:48:32 2015 +0300
163
164     dynlink.c: slim down gnu_lookup
165     
166     Do not reference dso->syms and dso->strings until point of use.
167     Check 'h1 == (h2|1)', the simplest condition, before the others.
168
169 commit 84389c64562e2b2ba43225b5b7a9df7d974479b1
170 Author: Alexander Monakov <amonakov@ispras.ru>
171 Date:   Sun Jun 28 02:48:31 2015 +0300
172
173     dynlink.c: use bloom filter in gnu hash lookup
174     
175     Introduce gnu_lookup_filtered and use it to speed up symbol lookups in
176     find_sym (do_dlsym is left as is, based on an expectation that
177     frequently dlsym queries will use a dlopen handle rather than
178     RTLD_NEXT or RTLD_DEFAULT, and will not need to look at more than one
179     DSO).
180
181 commit 66d45787c865a1807ae397a89a14699394ed4fa4
182 Author: Alexander Monakov <amonakov@ispras.ru>
183 Date:   Sun Jun 28 02:48:30 2015 +0300
184
185     dynlink.c: use a faster expression in gnu_hash
186     
187     With -Os, GCC uses a multiply rather than a shift and addition for 'h*33'.
188     Use a more efficient expression explicitely.
189
190 commit 6ba5517a460c6c438f64d69464fdfc3269a4c91a
191 Author: Rich Felker <dalias@aerifal.cx>
192 Date:   Thu Jun 25 22:22:00 2015 +0000
193
194     fix local-dynamic model TLS on mips and powerpc
195     
196     the TLS ABI spec for mips, powerpc, and some other (presently
197     unsupported) RISC archs has the return value of __tls_get_addr offset
198     by +0x8000 and the result of DTPOFF relocations offset by -0x8000. I
199     had previously assumed this part of the ABI was actually just an
200     implementation detail, since the adjustments cancel out. however, when
201     the local dynamic model is used for accessing TLS that's known to be
202     in the same DSO, either of the following may happen:
203     
204     1. the -0x8000 offset may already be applied to the argument structure
205     passed to __tls_get_addr at ld time, without any opportunity for
206     runtime relocations.
207     
208     2. __tls_get_addr may be used with a zero offset argument to obtain a
209     base address for the module's TLS, to which the caller then applies
210     immediate offsets for individual objects accessed using the local
211     dynamic model. since the immediate offsets have the -0x8000 adjustment
212     applied to them, the base address they use needs to include the
213     +0x8000 offset.
214     
215     it would be possible, but more complex, to store the pointers in the
216     dtv[] array with the +0x8000 offset pre-applied, to avoid the runtime
217     cost of adding 0x8000 on each call to __tls_get_addr. this change
218     could be made later if measurements show that it would help.
219
220 commit ce337daa00e42d4f2d9a4d9ae0ed51b20249d924
221 Author: Rich Felker <dalias@aerifal.cx>
222 Date:   Tue Jun 23 04:03:42 2015 +0000
223
224     make dynamic linker work around MAP_FAILED mmap failure on nommu kernels
225     
226     previously, loading of additional libraries beyond libc/ldso did not
227     work on nommu kernels, nor did loading programs via invocation of the
228     dynamic linker as a command.
229
230 commit a59341420fdedb288d9ff80e73609ae44e9cf258
231 Author: Rich Felker <dalias@aerifal.cx>
232 Date:   Tue Jun 23 00:12:25 2015 +0000
233
234     reimplement strverscmp to fix corner cases
235     
236     this interface is non-standardized and is a GNU invention, and as
237     such, our implementation should match the behavior of the GNU
238     function. one peculiarity the old implementation got wrong was the
239     handling of all-zero digit sequences: they are supposed to compare
240     greater than digit sequences of which they are a proper prefix, as in
241     009 < 00.
242     
243     in addition, high bytes were treated with char signedness rather than
244     as unsigned. this was wrong regardless of what the GNU function does
245     since the resulting order relation varied by arch.
246     
247     the new strverscmp implementation makes explicit the cases where the
248     order differs from what strcmp would produce, of which there are only
249     two.
250
251 commit 153e952e1a688859d7095345b17e6c1df74a295c
252 Author: Rich Felker <dalias@aerifal.cx>
253 Date:   Mon Jun 22 20:33:28 2015 +0000
254
255     fix regression/typo that disabled __simple_malloc when calloc is used
256     
257     commit ba819787ee93ceae94efd274f7849e317c1bff58 introduced this
258     regression. since the __malloc0 weak alias was not properly provided
259     by __simple_malloc, use of calloc forced the full malloc to be linked.
260
261 commit ba819787ee93ceae94efd274f7849e317c1bff58
262 Author: Rich Felker <dalias@aerifal.cx>
263 Date:   Mon Jun 22 18:50:09 2015 +0000
264
265     fix calloc when __simple_malloc implementation is used
266     
267     previously, calloc's implementation encoded assumptions about the
268     implementation of malloc, accessing a size_t word just prior to the
269     allocated memory to determine if it was obtained by mmap to optimize
270     out the zero-filling. when __simple_malloc is used (static linking a
271     program with no realloc/free), it doesn't matter if the result of this
272     check is wrong, since all allocations are zero-initialized anyway. but
273     the access could be invalid if it crosses a page boundary or if the
274     pointer is not sufficiently aligned, which can happen for very small
275     allocations.
276     
277     this patch fixes the issue by moving the zero-fill logic into malloc.c
278     with the full malloc, as a new function named __malloc0, which is
279     provided by a weak alias to __simple_malloc (which always gives
280     zero-filled memory) when the full malloc is not in use.
281
282 commit 55d061f031085f24d138664c897791aebe9a2fab
283 Author: Rich Felker <dalias@aerifal.cx>
284 Date:   Sat Jun 20 03:01:07 2015 +0000
285
286     provide __stack_chk_fail_local in libc.a
287     
288     this symbol is needed only on archs where the PLT call ABI is klunky,
289     and only for position-independent code compiled with stack protector.
290     thus references usually only appear in shared libraries or PIE
291     executables, but they can also appear when linking statically if some
292     of the object files being linked were built as PIC/PIE.
293     
294     normally libssp_nonshared.a from the compiler toolchain should provide
295     __stack_chk_fail_local, but reportedly it appears prior to -lc in the
296     link order, thus failing to satisfy references from libc itself (which
297     arise only if libc.a was built as PIC/PIE with stack protector
298     enabled).
299
300 commit ce3688eca920aa77549323f84e21f33522397115
301 Author: Rich Felker <dalias@aerifal.cx>
302 Date:   Sat Jun 20 02:54:30 2015 +0000
303
304     work around mips detached thread exit breakage due to kernel regression
305     
306     linux kernel commit 46e12c07b3b9603c60fc1d421ff18618241cb081 caused
307     the mips syscall mechanism to fail with EFAULT when the userspace
308     stack pointer is invalid, breaking __unmapself used for detached
309     thread exit. the workaround is to set $sp to a known-valid, readable
310     address, and the simplest one to obtain is the address of the current
311     function, which is available (per o32 calling convention) in $25.
312
313 commit 75eceb3ae824d54e865686c0c538551aeebf3372
314 Author: Rich Felker <dalias@aerifal.cx>
315 Date:   Wed Jun 17 17:21:46 2015 +0000
316
317     ignore ENOSYS error from mprotect in pthread_create and dynamic linker
318     
319     this error simply indicated a system without memory protection (NOMMU)
320     and should not cause failure in the caller.
321
322 commit 10d0268ccfab9152250eeeed3952ce3fed44131a
323 Author: Rich Felker <dalias@aerifal.cx>
324 Date:   Tue Jun 16 15:25:02 2015 +0000
325
326     switch to using trap number 31 for syscalls on sh
327     
328     nominally the low bits of the trap number on sh are the number of
329     syscall arguments, but they have never been used by the kernel, and
330     some code making syscalls does not even know the number of arguments
331     and needs to pass an arbitrary high number anyway.
332     
333     sh3/sh4 traditionally used the trap range 16-31 for syscalls, but part
334     of this range overlapped with hardware exceptions/interrupts on sh2
335     hardware, so an incompatible range 32-47 was chosen for sh2.
336     
337     using trap number 31 everywhere, since it's in the existing sh3/sh4
338     range and does not conflict with sh2 hardware, is a proposed
339     unification of the kernel syscall convention that will allow binaries
340     to be shared between sh2 and sh3/sh4. if this is not accepted into the
341     kernel, we can refit the sh2 target with runtime selection mechanisms
342     for the trap number, but doing so would be invasive and would entail
343     non-trivial overhead.
344
345 commit 3366a99b17847b58f2d8cc52cbb5d65deb824f8a
346 Author: Rich Felker <dalias@aerifal.cx>
347 Date:   Tue Jun 16 14:55:06 2015 +0000
348
349     switch sh port's __unmapself to generic version when running on sh2/nommu
350     
351     due to the way the interrupt and syscall trap mechanism works,
352     userspace on sh2 must never set the stack pointer to an invalid value.
353     thus, the approach used on most archs, where __unmapself executes with
354     no stack for the interval between SYS_munmap and SYS_exit, is not
355     viable on sh2.
356     
357     in order not to pessimize sh3/sh4, the sh asm version of __unmapself
358     is not removed. instead it's renamed and redirected through code that
359     calls either the generic (safe) __unmapself or the sh3/sh4 asm,
360     depending on compile-time and run-time conditions.
361
362 commit f9d84554bae0fa17c9a1d724549c4408022228a5
363 Author: Rich Felker <dalias@aerifal.cx>
364 Date:   Tue Jun 16 14:28:30 2015 +0000
365
366     add support for sh2 interrupt-masking-based atomics to sh port
367     
368     the sh2 target is being considered an ISA subset of sh3/sh4, in the
369     sense that binaries built for sh2 are intended to be usable on later
370     cpu models/kernels with mmu support. so rather than hard-coding
371     sh2-specific atomics, the runtime atomic selection mechanisms that was
372     already in place has been extended to add sh2 atomics.
373     
374     at this time, the sh2 atomics are not SMP-compatible; since the ISA
375     lacks actual atomic operations, the new code instead masks interrupts
376     for the duration of the atomic operation, producing an atomic result
377     on single-core. this is only possible because the kernel/hardware does
378     not impose protections against userspace doing so. additional changes
379     will be needed to support future SMP systems.
380     
381     care has been taken to avoid producing significant additional code
382     size in the case where it's known at compile-time that the target is
383     not sh2 and does not need sh2-specific code.
384
385 commit 1b0cdc8700d29ef018bf226d74b2b58b23bce91c
386 Author: Rich Felker <dalias@aerifal.cx>
387 Date:   Tue Jun 16 07:11:19 2015 +0000
388
389     refactor stdio open file list handling, move it out of global libc struct
390     
391     functions which open in-memory FILE stream variants all shared a tail
392     with __fdopen, adding the FILE structure to stdio's open file list.
393     replacing this common tail with a function call reduces code size and
394     duplication of logic. the list is also partially encapsulated now.
395     
396     function signatures were chosen to facilitate tail call optimization
397     and reduce the need for additional accessor functions.
398     
399     with these changes, static linked programs that do not use stdio no
400     longer have an open file list at all.
401
402 commit f22a9edaf8a6f2ca1d314d18b3785558279a5c03
403 Author: Rich Felker <dalias@aerifal.cx>
404 Date:   Tue Jun 16 06:18:00 2015 +0000
405
406     byte-based C locale, phase 3: make MB_CUR_MAX variable to activate code
407     
408     this patch activates the new byte-based C locale (high bytes treated
409     as abstract code unit "characters" rather than decoded as multibyte
410     characters) by making the value of MB_CUR_MAX depend on the active
411     locale. for the C locale, the LC_CTYPE category pointer is null,
412     yielding a value of 1. all other locales yield a value of 4.
413
414 commit 16f18d036d9a7bf590ee6eb86785c0a9658220b6
415 Author: Rich Felker <dalias@aerifal.cx>
416 Date:   Tue Jun 16 05:35:31 2015 +0000
417
418     byte-based C locale, phase 2: stdio and iconv (multibyte callers)
419     
420     this patch adjusts libc components which use the multibyte functions
421     internally, and which depend on them operating in a particular
422     encoding, to make the appropriate locale changes before calling them
423     and restore the calling thread's locale afterwards. activating the
424     byte-based C locale without these changes would cause regressions in
425     stdio and iconv.
426     
427     in the case of iconv, the current implementation was simply using the
428     multibyte functions as UTF-8 conversions. setting a multibyte UTF-8
429     locale for the duration of the iconv operation allows the code to
430     continue working.
431     
432     in the case of stdio, POSIX requires that FILE streams have an
433     encoding rule bound at the time of setting wide orientation. as long
434     as all locales, including the C locale, used the same encoding,
435     treating high bytes as UTF-8, there was no need to store an encoding
436     rule as part of the stream's state.
437     
438     a new locale field in the FILE structure points to the locale that
439     should be made active during fgetwc/fputwc/ungetwc on the stream. it
440     cannot point to the locale active at the time the stream becomes
441     oriented, because this locale could be mutable (the global locale) or
442     could be destroyed (locale_t objects produced by newlocale) before the
443     stream is closed. instead, a pointer to the static C or C.UTF-8 locale
444     object added in commit commit aeeac9ca5490d7d90fe061ab72da446c01ddf746
445     is used. this is valid since categories other than LC_CTYPE will not
446     affect these functions.
447
448 commit 1507ebf837334e9e07cfab1ca1c2e88449069a80
449 Author: Rich Felker <dalias@aerifal.cx>
450 Date:   Tue Jun 16 04:44:17 2015 +0000
451
452     byte-based C locale, phase 1: multibyte character handling functions
453     
454     this patch makes the functions which work directly on multibyte
455     characters treat the high bytes as individual abstract code units
456     rather than as multibyte sequences when MB_CUR_MAX is 1. since
457     MB_CUR_MAX is presently defined as a constant 4, all of the new code
458     added is dead code, and optimizing compilers' code generation should
459     not be affected at all. a future commit will activate the new code.
460     
461     as abstract code units, bytes 0x80 to 0xff are represented by wchar_t
462     values 0xdf80 to 0xdfff, at the end of the surrogates range. this
463     ensures that they will never be misinterpreted as Unicode characters,
464     and that all wctype functions return false for these "characters"
465     without needing locale-specific logic. a high range outside of Unicode
466     such as 0x7fffff80 to 0x7fffffff was also considered, but since C11's
467     char16_t also needs to be able to represent conversions of these
468     bytes, the surrogate range was the natural choice.
469
470 commit 38e2f727237230300fea6aff68802db04625fd23
471 Author: Rich Felker <dalias@aerifal.cx>
472 Date:   Tue Jun 16 04:21:38 2015 +0000
473
474     fix btowc corner case
475     
476     btowc is required to interpret its argument by conversion to unsigned
477     char, unless the argument is equal to EOF. since the conversion to
478     produces a non-character value anyway, we can just unconditionally
479     convert, for now.
480
481 commit ee59c296d56bf26f49f354d6eb32b4b6d4190188
482 Author: Szabolcs Nagy <nsz@port70.net>
483 Date:   Wed Jun 3 10:32:14 2015 +0100
484
485     arm: add vdso support
486     
487     vdso will be available on arm in linux v4.2, the user-space code
488     for it is in kernel commit 8512287a8165592466cb9cb347ba94892e9c56a5
489
490 commit e3bc22f1eff87b8f029a6ab31f1a269d69e4b053
491 Author: Rich Felker <dalias@aerifal.cx>
492 Date:   Sun Jun 14 01:59:02 2015 +0000
493
494     refactor malloc's expand_heap to share with __simple_malloc
495     
496     this extends the brk/stack collision protection added to full malloc
497     in commit 276904c2f6bde3a31a24ebfa201482601d18b4f9 to also protect the
498     __simple_malloc function used in static-linked programs that don't
499     reference the free function.
500     
501     it also extends support for using mmap when brk fails, which full
502     malloc got in commit 5446303328adf4b4e36d9fba21848e6feb55fab4, to
503     __simple_malloc.
504     
505     since __simple_malloc may expand the heap by arbitrarily large
506     increments, the stack collision detection is enhanced to detect
507     interval overlap rather than just proximity of a single address to the
508     stack. code size is increased a bit, but this is partly offset by the
509     sharing of code between the two malloc implementations, which due to
510     linking semantics, both get linked in a program that needs the full
511     malloc with realloc/free support.
512
513 commit 4ef9b828c1f39553a69e0635ac91f0fcadd6e8c6
514 Author: Rich Felker <dalias@aerifal.cx>
515 Date:   Sat Jun 13 20:53:02 2015 +0000
516
517     remove cancellation points in stdio
518     
519     commit 58165923890865a6ac042fafce13f440ee986fd9 added these optional
520     cancellation points on the basis that cancellable stdio could be
521     useful, to unblock threads stuck on stdio operations that will never
522     complete. however, the only way to ensure that cancellation can
523     achieve this is to violate the rules for side effects when
524     cancellation is acted upon, discarding knowledge of any partial data
525     transfer already completed. our implementation exhibited this behavior
526     and was thus non-conforming.
527     
528     in addition to improving correctness, removing these cancellation
529     points moderately reduces code size, and should significantly improve
530     performance on i386, where sysenter/syscall instructions can be used
531     instead of "int $128" for non-cancellable syscalls.
532
533 commit 536c6d5a4205e2a3f161f2983ce1e0ac3082187d
534 Author: Rich Felker <dalias@aerifal.cx>
535 Date:   Sat Jun 13 05:17:16 2015 +0000
536
537     fix idiom for setting stdio stream orientation to wide
538     
539     the old idiom, f->mode |= f->mode+1, was adapted from the idiom for
540     setting byte orientation, f->mode |= f->mode-1, but the adaptation was
541     incorrect. unless the stream was alreasdy set byte-oriented, this code
542     incremented f->mode each time it was executed, which would eventually
543     lead to overflow. it could be fixed by changing it to f->mode |= 1,
544     but upcoming changes will require slightly more work at the time of
545     wide orientation, so it makes sense to just call fwide. as an
546     optimization in the single-character functions, fwide is only called
547     if the stream is not already wide-oriented.
548
549 commit f8f565df467c13248104223f99abf7f37cef7584
550 Author: Rich Felker <dalias@aerifal.cx>
551 Date:   Sat Jun 13 04:42:38 2015 +0000
552
553     add printing of null %s arguments as "(null)" in wide printf
554     
555     this is undefined, but supported in our implementation of the normal
556     printf, so for consistency the wide variant should support it too.
557
558 commit f9e25d813860d53cd1e9b6145cc63375d2fe2529
559 Author: Rich Felker <dalias@aerifal.cx>
560 Date:   Sat Jun 13 04:37:27 2015 +0000
561
562     add %m support to wide printf
563
564 commit ec634aad91f57479ef17525e33ed446c780a61f4
565 Author: Rich Felker <dalias@aerifal.cx>
566 Date:   Thu Jun 11 05:01:04 2015 +0000
567
568     add sh asm for vfork
569
570 commit c30cbcb0a646b1f13a22c645616dce624465b883
571 Author: Rich Felker <dalias@aerifal.cx>
572 Date:   Wed Jun 10 02:27:40 2015 +0000
573
574     implement arch-generic version of __unmapself
575     
576     this can be used to put off writing an asm version of __unmapself for
577     new archs, or as a permanent solution on archs where it's not
578     practical or even possible to run momentarily with no stack.
579     
580     the concept here is simple: the caller takes a lock on a global shared
581     stack and uses it to make the munmap and exit syscalls. the only trick
582     is unlocking, which must be done after the thread exits, and this is
583     achieved by using the set_tid_address syscall to have the kernel zero
584     and futex-wake the lock word as part of the exit syscall.
585
586 commit 276904c2f6bde3a31a24ebfa201482601d18b4f9
587 Author: Rich Felker <dalias@aerifal.cx>
588 Date:   Tue Jun 9 20:30:35 2015 +0000
589
590     in malloc, refuse to use brk if it grows into stack
591     
592     the linux/nommu fdpic ELF loader sets up the brk range to overlap
593     entirely with the main thread's stack (but growing from opposite
594     ends), so that the resulting failure mode for malloc is not to return
595     a null pointer but to start returning pointers to memory that overlaps
596     with the caller's stack. needless to say this extremely dangerous and
597     makes brk unusable.
598     
599     since it's non-trivial to detect execution environments that might be
600     affected by this kernel bug, and since the severity of the bug makes
601     any sort of detection that might yield false-negatives unsafe, we
602     instead check the proximity of the brk to the stack pointer each time
603     the brk is to be expanded. both the main thread's stack (where the
604     real known risk lies) and the calling thread's stack are checked. an
605     arbitrary gap distance of 8 MB is imposed, chosen to be larger than
606     linux default main-thread stack reservation sizes and larger than any
607     reasonable stack configuration on nommu.
608     
609     the effeciveness of this patch relies on an assumption that the amount
610     by which the brk is being grown is smaller than the gap limit, which
611     is always true for malloc's use of brk. reliance on this assumption is
612     why the check is being done in malloc-specific code and not in __brk.
613
614 commit bd1eaceaa3975bd2a2a34e211cff896affaecadf
615 Author: Rich Felker <dalias@aerifal.cx>
616 Date:   Tue Jun 9 20:09:27 2015 +0000
617
618     fix spurious errors from pwd/grp functions when nscd backend is absent
619     
620     for several pwd/grp functions, the only way the caller can distinguish
621     between a successful negative result ("no such user/group") and an
622     internal error is by clearing errno before the call and checking errno
623     afterwards. the nscd backend support code correctly simulated a
624     not-found response on systems where such a backend is not running, but
625     failed to restore errno.
626     
627     this commit also fixed an outdated/incorrect comment.
628
629 commit 75ce4503950621b11fcc7f1fd1187dbcf3cde312
630 Author: Rich Felker <dalias@aerifal.cx>
631 Date:   Sun Jun 7 20:55:23 2015 +0000
632
633     fix regression in pre-v7 arm on kernels with kuser helper removed
634     
635     the arm atomics/TLS runtime selection code is called from
636     __set_thread_area and depends on having libc.auxv and __hwcap
637     available. commit 71f099cb7db821c51d8f39dfac622c61e54d794c moved the
638     first call to __set_thread_area to the top of dynamic linking stage 3,
639     before this data is made available, causing the runtime detection code
640     to always see __hwcap as zero and thereby select the atomics/TLS
641     implementations based on kuser helper.
642     
643     upcoming work on superh will use similar runtime detection.
644     
645     ideally this early-init code should be cleanly refactored and shared
646     between the dynamic linker and static-linked startup.
647
648 commit 32f3c4f70633488550c29a2444f819aafdf345ff
649 Author: Rich Felker <dalias@aerifal.cx>
650 Date:   Sun Jun 7 03:09:16 2015 +0000
651
652     add multiple inclusion guard to locale_impl.h
653
654 commit 04b8360adbb6487f61aa0c00e53ec3a90a5a0d29
655 Author: Rich Felker <dalias@aerifal.cx>
656 Date:   Sun Jun 7 02:59:49 2015 +0000
657
658     remove redefinition of MB_CUR_MAX in locale_impl.h
659     
660     unless/until the byte-based C locale is implemented, defining
661     MB_CUR_MAX to 1 in the C locale is wrong. no internal code currently
662     uses the MB_CUR_MAX macro, but having it defined inconsistently is
663     error-prone. applications get the value from stdlib.h and were
664     unaffected.
665
666 commit 16bf466532d7328e971012b0731ad493b017ad29
667 Author: Rich Felker <dalias@aerifal.cx>
668 Date:   Sat Jun 6 18:53:02 2015 +0000
669
670     make static C and C.UTF-8 locales available outside of newlocale
671
672 commit 312eea2ea4f4363fb01b73660c08bfcf43dd3bb4
673 Author: Rich Felker <dalias@aerifal.cx>
674 Date:   Sat Jun 6 18:20:30 2015 +0000
675
676     remove another invalid skip of locking in ungetwc
677
678 commit 3d7e32d28dc9962e9efc1c317c5b44b5b2df3008
679 Author: Rich Felker <dalias@aerifal.cx>
680 Date:   Sat Jun 6 18:16:22 2015 +0000
681
682     add macro version of ctype.h isascii function
683     
684     presumably internal code (ungetwc and fputwc) was written assuming a
685     macro implementation existed; otherwise use of isascii is just a
686     pessimization.
687
688 commit 7e816a6487932cbb3cb71d94b609e50e81f4e5bf
689 Author: Rich Felker <dalias@aerifal.cx>
690 Date:   Sat Jun 6 18:11:17 2015 +0000
691
692     remove invalid skip of locking in ungetwc
693     
694     aside from being invalid, the early check only optimized the error
695     case, and likely pessimized the common case by separating the
696     two branches on isascii(c) at opposite ends of the function.
697
698 commit 63f4b9f18f3674124d8bcb119739fec85e6da005
699 Author: Timo Teräs <timo.teras@iki.fi>
700 Date:   Fri Jun 5 10:39:42 2015 +0300
701
702     fix uselocale((locale_t)0) not to modify locale
703     
704     commit 68630b55c0c7219fe9df70dc28ffbf9efc8021d8 made the new locale to
705     be assigned unconditonally resulting in crashes later on.
706
707 --- a/.gitignore
708 +++ b/.gitignore
709 @@ -7,5 +7,7 @@ arch/*/bits/alltypes.h
710  config.mak
711  include/bits
712  tools/musl-gcc
713 +tools/musl-clang
714 +tools/ld.musl-clang
715  lib/musl-gcc.specs
716  src/internal/version.h
717 --- a/Makefile
718 +++ b/Makefile
719 @@ -51,6 +51,9 @@ TOOL_LIBS = lib/musl-gcc.specs
720  ALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS)
721  ALL_TOOLS = tools/musl-gcc
722  
723 +WRAPCC_GCC = gcc
724 +WRAPCC_CLANG = clang
725 +
726  LDSO_PATHNAME = $(syslibdir)/ld-musl-$(ARCH)$(SUBARCH).so.1
727  
728  -include config.mak
729 @@ -155,7 +158,11 @@ lib/musl-gcc.specs: tools/musl-gcc.specs
730         sh $< "$(includedir)" "$(libdir)" "$(LDSO_PATHNAME)" > $@
731  
732  tools/musl-gcc: config.mak
733 -       printf '#!/bin/sh\nexec "$${REALGCC:-gcc}" "$$@" -specs "%s/musl-gcc.specs"\n' "$(libdir)" > $@
734 +       printf '#!/bin/sh\nexec "$${REALGCC:-$(WRAPCC_GCC)}" "$$@" -specs "%s/musl-gcc.specs"\n' "$(libdir)" > $@
735 +       chmod +x $@
736 +
737 +tools/%-clang: tools/%-clang.in config.mak
738 +       sed -e 's!@CC@!$(WRAPCC_CLANG)!g' -e 's!@PREFIX@!$(prefix)!g' -e 's!@INCDIR@!$(includedir)!g' -e 's!@LIBDIR@!$(libdir)!g' -e 's!@LDSO@!$(LDSO_PATHNAME)!g' $< > $@
739         chmod +x $@
740  
741  $(DESTDIR)$(bindir)/%: tools/%
742 --- a/arch/arm/syscall_arch.h
743 +++ b/arch/arm/syscall_arch.h
744 @@ -72,3 +72,7 @@ static inline long __syscall6(long n, lo
745         register long r5 __asm__("r5") = f;
746         __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
747  }
748 +
749 +#define VDSO_USEFUL
750 +#define VDSO_CGT_SYM "__vdso_clock_gettime"
751 +#define VDSO_CGT_VER "LINUX_2.6"
752 --- a/arch/mips/bits/signal.h
753 +++ b/arch/mips/bits/signal.h
754 @@ -28,7 +28,7 @@ struct sigcontext
755  typedef struct
756  {
757         unsigned regmask, status;
758 -       unsigned long long pc, regs[32], fpregs[32];
759 +       unsigned long long pc, gregs[32], fpregs[32];
760         unsigned ownedfp, fpc_csr, fpc_eir, used_math, dsp;
761         unsigned long long mdhi, mdlo;
762         unsigned long hi1, lo1, hi2, lo2, hi3, lo3;
763 --- a/arch/mips/bits/socket.h
764 +++ b/arch/mips/bits/socket.h
765 @@ -22,26 +22,31 @@ struct cmsghdr
766  #define SOL_SOCKET     65535
767  
768  #define SO_DEBUG        1
769 -#define SO_REUSEADDR    4
770 -#define SO_TYPE         0x1008
771 -#define SO_ERROR        0x1007
772 -#define SO_DONTROUTE    16
773 -#define SO_BROADCAST    32
774 +
775 +#define SO_REUSEADDR    0x0004
776 +#define SO_KEEPALIVE    0x0008
777 +#define SO_DONTROUTE    0x0010
778 +#define SO_BROADCAST    0x0020
779 +#define SO_LINGER       0x0080
780 +#define SO_OOBINLINE    0x0100
781 +#define SO_REUSEPORT    0x0200
782  #define SO_SNDBUF       0x1001
783  #define SO_RCVBUF       0x1002
784 -#define SO_KEEPALIVE    8
785 -#define SO_OOBINLINE    256
786 +#define SO_SNDLOWAT     0x1003
787 +#define SO_RCVLOWAT     0x1004
788 +#define SO_RCVTIMEO     0x1006
789 +#define SO_SNDTIMEO     0x1005
790 +#define SO_ERROR        0x1007
791 +#define SO_TYPE         0x1008
792 +#define SO_ACCEPTCONN   0x1009
793 +#define SO_PROTOCOL     0x1028
794 +#define SO_DOMAIN       0x1029
795 +
796  #define SO_NO_CHECK     11
797  #define SO_PRIORITY     12
798 -#define SO_LINGER       128
799  #define SO_BSDCOMPAT    14
800 -#define SO_REUSEPORT    512
801  #define SO_PASSCRED     17
802  #define SO_PEERCRED     18
803 -#define SO_RCVLOWAT     0x1004
804 -#define SO_SNDLOWAT     0x1003
805 -#define SO_RCVTIMEO     0x1006
806 -#define SO_SNDTIMEO     0x1005
807  #define SO_SNDBUFFORCE  31
808  #define SO_RCVBUFFORCE  33
809  
810 --- a/arch/mips/pthread_arch.h
811 +++ b/arch/mips/pthread_arch.h
812 @@ -13,4 +13,6 @@ static inline struct pthread *__pthread_
813  #define TLS_ABOVE_TP
814  #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
815  
816 +#define DTP_OFFSET 0x8000
817 +
818  #define CANCEL_REG_IP (3-(union {int __i; char __b;}){1}.__b)
819 --- a/arch/powerpc/bits/socket.h
820 +++ b/arch/powerpc/bits/socket.h
821 @@ -24,8 +24,6 @@ struct cmsghdr
822  #define SO_BROADCAST    6
823  #define SO_SNDBUF       7
824  #define SO_RCVBUF       8
825 -#define SO_SNDBUFFORCE  32
826 -#define SO_RCVBUFFORCE  33
827  #define SO_KEEPALIVE    9
828  #define SO_OOBINLINE    10
829  #define SO_NO_CHECK     11
830 @@ -39,4 +37,8 @@ struct cmsghdr
831  #define SO_SNDTIMEO     19
832  #define SO_PASSCRED     20
833  #define SO_PEERCRED     21
834
835 +#define SO_ACCEPTCONN   30
836 +#define SO_SNDBUFFORCE  32
837 +#define SO_RCVBUFFORCE  33
838 +#define SO_PROTOCOL     38
839 +#define SO_DOMAIN       39
840 --- a/arch/powerpc/pthread_arch.h
841 +++ b/arch/powerpc/pthread_arch.h
842 @@ -12,6 +12,8 @@ static inline struct pthread *__pthread_
843  #define TLS_ABOVE_TP
844  #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
845  
846 +#define DTP_OFFSET 0x8000
847 +
848  // offset of the PC register in mcontext_t, divided by the system wordsize
849  // the kernel calls the ip "nip", it's the first saved value after the 32
850  // GPRs.
851 --- /dev/null
852 +++ b/arch/sh/src/__set_thread_area.c
853 @@ -0,0 +1,34 @@
854 +#include "pthread_impl.h"
855 +#include "libc.h"
856 +#include "sh_atomic.h"
857 +#include <elf.h>
858 +
859 +/* Also perform sh-specific init */
860 +
861 +#define CPU_HAS_LLSC 0x0040
862 +
863 +__attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model, __sh_nommu;
864 +
865 +int __set_thread_area(void *p)
866 +{
867 +       size_t *aux;
868 +       __asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
869 +#ifndef __SH4A__
870 +       if (__hwcap & CPU_HAS_LLSC) {
871 +               __sh_atomic_model = SH_A_LLSC;
872 +               return 0;
873 +       }
874 +#if !defined(__SH3__) && !defined(__SH4__)
875 +       for (aux=libc.auxv; *aux; aux+=2) {
876 +               if (*aux != AT_PLATFORM) continue;
877 +               const char *s = (void *)aux[1];
878 +               if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
879 +               __sh_atomic_model = SH_A_IMASK;
880 +               __sh_nommu = 1;
881 +               return 0;
882 +       }
883 +#endif
884 +       /* __sh_atomic_model = SH_A_GUSA; */ /* 0, default */
885 +#endif
886 +       return 0;
887 +}
888 --- /dev/null
889 +++ b/arch/sh/src/__unmapself.c
890 @@ -0,0 +1,19 @@
891 +#include "pthread_impl.h"
892 +
893 +void __unmapself_sh_mmu(void *, size_t);
894 +void __unmapself_sh_nommu(void *, size_t);
895 +
896 +#if !defined(__SH3__) && !defined(__SH4__)
897 +#define __unmapself __unmapself_sh_nommu
898 +#include "../../../src/thread/__unmapself.c"
899 +#undef __unmapself
900 +extern __attribute__((__visibility__("hidden"))) unsigned __sh_nommu;
901 +#else
902 +#define __sh_nommu 0
903 +#endif
904 +
905 +void __unmapself(void *base, size_t size)
906 +{
907 +       if (__sh_nommu) __unmapself_sh_nommu(base, size);
908 +       else __unmapself_sh_mmu(base, size);
909 +}
910 --- a/arch/sh/src/atomic.c
911 +++ b/arch/sh/src/atomic.c
912 @@ -1,8 +1,26 @@
913  #ifndef __SH4A__
914  
915 +#include "sh_atomic.h"
916  #include "atomic.h"
917  #include "libc.h"
918  
919 +static inline unsigned mask()
920 +{
921 +       unsigned sr;
922 +       __asm__ __volatile__ ( "\n"
923 +       "       stc sr,r0 \n"
924 +       "       mov r0,%0 \n"
925 +       "       or #0xf0,r0 \n"
926 +       "       ldc r0,sr \n"
927 +       : "=&r"(sr) : : "memory", "r0" );
928 +       return sr;
929 +}
930 +
931 +static inline void unmask(unsigned sr)
932 +{
933 +       __asm__ __volatile__ ( "ldc %0,sr" : : "r"(sr) : "memory" );
934 +}
935 +
936  /* gusa is a hack in the kernel which lets you create a sequence of instructions
937   * which will be restarted if the process is preempted in the middle of the
938   * sequence. It will do for implementing atomics on non-smp systems. ABI is:
939 @@ -25,11 +43,17 @@
940         "       mov.l " new ", @" mem "\n" \
941         "1:     mov r1, r15\n"
942  
943 -#define CPU_HAS_LLSC 0x0040
944 -
945  int __sh_cas(volatile int *p, int t, int s)
946  {
947 -       if (__hwcap & CPU_HAS_LLSC) return __sh_cas_llsc(p, t, s);
948 +       if (__sh_atomic_model == SH_A_LLSC) return __sh_cas_llsc(p, t, s);
949 +
950 +       if (__sh_atomic_model == SH_A_IMASK) {
951 +               unsigned sr = mask();
952 +               int old = *p;
953 +               if (old==t) *p = s;
954 +               unmask(sr);
955 +               return old;
956 +       }
957  
958         int old;
959         __asm__ __volatile__(
960 @@ -43,7 +67,15 @@ int __sh_cas(volatile int *p, int t, int
961  
962  int __sh_swap(volatile int *x, int v)
963  {
964 -       if (__hwcap & CPU_HAS_LLSC) return __sh_swap_llsc(x, v);
965 +       if (__sh_atomic_model == SH_A_LLSC) return __sh_swap_llsc(x, v);
966 +
967 +       if (__sh_atomic_model == SH_A_IMASK) {
968 +               unsigned sr = mask();
969 +               int old = *x;
970 +               *x = v;
971 +               unmask(sr);
972 +               return old;
973 +       }
974  
975         int old;
976         __asm__ __volatile__(
977 @@ -55,7 +87,15 @@ int __sh_swap(volatile int *x, int v)
978  
979  int __sh_fetch_add(volatile int *x, int v)
980  {
981 -       if (__hwcap & CPU_HAS_LLSC) return __sh_fetch_add_llsc(x, v);
982 +       if (__sh_atomic_model == SH_A_LLSC) return __sh_fetch_add_llsc(x, v);
983 +
984 +       if (__sh_atomic_model == SH_A_IMASK) {
985 +               unsigned sr = mask();
986 +               int old = *x;
987 +               *x = old + v;
988 +               unmask(sr);
989 +               return old;
990 +       }
991  
992         int old, dummy;
993         __asm__ __volatile__(
994 @@ -69,7 +109,7 @@ int __sh_fetch_add(volatile int *x, int
995  
996  void __sh_store(volatile int *p, int x)
997  {
998 -       if (__hwcap & CPU_HAS_LLSC) return __sh_store_llsc(p, x);
999 +       if (__sh_atomic_model == SH_A_LLSC) return __sh_store_llsc(p, x);
1000         __asm__ __volatile__(
1001                 "       mov.l %1, @%0\n"
1002                 : : "r"(p), "r"(x) : "memory");
1003 @@ -77,7 +117,15 @@ void __sh_store(volatile int *p, int x)
1004  
1005  void __sh_and(volatile int *x, int v)
1006  {
1007 -       if (__hwcap & CPU_HAS_LLSC) return __sh_and_llsc(x, v);
1008 +       if (__sh_atomic_model == SH_A_LLSC) return __sh_and_llsc(x, v);
1009 +
1010 +       if (__sh_atomic_model == SH_A_IMASK) {
1011 +               unsigned sr = mask();
1012 +               int old = *x;
1013 +               *x = old & v;
1014 +               unmask(sr);
1015 +               return;
1016 +       }
1017  
1018         int dummy;
1019         __asm__ __volatile__(
1020 @@ -89,7 +137,15 @@ void __sh_and(volatile int *x, int v)
1021  
1022  void __sh_or(volatile int *x, int v)
1023  {
1024 -       if (__hwcap & CPU_HAS_LLSC) return __sh_or_llsc(x, v);
1025 +       if (__sh_atomic_model == SH_A_LLSC) return __sh_or_llsc(x, v);
1026 +
1027 +       if (__sh_atomic_model == SH_A_IMASK) {
1028 +               unsigned sr = mask();
1029 +               int old = *x;
1030 +               *x = old | v;
1031 +               unmask(sr);
1032 +               return;
1033 +       }
1034  
1035         int dummy;
1036         __asm__ __volatile__(
1037 --- /dev/null
1038 +++ b/arch/sh/src/sh_atomic.h
1039 @@ -0,0 +1,15 @@
1040 +#ifndef _SH_ATOMIC_H
1041 +#define _SH_ATOMIC_H
1042 +
1043 +#define SH_A_GUSA 0
1044 +#define SH_A_LLSC 1
1045 +#define SH_A_CAS 2
1046 +#if !defined(__SH3__) && !defined(__SH4__)
1047 +#define SH_A_IMASK 3
1048 +#else
1049 +#define SH_A_IMASK -1LL /* unmatchable by unsigned int */
1050 +#endif
1051 +
1052 +extern __attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model;
1053 +
1054 +#endif
1055 --- a/arch/sh/syscall_arch.h
1056 +++ b/arch/sh/syscall_arch.h
1057 @@ -8,7 +8,7 @@
1058   */
1059  #define __asm_syscall(trapno, ...) do {   \
1060         __asm__ __volatile__ (                \
1061 -               "trapa #" #trapno "\n"            \
1062 +               "trapa #31\n"            \
1063                 "or r0, r0\n"                     \
1064                 "or r0, r0\n"                     \
1065                 "or r0, r0\n"                     \
1066 --- a/configure
1067 +++ b/configure
1068 @@ -28,7 +28,7 @@ Optional features:
1069    --enable-debug          build with debugging information [disabled]
1070    --enable-warnings       build with recommended warnings flags [disabled]
1071    --enable-visibility     use global visibility options to optimize PIC [auto]
1072 -  --enable-gcc-wrapper    build musl-gcc toolchain wrapper [auto]
1073 +  --enable-wrapper=...    build given musl toolchain wrapper [auto]
1074    --disable-shared        inhibit building shared library [enabled]
1075    --disable-static        inhibit building static library [enabled]
1076  
1077 @@ -123,6 +123,8 @@ bindir='$(exec_prefix)/bin'
1078  libdir='$(prefix)/lib'
1079  includedir='$(prefix)/include'
1080  syslibdir='/lib'
1081 +tools=
1082 +tool_libs=
1083  target=
1084  optimize=auto
1085  debug=no
1086 @@ -131,6 +133,8 @@ visibility=auto
1087  shared=auto
1088  static=yes
1089  wrapper=auto
1090 +gcc_wrapper=no
1091 +clang_wrapper=no
1092  
1093  for arg ; do
1094  case "$arg" in
1095 @@ -154,7 +158,12 @@ case "$arg" in
1096  --disable-warnings|--enable-warnings=no) warnings=no ;;
1097  --enable-visibility|--enable-visibility=yes) visibility=yes ;;
1098  --disable-visibility|--enable-visibility=no) visibility=no ;;
1099 ---enable-gcc-wrapper|--enable-gcc-wrapper=yes) wrapper=yes ;;
1100 +--enable-wrapper|--enable-wrapper=yes) wrapper=detect ;;
1101 +--enable-wrapper=all) wrapper=yes ; gcc_wrapper=yes ; clang_wrapper=yes ;;
1102 +--enable-wrapper=gcc) wrapper=yes ; gcc_wrapper=yes ;;
1103 +--enable-wrapper=clang) wrapper=yes ; clang_wrapper=yes ;;
1104 +--disable-wrapper|--enable-wrapper=no) wrapper=no ;;
1105 +--enable-gcc-wrapper|--enable-gcc-wrapper=yes) wrapper=yes ; gcc_wrapper=yes ;;
1106  --disable-gcc-wrapper|--enable-gcc-wrapper=no) wrapper=no ;;
1107  --enable-*|--disable-*|--with-*|--without-*|--*dir=*|--build=*) ;;
1108  --host=*|--target=*) target=${arg#*=} ;;
1109 @@ -215,36 +224,51 @@ tryldflag LDFLAGS_TRY -Werror=unknown-wa
1110  tryldflag LDFLAGS_TRY -Werror=unused-command-line-argument
1111  
1112  #
1113 -# Need to know if the compiler is gcc to decide whether to build the
1114 -# musl-gcc wrapper, and for critical bug detection in some gcc versions.
1115 +# Need to know if the compiler is gcc or clang to decide which toolchain
1116 +# wrappers to build.
1117  #
1118 -printf "checking whether compiler is gcc... "
1119 -if fnmatch '*gcc\ version*' "$(LC_ALL=C $CC -v 2>&1)" ; then
1120 -cc_is_gcc=yes
1121 +printf "checking for C compiler family... "
1122 +cc_ver="$(LC_ALL=C $CC -v 2>&1)"
1123 +cc_family=unknown
1124 +if fnmatch '*gcc\ version*' "$cc_ver" ; then
1125 +cc_family=gcc
1126 +elif fnmatch '*clang\ version*' "$cc_ver" ; then
1127 +cc_family=clang
1128 +fi
1129 +echo "$cc_family"
1130 +
1131 +#
1132 +# Figure out toolchain wrapper to build
1133 +#
1134 +if test "$wrapper" = auto -o "$wrapper" = detect ; then
1135 +echo "#include <stdlib.h>" > "$tmpc"
1136 +echo "#if ! __GLIBC__" >> "$tmpc"
1137 +echo "#error no" >> "$tmpc"
1138 +echo "#endif" >> "$tmpc"
1139 +printf "checking for toolchain wrapper to build... "
1140 +if test "$wrapper" = auto && ! $CC -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
1141 +echo "none"
1142 +elif test "$cc_family" = gcc ; then
1143 +gcc_wrapper=yes
1144 +echo "gcc"
1145 +elif test "$cc_family" = clang ; then
1146 +clang_wrapper=yes
1147 +echo "clang"
1148  else
1149 -cc_is_gcc=no
1150 +echo "none"
1151 +if test "$wrapper" = detect ; then
1152 +fail "$0: could not find an appropriate toolchain wrapper"
1153  fi
1154 -echo "$cc_is_gcc"
1155 -
1156 -#
1157 -# Only build musl-gcc wrapper if toolchain does not already target musl
1158 -#
1159 -if test "$wrapper" = auto ; then
1160 -printf "checking whether to build musl-gcc wrapper... "
1161 -if test "$cc_is_gcc" = yes ; then
1162 -wrapper=yes
1163 -while read line ; do
1164 -case "$line" in */ld-musl-*) wrapper=no ;; esac
1165 -done <<EOF
1166 -$($CC -dumpspecs)
1167 -EOF
1168 -else
1169 -wrapper=no
1170  fi
1171 -echo "$wrapper"
1172  fi
1173  
1174 -
1175 +if test "$gcc_wrapper" = yes ; then
1176 +tools="$tools tools/musl-gcc"
1177 +tool_libs="$tool_libs lib/musl-gcc.specs"
1178 +fi
1179 +if test "$clang_wrapper" = yes ; then
1180 +tools="$tools tools/musl-clang tools/ld.musl-clang"
1181 +fi
1182  
1183  #
1184  # Find the target architecture
1185 @@ -580,11 +604,13 @@ LDFLAGS = $LDFLAGS_AUTO $LDFLAGS
1186  CROSS_COMPILE = $CROSS_COMPILE
1187  LIBCC = $LIBCC
1188  OPTIMIZE_GLOBS = $OPTIMIZE_GLOBS
1189 +ALL_TOOLS = $tools
1190 +TOOL_LIBS = $tool_libs
1191  EOF
1192  test "x$static" = xno && echo "STATIC_LIBS ="
1193  test "x$shared" = xno && echo "SHARED_LIBS ="
1194 -test "x$wrapper" = xno && echo "ALL_TOOLS ="
1195 -test "x$wrapper" = xno && echo "TOOL_LIBS ="
1196 +test "x$cc_family" = xgcc && echo 'WRAPCC_GCC = $(CC)'
1197 +test "x$cc_family" = xclang && echo 'WRAPCC_CLANG = $(CC)'
1198  exec 1>&3 3>&-
1199  
1200  printf "done\n"
1201 --- a/include/ctype.h
1202 +++ b/include/ctype.h
1203 @@ -64,6 +64,7 @@ int   isascii(int);
1204  int   toascii(int);
1205  #define _tolower(a) ((a)|0x20)
1206  #define _toupper(a) ((a)&0x5f)
1207 +#define isascii(a) (0 ? isascii(a) : (unsigned)(a) < 128)
1208  
1209  #endif
1210  
1211 --- a/include/stdlib.h
1212 +++ b/include/stdlib.h
1213 @@ -76,7 +76,8 @@ size_t wcstombs (char *__restrict, const
1214  #define EXIT_FAILURE 1
1215  #define EXIT_SUCCESS 0
1216  
1217 -#define MB_CUR_MAX ((size_t)+4)
1218 +size_t __ctype_get_mb_cur_max(void);
1219 +#define MB_CUR_MAX (__ctype_get_mb_cur_max())
1220  
1221  #define RAND_MAX (0x7fffffff)
1222  
1223 --- a/include/sys/socket.h
1224 +++ b/include/sys/socket.h
1225 @@ -177,8 +177,11 @@ struct linger
1226  #define SO_SNDLOWAT     19
1227  #define SO_RCVTIMEO     20
1228  #define SO_SNDTIMEO     21
1229 +#define SO_ACCEPTCONN   30
1230  #define SO_SNDBUFFORCE  32
1231  #define SO_RCVBUFFORCE  33
1232 +#define SO_PROTOCOL     38
1233 +#define SO_DOMAIN       39
1234  #endif
1235  
1236  #define SO_SECURITY_AUTHENTICATION              22
1237 @@ -195,7 +198,6 @@ struct linger
1238  #define SO_TIMESTAMP            29
1239  #define SCM_TIMESTAMP           SO_TIMESTAMP
1240  
1241 -#define SO_ACCEPTCONN           30
1242  #define SO_PEERSEC              31
1243  #define SO_PASSSEC              34
1244  #define SO_TIMESTAMPNS          35
1245 @@ -203,8 +205,6 @@ struct linger
1246  #define SO_MARK                 36
1247  #define SO_TIMESTAMPING         37
1248  #define SCM_TIMESTAMPING        SO_TIMESTAMPING
1249 -#define SO_PROTOCOL             38
1250 -#define SO_DOMAIN               39
1251  #define SO_RXQ_OVFL             40
1252  #define SO_WIFI_STATUS          41
1253  #define SCM_WIFI_STATUS         SO_WIFI_STATUS
1254 --- a/include/unistd.h
1255 +++ b/include/unistd.h
1256 @@ -185,7 +185,7 @@ int setresgid(gid_t, gid_t, gid_t);
1257  int getresuid(uid_t *, uid_t *, uid_t *);
1258  int getresgid(gid_t *, gid_t *, gid_t *);
1259  char *get_current_dir_name(void);
1260 -void syncfs(int);
1261 +int syncfs(int);
1262  int euidaccess(const char *, int);
1263  int eaccess(const char *, int);
1264  #endif
1265 --- a/src/ctype/__ctype_get_mb_cur_max.c
1266 +++ b/src/ctype/__ctype_get_mb_cur_max.c
1267 @@ -1,6 +1,7 @@
1268 -#include <stddef.h>
1269 +#include <stdlib.h>
1270 +#include "locale_impl.h"
1271  
1272  size_t __ctype_get_mb_cur_max()
1273  {
1274 -       return 4;
1275 +       return MB_CUR_MAX;
1276  }
1277 --- a/src/ctype/isascii.c
1278 +++ b/src/ctype/isascii.c
1279 @@ -1,4 +1,5 @@
1280  #include <ctype.h>
1281 +#undef isascii
1282  
1283  int isascii(int c)
1284  {
1285 --- a/src/env/__stack_chk_fail.c
1286 +++ b/src/env/__stack_chk_fail.c
1287 @@ -25,4 +25,8 @@ void __stack_chk_fail_local(void)
1288         a_crash();
1289  }
1290  
1291 +#else
1292 +
1293 +weak_alias(__stack_chk_fail, __stack_chk_fail_local);
1294 +
1295  #endif
1296 --- a/src/internal/libc.h
1297 +++ b/src/internal/libc.h
1298 @@ -17,8 +17,6 @@ struct __libc {
1299         int secure;
1300         volatile int threads_minus_1;
1301         size_t *auxv;
1302 -       FILE *ofl_head;
1303 -       volatile int ofl_lock[2];
1304         size_t tls_size;
1305         size_t page_size;
1306         struct __locale_struct global_locale;
1307 --- a/src/internal/locale_impl.h
1308 +++ b/src/internal/locale_impl.h
1309 @@ -1,3 +1,6 @@
1310 +#ifndef _LOCALE_IMPL_H
1311 +#define _LOCALE_IMPL_H
1312 +
1313  #include <locale.h>
1314  #include <stdlib.h>
1315  #include "libc.h"
1316 @@ -12,6 +15,10 @@ struct __locale_map {
1317         const struct __locale_map *next;
1318  };
1319  
1320 +extern const struct __locale_map __c_dot_utf8;
1321 +extern const struct __locale_struct __c_locale;
1322 +extern const struct __locale_struct __c_dot_utf8_locale;
1323 +
1324  const struct __locale_map *__get_locale(int, const char *);
1325  const char *__mo_lookup(const void *, size_t, const char *);
1326  const char *__lctrans(const char *, const struct __locale_map *);
1327 @@ -20,9 +27,14 @@ const char *__lctrans_cur(const char *);
1328  #define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])
1329  #define LCTRANS_CUR(msg) __lctrans_cur(msg)
1330  
1331 +#define C_LOCALE ((locale_t)&__c_locale)
1332 +#define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale)
1333 +
1334  #define CURRENT_LOCALE (__pthread_self()->locale)
1335  
1336  #define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
1337  
1338  #undef MB_CUR_MAX
1339  #define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
1340 +
1341 +#endif
1342 --- a/src/internal/pthread_impl.h
1343 +++ b/src/internal/pthread_impl.h
1344 @@ -94,6 +94,10 @@ struct __timer {
1345  #define CANARY canary
1346  #endif
1347  
1348 +#ifndef DTP_OFFSET
1349 +#define DTP_OFFSET 0
1350 +#endif
1351 +
1352  #define SIGTIMER 32
1353  #define SIGCANCEL 33
1354  #define SIGSYNCCALL 34
1355 --- a/src/internal/sh/syscall.s
1356 +++ b/src/internal/sh/syscall.s
1357 @@ -13,7 +13,7 @@ __syscall:
1358         mov.l @r15, r7
1359         mov.l @(4,r15), r0
1360         mov.l @(8,r15), r1
1361 -       trapa #22
1362 +       trapa #31
1363         or r0, r0
1364         or r0, r0
1365         or r0, r0
1366 --- a/src/internal/stdio_impl.h
1367 +++ b/src/internal/stdio_impl.h
1368 @@ -47,6 +47,7 @@ struct _IO_FILE {
1369         unsigned char *shend;
1370         off_t shlim, shcnt;
1371         FILE *prev_locked, *next_locked;
1372 +       struct __locale_struct *locale;
1373  };
1374  
1375  size_t __stdio_read(FILE *, unsigned char *, size_t);
1376 @@ -75,8 +76,9 @@ int __putc_unlocked(int, FILE *);
1377  FILE *__fdopen(int, const char *);
1378  int __fmodeflags(const char *);
1379  
1380 -#define OFLLOCK() LOCK(libc.ofl_lock)
1381 -#define OFLUNLOCK() UNLOCK(libc.ofl_lock)
1382 +FILE *__ofl_add(FILE *f);
1383 +FILE **__ofl_lock(void);
1384 +void __ofl_unlock(void);
1385  
1386  #define feof(f) ((f)->flags & F_EOF)
1387  #define ferror(f) ((f)->flags & F_ERR)
1388 --- a/src/ldso/dynlink.c
1389 +++ b/src/ldso/dynlink.c
1390 @@ -156,7 +156,7 @@ static uint32_t gnu_hash(const char *s0)
1391         const unsigned char *s = (void *)s0;
1392         uint_fast32_t h = 5381;
1393         for (; *s; s++)
1394 -               h = h*33 + *s;
1395 +               h += h*32 + *s;
1396         return h;
1397  }
1398  
1399 @@ -174,32 +174,39 @@ static Sym *sysv_lookup(const char *s, u
1400         return 0;
1401  }
1402  
1403 -static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
1404 +static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s)
1405  {
1406 -       Sym *syms = dso->syms;
1407 -       char *strings = dso->strings;
1408 -       uint32_t *hashtab = dso->ghashtab;
1409         uint32_t nbuckets = hashtab[0];
1410         uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
1411 -       uint32_t h2;
1412 -       uint32_t *hashval;
1413         uint32_t i = buckets[h1 % nbuckets];
1414  
1415         if (!i) return 0;
1416  
1417 -       hashval = buckets + nbuckets + (i - hashtab[1]);
1418 +       uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);
1419  
1420         for (h1 |= 1; ; i++) {
1421 -               h2 = *hashval++;
1422 -               if ((!dso->versym || dso->versym[i] >= 0)
1423 -                   && (h1 == (h2|1)) && !strcmp(s, strings + syms[i].st_name))
1424 -                       return syms+i;
1425 +               uint32_t h2 = *hashval++;
1426 +               if ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0)
1427 +                   && !strcmp(s, dso->strings + dso->syms[i].st_name))
1428 +                       return dso->syms+i;
1429                 if (h2 & 1) break;
1430         }
1431  
1432         return 0;
1433  }
1434  
1435 +static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask)
1436 +{
1437 +       const size_t *bloomwords = (const void *)(hashtab+4);
1438 +       size_t f = bloomwords[fofs & (hashtab[2]-1)];
1439 +       if (!(f & fmask)) return 0;
1440 +
1441 +       f >>= (h1 >> hashtab[3]) % (8 * sizeof f);
1442 +       if (!(f & 1)) return 0;
1443 +
1444 +       return gnu_lookup(h1, hashtab, dso, s);
1445 +}
1446 +
1447  #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
1448  #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
1449  
1450 @@ -209,14 +216,20 @@ static Sym *gnu_lookup(const char *s, ui
1451  
1452  static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
1453  {
1454 -       uint32_t h = 0, gh = 0;
1455 +       uint32_t h = 0, gh, gho, *ght;
1456 +       size_t ghm = 0;
1457         struct symdef def = {0};
1458         for (; dso; dso=dso->next) {
1459                 Sym *sym;
1460                 if (!dso->global) continue;
1461 -               if (dso->ghashtab) {
1462 -                       if (!gh) gh = gnu_hash(s);
1463 -                       sym = gnu_lookup(s, gh, dso);
1464 +               if ((ght = dso->ghashtab)) {
1465 +                       if (!ghm) {
1466 +                               gh = gnu_hash(s);
1467 +                               int maskbits = 8 * sizeof ghm;
1468 +                               gho = gh / maskbits;
1469 +                               ghm = 1ul << gh % maskbits;
1470 +                       }
1471 +                       sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm);
1472                 } else {
1473                         if (!h) h = sysv_hash(s);
1474                         sym = sysv_lookup(s, h, dso);
1475 @@ -337,7 +350,7 @@ static void do_relocs(struct dso *dso, s
1476                         *reloc_addr = def.dso->tls_id;
1477                         break;
1478                 case REL_DTPOFF:
1479 -                       *reloc_addr = tls_val + addend;
1480 +                       *reloc_addr = tls_val + addend - DTP_OFFSET;
1481                         break;
1482  #ifdef TLS_ABOVE_TP
1483                 case REL_TPOFF:
1484 @@ -423,6 +436,28 @@ static void reclaim_gaps(struct dso *dso
1485         }
1486  }
1487  
1488 +static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
1489 +{
1490 +       char *q = mmap(p, n, prot, flags, fd, off);
1491 +       if (q != MAP_FAILED || errno != EINVAL) return q;
1492 +       /* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
1493 +       if (flags & MAP_ANONYMOUS) {
1494 +               memset(p, 0, n);
1495 +               return p;
1496 +       }
1497 +       ssize_t r;
1498 +       if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;
1499 +       for (q=p; n; q+=r, off+=r, n-=r) {
1500 +               r = read(fd, q, n);
1501 +               if (r < 0 && errno != EINTR) return MAP_FAILED;
1502 +               if (!r) {
1503 +                       memset(q, 0, n);
1504 +                       break;
1505 +               }
1506 +       }
1507 +       return p;
1508 +}
1509 +
1510  static void *map_library(int fd, struct dso *dso)
1511  {
1512         Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
1513 @@ -524,19 +559,20 @@ static void *map_library(int fd, struct
1514                 prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1515                         ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1516                         ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1517 -               if (mmap(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
1518 +               if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
1519                         goto error;
1520                 if (ph->p_memsz > ph->p_filesz) {
1521                         size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
1522                         size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
1523                         memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
1524 -                       if (pgbrk-(size_t)base < this_max && mmap((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
1525 +                       if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
1526                                 goto error;
1527                 }
1528         }
1529         for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
1530                 if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
1531 -                       if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC) < 0)
1532 +                       if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)
1533 +                           && errno != ENOSYS)
1534                                 goto error;
1535                         break;
1536                 }
1537 @@ -927,7 +963,8 @@ static void reloc_all(struct dso *p)
1538                 do_relocs(p, (void *)(p->base+dyn[DT_RELA]), dyn[DT_RELASZ], 3);
1539  
1540                 if (head != &ldso && p->relro_start != p->relro_end &&
1541 -                   mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ) < 0) {
1542 +                   mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ)
1543 +                   && errno != ENOSYS) {
1544                         error("Error relocating %s: RELRO protection failed: %m",
1545                                 p->name);
1546                         if (runtime) longjmp(*rtld_fail, 1);
1547 @@ -1078,7 +1115,7 @@ void *__tls_get_new(size_t *v)
1548         __block_all_sigs(&set);
1549         if (v[0]<=(size_t)self->dtv[0]) {
1550                 __restore_sigs(&set);
1551 -               return (char *)self->dtv[v[0]]+v[1];
1552 +               return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
1553         }
1554  
1555         /* This is safe without any locks held because, if the caller
1556 @@ -1111,7 +1148,7 @@ void *__tls_get_new(size_t *v)
1557                 if (p->tls_id == v[0]) break;
1558         }
1559         __restore_sigs(&set);
1560 -       return mem + v[1];
1561 +       return mem + v[1] + DTP_OFFSET;
1562  }
1563  
1564  static void update_tls_size()
1565 @@ -1192,6 +1229,17 @@ _Noreturn void __dls3(size_t *sp)
1566         char **argv_orig = argv;
1567         char **envp = argv+argc+1;
1568  
1569 +       /* Find aux vector just past environ[] and use it to initialize
1570 +        * global data that may be needed before we can make syscalls. */
1571 +       __environ = envp;
1572 +       for (i=argc+1; argv[i]; i++);
1573 +       libc.auxv = auxv = (void *)(argv+i+1);
1574 +       decode_vec(auxv, aux, AUX_CNT);
1575 +       __hwcap = aux[AT_HWCAP];
1576 +       libc.page_size = aux[AT_PAGESZ];
1577 +       libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
1578 +               || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);
1579 +
1580         /* Setup early thread pointer in builtin_tls for ldso/libc itself to
1581          * use during dynamic linking. If possible it will also serve as the
1582          * thread pointer at runtime. */
1583 @@ -1200,25 +1248,11 @@ _Noreturn void __dls3(size_t *sp)
1584                 a_crash();
1585         }
1586  
1587 -       /* Find aux vector just past environ[] */
1588 -       for (i=argc+1; argv[i]; i++)
1589 -               if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16))
1590 -                       env_path = argv[i]+16;
1591 -               else if (!memcmp(argv[i], "LD_PRELOAD=", 11))
1592 -                       env_preload = argv[i]+11;
1593 -       auxv = (void *)(argv+i+1);
1594 -
1595 -       decode_vec(auxv, aux, AUX_CNT);
1596 -
1597         /* Only trust user/env if kernel says we're not suid/sgid */
1598 -       if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
1599 -         || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]) {
1600 -               env_path = 0;
1601 -               env_preload = 0;
1602 -               libc.secure = 1;
1603 +       if (!libc.secure) {
1604 +               env_path = getenv("LD_LIBRARY_PATH");
1605 +               env_preload = getenv("LD_PRELOAD");
1606         }
1607 -       libc.page_size = aux[AT_PAGESZ];
1608 -       libc.auxv = auxv;
1609  
1610         /* If the main program was already loaded by the kernel,
1611          * AT_PHDR will point to some location other than the dynamic
1612 @@ -1523,7 +1557,7 @@ void *__tls_get_addr(size_t *);
1613  static void *do_dlsym(struct dso *p, const char *s, void *ra)
1614  {
1615         size_t i;
1616 -       uint32_t h = 0, gh = 0;
1617 +       uint32_t h = 0, gh = 0, *ght;
1618         Sym *sym;
1619         if (p == head || p == RTLD_DEFAULT || p == RTLD_NEXT) {
1620                 if (p == RTLD_DEFAULT) {
1621 @@ -1541,9 +1575,9 @@ static void *do_dlsym(struct dso *p, con
1622         }
1623         if (invalid_dso_handle(p))
1624                 return 0;
1625 -       if (p->ghashtab) {
1626 +       if ((ght = p->ghashtab)) {
1627                 gh = gnu_hash(s);
1628 -               sym = gnu_lookup(s, gh, p);
1629 +               sym = gnu_lookup(gh, ght, p, s);
1630         } else {
1631                 h = sysv_hash(s);
1632                 sym = sysv_lookup(s, h, p);
1633 @@ -1553,9 +1587,9 @@ static void *do_dlsym(struct dso *p, con
1634         if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
1635                 return p->base + sym->st_value;
1636         if (p->deps) for (i=0; p->deps[i]; i++) {
1637 -               if (p->deps[i]->ghashtab) {
1638 +               if ((ght = p->deps[i]->ghashtab)) {
1639                         if (!gh) gh = gnu_hash(s);
1640 -                       sym = gnu_lookup(s, gh, p->deps[i]);
1641 +                       sym = gnu_lookup(gh, ght, p->deps[i], s);
1642                 } else {
1643                         if (!h) h = sysv_hash(s);
1644                         sym = sysv_lookup(s, h, p->deps[i]);
1645 --- a/src/linux/syncfs.c
1646 +++ b/src/linux/syncfs.c
1647 @@ -2,7 +2,7 @@
1648  #include <unistd.h>
1649  #include "syscall.h"
1650  
1651 -void syncfs(int fd)
1652 +int syncfs(int fd)
1653  {
1654 -       __syscall(SYS_syncfs, fd);
1655 +       return syscall(SYS_syncfs, fd);
1656  }
1657 --- /dev/null
1658 +++ b/src/locale/c_locale.c
1659 @@ -0,0 +1,15 @@
1660 +#include "locale_impl.h"
1661 +#include <stdint.h>
1662 +
1663 +static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
1664 +
1665 +const struct __locale_map __c_dot_utf8 = {
1666 +       .map = empty_mo,
1667 +       .map_size = sizeof empty_mo,
1668 +       .name = "C.UTF-8"
1669 +};
1670 +
1671 +const struct __locale_struct __c_locale = { 0 };
1672 +const struct __locale_struct __c_dot_utf8_locale = {
1673 +       .cat[LC_CTYPE] = &__c_dot_utf8
1674 +};
1675 --- a/src/locale/iconv.c
1676 +++ b/src/locale/iconv.c
1677 @@ -5,6 +5,7 @@
1678  #include <stdlib.h>
1679  #include <limits.h>
1680  #include <stdint.h>
1681 +#include "locale_impl.h"
1682  
1683  #define UTF_32BE    0300
1684  #define UTF_16LE    0301
1685 @@ -165,9 +166,12 @@ size_t iconv(iconv_t cd0, char **restric
1686         int err;
1687         unsigned char type = map[-1];
1688         unsigned char totype = tomap[-1];
1689 +       locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
1690  
1691         if (!in || !*in || !*inb) return 0;
1692  
1693 +       *ploc = UTF8_LOCALE;
1694 +
1695         for (; *inb; *in+=l, *inb-=l) {
1696                 c = *(unsigned char *)*in;
1697                 l = 1;
1698 @@ -431,6 +435,7 @@ size_t iconv(iconv_t cd0, char **restric
1699                         break;
1700                 }
1701         }
1702 +       *ploc = loc;
1703         return x;
1704  ilseq:
1705         err = EILSEQ;
1706 @@ -445,5 +450,6 @@ starved:
1707         x = -1;
1708  end:
1709         errno = err;
1710 +       *ploc = loc;
1711         return x;
1712  }
1713 --- a/src/locale/langinfo.c
1714 +++ b/src/locale/langinfo.c
1715 @@ -33,7 +33,8 @@ char *__nl_langinfo_l(nl_item item, loca
1716         int idx = item & 65535;
1717         const char *str;
1718  
1719 -       if (item == CODESET) return "UTF-8";
1720 +       if (item == CODESET)
1721 +               return MB_CUR_MAX==1 ? "UTF-8-CODE-UNITS" : "UTF-8";
1722         
1723         switch (cat) {
1724         case LC_NUMERIC:
1725 --- a/src/locale/locale_map.c
1726 +++ b/src/locale/locale_map.c
1727 @@ -24,14 +24,6 @@ static const char envvars[][12] = {
1728         "LC_MESSAGES",
1729  };
1730  
1731 -static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
1732 -
1733 -const struct __locale_map __c_dot_utf8 = {
1734 -       .map = empty_mo,
1735 -       .map_size = sizeof empty_mo,
1736 -       .name = "C.UTF-8"
1737 -};
1738 -
1739  const struct __locale_map *__get_locale(int cat, const char *val)
1740  {
1741         static int lock[2];
1742 @@ -107,8 +99,8 @@ const struct __locale_map *__get_locale(
1743          * sake of being able to do message translations at the
1744          * application level. */
1745         if (!new && (new = malloc(sizeof *new))) {
1746 -               new->map = empty_mo;
1747 -               new->map_size = sizeof empty_mo;
1748 +               new->map = __c_dot_utf8.map;
1749 +               new->map_size = __c_dot_utf8.map_size;
1750                 memcpy(new->name, val, n);
1751                 new->name[n] = 0;
1752                 new->next = loc_head;
1753 --- a/src/locale/newlocale.c
1754 +++ b/src/locale/newlocale.c
1755 @@ -3,16 +3,9 @@
1756  #include "locale_impl.h"
1757  #include "libc.h"
1758  
1759 -extern const struct __locale_map __c_dot_utf8;
1760 -
1761 -static const struct __locale_struct c_locale = { 0 };
1762 -static const struct __locale_struct c_dot_utf8_locale = {
1763 -       .cat[LC_CTYPE] = &__c_dot_utf8
1764 -};
1765 -
1766  int __loc_is_allocated(locale_t loc)
1767  {
1768 -       return loc && loc != &c_locale && loc != &c_dot_utf8_locale;
1769 +       return loc && loc != C_LOCALE && loc != UTF8_LOCALE;
1770  }
1771  
1772  locale_t __newlocale(int mask, const char *name, locale_t loc)
1773 @@ -44,9 +37,9 @@ locale_t __newlocale(int mask, const cha
1774         }
1775  
1776         if (!j)
1777 -               return (locale_t)&c_locale;
1778 -       if (j==1 && tmp.cat[LC_CTYPE]==c_dot_utf8_locale.cat[LC_CTYPE])
1779 -               return (locale_t)&c_dot_utf8_locale;
1780 +               return C_LOCALE;
1781 +       if (j==1 && tmp.cat[LC_CTYPE]==&__c_dot_utf8)
1782 +               return UTF8_LOCALE;
1783  
1784         if ((loc = malloc(sizeof *loc))) *loc = tmp;
1785  
1786 --- a/src/locale/uselocale.c
1787 +++ b/src/locale/uselocale.c
1788 @@ -8,9 +8,7 @@ locale_t __uselocale(locale_t new)
1789         locale_t old = self->locale;
1790         locale_t global = &libc.global_locale;
1791  
1792 -       if (new == LC_GLOBAL_LOCALE) new = global;
1793 -
1794 -       self->locale = new;
1795 +       if (new) self->locale = new == LC_GLOBAL_LOCALE ? global : new;
1796  
1797         return old == global ? LC_GLOBAL_LOCALE : old;
1798  }
1799 --- a/src/malloc/calloc.c
1800 +++ b/src/malloc/calloc.c
1801 @@ -1,22 +1,13 @@
1802  #include <stdlib.h>
1803  #include <errno.h>
1804  
1805 +void *__malloc0(size_t);
1806 +
1807  void *calloc(size_t m, size_t n)
1808  {
1809 -       void *p;
1810 -       size_t *z;
1811         if (n && m > (size_t)-1/n) {
1812                 errno = ENOMEM;
1813                 return 0;
1814         }
1815 -       n *= m;
1816 -       p = malloc(n);
1817 -       if (!p) return 0;
1818 -       /* Only do this for non-mmapped chunks */
1819 -       if (((size_t *)p)[-1] & 7) {
1820 -               /* Only write words that are not already zero */
1821 -               m = (n + sizeof *z - 1)/sizeof *z;
1822 -               for (z=p; m; m--, z++) if (*z) *z=0;
1823 -       }
1824 -       return p;
1825 +       return __malloc0(n * m);
1826  }
1827 --- /dev/null
1828 +++ b/src/malloc/expand_heap.c
1829 @@ -0,0 +1,72 @@
1830 +#include <limits.h>
1831 +#include <stdint.h>
1832 +#include <errno.h>
1833 +#include <sys/mman.h>
1834 +#include "libc.h"
1835 +#include "syscall.h"
1836 +
1837 +/* This function returns true if the interval [old,new]
1838 + * intersects the 'len'-sized interval below &libc.auxv
1839 + * (interpreted as the main-thread stack) or below &b
1840 + * (the current stack). It is used to defend against
1841 + * buggy brk implementations that can cross the stack. */
1842 +
1843 +static int traverses_stack_p(uintptr_t old, uintptr_t new)
1844 +{
1845 +       const uintptr_t len = 8<<20;
1846 +       uintptr_t a, b;
1847 +
1848 +       b = (uintptr_t)libc.auxv;
1849 +       a = b > len ? b-len : 0;
1850 +       if (new>a && old<b) return 1;
1851 +
1852 +       b = (uintptr_t)&b;
1853 +       a = b > len ? b-len : 0;
1854 +       if (new>a && old<b) return 1;
1855 +
1856 +       return 0;
1857 +}
1858 +
1859 +void *__mmap(void *, size_t, int, int, int, off_t);
1860 +
1861 +/* Expand the heap in-place if brk can be used, or otherwise via mmap,
1862 + * using an exponential lower bound on growth by mmap to make
1863 + * fragmentation asymptotically irrelevant. The size argument is both
1864 + * an input and an output, since the caller needs to know the size
1865 + * allocated, which will be larger than requested due to page alignment
1866 + * and mmap minimum size rules. The caller is responsible for locking
1867 + * to prevent concurrent calls. */
1868 +
1869 +void *__expand_heap(size_t *pn)
1870 +{
1871 +       static uintptr_t brk;
1872 +       static unsigned mmap_step;
1873 +       size_t n = *pn;
1874 +
1875 +       if (n > SIZE_MAX/2 - PAGE_SIZE) {
1876 +               errno = ENOMEM;
1877 +               return 0;
1878 +       }
1879 +       n += -n & PAGE_SIZE-1;
1880 +
1881 +       if (!brk) {
1882 +               brk = __syscall(SYS_brk, 0);
1883 +               brk += -brk & PAGE_SIZE-1;
1884 +       }
1885 +
1886 +       if (n < SIZE_MAX-brk && !traverses_stack_p(brk, brk+n)
1887 +           && __syscall(SYS_brk, brk+n)==brk+n) {
1888 +               *pn = n;
1889 +               brk += n;
1890 +               return (void *)(brk-n);
1891 +       }
1892 +
1893 +       size_t min = (size_t)PAGE_SIZE << mmap_step/2;
1894 +       if (n < min) n = min;
1895 +       void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
1896 +               MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
1897 +       if (area == MAP_FAILED) return 0;
1898 +       *pn = n;
1899 +       mmap_step++;
1900 +       return area;
1901 +}
1902 --- a/src/malloc/lite_malloc.c
1903 +++ b/src/malloc/lite_malloc.c
1904 @@ -4,43 +4,47 @@
1905  #include <errno.h>
1906  #include "libc.h"
1907  
1908 -uintptr_t __brk(uintptr_t);
1909 -
1910  #define ALIGN 16
1911  
1912 +void *__expand_heap(size_t *);
1913 +
1914  void *__simple_malloc(size_t n)
1915  {
1916 -       static uintptr_t cur, brk;
1917 -       uintptr_t base, new;
1918 +       static char *cur, *end;
1919         static volatile int lock[2];
1920 -       size_t align=1;
1921 +       size_t align=1, pad;
1922 +       void *p;
1923  
1924         if (!n) n++;
1925 -       if (n > SIZE_MAX/2) goto toobig;
1926 -
1927         while (align<n && align<ALIGN)
1928                 align += align;
1929 -       n = n + align - 1 & -align;
1930  
1931         LOCK(lock);
1932 -       if (!cur) cur = brk = __brk(0)+16;
1933 -       base = cur + align-1 & -align;
1934 -       if (n > SIZE_MAX - PAGE_SIZE - base) goto fail;
1935 -       if (base+n > brk) {
1936 -               new = base+n + PAGE_SIZE-1 & -PAGE_SIZE;
1937 -               if (__brk(new) != new) goto fail;
1938 -               brk = new;
1939 -       }
1940 -       cur = base+n;
1941 -       UNLOCK(lock);
1942  
1943 -       return (void *)base;
1944 +       pad = -(uintptr_t)cur & align-1;
1945 +
1946 +       if (n <= SIZE_MAX/2 + ALIGN) n += pad;
1947 +
1948 +       if (n > end-cur) {
1949 +               size_t m = n;
1950 +               char *new = __expand_heap(&m);
1951 +               if (!new) {
1952 +                       UNLOCK(lock);
1953 +                       return 0;
1954 +               }
1955 +               if (new != end) {
1956 +                       cur = new;
1957 +                       n -= pad;
1958 +                       pad = 0;
1959 +               }
1960 +               end = new + m;
1961 +       }
1962  
1963 -fail:
1964 +       p = cur + pad;
1965 +       cur += n;
1966         UNLOCK(lock);
1967 -toobig:
1968 -       errno = ENOMEM;
1969 -       return 0;
1970 +       return p;
1971  }
1972  
1973  weak_alias(__simple_malloc, malloc);
1974 +weak_alias(__simple_malloc, __malloc0);
1975 --- a/src/malloc/malloc.c
1976 +++ b/src/malloc/malloc.c
1977 @@ -13,7 +13,6 @@
1978  #define inline inline __attribute__((always_inline))
1979  #endif
1980  
1981 -uintptr_t __brk(uintptr_t);
1982  void *__mmap(void *, size_t, int, int, int, off_t);
1983  int __munmap(void *, size_t);
1984  void *__mremap(void *, size_t, size_t, int, ...);
1985 @@ -31,13 +30,9 @@ struct bin {
1986  };
1987  
1988  static struct {
1989 -       uintptr_t brk;
1990 -       size_t *heap;
1991         volatile uint64_t binmap;
1992         struct bin bins[64];
1993 -       volatile int brk_lock[2];
1994         volatile int free_lock[2];
1995 -       unsigned mmap_step;
1996  } mal;
1997  
1998  
1999 @@ -152,69 +147,52 @@ void __dump_heap(int x)
2000  }
2001  #endif
2002  
2003 +void *__expand_heap(size_t *);
2004 +
2005  static struct chunk *expand_heap(size_t n)
2006  {
2007 -       static int init;
2008 +       static int heap_lock[2];
2009 +       static void *end;
2010 +       void *p;
2011         struct chunk *w;
2012 -       uintptr_t new;
2013 -
2014 -       lock(mal.brk_lock);
2015 -
2016 -       if (!init) {
2017 -               mal.brk = __brk(0);
2018 -#ifdef SHARED
2019 -               mal.brk = mal.brk + PAGE_SIZE-1 & -PAGE_SIZE;
2020 -#endif
2021 -               mal.brk = mal.brk + 2*SIZE_ALIGN-1 & -SIZE_ALIGN;
2022 -               mal.heap = (void *)mal.brk;
2023 -               init = 1;
2024 -       }
2025 -
2026 -       if (n > SIZE_MAX - mal.brk - 2*PAGE_SIZE) goto fail;
2027 -       new = mal.brk + n + SIZE_ALIGN + PAGE_SIZE - 1 & -PAGE_SIZE;
2028 -       n = new - mal.brk;
2029 -
2030 -       if (__brk(new) != new) {
2031 -               size_t min = (size_t)PAGE_SIZE << mal.mmap_step/2;
2032 -               n += -n & PAGE_SIZE-1;
2033 -               if (n < min) n = min;
2034 -               void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
2035 -                       MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2036 -               if (area == MAP_FAILED) goto fail;
2037  
2038 -               mal.mmap_step++;
2039 -               area = (char *)area + SIZE_ALIGN - OVERHEAD;
2040 -               w = area;
2041 +       /* The argument n already accounts for the caller's chunk
2042 +        * overhead needs, but if the heap can't be extended in-place,
2043 +        * we need room for an extra zero-sized sentinel chunk. */
2044 +       n += SIZE_ALIGN;
2045 +
2046 +       lock(heap_lock);
2047 +
2048 +       p = __expand_heap(&n);
2049 +       if (!p) {
2050 +               unlock(heap_lock);
2051 +               return 0;
2052 +       }
2053 +
2054 +       /* If not just expanding existing space, we need to make a
2055 +        * new sentinel chunk below the allocated space. */
2056 +       if (p != end) {
2057 +               /* Valid/safe because of the prologue increment. */
2058                 n -= SIZE_ALIGN;
2059 +               p = (char *)p + SIZE_ALIGN;
2060 +               w = MEM_TO_CHUNK(p);
2061                 w->psize = 0 | C_INUSE;
2062 -               w->csize = n | C_INUSE;
2063 -               w = NEXT_CHUNK(w);
2064 -               w->psize = n | C_INUSE;
2065 -               w->csize = 0 | C_INUSE;
2066 -
2067 -               unlock(mal.brk_lock);
2068 -
2069 -               return area;
2070         }
2071  
2072 -       w = MEM_TO_CHUNK(mal.heap);
2073 -       w->psize = 0 | C_INUSE;
2074 -
2075 -       w = MEM_TO_CHUNK(new);
2076 +       /* Record new heap end and fill in footer. */
2077 +       end = (char *)p + n;
2078 +       w = MEM_TO_CHUNK(end);
2079         w->psize = n | C_INUSE;
2080         w->csize = 0 | C_INUSE;
2081  
2082 -       w = MEM_TO_CHUNK(mal.brk);
2083 +       /* Fill in header, which may be new or may be replacing a
2084 +        * zero-size sentinel header at the old end-of-heap. */
2085 +       w = MEM_TO_CHUNK(p);
2086         w->csize = n | C_INUSE;
2087 -       mal.brk = new;
2088 -       
2089 -       unlock(mal.brk_lock);
2090 +
2091 +       unlock(heap_lock);
2092  
2093         return w;
2094 -fail:
2095 -       unlock(mal.brk_lock);
2096 -       errno = ENOMEM;
2097 -       return 0;
2098  }
2099  
2100  static int adjust_size(size_t *n)
2101 @@ -378,6 +356,17 @@ void *malloc(size_t n)
2102         return CHUNK_TO_MEM(c);
2103  }
2104  
2105 +void *__malloc0(size_t n)
2106 +{
2107 +       void *p = malloc(n);
2108 +       if (p && !IS_MMAPPED(MEM_TO_CHUNK(p))) {
2109 +               size_t *z;
2110 +               n = (n + sizeof *z - 1)/sizeof *z;
2111 +               for (z=p; n; n--, z++) if (*z) *z=0;
2112 +       }
2113 +       return p;
2114 +}
2115 +
2116  void *realloc(void *p, size_t n)
2117  {
2118         struct chunk *self, *next;
2119 --- a/src/misc/syslog.c
2120 +++ b/src/misc/syslog.c
2121 @@ -48,12 +48,8 @@ void closelog(void)
2122  
2123  static void __openlog()
2124  {
2125 -       int fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
2126 -       if (fd < 0) return;
2127 -       if (connect(fd, (void *)&log_addr, sizeof log_addr) < 0)
2128 -               close(fd);
2129 -       else
2130 -               log_fd = fd;
2131 +       log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
2132 +       if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr);
2133  }
2134  
2135  void openlog(const char *ident, int opt, int facility)
2136 @@ -78,6 +74,11 @@ void openlog(const char *ident, int opt,
2137         pthread_setcancelstate(cs, 0);
2138  }
2139  
2140 +static int is_lost_conn(int e)
2141 +{
2142 +       return e==ECONNREFUSED || e==ECONNRESET || e==ENOTCONN || e==EPIPE;
2143 +}
2144 +
2145  static void _vsyslog(int priority, const char *message, va_list ap)
2146  {
2147         char timebuf[16];
2148 @@ -107,7 +108,10 @@ static void _vsyslog(int priority, const
2149                 if (l2 >= sizeof buf - l) l = sizeof buf - 1;
2150                 else l += l2;
2151                 if (buf[l-1] != '\n') buf[l++] = '\n';
2152 -               if (send(log_fd, buf, l, 0) < 0 && (log_opt & LOG_CONS)) {
2153 +               if (send(log_fd, buf, l, 0) < 0 && (!is_lost_conn(errno)
2154 +                   || connect(log_fd, (void *)&log_addr, sizeof log_addr) < 0
2155 +                   || send(log_fd, buf, l, 0) < 0)
2156 +                   && (log_opt & LOG_CONS)) {
2157                         fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
2158                         if (fd >= 0) {
2159                                 dprintf(fd, "%.*s", l-hlen, buf+hlen);
2160 --- a/src/multibyte/btowc.c
2161 +++ b/src/multibyte/btowc.c
2162 @@ -1,7 +1,10 @@
2163  #include <stdio.h>
2164  #include <wchar.h>
2165 +#include <stdlib.h>
2166 +#include "internal.h"
2167  
2168  wint_t btowc(int c)
2169  {
2170 -       return c<128U ? c : EOF;
2171 +       int b = (unsigned char)c;
2172 +       return b<128U ? b : (MB_CUR_MAX==1 && c!=EOF) ? CODEUNIT(c) : WEOF;
2173  }
2174 --- a/src/multibyte/internal.h
2175 +++ b/src/multibyte/internal.h
2176 @@ -23,3 +23,10 @@ extern const uint32_t bittab[];
2177  
2178  #define SA 0xc2u
2179  #define SB 0xf4u
2180 +
2181 +/* Arbitrary encoding for representing code units instead of characters. */
2182 +#define CODEUNIT(c) (0xdfff & (signed char)(c))
2183 +#define IS_CODEUNIT(c) ((unsigned)(c)-0xdf80 < 0x80)
2184 +
2185 +/* Get inline definition of MB_CUR_MAX. */
2186 +#include "locale_impl.h"
2187 --- a/src/multibyte/mbrtowc.c
2188 +++ b/src/multibyte/mbrtowc.c
2189 @@ -4,6 +4,7 @@
2190   * unnecessary.
2191   */
2192  
2193 +#include <stdlib.h>
2194  #include <wchar.h>
2195  #include <errno.h>
2196  #include "internal.h"
2197 @@ -27,6 +28,7 @@ size_t mbrtowc(wchar_t *restrict wc, con
2198         if (!n) return -2;
2199         if (!c) {
2200                 if (*s < 0x80) return !!(*wc = *s);
2201 +               if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
2202                 if (*s-SA > SB-SA) goto ilseq;
2203                 c = bittab[*s++-SA]; n--;
2204         }
2205 --- a/src/multibyte/mbsrtowcs.c
2206 +++ b/src/multibyte/mbsrtowcs.c
2207 @@ -7,6 +7,8 @@
2208  #include <stdint.h>
2209  #include <wchar.h>
2210  #include <errno.h>
2211 +#include <string.h>
2212 +#include <stdlib.h>
2213  #include "internal.h"
2214  
2215  size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st)
2216 @@ -24,6 +26,23 @@ size_t mbsrtowcs(wchar_t *restrict ws, c
2217                 }
2218         }
2219  
2220 +       if (MB_CUR_MAX==1) {
2221 +               if (!ws) return strlen((const char *)s);
2222 +               for (;;) {
2223 +                       if (!wn) {
2224 +                               *src = (const void *)s;
2225 +                               return wn0;
2226 +                       }
2227 +                       if (!*s) break;
2228 +                       c = *s++;
2229 +                       *ws++ = CODEUNIT(c);
2230 +                       wn--;
2231 +               }
2232 +               *ws = 0;
2233 +               *src = 0;
2234 +               return wn0-wn;
2235 +       }
2236 +
2237         if (!ws) for (;;) {
2238                 if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
2239                         while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
2240 --- a/src/multibyte/mbtowc.c
2241 +++ b/src/multibyte/mbtowc.c
2242 @@ -4,6 +4,7 @@
2243   * unnecessary.
2244   */
2245  
2246 +#include <stdlib.h>
2247  #include <wchar.h>
2248  #include <errno.h>
2249  #include "internal.h"
2250 @@ -19,6 +20,7 @@ int mbtowc(wchar_t *restrict wc, const c
2251         if (!wc) wc = &dummy;
2252  
2253         if (*s < 0x80) return !!(*wc = *s);
2254 +       if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
2255         if (*s-SA > SB-SA) goto ilseq;
2256         c = bittab[*s++-SA];
2257  
2258 --- a/src/multibyte/wcrtomb.c
2259 +++ b/src/multibyte/wcrtomb.c
2260 @@ -4,8 +4,10 @@
2261   * unnecessary.
2262   */
2263  
2264 +#include <stdlib.h>
2265  #include <wchar.h>
2266  #include <errno.h>
2267 +#include "internal.h"
2268  
2269  size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st)
2270  {
2271 @@ -13,6 +15,13 @@ size_t wcrtomb(char *restrict s, wchar_t
2272         if ((unsigned)wc < 0x80) {
2273                 *s = wc;
2274                 return 1;
2275 +       } else if (MB_CUR_MAX == 1) {
2276 +               if (!IS_CODEUNIT(wc)) {
2277 +                       errno = EILSEQ;
2278 +                       return -1;
2279 +               }
2280 +               *s = wc;
2281 +               return 1;
2282         } else if ((unsigned)wc < 0x800) {
2283                 *s++ = 0xc0 | (wc>>6);
2284                 *s = 0x80 | (wc&0x3f);
2285 --- a/src/multibyte/wctob.c
2286 +++ b/src/multibyte/wctob.c
2287 @@ -1,8 +1,10 @@
2288 -#include <stdio.h>
2289  #include <wchar.h>
2290 +#include <stdlib.h>
2291 +#include "internal.h"
2292  
2293  int wctob(wint_t c)
2294  {
2295         if (c < 128U) return c;
2296 +       if (MB_CUR_MAX==1 && IS_CODEUNIT(c)) return (unsigned char)c;
2297         return EOF;
2298  }
2299 --- a/src/network/ns_parse.c
2300 +++ b/src/network/ns_parse.c
2301 @@ -95,7 +95,7 @@ int ns_skiprr(const unsigned char *ptr,
2302                         p += r;
2303                 }
2304         }
2305 -       return ptr - p;
2306 +       return p - ptr;
2307  bad:
2308         errno = EMSGSIZE;
2309         return -1;
2310 --- a/src/passwd/nscd_query.c
2311 +++ b/src/passwd/nscd_query.c
2312 @@ -32,6 +32,7 @@ FILE *__nscd_query(int32_t req, const ch
2313                 },
2314                 .msg_iovlen = 2
2315         };
2316 +       int errno_save = errno;
2317  
2318         *swap = 0;
2319  retry:
2320 @@ -50,11 +51,14 @@ retry:
2321                 return f;
2322  
2323         if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
2324 -               /* If there isn't a running nscd we return -1 to indicate that
2325 -                * that is precisely what happened
2326 -                */
2327 -               if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT)
2328 +               /* If there isn't a running nscd we simulate a "not found"
2329 +                * result and the caller is responsible for calling
2330 +                * fclose on the (unconnected) socket. The value of
2331 +                * errno must be left unchanged in this case.  */
2332 +               if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT) {
2333 +                       errno = errno_save;
2334                         return f;
2335 +               }
2336                 goto error;
2337         }
2338  
2339 --- /dev/null
2340 +++ b/src/process/sh/vfork.s
2341 @@ -0,0 +1,23 @@
2342 +.global __vfork
2343 +.weak vfork
2344 +.type __vfork,@function
2345 +.type vfork,@function
2346 +__vfork:
2347 +vfork:
2348 +       mov #95, r3
2349 +       add r3, r3
2350 +
2351 +       trapa #31
2352 +       or    r0, r0
2353 +       or    r0, r0
2354 +       or    r0, r0
2355 +       or    r0, r0
2356 +       or    r0, r0
2357 +
2358 +       mov r0, r4
2359 +       mov.l 1f, r0
2360 +2:     braf r0
2361 +        nop
2362 +       .align 2
2363 +       .hidden __syscall_ret
2364 +1:     .long __syscall_ret@PLT-(2b+4-.)
2365 --- a/src/regex/fnmatch.c
2366 +++ b/src/regex/fnmatch.c
2367 @@ -18,6 +18,7 @@
2368  #include <stdlib.h>
2369  #include <wchar.h>
2370  #include <wctype.h>
2371 +#include "locale_impl.h"
2372  
2373  #define END 0
2374  #define UNMATCHABLE -2
2375 @@ -229,7 +230,7 @@ static int fnmatch_internal(const char *
2376          * On illegal sequences we may get it wrong, but in that case
2377          * we necessarily have a matching failure anyway. */
2378         for (s=endstr; s>str && tailcnt; tailcnt--) {
2379 -               if (s[-1] < 128U) s--;
2380 +               if (s[-1] < 128U || MB_CUR_MAX==1) s--;
2381                 else while ((unsigned char)*--s-0x80U<0x40 && s>str);
2382         }
2383         if (tailcnt) return FNM_NOMATCH;
2384 --- a/src/signal/sh/restore.s
2385 +++ b/src/signal/sh/restore.s
2386 @@ -2,7 +2,7 @@
2387  .type   __restore, @function
2388  __restore:
2389         mov   #119, r3  !__NR_sigreturn
2390 -       trapa #16
2391 +       trapa #31
2392  
2393         or    r0, r0
2394         or    r0, r0
2395 @@ -15,7 +15,7 @@ __restore:
2396  __restore_rt:
2397         mov   #100, r3  !__NR_rt_sigreturn
2398         add   #73, r3
2399 -       trapa #16
2400 +       trapa #31
2401  
2402         or    r0, r0
2403         or    r0, r0
2404 --- a/src/stdio/__fdopen.c
2405 +++ b/src/stdio/__fdopen.c
2406 @@ -54,13 +54,7 @@ FILE *__fdopen(int fd, const char *mode)
2407         if (!libc.threaded) f->lock = -1;
2408  
2409         /* Add new FILE to open file list */
2410 -       OFLLOCK();
2411 -       f->next = libc.ofl_head;
2412 -       if (libc.ofl_head) libc.ofl_head->prev = f;
2413 -       libc.ofl_head = f;
2414 -       OFLUNLOCK();
2415 -
2416 -       return f;
2417 +       return __ofl_add(f);
2418  }
2419  
2420  weak_alias(__fdopen, fdopen);
2421 --- a/src/stdio/__stdio_exit.c
2422 +++ b/src/stdio/__stdio_exit.c
2423 @@ -16,8 +16,7 @@ static void close_file(FILE *f)
2424  void __stdio_exit(void)
2425  {
2426         FILE *f;
2427 -       OFLLOCK();
2428 -       for (f=libc.ofl_head; f; f=f->next) close_file(f);
2429 +       for (f=*__ofl_lock(); f; f=f->next) close_file(f);
2430         close_file(__stdin_used);
2431         close_file(__stdout_used);
2432  }
2433 --- a/src/stdio/__stdio_read.c
2434 +++ b/src/stdio/__stdio_read.c
2435 @@ -1,12 +1,5 @@
2436  #include "stdio_impl.h"
2437  #include <sys/uio.h>
2438 -#include <pthread.h>
2439 -
2440 -static void cleanup(void *p)
2441 -{
2442 -       FILE *f = p;
2443 -       if (!f->lockcount) __unlockfile(f);
2444 -}
2445  
2446  size_t __stdio_read(FILE *f, unsigned char *buf, size_t len)
2447  {
2448 @@ -16,9 +9,7 @@ size_t __stdio_read(FILE *f, unsigned ch
2449         };
2450         ssize_t cnt;
2451  
2452 -       pthread_cleanup_push(cleanup, f);
2453 -       cnt = syscall_cp(SYS_readv, f->fd, iov, 2);
2454 -       pthread_cleanup_pop(0);
2455 +       cnt = syscall(SYS_readv, f->fd, iov, 2);
2456         if (cnt <= 0) {
2457                 f->flags |= F_EOF ^ ((F_ERR^F_EOF) & cnt);
2458                 return cnt;
2459 --- a/src/stdio/__stdio_write.c
2460 +++ b/src/stdio/__stdio_write.c
2461 @@ -1,12 +1,5 @@
2462  #include "stdio_impl.h"
2463  #include <sys/uio.h>
2464 -#include <pthread.h>
2465 -
2466 -static void cleanup(void *p)
2467 -{
2468 -       FILE *f = p;
2469 -       if (!f->lockcount) __unlockfile(f);
2470 -}
2471  
2472  size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
2473  {
2474 @@ -19,9 +12,7 @@ size_t __stdio_write(FILE *f, const unsi
2475         int iovcnt = 2;
2476         ssize_t cnt;
2477         for (;;) {
2478 -               pthread_cleanup_push(cleanup, f);
2479 -               cnt = syscall_cp(SYS_writev, f->fd, iov, iovcnt);
2480 -               pthread_cleanup_pop(0);
2481 +               cnt = syscall(SYS_writev, f->fd, iov, iovcnt);
2482                 if (cnt == rem) {
2483                         f->wend = f->buf + f->buf_size;
2484                         f->wpos = f->wbase = f->buf;
2485 @@ -34,11 +25,8 @@ size_t __stdio_write(FILE *f, const unsi
2486                 }
2487                 rem -= cnt;
2488                 if (cnt > iov[0].iov_len) {
2489 -                       f->wpos = f->wbase = f->buf;
2490                         cnt -= iov[0].iov_len;
2491                         iov++; iovcnt--;
2492 -               } else if (iovcnt == 2) {
2493 -                       f->wbase += cnt;
2494                 }
2495                 iov[0].iov_base = (char *)iov[0].iov_base + cnt;
2496                 iov[0].iov_len -= cnt;
2497 --- a/src/stdio/fclose.c
2498 +++ b/src/stdio/fclose.c
2499 @@ -14,11 +14,11 @@ int fclose(FILE *f)
2500         __unlist_locked_file(f);
2501  
2502         if (!(perm = f->flags & F_PERM)) {
2503 -               OFLLOCK();
2504 +               FILE **head = __ofl_lock();
2505                 if (f->prev) f->prev->next = f->next;
2506                 if (f->next) f->next->prev = f->prev;
2507 -               if (libc.ofl_head == f) libc.ofl_head = f->next;
2508 -               OFLUNLOCK();
2509 +               if (*head == f) *head = f->next;
2510 +               __ofl_unlock();
2511         }
2512  
2513         r = fflush(f);
2514 --- a/src/stdio/fflush.c
2515 +++ b/src/stdio/fflush.c
2516 @@ -35,13 +35,12 @@ int fflush(FILE *f)
2517  
2518         r = __stdout_used ? fflush(__stdout_used) : 0;
2519  
2520 -       OFLLOCK();
2521 -       for (f=libc.ofl_head; f; f=f->next) {
2522 +       for (f=*__ofl_lock(); f; f=f->next) {
2523                 FLOCK(f);
2524                 if (f->wpos > f->wbase) r |= __fflush_unlocked(f);
2525                 FUNLOCK(f);
2526         }
2527 -       OFLUNLOCK();
2528 +       __ofl_unlock();
2529         
2530         return r;
2531  }
2532 --- a/src/stdio/fgetwc.c
2533 +++ b/src/stdio/fgetwc.c
2534 @@ -1,8 +1,9 @@
2535  #include "stdio_impl.h"
2536 +#include "locale_impl.h"
2537  #include <wchar.h>
2538  #include <errno.h>
2539  
2540 -wint_t __fgetwc_unlocked(FILE *f)
2541 +static wint_t __fgetwc_unlocked_internal(FILE *f)
2542  {
2543         mbstate_t st = { 0 };
2544         wchar_t wc;
2545 @@ -10,8 +11,6 @@ wint_t __fgetwc_unlocked(FILE *f)
2546         unsigned char b;
2547         size_t l;
2548  
2549 -       f->mode |= f->mode+1;
2550 -
2551         /* Convert character from buffer if possible */
2552         if (f->rpos < f->rend) {
2553                 l = mbrtowc(&wc, (void *)f->rpos, f->rend - f->rpos, &st);
2554 @@ -39,6 +38,16 @@ wint_t __fgetwc_unlocked(FILE *f)
2555         return wc;
2556  }
2557  
2558 +wint_t __fgetwc_unlocked(FILE *f)
2559 +{
2560 +       locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
2561 +       if (f->mode <= 0) fwide(f, 1);
2562 +       *ploc = f->locale;
2563 +       wchar_t wc = __fgetwc_unlocked_internal(f);
2564 +       *ploc = loc;
2565 +       return wc;
2566 +}
2567 +
2568  wint_t fgetwc(FILE *f)
2569  {
2570         wint_t c;
2571 --- a/src/stdio/fmemopen.c
2572 +++ b/src/stdio/fmemopen.c
2573 @@ -110,11 +110,5 @@ FILE *fmemopen(void *restrict buf, size_
2574  
2575         if (!libc.threaded) f->lock = -1;
2576  
2577 -       OFLLOCK();
2578 -       f->next = libc.ofl_head;
2579 -       if (libc.ofl_head) libc.ofl_head->prev = f;
2580 -       libc.ofl_head = f;
2581 -       OFLUNLOCK();
2582 -
2583 -       return f;
2584 +       return __ofl_add(f);
2585  }
2586 --- a/src/stdio/fopen.c
2587 +++ b/src/stdio/fopen.c
2588 @@ -18,7 +18,7 @@ FILE *fopen(const char *restrict filenam
2589         /* Compute the flags to pass to open() */
2590         flags = __fmodeflags(mode);
2591  
2592 -       fd = sys_open_cp(filename, flags, 0666);
2593 +       fd = sys_open(filename, flags, 0666);
2594         if (fd < 0) return 0;
2595         if (flags & O_CLOEXEC)
2596                 __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
2597 --- a/src/stdio/fputwc.c
2598 +++ b/src/stdio/fputwc.c
2599 @@ -1,4 +1,5 @@
2600  #include "stdio_impl.h"
2601 +#include "locale_impl.h"
2602  #include <wchar.h>
2603  #include <limits.h>
2604  #include <ctype.h>
2605 @@ -7,8 +8,10 @@ wint_t __fputwc_unlocked(wchar_t c, FILE
2606  {
2607         char mbc[MB_LEN_MAX];
2608         int l;
2609 +       locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
2610  
2611 -       f->mode |= f->mode+1;
2612 +       if (f->mode <= 0) fwide(f, 1);
2613 +       *ploc = f->locale;
2614  
2615         if (isascii(c)) {
2616                 c = putc_unlocked(c, f);
2617 @@ -20,6 +23,8 @@ wint_t __fputwc_unlocked(wchar_t c, FILE
2618                 l = wctomb(mbc, c);
2619                 if (l < 0 || __fwritex((void *)mbc, l, f) < l) c = WEOF;
2620         }
2621 +       if (c==WEOF) f->flags |= F_ERR;
2622 +       *ploc = loc;
2623         return c;
2624  }
2625  
2626 --- a/src/stdio/fputws.c
2627 +++ b/src/stdio/fputws.c
2628 @@ -1,23 +1,28 @@
2629  #include "stdio_impl.h"
2630 +#include "locale_impl.h"
2631  #include <wchar.h>
2632  
2633  int fputws(const wchar_t *restrict ws, FILE *restrict f)
2634  {
2635         unsigned char buf[BUFSIZ];
2636         size_t l=0;
2637 +       locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
2638  
2639         FLOCK(f);
2640  
2641 -       f->mode |= f->mode+1;
2642 +       fwide(f, 1);
2643 +       *ploc = f->locale;
2644  
2645         while (ws && (l = wcsrtombs((void *)buf, (void*)&ws, sizeof buf, 0))+1 > 1)
2646                 if (__fwritex(buf, l, f) < l) {
2647                         FUNLOCK(f);
2648 +                       *ploc = loc;
2649                         return -1;
2650                 }
2651  
2652         FUNLOCK(f);
2653  
2654 +       *ploc = loc;
2655         return l; /* 0 or -1 */
2656  }
2657  
2658 --- a/src/stdio/fwide.c
2659 +++ b/src/stdio/fwide.c
2660 @@ -1,13 +1,14 @@
2661 -#include <wchar.h>
2662  #include "stdio_impl.h"
2663 -
2664 -#define SH (8*sizeof(int)-1)
2665 -#define NORMALIZE(x) ((x)>>SH | -((-(x))>>SH))
2666 +#include "locale_impl.h"
2667  
2668  int fwide(FILE *f, int mode)
2669  {
2670         FLOCK(f);
2671 -       if (!f->mode) f->mode = NORMALIZE(mode);
2672 +       if (mode) {
2673 +               if (!f->locale) f->locale = MB_CUR_MAX==1
2674 +                       ? C_LOCALE : UTF8_LOCALE;
2675 +               if (!f->mode) f->mode = mode>0 ? 1 : -1;
2676 +       }
2677         mode = f->mode;
2678         FUNLOCK(f);
2679         return mode;
2680 --- /dev/null
2681 +++ b/src/stdio/ofl.c
2682 @@ -0,0 +1,16 @@
2683 +#include "stdio_impl.h"
2684 +#include "libc.h"
2685 +
2686 +static FILE *ofl_head;
2687 +static volatile int ofl_lock[2];
2688 +
2689 +FILE **__ofl_lock()
2690 +{
2691 +       LOCK(ofl_lock);
2692 +       return &ofl_head;
2693 +}
2694 +
2695 +void __ofl_unlock()
2696 +{
2697 +       UNLOCK(ofl_lock);
2698 +}
2699 --- /dev/null
2700 +++ b/src/stdio/ofl_add.c
2701 @@ -0,0 +1,11 @@
2702 +#include "stdio_impl.h"
2703 +
2704 +FILE *__ofl_add(FILE *f)
2705 +{
2706 +       FILE **head = __ofl_lock();
2707 +       f->next = *head;
2708 +       if (*head) (*head)->prev = f;
2709 +       *head = f;
2710 +       __ofl_unlock();
2711 +       return f;
2712 +}
2713 --- a/src/stdio/open_memstream.c
2714 +++ b/src/stdio/open_memstream.c
2715 @@ -79,11 +79,5 @@ FILE *open_memstream(char **bufp, size_t
2716  
2717         if (!libc.threaded) f->lock = -1;
2718  
2719 -       OFLLOCK();
2720 -       f->next = libc.ofl_head;
2721 -       if (libc.ofl_head) libc.ofl_head->prev = f;
2722 -       libc.ofl_head = f;
2723 -       OFLUNLOCK();
2724 -
2725 -       return f;
2726 +       return __ofl_add(f);
2727  }
2728 --- a/src/stdio/open_wmemstream.c
2729 +++ b/src/stdio/open_wmemstream.c
2730 @@ -81,11 +81,5 @@ FILE *open_wmemstream(wchar_t **bufp, si
2731  
2732         if (!libc.threaded) f->lock = -1;
2733  
2734 -       OFLLOCK();
2735 -       f->next = libc.ofl_head;
2736 -       if (libc.ofl_head) libc.ofl_head->prev = f;
2737 -       libc.ofl_head = f;
2738 -       OFLUNLOCK();
2739 -
2740 -       return f;
2741 +       return __ofl_add(f);
2742  }
2743 --- a/src/stdio/ungetwc.c
2744 +++ b/src/stdio/ungetwc.c
2745 @@ -1,4 +1,5 @@
2746  #include "stdio_impl.h"
2747 +#include "locale_impl.h"
2748  #include <wchar.h>
2749  #include <limits.h>
2750  #include <ctype.h>
2751 @@ -8,21 +9,19 @@ wint_t ungetwc(wint_t c, FILE *f)
2752  {
2753         unsigned char mbc[MB_LEN_MAX];
2754         int l=1;
2755 -
2756 -       if (c == WEOF) return c;
2757 -
2758 -       /* Try conversion early so we can fail without locking if invalid */
2759 -       if (!isascii(c) && (l = wctomb((void *)mbc, c)) < 0)
2760 -               return WEOF;
2761 +       locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
2762  
2763         FLOCK(f);
2764  
2765 -       f->mode |= f->mode+1;
2766 +       if (f->mode <= 0) fwide(f, 1);
2767 +       *ploc = f->locale;
2768  
2769         if (!f->rpos) __toread(f);
2770 -       if (!f->rpos || f->rpos < f->buf - UNGET + l) {
2771 +       if (!f->rpos || f->rpos < f->buf - UNGET + l || c == WEOF ||
2772 +           (!isascii(c) && (l = wctomb((void *)mbc, c)) < 0)) {
2773                 FUNLOCK(f);
2774 -               return EOF;
2775 +               *ploc = loc;
2776 +               return WEOF;
2777         }
2778  
2779         if (isascii(c)) *--f->rpos = c;
2780 @@ -31,5 +30,6 @@ wint_t ungetwc(wint_t c, FILE *f)
2781         f->flags &= ~F_EOF;
2782  
2783         FUNLOCK(f);
2784 +       *ploc = loc;
2785         return c;
2786  }
2787 --- a/src/stdio/vfwprintf.c
2788 +++ b/src/stdio/vfwprintf.c
2789 @@ -293,7 +293,10 @@ static int wprintf_core(FILE *f, const w
2790                         if ((fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
2791                         l=w;
2792                         continue;
2793 +               case 'm':
2794 +                       arg.p = strerror(errno);
2795                 case 's':
2796 +                       if (!arg.p) arg.p = "(null)";
2797                         bs = arg.p;
2798                         if (p<0) p = INT_MAX;
2799                         for (i=l=0; l<p && (i=mbtowc(&wc, bs, MB_LEN_MAX))>0; bs+=i, l++);
2800 @@ -356,7 +359,7 @@ int vfwprintf(FILE *restrict f, const wc
2801         }
2802  
2803         FLOCK(f);
2804 -       f->mode |= f->mode+1;
2805 +       fwide(f, 1);
2806         olderr = f->flags & F_ERR;
2807         f->flags &= ~F_ERR;
2808         ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
2809 --- a/src/stdio/vfwscanf.c
2810 +++ b/src/stdio/vfwscanf.c
2811 @@ -104,7 +104,7 @@ int vfwscanf(FILE *restrict f, const wch
2812  
2813         FLOCK(f);
2814  
2815 -       f->mode |= f->mode+1;
2816 +       fwide(f, 1);
2817  
2818         for (p=fmt; *p; p++) {
2819  
2820 --- a/src/string/strverscmp.c
2821 +++ b/src/string/strverscmp.c
2822 @@ -2,40 +2,33 @@
2823  #include <ctype.h>
2824  #include <string.h>
2825  
2826 -int strverscmp(const char *l, const char *r)
2827 +int strverscmp(const char *l0, const char *r0)
2828  {
2829 -       int haszero=1;
2830 -       while (*l==*r) {
2831 -               if (!*l) return 0;
2832 +       const unsigned char *l = (const void *)l0;
2833 +       const unsigned char *r = (const void *)r0;
2834 +       size_t i, dp, j;
2835 +       int z = 1;
2836  
2837 -               if (*l=='0') {
2838 -                       if (haszero==1) {
2839 -                               haszero=0;
2840 -                       }
2841 -               } else if (isdigit(*l)) {
2842 -                       if (haszero==1) {
2843 -                               haszero=2;
2844 -                       }
2845 -               } else {
2846 -                       haszero=1;
2847 -               }
2848 -               l++; r++;
2849 +       /* Find maximal matching prefix and track its maximal digit
2850 +        * suffix and whether those digits are all zeros. */
2851 +       for (dp=i=0; l[i]==r[i]; i++) {
2852 +               int c = l[i];
2853 +               if (!c) return 0;
2854 +               if (!isdigit(c)) dp=i+1, z=1;
2855 +               else if (c!='0') z=0;
2856         }
2857 -       if (haszero==1 && (*l=='0' || *r=='0')) {
2858 -               haszero=0;
2859 -       }
2860 -       if ((isdigit(*l) && isdigit(*r) ) && haszero) {
2861 -               size_t lenl=0, lenr=0;
2862 -               while (isdigit(l[lenl]) ) lenl++;
2863 -               while (isdigit(r[lenr]) ) lenr++;
2864 -               if (lenl==lenr) {
2865 -                       return (*l -  *r);
2866 -               } else if (lenl>lenr) {
2867 -                       return 1;
2868 -               } else {
2869 -                       return -1;
2870 -               }
2871 -       } else {
2872 -               return (*l -  *r);
2873 +
2874 +       if (l[dp]!='0' && r[dp]!='0') {
2875 +               /* If we're not looking at a digit sequence that began
2876 +                * with a zero, longest digit string is greater. */
2877 +               for (j=i; isdigit(l[j]); j++)
2878 +                       if (!isdigit(r[j])) return 1;
2879 +               if (isdigit(r[j])) return -1;
2880 +       } else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) {
2881 +               /* Otherwise, if common prefix of digit sequence is
2882 +                * all zeros, digits order less than non-digits. */
2883 +               return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0');
2884         }
2885 +
2886 +       return l[i] - r[i];
2887  }
2888 --- a/src/thread/__tls_get_addr.c
2889 +++ b/src/thread/__tls_get_addr.c
2890 @@ -8,9 +8,9 @@ void *__tls_get_addr(size_t *v)
2891         __attribute__((__visibility__("hidden")))
2892         void *__tls_get_new(size_t *);
2893         if (v[0]<=(size_t)self->dtv[0])
2894 -               return (char *)self->dtv[v[0]]+v[1];
2895 +               return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
2896         return __tls_get_new(v);
2897  #else
2898 -       return (char *)self->dtv[1]+v[1];
2899 +       return (char *)self->dtv[1]+v[1]+DTP_OFFSET;
2900  #endif
2901  }
2902 --- /dev/null
2903 +++ b/src/thread/__unmapself.c
2904 @@ -0,0 +1,29 @@
2905 +#include "pthread_impl.h"
2906 +#include "atomic.h"
2907 +#include "syscall.h"
2908 +/* cheat and reuse CRTJMP macro from dynlink code */
2909 +#include "dynlink.h"
2910 +
2911 +static volatile int lock;
2912 +static void *unmap_base;
2913 +static size_t unmap_size;
2914 +static char shared_stack[256];
2915 +
2916 +static void do_unmap()
2917 +{
2918 +       __syscall(SYS_munmap, unmap_base, unmap_size);
2919 +       __syscall(SYS_exit);
2920 +}
2921 +
2922 +void __unmapself(void *base, size_t size)
2923 +{
2924 +       int tid=__pthread_self()->tid;
2925 +       char *stack = shared_stack + sizeof shared_stack;
2926 +       stack -= (uintptr_t)stack % 16;
2927 +       while (lock || a_cas(&lock, 0, tid))
2928 +               a_spin();
2929 +       __syscall(SYS_set_tid_address, &lock);
2930 +       unmap_base = base;
2931 +       unmap_size = size;
2932 +       CRTJMP(do_unmap, stack);
2933 +}
2934 --- a/src/thread/mips/__unmapself.s
2935 +++ b/src/thread/mips/__unmapself.s
2936 @@ -2,6 +2,7 @@
2937  .global __unmapself
2938  .type   __unmapself,@function
2939  __unmapself:
2940 +       move $sp, $25
2941         li $2, 4091
2942         syscall
2943         li $4, 0
2944 --- a/src/thread/pthread_create.c
2945 +++ b/src/thread/pthread_create.c
2946 @@ -191,8 +191,9 @@ int __pthread_create(pthread_t *restrict
2947         if (!libc.can_do_threads) return ENOSYS;
2948         self = __pthread_self();
2949         if (!libc.threaded) {
2950 -               for (FILE *f=libc.ofl_head; f; f=f->next)
2951 +               for (FILE *f=*__ofl_lock(); f; f=f->next)
2952                         init_file_lock(f);
2953 +               __ofl_unlock();
2954                 init_file_lock(__stdin_used);
2955                 init_file_lock(__stdout_used);
2956                 init_file_lock(__stderr_used);
2957 @@ -231,7 +232,8 @@ int __pthread_create(pthread_t *restrict
2958                 if (guard) {
2959                         map = __mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0);
2960                         if (map == MAP_FAILED) goto fail;
2961 -                       if (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE)) {
2962 +                       if (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE)
2963 +                           && errno != ENOSYS) {
2964                                 __munmap(map, size);
2965                                 goto fail;
2966                         }
2967 --- a/src/thread/sh/__set_thread_area.s
2968 +++ b/src/thread/sh/__set_thread_area.s
2969 @@ -1,6 +0,0 @@
2970 -.global __set_thread_area
2971 -.type   __set_thread_area, @function
2972 -__set_thread_area:
2973 -       ldc r4, gbr
2974 -       rts
2975 -        mov #0, r0
2976 --- a/src/thread/sh/__unmapself.s
2977 +++ b/src/thread/sh/__unmapself.s
2978 @@ -1,9 +1,9 @@
2979  .text
2980 -.global __unmapself
2981 -.type   __unmapself, @function
2982 -__unmapself:
2983 +.global __unmapself_sh_mmu
2984 +.type   __unmapself_sh_mmu, @function
2985 +__unmapself_sh_mmu:
2986         mov   #91, r3  ! SYS_munmap
2987 -       trapa #18
2988 +       trapa #31
2989  
2990         or    r0, r0
2991         or    r0, r0
2992 @@ -13,7 +13,7 @@ __unmapself:
2993  
2994         mov   #1, r3   ! SYS_exit
2995         mov   #0, r4
2996 -       trapa #17
2997 +       trapa #31
2998  
2999         or    r0, r0
3000         or    r0, r0
3001 --- a/src/thread/sh/clone.s
3002 +++ b/src/thread/sh/clone.s
3003 @@ -17,7 +17,7 @@ __clone:
3004         mov.l @r15,     r6   ! r6 = ptid
3005         mov.l @(8,r15), r7   ! r7 = ctid
3006         mov.l @(4,r15), r0   ! r0 = tls
3007 -       trapa #21
3008 +       trapa #31
3009  
3010         or r0, r0
3011         or r0, r0
3012 @@ -38,7 +38,7 @@ __clone:
3013  
3014         mov   #1, r3   ! __NR_exit
3015         mov   r0, r4
3016 -       trapa #17
3017 +       trapa #31
3018  
3019         or   r0, r0
3020         or   r0, r0
3021 --- a/src/thread/sh/syscall_cp.s
3022 +++ b/src/thread/sh/syscall_cp.s
3023 @@ -31,7 +31,7 @@ L1:   .long __cancel@PLT-(1b-.)
3024         mov.l @(4,r15), r7
3025         mov.l @(8,r15), r0
3026         mov.l @(12,r15), r1
3027 -       trapa #22
3028 +       trapa #31
3029  
3030  __cp_end:
3031         ! work around hardware bug
3032 --- a/src/time/__tz.c
3033 +++ b/src/time/__tz.c
3034 @@ -125,7 +125,8 @@ static void do_tzset()
3035                 "/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
3036  
3037         s = getenv("TZ");
3038 -       if (!s || !*s) s = "/etc/localtime";
3039 +       if (!s) s = "/etc/localtime";
3040 +       if (!*s) s = __gmt;
3041  
3042         if (old_tz && !strcmp(s, old_tz)) return;
3043  
3044 --- a/src/unistd/sh/pipe.s
3045 +++ b/src/unistd/sh/pipe.s
3046 @@ -2,7 +2,7 @@
3047  .type   pipe, @function
3048  pipe:
3049         mov    #42, r3
3050 -       trapa  #17
3051 +       trapa  #31
3052  
3053         ! work around hardware bug
3054         or     r0, r0
3055 --- /dev/null
3056 +++ b/tools/ld.musl-clang.in
3057 @@ -0,0 +1,51 @@
3058 +#!/bin/sh
3059 +cc="@CC@"
3060 +libc_lib="@LIBDIR@"
3061 +ldso="@LDSO@"
3062 +cleared=
3063 +shared=
3064 +userlinkdir=
3065 +userlink=
3066 +
3067 +for x ; do
3068 +    test "$cleared" || set -- ; cleared=1
3069 +
3070 +    case "$x" in
3071 +        -L-user-start)
3072 +            userlinkdir=1
3073 +            ;;
3074 +        -L-user-end)
3075 +            userlinkdir=
3076 +            ;;
3077 +        -L*)
3078 +            test "$userlinkdir" && set -- "$@" "$x"
3079 +            ;;
3080 +        -l-user-start)
3081 +            userlink=1
3082 +            ;;
3083 +        -l-user-end)
3084 +            userlink=
3085 +            ;;
3086 +        crtbegin*.o|crtend*.o)
3087 +            set -- "$@" $($cc -print-file-name=$x)
3088 +            ;;
3089 +        -lgcc|-lgcc_eh)
3090 +            file=lib${x#-l}.a
3091 +            set -- "$@" $($cc -print-file-name=$file)
3092 +            ;;
3093 +        -l*)
3094 +            test "$userlink" && set -- "$@" "$x"
3095 +            ;;
3096 +        -shared)
3097 +            shared=1
3098 +            set -- "$@" -shared
3099 +            ;;
3100 +        -sysroot=*|--sysroot=*)
3101 +            ;;
3102 +        *)
3103 +            set -- "$@" "$x"
3104 +            ;;
3105 +    esac
3106 +done
3107 +
3108 +exec $($cc -print-prog-name=ld) -nostdlib "$@" -lc -dynamic-linker "$ldso"
3109 --- /dev/null
3110 +++ b/tools/musl-clang.in
3111 @@ -0,0 +1,35 @@
3112 +#!/bin/sh
3113 +cc="@CC@"
3114 +libc="@PREFIX@"
3115 +libc_inc="@INCDIR@"
3116 +libc_lib="@LIBDIR@"
3117 +thisdir="`cd "$(dirname "$0")"; pwd`"
3118 +
3119 +# prevent clang from running the linker (and erroring) on no input.
3120 +sflags=
3121 +eflags=
3122 +for x ; do
3123 +    case "$x" in
3124 +        -l*) input=1 ;;
3125 +        *) input= ;;
3126 +    esac
3127 +    if test "$input" ; then
3128 +        sflags="-l-user-start"
3129 +        eflags="-l-user-end"
3130 +        break
3131 +    fi
3132 +done
3133 +
3134 +exec $cc \
3135 +    -B"$thisdir" \
3136 +    -fuse-ld=musl-clang \
3137 +    -static-libgcc \
3138 +    -nostdinc \
3139 +    --sysroot "$libc" \
3140 +    -isystem "$libc_inc" \
3141 +    -L-user-start \
3142 +    $sflags \
3143 +    "$@" \
3144 +    $eflags \
3145 +    -L"$libc_lib" \
3146 +    -L-user-end