1 commit 3975577922aedab7d60788dd320a2c8e4e94bc6e
2 Author: Roman Yeryomin <roman@ubnt.com>
3 Date: Thu Jul 2 12:29:00 2015 +0300
5 socket.h: cleanup/reorder mips and powerpc bits/socket.h
7 ....to be somewhat consistent and easily comparable with asm/socket.h
9 Signed-off-by: Roman Yeryomin <roman@ubnt.com>
11 commit 29ec7677a73a5227badbb1064205be09e707e466
12 Author: Roman Yeryomin <roman@ubnt.com>
13 Date: Thu Jul 2 12:28:41 2015 +0300
15 socket.h: fix SO_* for mips
17 Signed-off-by: Roman Yeryomin <roman@ubnt.com>
19 commit 3fffa7a658aa925b8f95d36aef7531c1827dbf28
20 Author: Felix Fietkau <nbd@openwrt.org>
21 Date: Tue Jul 21 15:01:25 2015 +0200
23 mips: fix mcontext_t register array field name
25 glibc and uclibc use gregs instead of regs
27 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
29 commit 0f9c2666aca95eb98eb0ef4f4d8d1473c8ce3fa0
30 Author: Rich Felker <dalias@aerifal.cx>
31 Date: Thu Jul 9 18:36:02 2015 +0000
33 handle loss of syslog socket connection
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.
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.
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
58 commit 11894f6d3a80be950a490dc7dfab349f057a545f
59 Author: Rich Felker <dalias@aerifal.cx>
60 Date: Thu Jul 9 17:07:35 2015 +0000
62 fix incorrect void return type for syncfs function
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.
68 commit e8cbe0bad4284906230a53af4c91ad2b9713d03b
69 Author: Rich Felker <dalias@aerifal.cx>
70 Date: Wed Jul 8 02:46:45 2015 +0000
72 fix negated return value of ns_skiprr, breakage in related functions
74 due to a reversed pointer difference computation, ns_skiprr always
75 returned a negative value, which functions using it would interpret as
80 commit fb58545f8d1c5fa32122244caeaf3625c12ddc01
81 Author: Shiz <hi@shiz.me>
82 Date: Sun Jun 28 23:08:21 2015 +0200
84 add musl-clang, a wrapper for system clang installs
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.
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.
98 commit f8db6f74b2c74a50c4dec7e30be5215f0e2c37a6
99 Author: Shiz <hi@shiz.me>
100 Date: Sun Jun 28 23:08:20 2015 +0200
102 build: fix musl-targeting toolchain test
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.
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.
117 commit b3cd7d13fe630ba1847326242525298e361018c1
118 Author: Shiz <hi@shiz.me>
119 Date: Sun Jun 28 23:08:19 2015 +0200
121 build: overhaul wrapper script system for multiple wrapper support
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.
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.
136 commit 2a780aa3050b86d888489361f04220bfb58890a1
137 Author: Rich Felker <dalias@aerifal.cx>
138 Date: Mon Jul 6 22:13:11 2015 +0000
140 treat empty TZ environment variable as GMT rather than default
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.
146 commit 8f08a58c635bea5cdfae6bc0e323c80aa9ff82a7
147 Author: Alexander Monakov <amonakov@ispras.ru>
148 Date: Sun Jun 28 02:48:33 2015 +0300
150 dynlink.c: pass gnu-hash table pointer to gnu_lookup
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.
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.
160 commit 5b4286e12cd6baac343b10a41dc17ac578832089
161 Author: Alexander Monakov <amonakov@ispras.ru>
162 Date: Sun Jun 28 02:48:32 2015 +0300
164 dynlink.c: slim down gnu_lookup
166 Do not reference dso->syms and dso->strings until point of use.
167 Check 'h1 == (h2|1)', the simplest condition, before the others.
169 commit 84389c64562e2b2ba43225b5b7a9df7d974479b1
170 Author: Alexander Monakov <amonakov@ispras.ru>
171 Date: Sun Jun 28 02:48:31 2015 +0300
173 dynlink.c: use bloom filter in gnu hash lookup
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
181 commit 66d45787c865a1807ae397a89a14699394ed4fa4
182 Author: Alexander Monakov <amonakov@ispras.ru>
183 Date: Sun Jun 28 02:48:30 2015 +0300
185 dynlink.c: use a faster expression in gnu_hash
187 With -Os, GCC uses a multiply rather than a shift and addition for 'h*33'.
188 Use a more efficient expression explicitely.
190 commit 6ba5517a460c6c438f64d69464fdfc3269a4c91a
191 Author: Rich Felker <dalias@aerifal.cx>
192 Date: Thu Jun 25 22:22:00 2015 +0000
194 fix local-dynamic model TLS on mips and powerpc
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:
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
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
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.
220 commit ce337daa00e42d4f2d9a4d9ae0ed51b20249d924
221 Author: Rich Felker <dalias@aerifal.cx>
222 Date: Tue Jun 23 04:03:42 2015 +0000
224 make dynamic linker work around MAP_FAILED mmap failure on nommu kernels
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.
230 commit a59341420fdedb288d9ff80e73609ae44e9cf258
231 Author: Rich Felker <dalias@aerifal.cx>
232 Date: Tue Jun 23 00:12:25 2015 +0000
234 reimplement strverscmp to fix corner cases
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
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.
247 the new strverscmp implementation makes explicit the cases where the
248 order differs from what strcmp would produce, of which there are only
251 commit 153e952e1a688859d7095345b17e6c1df74a295c
252 Author: Rich Felker <dalias@aerifal.cx>
253 Date: Mon Jun 22 20:33:28 2015 +0000
255 fix regression/typo that disabled __simple_malloc when calloc is used
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.
261 commit ba819787ee93ceae94efd274f7849e317c1bff58
262 Author: Rich Felker <dalias@aerifal.cx>
263 Date: Mon Jun 22 18:50:09 2015 +0000
265 fix calloc when __simple_malloc implementation is used
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
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.
282 commit 55d061f031085f24d138664c897791aebe9a2fab
283 Author: Rich Felker <dalias@aerifal.cx>
284 Date: Sat Jun 20 03:01:07 2015 +0000
286 provide __stack_chk_fail_local in libc.a
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.
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
300 commit ce3688eca920aa77549323f84e21f33522397115
301 Author: Rich Felker <dalias@aerifal.cx>
302 Date: Sat Jun 20 02:54:30 2015 +0000
304 work around mips detached thread exit breakage due to kernel regression
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.
313 commit 75eceb3ae824d54e865686c0c538551aeebf3372
314 Author: Rich Felker <dalias@aerifal.cx>
315 Date: Wed Jun 17 17:21:46 2015 +0000
317 ignore ENOSYS error from mprotect in pthread_create and dynamic linker
319 this error simply indicated a system without memory protection (NOMMU)
320 and should not cause failure in the caller.
322 commit 10d0268ccfab9152250eeeed3952ce3fed44131a
323 Author: Rich Felker <dalias@aerifal.cx>
324 Date: Tue Jun 16 15:25:02 2015 +0000
326 switch to using trap number 31 for syscalls on sh
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.
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.
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.
345 commit 3366a99b17847b58f2d8cc52cbb5d65deb824f8a
346 Author: Rich Felker <dalias@aerifal.cx>
347 Date: Tue Jun 16 14:55:06 2015 +0000
349 switch sh port's __unmapself to generic version when running on sh2/nommu
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
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.
362 commit f9d84554bae0fa17c9a1d724549c4408022228a5
363 Author: Rich Felker <dalias@aerifal.cx>
364 Date: Tue Jun 16 14:28:30 2015 +0000
366 add support for sh2 interrupt-masking-based atomics to sh port
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.
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.
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.
385 commit 1b0cdc8700d29ef018bf226d74b2b58b23bce91c
386 Author: Rich Felker <dalias@aerifal.cx>
387 Date: Tue Jun 16 07:11:19 2015 +0000
389 refactor stdio open file list handling, move it out of global libc struct
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.
396 function signatures were chosen to facilitate tail call optimization
397 and reduce the need for additional accessor functions.
399 with these changes, static linked programs that do not use stdio no
400 longer have an open file list at all.
402 commit f22a9edaf8a6f2ca1d314d18b3785558279a5c03
403 Author: Rich Felker <dalias@aerifal.cx>
404 Date: Tue Jun 16 06:18:00 2015 +0000
406 byte-based C locale, phase 3: make MB_CUR_MAX variable to activate code
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.
414 commit 16f18d036d9a7bf590ee6eb86785c0a9658220b6
415 Author: Rich Felker <dalias@aerifal.cx>
416 Date: Tue Jun 16 05:35:31 2015 +0000
418 byte-based C locale, phase 2: stdio and iconv (multibyte callers)
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
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
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.
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.
448 commit 1507ebf837334e9e07cfab1ca1c2e88449069a80
449 Author: Rich Felker <dalias@aerifal.cx>
450 Date: Tue Jun 16 04:44:17 2015 +0000
452 byte-based C locale, phase 1: multibyte character handling functions
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.
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.
470 commit 38e2f727237230300fea6aff68802db04625fd23
471 Author: Rich Felker <dalias@aerifal.cx>
472 Date: Tue Jun 16 04:21:38 2015 +0000
474 fix btowc corner case
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
481 commit ee59c296d56bf26f49f354d6eb32b4b6d4190188
482 Author: Szabolcs Nagy <nsz@port70.net>
483 Date: Wed Jun 3 10:32:14 2015 +0100
485 arm: add vdso support
487 vdso will be available on arm in linux v4.2, the user-space code
488 for it is in kernel commit 8512287a8165592466cb9cb347ba94892e9c56a5
490 commit e3bc22f1eff87b8f029a6ab31f1a269d69e4b053
491 Author: Rich Felker <dalias@aerifal.cx>
492 Date: Sun Jun 14 01:59:02 2015 +0000
494 refactor malloc's expand_heap to share with __simple_malloc
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.
501 it also extends support for using mmap when brk fails, which full
502 malloc got in commit 5446303328adf4b4e36d9fba21848e6feb55fab4, to
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.
513 commit 4ef9b828c1f39553a69e0635ac91f0fcadd6e8c6
514 Author: Rich Felker <dalias@aerifal.cx>
515 Date: Sat Jun 13 20:53:02 2015 +0000
517 remove cancellation points in stdio
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.
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.
533 commit 536c6d5a4205e2a3f161f2983ce1e0ac3082187d
534 Author: Rich Felker <dalias@aerifal.cx>
535 Date: Sat Jun 13 05:17:16 2015 +0000
537 fix idiom for setting stdio stream orientation to wide
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.
549 commit f8f565df467c13248104223f99abf7f37cef7584
550 Author: Rich Felker <dalias@aerifal.cx>
551 Date: Sat Jun 13 04:42:38 2015 +0000
553 add printing of null %s arguments as "(null)" in wide printf
555 this is undefined, but supported in our implementation of the normal
556 printf, so for consistency the wide variant should support it too.
558 commit f9e25d813860d53cd1e9b6145cc63375d2fe2529
559 Author: Rich Felker <dalias@aerifal.cx>
560 Date: Sat Jun 13 04:37:27 2015 +0000
562 add %m support to wide printf
564 commit ec634aad91f57479ef17525e33ed446c780a61f4
565 Author: Rich Felker <dalias@aerifal.cx>
566 Date: Thu Jun 11 05:01:04 2015 +0000
570 commit c30cbcb0a646b1f13a22c645616dce624465b883
571 Author: Rich Felker <dalias@aerifal.cx>
572 Date: Wed Jun 10 02:27:40 2015 +0000
574 implement arch-generic version of __unmapself
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.
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.
586 commit 276904c2f6bde3a31a24ebfa201482601d18b4f9
587 Author: Rich Felker <dalias@aerifal.cx>
588 Date: Tue Jun 9 20:30:35 2015 +0000
590 in malloc, refuse to use brk if it grows into stack
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
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.
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.
614 commit bd1eaceaa3975bd2a2a34e211cff896affaecadf
615 Author: Rich Felker <dalias@aerifal.cx>
616 Date: Tue Jun 9 20:09:27 2015 +0000
618 fix spurious errors from pwd/grp functions when nscd backend is absent
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.
627 this commit also fixed an outdated/incorrect comment.
629 commit 75ce4503950621b11fcc7f1fd1187dbcf3cde312
630 Author: Rich Felker <dalias@aerifal.cx>
631 Date: Sun Jun 7 20:55:23 2015 +0000
633 fix regression in pre-v7 arm on kernels with kuser helper removed
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.
643 upcoming work on superh will use similar runtime detection.
645 ideally this early-init code should be cleanly refactored and shared
646 between the dynamic linker and static-linked startup.
648 commit 32f3c4f70633488550c29a2444f819aafdf345ff
649 Author: Rich Felker <dalias@aerifal.cx>
650 Date: Sun Jun 7 03:09:16 2015 +0000
652 add multiple inclusion guard to locale_impl.h
654 commit 04b8360adbb6487f61aa0c00e53ec3a90a5a0d29
655 Author: Rich Felker <dalias@aerifal.cx>
656 Date: Sun Jun 7 02:59:49 2015 +0000
658 remove redefinition of MB_CUR_MAX in locale_impl.h
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
666 commit 16bf466532d7328e971012b0731ad493b017ad29
667 Author: Rich Felker <dalias@aerifal.cx>
668 Date: Sat Jun 6 18:53:02 2015 +0000
670 make static C and C.UTF-8 locales available outside of newlocale
672 commit 312eea2ea4f4363fb01b73660c08bfcf43dd3bb4
673 Author: Rich Felker <dalias@aerifal.cx>
674 Date: Sat Jun 6 18:20:30 2015 +0000
676 remove another invalid skip of locking in ungetwc
678 commit 3d7e32d28dc9962e9efc1c317c5b44b5b2df3008
679 Author: Rich Felker <dalias@aerifal.cx>
680 Date: Sat Jun 6 18:16:22 2015 +0000
682 add macro version of ctype.h isascii function
684 presumably internal code (ungetwc and fputwc) was written assuming a
685 macro implementation existed; otherwise use of isascii is just a
688 commit 7e816a6487932cbb3cb71d94b609e50e81f4e5bf
689 Author: Rich Felker <dalias@aerifal.cx>
690 Date: Sat Jun 6 18:11:17 2015 +0000
692 remove invalid skip of locking in ungetwc
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.
698 commit 63f4b9f18f3674124d8bcb119739fec85e6da005
699 Author: Timo Teräs <timo.teras@iki.fi>
700 Date: Fri Jun 5 10:39:42 2015 +0300
702 fix uselocale((locale_t)0) not to modify locale
704 commit 68630b55c0c7219fe9df70dc28ffbf9efc8021d8 made the new locale to
705 be assigned unconditonally resulting in crashes later on.
709 @@ -7,5 +7,7 @@ arch/*/bits/alltypes.h
716 src/internal/version.h
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
724 +WRAPCC_CLANG = clang
726 LDSO_PATHNAME = $(syslibdir)/ld-musl-$(ARCH)$(SUBARCH).so.1
729 @@ -155,7 +158,11 @@ lib/musl-gcc.specs: tools/musl-gcc.specs
730 sh $< "$(includedir)" "$(libdir)" "$(LDSO_PATHNAME)" > $@
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)" > $@
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' $< > $@
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));
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
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
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
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
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
810 --- a/arch/mips/pthread_arch.h
811 +++ b/arch/mips/pthread_arch.h
812 @@ -13,4 +13,6 @@ static inline struct pthread *__pthread_
814 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
816 +#define DTP_OFFSET 0x8000
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
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
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_
844 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
846 +#define DTP_OFFSET 0x8000
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
852 +++ b/arch/sh/src/__set_thread_area.c
854 +#include "pthread_impl.h"
856 +#include "sh_atomic.h"
859 +/* Also perform sh-specific init */
861 +#define CPU_HAS_LLSC 0x0040
863 +__attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model, __sh_nommu;
865 +int __set_thread_area(void *p)
868 + __asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
870 + if (__hwcap & CPU_HAS_LLSC) {
871 + __sh_atomic_model = SH_A_LLSC;
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;
884 + /* __sh_atomic_model = SH_A_GUSA; */ /* 0, default */
889 +++ b/arch/sh/src/__unmapself.c
891 +#include "pthread_impl.h"
893 +void __unmapself_sh_mmu(void *, size_t);
894 +void __unmapself_sh_nommu(void *, size_t);
896 +#if !defined(__SH3__) && !defined(__SH4__)
897 +#define __unmapself __unmapself_sh_nommu
898 +#include "../../../src/thread/__unmapself.c"
900 +extern __attribute__((__visibility__("hidden"))) unsigned __sh_nommu;
902 +#define __sh_nommu 0
905 +void __unmapself(void *base, size_t size)
907 + if (__sh_nommu) __unmapself_sh_nommu(base, size);
908 + else __unmapself_sh_mmu(base, size);
910 --- a/arch/sh/src/atomic.c
911 +++ b/arch/sh/src/atomic.c
915 +#include "sh_atomic.h"
919 +static inline unsigned mask()
922 + __asm__ __volatile__ ( "\n"
927 + : "=&r"(sr) : : "memory", "r0" );
931 +static inline void unmask(unsigned sr)
933 + __asm__ __volatile__ ( "ldc %0,sr" : : "r"(sr) : "memory" );
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:
940 " mov.l " new ", @" mem "\n" \
943 -#define CPU_HAS_LLSC 0x0040
945 int __sh_cas(volatile int *p, int t, int s)
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);
950 + if (__sh_atomic_model == SH_A_IMASK) {
951 + unsigned sr = mask();
953 + if (old==t) *p = s;
959 __asm__ __volatile__(
960 @@ -43,7 +67,15 @@ int __sh_cas(volatile int *p, int t, int
962 int __sh_swap(volatile int *x, int v)
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);
967 + if (__sh_atomic_model == SH_A_IMASK) {
968 + unsigned sr = mask();
976 __asm__ __volatile__(
977 @@ -55,7 +87,15 @@ int __sh_swap(volatile int *x, int v)
979 int __sh_fetch_add(volatile int *x, int v)
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);
984 + if (__sh_atomic_model == SH_A_IMASK) {
985 + unsigned sr = mask();
993 __asm__ __volatile__(
994 @@ -69,7 +109,7 @@ int __sh_fetch_add(volatile int *x, int
996 void __sh_store(volatile int *p, int x)
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__(
1002 : : "r"(p), "r"(x) : "memory");
1003 @@ -77,7 +117,15 @@ void __sh_store(volatile int *p, int x)
1005 void __sh_and(volatile int *x, int v)
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);
1010 + if (__sh_atomic_model == SH_A_IMASK) {
1011 + unsigned sr = mask();
1019 __asm__ __volatile__(
1020 @@ -89,7 +137,15 @@ void __sh_and(volatile int *x, int v)
1022 void __sh_or(volatile int *x, int v)
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);
1027 + if (__sh_atomic_model == SH_A_IMASK) {
1028 + unsigned sr = mask();
1036 __asm__ __volatile__(
1038 +++ b/arch/sh/src/sh_atomic.h
1040 +#ifndef _SH_ATOMIC_H
1041 +#define _SH_ATOMIC_H
1043 +#define SH_A_GUSA 0
1044 +#define SH_A_LLSC 1
1046 +#if !defined(__SH3__) && !defined(__SH4__)
1047 +#define SH_A_IMASK 3
1049 +#define SH_A_IMASK -1LL /* unmatchable by unsigned int */
1052 +extern __attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model;
1055 --- a/arch/sh/syscall_arch.h
1056 +++ b/arch/sh/syscall_arch.h
1059 #define __asm_syscall(trapno, ...) do { \
1060 __asm__ __volatile__ ( \
1061 - "trapa #" #trapno "\n" \
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]
1077 @@ -123,6 +123,8 @@ bindir='$(exec_prefix)/bin'
1078 libdir='$(prefix)/lib'
1079 includedir='$(prefix)/include'
1086 @@ -131,6 +133,8 @@ visibility=auto
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
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.
1118 -printf "checking whether compiler is gcc... "
1119 -if fnmatch '*gcc\ version*' "$(LC_ALL=C $CC -v 2>&1)" ; then
1121 +printf "checking for C compiler family... "
1122 +cc_ver="$(LC_ALL=C $CC -v 2>&1)"
1124 +if fnmatch '*gcc\ version*' "$cc_ver" ; then
1126 +elif fnmatch '*clang\ version*' "$cc_ver" ; then
1132 +# Figure out toolchain wrapper to build
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
1142 +elif test "$cc_family" = gcc ; then
1145 +elif test "$cc_family" = clang ; then
1151 +if test "$wrapper" = detect ; then
1152 +fail "$0: could not find an appropriate toolchain wrapper"
1157 -# Only build musl-gcc wrapper if toolchain does not already target musl
1159 -if test "$wrapper" = auto ; then
1160 -printf "checking whether to build musl-gcc wrapper... "
1161 -if test "$cc_is_gcc" = yes ; then
1163 -while read line ; do
1164 -case "$line" in */ld-musl-*) wrapper=no ;; esac
1175 +if test "$gcc_wrapper" = yes ; then
1176 +tools="$tools tools/musl-gcc"
1177 +tool_libs="$tool_libs lib/musl-gcc.specs"
1179 +if test "$clang_wrapper" = yes ; then
1180 +tools="$tools tools/musl-clang tools/ld.musl-clang"
1184 # Find the target architecture
1185 @@ -580,11 +604,13 @@ LDFLAGS = $LDFLAGS_AUTO $LDFLAGS
1186 CROSS_COMPILE = $CROSS_COMPILE
1188 OPTIMIZE_GLOBS = $OPTIMIZE_GLOBS
1190 +TOOL_LIBS = $tool_libs
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)'
1201 --- a/include/ctype.h
1202 +++ b/include/ctype.h
1203 @@ -64,6 +64,7 @@ int isascii(int);
1205 #define _tolower(a) ((a)|0x20)
1206 #define _toupper(a) ((a)&0x5f)
1207 +#define isascii(a) (0 ? isascii(a) : (unsigned)(a) < 128)
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
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())
1221 #define RAND_MAX (0x7fffffff)
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
1236 #define SO_SECURITY_AUTHENTICATION 22
1237 @@ -195,7 +198,6 @@ struct linger
1238 #define SO_TIMESTAMP 29
1239 #define SCM_TIMESTAMP SO_TIMESTAMP
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
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);
1262 int euidaccess(const char *, int);
1263 int eaccess(const char *, int);
1265 --- a/src/ctype/__ctype_get_mb_cur_max.c
1266 +++ b/src/ctype/__ctype_get_mb_cur_max.c
1268 -#include <stddef.h>
1269 +#include <stdlib.h>
1270 +#include "locale_impl.h"
1272 size_t __ctype_get_mb_cur_max()
1275 + return MB_CUR_MAX;
1277 --- a/src/ctype/isascii.c
1278 +++ b/src/ctype/isascii.c
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)
1293 +weak_alias(__stack_chk_fail, __stack_chk_fail_local);
1296 --- a/src/internal/libc.h
1297 +++ b/src/internal/libc.h
1298 @@ -17,8 +17,6 @@ struct __libc {
1300 volatile int threads_minus_1;
1303 - volatile int ofl_lock[2];
1306 struct __locale_struct global_locale;
1307 --- a/src/internal/locale_impl.h
1308 +++ b/src/internal/locale_impl.h
1310 +#ifndef _LOCALE_IMPL_H
1311 +#define _LOCALE_IMPL_H
1316 @@ -12,6 +15,10 @@ struct __locale_map {
1317 const struct __locale_map *next;
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;
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)
1331 +#define C_LOCALE ((locale_t)&__c_locale)
1332 +#define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale)
1334 #define CURRENT_LOCALE (__pthread_self()->locale)
1336 #define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
1339 #define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
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
1349 +#define DTP_OFFSET 0
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:
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;
1371 FILE *prev_locked, *next_locked;
1372 + struct __locale_struct *locale;
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 *);
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);
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;
1399 @@ -174,32 +174,39 @@ static Sym *sysv_lookup(const char *s, u
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)
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);
1412 - uint32_t *hashval;
1413 uint32_t i = buckets[h1 % nbuckets];
1417 - hashval = buckets + nbuckets + (i - hashtab[1]);
1418 + uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);
1420 for (h1 |= 1; ; i++) {
1422 - if ((!dso->versym || dso->versym[i] >= 0)
1423 - && (h1 == (h2|1)) && !strcmp(s, strings + syms[i].st_name))
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;
1435 +static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask)
1437 + const size_t *bloomwords = (const void *)(hashtab+4);
1438 + size_t f = bloomwords[fofs & (hashtab[2]-1)];
1439 + if (!(f & fmask)) return 0;
1441 + f >>= (h1 >> hashtab[3]) % (8 * sizeof f);
1442 + if (!(f & 1)) return 0;
1444 + return gnu_lookup(h1, hashtab, dso, s);
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)
1450 @@ -209,14 +216,20 @@ static Sym *gnu_lookup(const char *s, ui
1452 static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
1454 - uint32_t h = 0, gh = 0;
1455 + uint32_t h = 0, gh, gho, *ght;
1457 struct symdef def = {0};
1458 for (; dso; dso=dso->next) {
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)) {
1467 + int maskbits = 8 * sizeof ghm;
1468 + gho = gh / maskbits;
1469 + ghm = 1ul << gh % maskbits;
1471 + sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm);
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;
1479 - *reloc_addr = tls_val + addend;
1480 + *reloc_addr = tls_val + addend - DTP_OFFSET;
1484 @@ -423,6 +436,28 @@ static void reclaim_gaps(struct dso *dso
1488 +static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
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) {
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;
1510 static void *map_library(int fd, struct dso *dso)
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)
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)
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)
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);
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",
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;
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;
1559 __restore_sigs(&set);
1560 - return mem + v[1];
1561 + return mem + v[1] + DTP_OFFSET;
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;
1569 + /* Find aux vector just past environ[] and use it to initialize
1570 + * global data that may be needed before we can make syscalls. */
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]);
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)
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);
1595 - decode_vec(auxv, aux, AUX_CNT);
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]) {
1603 + if (!libc.secure) {
1604 + env_path = getenv("LD_LIBRARY_PATH");
1605 + env_preload = getenv("LD_PRELOAD");
1607 - libc.page_size = aux[AT_PAGESZ];
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)
1616 - uint32_t h = 0, gh = 0;
1617 + uint32_t h = 0, gh = 0, *ght;
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
1623 if (invalid_dso_handle(p))
1625 - if (p->ghashtab) {
1626 + if ((ght = p->ghashtab)) {
1628 - sym = gnu_lookup(s, gh, p);
1629 + sym = gnu_lookup(gh, ght, p, 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);
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
1649 #include "syscall.h"
1651 -void syncfs(int fd)
1654 - __syscall(SYS_syncfs, fd);
1655 + return syscall(SYS_syncfs, fd);
1658 +++ b/src/locale/c_locale.c
1660 +#include "locale_impl.h"
1661 +#include <stdint.h>
1663 +static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
1665 +const struct __locale_map __c_dot_utf8 = {
1667 + .map_size = sizeof empty_mo,
1671 +const struct __locale_struct __c_locale = { 0 };
1672 +const struct __locale_struct __c_dot_utf8_locale = {
1673 + .cat[LC_CTYPE] = &__c_dot_utf8
1675 --- a/src/locale/iconv.c
1676 +++ b/src/locale/iconv.c
1681 +#include "locale_impl.h"
1683 #define UTF_32BE 0300
1684 #define UTF_16LE 0301
1685 @@ -165,9 +166,12 @@ size_t iconv(iconv_t cd0, char **restric
1687 unsigned char type = map[-1];
1688 unsigned char totype = tomap[-1];
1689 + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
1691 if (!in || !*in || !*inb) return 0;
1693 + *ploc = UTF8_LOCALE;
1695 for (; *inb; *in+=l, *inb-=l) {
1696 c = *(unsigned char *)*in;
1698 @@ -431,6 +435,7 @@ size_t iconv(iconv_t cd0, char **restric
1706 @@ -445,5 +450,6 @@ starved:
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;
1719 - if (item == CODESET) return "UTF-8";
1720 + if (item == CODESET)
1721 + return MB_CUR_MAX==1 ? "UTF-8-CODE-UNITS" : "UTF-8";
1725 --- a/src/locale/locale_map.c
1726 +++ b/src/locale/locale_map.c
1727 @@ -24,14 +24,6 @@ static const char envvars[][12] = {
1731 -static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
1733 -const struct __locale_map __c_dot_utf8 = {
1735 - .map_size = sizeof empty_mo,
1739 const struct __locale_map *__get_locale(int cat, const char *val)
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);
1752 new->next = loc_head;
1753 --- a/src/locale/newlocale.c
1754 +++ b/src/locale/newlocale.c
1756 #include "locale_impl.h"
1759 -extern const struct __locale_map __c_dot_utf8;
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
1766 int __loc_is_allocated(locale_t loc)
1768 - return loc && loc != &c_locale && loc != &c_dot_utf8_locale;
1769 + return loc && loc != C_LOCALE && loc != UTF8_LOCALE;
1772 locale_t __newlocale(int mask, const char *name, locale_t loc)
1773 @@ -44,9 +37,9 @@ locale_t __newlocale(int mask, const cha
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;
1781 + if (j==1 && tmp.cat[LC_CTYPE]==&__c_dot_utf8)
1782 + return UTF8_LOCALE;
1784 if ((loc = malloc(sizeof *loc))) *loc = tmp;
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;
1792 - if (new == LC_GLOBAL_LOCALE) new = global;
1794 - self->locale = new;
1795 + if (new) self->locale = new == LC_GLOBAL_LOCALE ? global : new;
1797 return old == global ? LC_GLOBAL_LOCALE : old;
1799 --- a/src/malloc/calloc.c
1800 +++ b/src/malloc/calloc.c
1805 +void *__malloc0(size_t);
1807 void *calloc(size_t m, size_t n)
1811 if (n && m > (size_t)-1/n) {
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;
1825 + return __malloc0(n * m);
1828 +++ b/src/malloc/expand_heap.c
1830 +#include <limits.h>
1831 +#include <stdint.h>
1833 +#include <sys/mman.h>
1835 +#include "syscall.h"
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. */
1843 +static int traverses_stack_p(uintptr_t old, uintptr_t new)
1845 + const uintptr_t len = 8<<20;
1848 + b = (uintptr_t)libc.auxv;
1849 + a = b > len ? b-len : 0;
1850 + if (new>a && old<b) return 1;
1852 + b = (uintptr_t)&b;
1853 + a = b > len ? b-len : 0;
1854 + if (new>a && old<b) return 1;
1859 +void *__mmap(void *, size_t, int, int, int, off_t);
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. */
1869 +void *__expand_heap(size_t *pn)
1871 + static uintptr_t brk;
1872 + static unsigned mmap_step;
1875 + if (n > SIZE_MAX/2 - PAGE_SIZE) {
1879 + n += -n & PAGE_SIZE-1;
1882 + brk = __syscall(SYS_brk, 0);
1883 + brk += -brk & PAGE_SIZE-1;
1886 + if (n < SIZE_MAX-brk && !traverses_stack_p(brk, brk+n)
1887 + && __syscall(SYS_brk, brk+n)==brk+n) {
1890 + return (void *)(brk-n);
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;
1902 --- a/src/malloc/lite_malloc.c
1903 +++ b/src/malloc/lite_malloc.c
1908 -uintptr_t __brk(uintptr_t);
1912 +void *__expand_heap(size_t *);
1914 void *__simple_malloc(size_t n)
1916 - static uintptr_t cur, brk;
1917 - uintptr_t base, new;
1918 + static char *cur, *end;
1919 static volatile int lock[2];
1921 + size_t align=1, pad;
1925 - if (n > SIZE_MAX/2) goto toobig;
1927 while (align<n && align<ALIGN)
1929 - n = n + align - 1 & -align;
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;
1943 - return (void *)base;
1944 + pad = -(uintptr_t)cur & align-1;
1946 + if (n <= SIZE_MAX/2 + ALIGN) n += pad;
1948 + if (n > end-cur) {
1950 + char *new = __expand_heap(&m);
1973 weak_alias(__simple_malloc, malloc);
1974 +weak_alias(__simple_malloc, __malloc0);
1975 --- a/src/malloc/malloc.c
1976 +++ b/src/malloc/malloc.c
1978 #define inline inline __attribute__((always_inline))
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 {
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;
1999 @@ -152,69 +147,52 @@ void __dump_heap(int x)
2003 +void *__expand_heap(size_t *);
2005 static struct chunk *expand_heap(size_t n)
2008 + static int heap_lock[2];
2014 - lock(mal.brk_lock);
2017 - mal.brk = __brk(0);
2019 - mal.brk = mal.brk + PAGE_SIZE-1 & -PAGE_SIZE;
2021 - mal.brk = mal.brk + 2*SIZE_ALIGN-1 & -SIZE_ALIGN;
2022 - mal.heap = (void *)mal.brk;
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;
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;
2039 - area = (char *)area + SIZE_ALIGN - OVERHEAD;
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. */
2048 + p = __expand_heap(&n);
2050 + unlock(heap_lock);
2054 + /* If not just expanding existing space, we need to make a
2055 + * new sentinel chunk below the allocated space. */
2057 + /* Valid/safe because of the prologue increment. */
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;
2067 - unlock(mal.brk_lock);
2072 - w = MEM_TO_CHUNK(mal.heap);
2073 - w->psize = 0 | C_INUSE;
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;
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;
2089 - unlock(mal.brk_lock);
2091 + unlock(heap_lock);
2095 - unlock(mal.brk_lock);
2100 static int adjust_size(size_t *n)
2101 @@ -378,6 +356,17 @@ void *malloc(size_t n)
2102 return CHUNK_TO_MEM(c);
2105 +void *__malloc0(size_t n)
2107 + void *p = malloc(n);
2108 + if (p && !IS_MMAPPED(MEM_TO_CHUNK(p))) {
2110 + n = (n + sizeof *z - 1)/sizeof *z;
2111 + for (z=p; n; n--, z++) if (*z) *z=0;
2116 void *realloc(void *p, size_t n)
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)
2123 static void __openlog()
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)
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);
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);
2140 +static int is_lost_conn(int e)
2142 + return e==ECONNREFUSED || e==ECONNRESET || e==ENOTCONN || e==EPIPE;
2145 static void _vsyslog(int priority, const char *message, va_list ap)
2148 @@ -107,7 +108,10 @@ static void _vsyslog(int priority, const
2149 if (l2 >= sizeof buf - l) l = sizeof buf - 1;
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);
2159 dprintf(fd, "%.*s", l-hlen, buf+hlen);
2160 --- a/src/multibyte/btowc.c
2161 +++ b/src/multibyte/btowc.c
2165 +#include <stdlib.h>
2166 +#include "internal.h"
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;
2174 --- a/src/multibyte/internal.h
2175 +++ b/src/multibyte/internal.h
2176 @@ -23,3 +23,10 @@ extern const uint32_t bittab[];
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)
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
2193 +#include <stdlib.h>
2196 #include "internal.h"
2197 @@ -27,6 +28,7 @@ size_t mbrtowc(wchar_t *restrict wc, con
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--;
2205 --- a/src/multibyte/mbsrtowcs.c
2206 +++ b/src/multibyte/mbsrtowcs.c
2211 +#include <string.h>
2212 +#include <stdlib.h>
2213 #include "internal.h"
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
2220 + if (MB_CUR_MAX==1) {
2221 + if (!ws) return strlen((const char *)s);
2224 + *src = (const void *)s;
2229 + *ws++ = CODEUNIT(c);
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
2246 +#include <stdlib.h>
2249 #include "internal.h"
2250 @@ -19,6 +20,7 @@ int mbtowc(wchar_t *restrict wc, const c
2251 if (!wc) wc = &dummy;
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];
2258 --- a/src/multibyte/wcrtomb.c
2259 +++ b/src/multibyte/wcrtomb.c
2264 +#include <stdlib.h>
2267 +#include "internal.h"
2269 size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st)
2271 @@ -13,6 +15,13 @@ size_t wcrtomb(char *restrict s, wchar_t
2272 if ((unsigned)wc < 0x80) {
2275 + } else if (MB_CUR_MAX == 1) {
2276 + if (!IS_CODEUNIT(wc)) {
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
2290 +#include <stdlib.h>
2291 +#include "internal.h"
2295 if (c < 128U) return c;
2296 + if (MB_CUR_MAX==1 && IS_CODEUNIT(c)) return (unsigned char)c;
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,
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
2316 + int errno_save = errno;
2320 @@ -50,11 +51,14 @@ retry:
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
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;
2340 +++ b/src/process/sh/vfork.s
2344 +.type __vfork,@function
2345 +.type vfork,@function
2363 + .hidden __syscall_ret
2364 +1: .long __syscall_ret@PLT-(2b+4-.)
2365 --- a/src/regex/fnmatch.c
2366 +++ b/src/regex/fnmatch.c
2371 +#include "locale_impl.h"
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);
2383 if (tailcnt) return FNM_NOMATCH;
2384 --- a/src/signal/sh/restore.s
2385 +++ b/src/signal/sh/restore.s
2387 .type __restore, @function
2389 mov #119, r3 !__NR_sigreturn
2395 @@ -15,7 +15,7 @@ __restore:
2397 mov #100, r3 !__NR_rt_sigreturn
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;
2409 /* Add new FILE to open file list */
2411 - f->next = libc.ofl_head;
2412 - if (libc.ofl_head) libc.ofl_head->prev = f;
2413 - libc.ofl_head = f;
2417 + return __ofl_add(f);
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)
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);
2433 --- a/src/stdio/__stdio_read.c
2434 +++ b/src/stdio/__stdio_read.c
2436 #include "stdio_impl.h"
2437 #include <sys/uio.h>
2438 -#include <pthread.h>
2440 -static void cleanup(void *p)
2443 - if (!f->lockcount) __unlockfile(f);
2446 size_t __stdio_read(FILE *f, unsigned char *buf, size_t len)
2448 @@ -16,9 +9,7 @@ size_t __stdio_read(FILE *f, unsigned ch
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);
2457 f->flags |= F_EOF ^ ((F_ERR^F_EOF) & cnt);
2459 --- a/src/stdio/__stdio_write.c
2460 +++ b/src/stdio/__stdio_write.c
2462 #include "stdio_impl.h"
2463 #include <sys/uio.h>
2464 -#include <pthread.h>
2466 -static void cleanup(void *p)
2469 - if (!f->lockcount) __unlockfile(f);
2472 size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
2474 @@ -19,9 +12,7 @@ size_t __stdio_write(FILE *f, const unsi
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);
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
2488 if (cnt > iov[0].iov_len) {
2489 - f->wpos = f->wbase = f->buf;
2490 cnt -= iov[0].iov_len;
2492 - } else if (iovcnt == 2) {
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);
2502 if (!(perm = f->flags & F_PERM)) {
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;
2509 + if (*head == f) *head = f->next;
2514 --- a/src/stdio/fflush.c
2515 +++ b/src/stdio/fflush.c
2516 @@ -35,13 +35,12 @@ int fflush(FILE *f)
2518 r = __stdout_used ? fflush(__stdout_used) : 0;
2521 - for (f=libc.ofl_head; f; f=f->next) {
2522 + for (f=*__ofl_lock(); f; f=f->next) {
2524 if (f->wpos > f->wbase) r |= __fflush_unlocked(f);
2532 --- a/src/stdio/fgetwc.c
2533 +++ b/src/stdio/fgetwc.c
2535 #include "stdio_impl.h"
2536 +#include "locale_impl.h"
2540 -wint_t __fgetwc_unlocked(FILE *f)
2541 +static wint_t __fgetwc_unlocked_internal(FILE *f)
2543 mbstate_t st = { 0 };
2545 @@ -10,8 +11,6 @@ wint_t __fgetwc_unlocked(FILE *f)
2549 - f->mode |= f->mode+1;
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)
2558 +wint_t __fgetwc_unlocked(FILE *f)
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);
2568 wint_t fgetwc(FILE *f)
2571 --- a/src/stdio/fmemopen.c
2572 +++ b/src/stdio/fmemopen.c
2573 @@ -110,11 +110,5 @@ FILE *fmemopen(void *restrict buf, size_
2575 if (!libc.threaded) f->lock = -1;
2578 - f->next = libc.ofl_head;
2579 - if (libc.ofl_head) libc.ofl_head->prev = f;
2580 - libc.ofl_head = f;
2584 + return __ofl_add(f);
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);
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
2600 #include "stdio_impl.h"
2601 +#include "locale_impl.h"
2605 @@ -7,8 +8,10 @@ wint_t __fputwc_unlocked(wchar_t c, FILE
2607 char mbc[MB_LEN_MAX];
2609 + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
2611 - f->mode |= f->mode+1;
2612 + if (f->mode <= 0) fwide(f, 1);
2613 + *ploc = f->locale;
2616 c = putc_unlocked(c, f);
2617 @@ -20,6 +23,8 @@ wint_t __fputwc_unlocked(wchar_t c, FILE
2619 if (l < 0 || __fwritex((void *)mbc, l, f) < l) c = WEOF;
2621 + if (c==WEOF) f->flags |= F_ERR;
2626 --- a/src/stdio/fputws.c
2627 +++ b/src/stdio/fputws.c
2629 #include "stdio_impl.h"
2630 +#include "locale_impl.h"
2633 int fputws(const wchar_t *restrict ws, FILE *restrict f)
2635 unsigned char buf[BUFSIZ];
2637 + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
2641 - f->mode |= f->mode+1;
2643 + *ploc = f->locale;
2645 while (ws && (l = wcsrtombs((void *)buf, (void*)&ws, sizeof buf, 0))+1 > 1)
2646 if (__fwritex(buf, l, f) < l) {
2655 return l; /* 0 or -1 */
2658 --- a/src/stdio/fwide.c
2659 +++ b/src/stdio/fwide.c
2662 #include "stdio_impl.h"
2664 -#define SH (8*sizeof(int)-1)
2665 -#define NORMALIZE(x) ((x)>>SH | -((-(x))>>SH))
2666 +#include "locale_impl.h"
2668 int fwide(FILE *f, int mode)
2671 - if (!f->mode) f->mode = NORMALIZE(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;
2681 +++ b/src/stdio/ofl.c
2683 +#include "stdio_impl.h"
2686 +static FILE *ofl_head;
2687 +static volatile int ofl_lock[2];
2689 +FILE **__ofl_lock()
2695 +void __ofl_unlock()
2700 +++ b/src/stdio/ofl_add.c
2702 +#include "stdio_impl.h"
2704 +FILE *__ofl_add(FILE *f)
2706 + FILE **head = __ofl_lock();
2708 + if (*head) (*head)->prev = f;
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
2717 if (!libc.threaded) f->lock = -1;
2720 - f->next = libc.ofl_head;
2721 - if (libc.ofl_head) libc.ofl_head->prev = f;
2722 - libc.ofl_head = f;
2726 + return __ofl_add(f);
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
2732 if (!libc.threaded) f->lock = -1;
2735 - f->next = libc.ofl_head;
2736 - if (libc.ofl_head) libc.ofl_head->prev = f;
2737 - libc.ofl_head = f;
2741 + return __ofl_add(f);
2743 --- a/src/stdio/ungetwc.c
2744 +++ b/src/stdio/ungetwc.c
2746 #include "stdio_impl.h"
2747 +#include "locale_impl.h"
2751 @@ -8,21 +9,19 @@ wint_t ungetwc(wint_t c, FILE *f)
2753 unsigned char mbc[MB_LEN_MAX];
2756 - if (c == WEOF) return c;
2758 - /* Try conversion early so we can fail without locking if invalid */
2759 - if (!isascii(c) && (l = wctomb((void *)mbc, c)) < 0)
2761 + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
2765 - f->mode |= f->mode+1;
2766 + if (f->mode <= 0) fwide(f, 1);
2767 + *ploc = f->locale;
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)) {
2779 if (isascii(c)) *--f->rpos = c;
2780 @@ -31,5 +30,6 @@ wint_t ungetwc(wint_t c, FILE *f)
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, "");
2794 + arg.p = strerror(errno);
2796 + if (!arg.p) arg.p = "(null)";
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
2804 - f->mode |= f->mode+1;
2806 olderr = 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
2815 - f->mode |= f->mode+1;
2818 for (p=fmt; *p; p++) {
2820 --- a/src/string/strverscmp.c
2821 +++ b/src/string/strverscmp.c
2826 -int strverscmp(const char *l, const char *r)
2827 +int strverscmp(const char *l0, const char *r0)
2831 - if (!*l) return 0;
2832 + const unsigned char *l = (const void *)l0;
2833 + const unsigned char *r = (const void *)r0;
2841 - } else if (isdigit(*l)) {
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++) {
2854 + if (!isdigit(c)) dp=i+1, z=1;
2855 + else if (c!='0') z=0;
2857 - if (haszero==1 && (*l=='0' || *r=='0')) {
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++;
2866 - } else if (lenl>lenr) {
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');
2886 + return l[i] - r[i];
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);
2898 - return (char *)self->dtv[1]+v[1];
2899 + return (char *)self->dtv[1]+v[1]+DTP_OFFSET;
2903 +++ b/src/thread/__unmapself.c
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"
2911 +static volatile int lock;
2912 +static void *unmap_base;
2913 +static size_t unmap_size;
2914 +static char shared_stack[256];
2916 +static void do_unmap()
2918 + __syscall(SYS_munmap, unmap_base, unmap_size);
2919 + __syscall(SYS_exit);
2922 +void __unmapself(void *base, size_t size)
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))
2929 + __syscall(SYS_set_tid_address, &lock);
2930 + unmap_base = base;
2931 + unmap_size = size;
2932 + CRTJMP(do_unmap, stack);
2934 --- a/src/thread/mips/__unmapself.s
2935 +++ b/src/thread/mips/__unmapself.s
2938 .type __unmapself,@function
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)
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
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);
2967 --- a/src/thread/sh/__set_thread_area.s
2968 +++ b/src/thread/sh/__set_thread_area.s
2970 -.global __set_thread_area
2971 -.type __set_thread_area, @function
2976 --- a/src/thread/sh/__unmapself.s
2977 +++ b/src/thread/sh/__unmapself.s
2980 -.global __unmapself
2981 -.type __unmapself, @function
2983 +.global __unmapself_sh_mmu
2984 +.type __unmapself_sh_mmu, @function
2985 +__unmapself_sh_mmu:
2986 mov #91, r3 ! SYS_munmap
2992 @@ -13,7 +13,7 @@ __unmapself:
2994 mov #1, r3 ! SYS_exit
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
3012 @@ -38,7 +38,7 @@ __clone:
3014 mov #1, r3 ! __NR_exit
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-.)
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";
3038 - if (!s || !*s) s = "/etc/localtime";
3039 + if (!s) s = "/etc/localtime";
3040 + if (!*s) s = __gmt;
3042 if (old_tz && !strcmp(s, old_tz)) return;
3044 --- a/src/unistd/sh/pipe.s
3045 +++ b/src/unistd/sh/pipe.s
3047 .type pipe, @function
3053 ! work around hardware bug
3056 +++ b/tools/ld.musl-clang.in
3060 +libc_lib="@LIBDIR@"
3068 + test "$cleared" || set -- ; cleared=1
3078 + test "$userlinkdir" && set -- "$@" "$x"
3086 + crtbegin*.o|crtend*.o)
3087 + set -- "$@" $($cc -print-file-name=$x)
3091 + set -- "$@" $($cc -print-file-name=$file)
3094 + test "$userlink" && set -- "$@" "$x"
3098 + set -- "$@" -shared
3100 + -sysroot=*|--sysroot=*)
3108 +exec $($cc -print-prog-name=ld) -nostdlib "$@" -lc -dynamic-linker "$ldso"
3110 +++ b/tools/musl-clang.in
3115 +libc_inc="@INCDIR@"
3116 +libc_lib="@LIBDIR@"
3117 +thisdir="`cd "$(dirname "$0")"; pwd`"
3119 +# prevent clang from running the linker (and erroring) on no input.
3127 + if test "$input" ; then
3128 + sflags="-l-user-start"
3129 + eflags="-l-user-end"
3136 + -fuse-ld=musl-clang \
3139 + --sysroot "$libc" \
3140 + -isystem "$libc_inc" \