939de6bcd62dc1e2d8c6984196fcfa95019f93ac
[openwrt/staging/chunkeey.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