opkg: fix duplicate check_signature line for smime variant (#19863)
[openwrt.git] / toolchain / musl / patches / 001-git-2015-06-04.patch
1 commit b6a6cd703ffefa6352249fb01f4da28d85d17306
2 Author: Rich Felker <dalias@aerifal.cx>
3 Date:   Thu Jun 4 11:45:17 2015 -0400
4
5     fix dynamic linker regression processing R_*_NONE type relocations
6     
7     commit f3ddd173806fd5c60b3f034528ca24542aecc5b9 inadvertently removed
8     the early check for "none" type relocations, causing the address
9     dso->base+0 to be dereferenced to obtain an addend. shared libraries,
10     (including libc.so) and PIE executables were unaffected, since their
11     base addresses are the actual address of their mappings and are
12     readable. non-PIE main executables, however, have a base address of 0
13     because their load addresses are absolute and not offset at load time.
14     
15     in practice none-type relocations do not arise with toolchains that
16     are in use except on mips, and on mips it's moderately rare for a
17     non-PIE executable to have a relocation table, since the mips-specific
18     got processing serves in its place for most purposes.
19
20 commit 585ba14df4799d50ec9682ce75825d2eafec2a6a
21 Author: Rich Felker <dalias@aerifal.cx>
22 Date:   Wed Jun 3 02:00:44 2015 -0400
23
24     add additional Makefile dependency rules for rcrt1.o PIE start file
25
26 commit 2b4fcfdacf93c3dfd6ac15e31790a9e154374679
27 Author: Rich Felker <dalias@aerifal.cx>
28 Date:   Thu May 28 23:08:12 2015 -0400
29
30     fix failure of ungetc and ungetwc to work on files in eof status
31     
32     these functions were written to handle clearing eof status, but failed
33     to account for the __toread function's handling of eof. with this
34     patch applied, __toread still returns EOF when the file is in eof
35     status, so that read operations will fail, but it also sets up valid
36     buffer pointers for read mode, which are set to the end of the buffer
37     rather than the beginning in order to make the whole buffer available
38     to ungetc/ungetwc.
39     
40     minor changes to __uflow were needed since it's now possible to have
41     non-zero buffer pointers while in eof status. as made, these changes
42     remove a 'fast path' bypassing the function call to __toread, which
43     could be reintroduced with slightly different logic, but since
44     ordinary files have a syscall in f->read, optimizing the code path
45     does not seem worthwhile.
46     
47     the __stdio_read function is also updated not to zero the read buffer
48     pointers on eof/error. while not necessary for correctness, this
49     change avoids the overhead of calling __toread in ungetc after
50     reaching eof, and it also reduces code size and increases consistency
51     with the fmemopen read operation which does not zero the pointers.
52
53 commit b6e7c664677ab7c77f183b8c41105f2be519800c
54 Author: Rich Felker <dalias@aerifal.cx>
55 Date:   Thu May 28 15:37:23 2015 -0400
56
57     add missing legacy LFS64 macros in sys/resource.h
58     
59     based on patch by Felix Janda, with RLIM64_SAVED_CUR and
60     RLIM64_SAVED_MAX added for completeness.
61
62 commit fc431d3f76bb9bde34a89e4a3e4d0c27de959855
63 Author: Shiz <hi@shiz.me>
64 Date:   Thu May 28 05:52:22 2015 +0200
65
66     configure: work around compilers that merely warn for unknown options
67     
68     some compilers (such as clang) accept unknown options without error,
69     but then print warnings on each invocation, cluttering the build
70     output and burying meaningful warnings. this patch makes configure's
71     tryflag and tryldflag functions use additional options to turn the
72     unknown-option warnings into errors, if available, but only at check
73     time. these options are not output in config.mak to avoid the risk of
74     spurious build breakage; if they work, they will have already done
75     their job at configure time.
76
77 commit aeeac9ca5490d7d90fe061ab72da446c01ddf746
78 Author: Rich Felker <dalias@aerifal.cx>
79 Date:   Wed May 27 15:54:47 2015 -0400
80
81     implement fail-safe static locales for newlocale
82     
83     this frees applications which need to make temporary use of the C
84     locale (via uselocale) from the possibility that newlocale might fail.
85     
86     the C.UTF-8 locale is also provided as a static locale. presently they
87     behave the same, but this may change in the future.
88
89 commit 11858d31aa020df3e7e7dedf49f9870ce12f31cc
90 Author: Rich Felker <dalias@aerifal.cx>
91 Date:   Wed May 27 03:32:46 2015 -0400
92
93     rename internal locale file handling locale maps
94     
95     since the __setlocalecat function was removed, the filename
96     __setlocalecat.c no longer made sense.
97
98 commit 61a3364d246e72b903da8b76c2e27a225a51351e
99 Author: Rich Felker <dalias@aerifal.cx>
100 Date:   Wed May 27 03:22:52 2015 -0400
101
102     overhaul locale internals to treat categories roughly uniformly
103     
104     previously, LC_MESSAGES was treated specially as the only category
105     which could be set to a locale name without a definition file, in
106     order to facilitate gettext message translations when no libc locale
107     was available. LC_NUMERIC was completely un-settable, and LC_CTYPE
108     stored a flag intended to be used for a possible future byte-based C
109     locale, instead of storing a __locale_map pointer like the other
110     categories use.
111     
112     this patch changes all categories to be represented by pointers to
113     __locale_map structures, and allows locale names without definition
114     files to be treated as valid locales with trivial definition when used
115     in any category. outwardly visible functional changes should be minor,
116     limited mainly to the strings read back from setlocale and the way
117     gettext handles translations in categories other than LC_MESSAGES.
118     
119     various internal refactoring has also been performed, and improvements
120     in const correctness have been made.
121
122 commit 63c188ec42e76ff768e81f6b65b11c68fc43351e
123 Author: Rich Felker <dalias@aerifal.cx>
124 Date:   Wed May 27 00:22:43 2015 -0400
125
126     replace atomics with locks in locale-setting code
127     
128     this is part of a general program of removing direct use of atomics
129     where they are not necessary to meet correctness or performance needs,
130     but in this case it's also an optimization. only the global locale
131     needs synchronization; allocated locales referenced with locale_t
132     handles are immutable during their lifetimes, and using atomics to
133     initialize them increases their cost of setup.
134
135 commit dc031ee0b1ba11baa00cd7f0769e461a5f396c71
136 Author: Rich Felker <dalias@aerifal.cx>
137 Date:   Tue May 26 03:37:41 2015 -0400
138
139     add rcrt1 start file for fully static-linked PIE
140     
141     static-linked PIE files need startup code to relocate themselves, much
142     like the dynamic linker does. rcrt1.c reuses the code in dlstart.c,
143     stage 1 of the dynamic linker, which in turn reuses crt_arch.h, to
144     achieve static PIE with no new code. only relative relocations are
145     supported.
146     
147     existing toolchains that don't yet support static PIE directly can be
148     repurposed by passing "-shared -Wl,-Bstatic -Wl,-Bsymbolic" instead of
149     "-static -pie" and substituting rcrt1.o in place of crt1.o.
150     
151     all libraries being linked must be built as PIC/PIE; TEXTRELs are not
152     supported at this time.
153
154 commit ed0c8249825161036356a3616e8c5247c15d0927
155 Author: Rich Felker <dalias@aerifal.cx>
156 Date:   Tue May 26 02:31:04 2015 -0400
157
158     fix incorrect application of visibility to Scrt1.o
159     
160     commit de2b67f8d41e08caa56bf6540277f6561edb647f attempted to avoid
161     having vis.h affect crt files, but the Makefile variable used,
162     CRT_LIBS, refers to the final output copies in the lib directory, not
163     the copies in the crt build directory, and thus the -DCRT was not
164     applied.
165     
166     while unlikely to be noticed, this regression probably broke
167     production of PIE executables whose main functions are not in the
168     executable but rather a shared library.
169
170 commit 9bbddf730f7837cf87f4c789fbb41a312e295d6c
171 Author: Rich Felker <dalias@aerifal.cx>
172 Date:   Mon May 25 23:33:59 2015 -0400
173
174     reprocess all libc/ldso symbolic relocations in dynamic linking stage 3
175     
176     commit f3ddd173806fd5c60b3f034528ca24542aecc5b9 introduced early
177     relocations and subsequent reprocessing as part of the dynamic linker
178     bootstrap overhaul, to allow use of arbitrary libc functions before
179     the main application and libraries are loaded, but only reprocessed
180     GOT/PLT relocation types.
181     
182     commit c093e2e8201524db0d638920e76bcb6b1d925f3a added reprocessing of
183     non-GOT/PLT relocations to fix an actual regression that was observed
184     on powerpc, but only for RELA format tables with out-of-line addends.
185     REL table (inline addends at the relocation address) reprocessing is
186     trickier because the first relocation pass clobbers the addends.
187     
188     this patch extends symbolic relocation reprocessing for libc/ldso to
189     support all relocation types, whether REL or RELA format tables are
190     used. it is believed not to alter behavior on any existing archs for
191     the current dynamic linker and libc code. the motivations for this
192     change are consistency and future-proofing. it ensures that behavior
193     does not differ depending on whether REL or RELA tables are used,
194     which could lead to undetected arch-specific bugs. it also ensures
195     that, if in the future code depending on additional relocation types
196     is added to libc.so, either at the source level or as part of the
197     compiler runtime that gets pulled in (for example, soft-float with TLS
198     for fenv), the new code will work properly.
199     
200     the implementation concept is simple: stage 2 of the dynamic linker
201     counts the number of symbolic relocations in the libc/ldso REL table
202     and allocates a VLA to save their addends into; stage 3 then uses the
203     saved addends in place of the inline ones which were clobbered. for
204     stack safety, a hard limit (currently 4k) is imposed on the number of
205     such addends; this should be a couple orders of magnitude larger than
206     the actual need. this number is not a runtime variable that could
207     break fail-safety; it is constant for a given libc.so build.
208
209 commit 768b82c6de24e480267c4c251c440edfc71800e3
210 Author: Rich Felker <dalias@aerifal.cx>
211 Date:   Mon May 25 19:15:17 2015 -0400
212
213     move call to dynamic linker stage-3 into stage-2 function
214     
215     this move eliminates a duplicate "by-hand" symbol lookup loop from the
216     stage-1 code and replaces it with a call to find_sym, which can be
217     used once we're in stage 2. it reduces the size of the stage 1 code,
218     which is helpful because stage 1 will become the crt start file for
219     static-PIE executables, and it will allow stage 3 to access stage 2's
220     automatic storage, which will be important in an upcoming commit.
221
222 commit 967bcbf67c3ffac587de4d79abc1e5e072d83e3e
223 Author: Rich Felker <dalias@aerifal.cx>
224 Date:   Mon May 25 16:02:49 2015 -0400
225
226     mark mips crt code as code
227     
228     otherwise disassemblers treat it as data.
229
230 commit 7b75c4877ddf22f219f944c61d939df1dee4f6d3
231 Author: Rich Felker <dalias@aerifal.cx>
232 Date:   Mon May 25 15:56:36 2015 -0400
233
234     mark mips cancellable syscall code as code
235     
236     otherwise disassemblers treat it as data.
237
238 commit 0e0e49421f08cfd670975ecd3604f7f9015e1833
239 Author: Rich Felker <dalias@aerifal.cx>
240 Date:   Mon May 25 00:32:37 2015 -0400
241
242     simplify/shrink relocation processing in dynamic linker stage 1
243     
244     the outer-loop approach made sense when we were also processing
245     DT_JMPREL, which might be in REL or RELA form, to avoid major code
246     duplication. commit 09db855b35709aa627d7055c57a98e1e471920ab removed
247     processing of DT_JMPREL, and in the remaining two tables, the format
248     (REL or RELA) is known by the name of the table. simply writing two
249     versions of the loop results in smaller and simpler code.
250
251 commit 09db855b35709aa627d7055c57a98e1e471920ab
252 Author: Rich Felker <dalias@aerifal.cx>
253 Date:   Mon May 25 00:25:56 2015 -0400
254
255     remove processing of DT_JMPREL from dynamic linker stage 1 bootstrap
256     
257     the DT_JMPREL relocation table necessarily consists entirely of
258     JMP_SLOT (REL_PLT in internal nomenclature) relocations, which are
259     symbolic; they cannot be resolved in stage 1, so there is no point in
260     processing them.
261
262 commit 9f26ebded188ed78c3571a4ca1477dd6351bc647
263 Author: Rich Felker <dalias@aerifal.cx>
264 Date:   Sun May 24 23:03:47 2015 -0400
265
266     fix stack alignment code in mips crt_arch.h
267     
268     the instruction used to align the stack, "and $sp, $sp, -8", does not
269     actually exist; it's expanded to 2 instructions using the 'at'
270     (assembler temporary) register, and thus cannot be used in a branch
271     delay slot. since alignment mod 16 commutes with subtracting 8, simply
272     swapping these two operations fixes the problem.
273     
274     crt1.o was not affected because it's still being generated from a
275     dedicated asm source file. dlstart.lo was not affected because the
276     stack pointer it receives is already aligned by the kernel. but
277     Scrt1.o was affected in cases where the dynamic linker gave it a
278     misaligned stack pointer.
279
280 commit 63caf1d207d143fe405bbe0cda9aac8deca1171a
281 Author: Rich Felker <dalias@aerifal.cx>
282 Date:   Fri May 22 01:50:05 2015 -0400
283
284     add .text section directive to all crt_arch.h files missing it
285     
286     i386 and x86_64 versions already had the .text directive; other archs
287     did not. normally, top-level (file scope) __asm__ starts in the .text
288     section anyway, but problems were reported with some versions of
289     clang, and it seems preferable to set it explicitly anyway, at least
290     for the sake of consistency between archs.
291
292 commit 3b0e83264d156f9e496ab32badd89e4447b807aa
293 Author: Rich Felker <dalias@aerifal.cx>
294 Date:   Thu May 21 17:06:28 2015 -0400
295
296     remove outdated and misleading comment in iconv.c
297     
298     the comment claimed that EUC/GBK/Big5 are not implemented, which has
299     been incorrect since commit 19b4a0a20efc6b9df98b6a43536ecdd628ba4643.
300
301 commit 39b8ce66f2ed9c17427ec3a48be9bda29b93b9d7
302 Author: Rich Felker <dalias@aerifal.cx>
303 Date:   Thu May 21 17:01:23 2015 -0400
304
305     in iconv_open, accept "CHAR" and "" as aliases for "UTF-8"
306     
307     while not a requirement, it's common convention in other iconv
308     implementations to accept "CHAR" as an alias for nl_langinfo(CODESET),
309     meaning the encoding used for char[] strings in the current locale,
310     and also "" as an alternate form. supporting this is not costly and
311     improves compatibility.
312
313 commit c648cefb27984db60474ec1747cbfde83c2856d0
314 Author: Rich Felker <dalias@aerifal.cx>
315 Date:   Wed May 20 00:17:35 2015 -0400
316
317     fix inconsistency in a_and and a_or argument types on x86[_64]
318     
319     conceptually, and on other archs, these functions take a pointer to
320     int, but in the i386, x86_64, and x32 versions of atomic.h, they took
321     a pointer to void instead.
322
323 commit 390f93ef69153bf2087fcf3baa1776ad9a6765ab
324 Author: Bobby Bingham <koorogi@koorogi.info>
325 Date:   Sun May 17 13:46:38 2015 -0500
326
327     inline llsc atomics when building for sh4a
328     
329     If we're building for sh4a, the compiler is already free to use
330     instructions only available on sh4a, so we can do the same and inline the
331     llsc atomics. If we're building for an older processor, we still do the
332     same runtime atomics selection as before.
333
334 commit c093e2e8201524db0d638920e76bcb6b1d925f3a
335 Author: Rich Felker <dalias@aerifal.cx>
336 Date:   Mon May 18 16:51:54 2015 -0400
337
338     reprocess libc/ldso RELA relocations in stage 3 of dynamic linking
339     
340     this fixes a regression on powerpc that was introduced in commit
341     f3ddd173806fd5c60b3f034528ca24542aecc5b9. global data accesses on
342     powerpc seem to be using a translation-unit-local GOT filled via
343     R_PPC_ADDR32 relocations rather than R_PPC_GLOB_DAT. being a non-GOT
344     relocation type, these were not reprocessed after adding the main
345     application and its libraries to the chain, causing libc code not to
346     see copy relocations in the main program, and therefore to use the
347     pre-copy-relocation addresses for global data objects (like environ).
348     
349     the motivation for the dynamic linker only reprocessing GOT/PLT
350     relocation types in stage 3 is that these types always have a zero
351     addend, making them safe to process again even if the storage for the
352     addend has been clobbered. other relocation types which can be used
353     for address constants in initialized data objects may have non-zero
354     addends which will be clobbered during the first pass of relocation
355     processing if they're stored inline (REL form) rather than out-of-line
356     (RELA form).
357     
358     powerpc generally uses only RELA, so this patch is sufficient to fix
359     the regression in practice, but is not fully general, and would not
360     suffice if an alternate toolchain generated REL for powerpc.
361
362 commit 43e9f652bf4b2195b04fc14c93db591b30a7b790
363 Author: Rich Felker <dalias@aerifal.cx>
364 Date:   Mon May 18 12:11:25 2015 -0400
365
366     fix null pointer dereference in dcngettext under specific conditions
367     
368     if setlocale has not been called, the current locale's messages_name
369     may be a null pointer. the code path where it's assumed to be non-null
370     was only reachable if bindtextdomain had already been called, which is
371     normally not done in programs which do not call setlocale, so the
372     omitted check went unnoticed.
373     
374     patch from Void Linux, with description rewritten.
375
376 commit 68630b55c0c7219fe9df70dc28ffbf9efc8021d8
377 Author: Rich Felker <dalias@aerifal.cx>
378 Date:   Sat May 16 01:53:54 2015 -0400
379
380     eliminate costly tricks to avoid TLS access for current locale state
381     
382     the code being removed used atomics to track whether any threads might
383     be using a locale other than the current global locale, and whether
384     any threads might have abstract 8-bit (non-UTF-8) LC_CTYPE active, a
385     feature which was never committed (still pending). the motivations
386     were to support early execution prior to setup of the thread pointer,
387     to partially support systems (ancient kernels) where thread pointer
388     setup is not possible, and to avoid high performance cost on archs
389     where accessing the thread pointer may be very slow.
390     
391     since commit 19a1fe670acb3ab9ead0fe31859ca7d4fe40dd54, the thread
392     pointer is always available, so these hacks are no longer needed.
393     removing them greatly simplifies the affected code.
394
395 commit 707d7c30f3379441de9b320536ddfd354f4c2143
396 Author: Rich Felker <dalias@aerifal.cx>
397 Date:   Sat May 16 01:15:40 2015 -0400
398
399     in i386 __set_thread_area, don't assume %gs register is initially zero
400     
401     commit f630df09b1fd954eda16e2f779da0b5ecc9d80d3 added logic to handle
402     the case where __set_thread_area is called more than once by reusing
403     the GDT slot already in the %gs register, and only setting up a new
404     GDT slot when %gs is zero. this created a hidden assumption that %gs
405     is zero when a new process image starts, which is true in practice on
406     Linux, but does not seem to be documented ABI, and fails to hold under
407     qemu app-level emulation.
408     
409     while it would in theory be possible to zero %gs in the entry point
410     code, this code is shared between static and dynamic binaries, and
411     dynamic binaries must not clobber the value of %gs already setup by
412     the dynamic linker.
413     
414     the alternative solution implemented in this commit simply uses global
415     data to store the GDT index that's selected. __set_thread_area should
416     only be called in the initial thread anyway (subsequent threads get
417     their thread pointer setup by __clone), but even if it were called by
418     another thread, it would simply read and write back the same GDT index
419     that was already assigned to the initial thread, and thus (in the x86
420     memory model) there is no data race.
421
422 commit c0f10cf06725bd0de37f3ced7954a653bf9f1049
423 Author: Rich Felker <dalias@aerifal.cx>
424 Date:   Thu May 14 18:51:27 2015 -0400
425
426     make arm reloc.h CRTJMP macro compatible with thumb
427     
428     compilers targeting armv7 may be configured to produce thumb2 code
429     instead of arm code by default, and in the future we may wish to
430     support targets where only the thumb instruction set is available.
431     
432     the instructions this patch omits in thumb mode are needed only for
433     non-thumb versions of armv4 or earlier, which are not supported by any
434     current compilers/toolchains and thus rather pointless to have. at
435     some point these compatibility return sequences may be removed from
436     all asm source files, and in that case it would make sense to remove
437     them here too and remove the ifdef.
438
439 commit 83340c7a580e91b22f58321b7cf6d976af61084c
440 Author: Rich Felker <dalias@aerifal.cx>
441 Date:   Thu May 14 18:26:16 2015 -0400
442
443     make arm crt_arch.h compatible with thumb code generation
444     
445     compilers targeting armv7 may be configured to produce thumb2 code
446     instead of arm code by default, and in the future we may wish to
447     support targets where only the thumb instruction set is available.
448     
449     the changes made here avoid operating directly on the sp register,
450     which is not possible in thumb code, and address an issue with the way
451     the address of _DYNAMIC is computed.
452     
453     previously, the relative address of _DYNAMIC was stored with an
454     additional offset of -8 versus the pc-relative add instruction, since
455     on arm the pc register evaluates to ".+8". in thumb code, it instead
456     evaluates to ".+4". both are two (normal-size) instructions beyond "."
457     in the current execution mode, so the numbered label 2 used in the
458     relative address expression is simply moved two instructions ahead to
459     be compatible with both instruction sets.
460
461 --- a/Makefile
462 +++ b/Makefile
463 @@ -44,7 +44,7 @@ ALL_INCLUDES = $(sort $(wildcard include
464  
465  EMPTY_LIB_NAMES = m rt pthread crypt util xnet resolv dl
466  EMPTY_LIBS = $(EMPTY_LIB_NAMES:%=lib/lib%.a)
467 -CRT_LIBS = lib/crt1.o lib/Scrt1.o lib/crti.o lib/crtn.o
468 +CRT_LIBS = lib/crt1.o lib/Scrt1.o lib/rcrt1.o lib/crti.o lib/crtn.o
469  STATIC_LIBS = lib/libc.a
470  SHARED_LIBS = lib/libc.so
471  TOOL_LIBS = lib/musl-gcc.specs
472 @@ -85,11 +85,13 @@ src/internal/version.h: $(wildcard VERSI
473  
474  src/internal/version.lo: src/internal/version.h
475  
476 -src/ldso/dlstart.lo src/ldso/dynlink.lo: src/internal/dynlink.h arch/$(ARCH)/reloc.h
477 +crt/rcrt1.o src/ldso/dlstart.lo src/ldso/dynlink.lo: src/internal/dynlink.h arch/$(ARCH)/reloc.h
478  
479 -crt/crt1.o crt/Scrt1.o src/ldso/dlstart.lo: $(wildcard arch/$(ARCH)/crt_arch.h)
480 +crt/crt1.o crt/Scrt1.o crt/rcrt1.o src/ldso/dlstart.lo: $(wildcard arch/$(ARCH)/crt_arch.h)
481  
482 -crt/Scrt1.o: CFLAGS += -fPIC
483 +crt/rcrt1.o: src/ldso/dlstart.c
484 +
485 +crt/Scrt1.o crt/rcrt1.o: CFLAGS += -fPIC
486  
487  OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=src/%))
488  $(OPTIMIZE_SRCS:%.c=%.o) $(OPTIMIZE_SRCS:%.c=%.lo): CFLAGS += -O3
489 @@ -104,7 +106,7 @@ NOSSP_SRCS = $(wildcard crt/*.c) \
490         src/ldso/dlstart.c src/ldso/dynlink.c
491  $(NOSSP_SRCS:%.c=%.o) $(NOSSP_SRCS:%.c=%.lo): CFLAGS += $(CFLAGS_NOSSP)
492  
493 -$(CRT_LIBS): CFLAGS += -DCRT
494 +$(CRT_LIBS:lib/%=crt/%): CFLAGS += -DCRT
495  
496  # This incantation ensures that changes to any subarch asm files will
497  # force the corresponding object file to be rebuilt, even if the implicit
498 --- a/arch/aarch64/crt_arch.h
499 +++ b/arch/aarch64/crt_arch.h
500 @@ -1,4 +1,5 @@
501  __asm__(
502 +".text \n"
503  ".global " START "\n"
504  ".type " START ",%function\n"
505  START ":\n"
506 --- a/arch/arm/crt_arch.h
507 +++ b/arch/arm/crt_arch.h
508 @@ -1,15 +1,18 @@
509  __asm__(
510 +".text \n"
511  ".global " START " \n"
512  ".type " START ",%function \n"
513  START ": \n"
514  "      mov fp, #0 \n"
515  "      mov lr, #0 \n"
516 -"      mov a1, sp \n"
517  "      ldr a2, 1f \n"
518 -"2:    add a2, pc, a2 \n"
519 -"      and sp, sp, #-16 \n"
520 +"      add a2, pc, a2 \n"
521 +"      mov a1, sp \n"
522 +"2:    and ip, a1, #-16 \n"
523 +"      mov sp, ip \n"
524  "      bl " START "_c \n"
525  ".weak _DYNAMIC \n"
526  ".hidden _DYNAMIC \n"
527 -"1:    .word _DYNAMIC-2b-8 \n"
528 +".align 2 \n"
529 +"1:    .word _DYNAMIC-2b \n"
530  );
531 --- a/arch/arm/reloc.h
532 +++ b/arch/arm/reloc.h
533 @@ -28,5 +28,10 @@
534  #define REL_TPOFF       R_ARM_TLS_TPOFF32
535  //#define REL_TLSDESC     R_ARM_TLS_DESC
536  
537 +#ifdef __thumb__
538 +#define CRTJMP(pc,sp) __asm__ __volatile__( \
539 +       "mov sp,%1 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
540 +#else
541  #define CRTJMP(pc,sp) __asm__ __volatile__( \
542         "mov sp,%1 ; tst %0,#1 ; moveq pc,%0 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
543 +#endif
544 --- a/arch/i386/atomic.h
545 +++ b/arch/i386/atomic.h
546 @@ -50,16 +50,16 @@ static inline int a_cas(volatile int *p,
547         return t;
548  }
549  
550 -static inline void a_or(volatile void *p, int v)
551 +static inline void a_or(volatile int *p, int v)
552  {
553         __asm__( "lock ; orl %1, %0"
554 -               : "=m"(*(int *)p) : "r"(v) : "memory" );
555 +               : "=m"(*p) : "r"(v) : "memory" );
556  }
557  
558 -static inline void a_and(volatile void *p, int v)
559 +static inline void a_and(volatile int *p, int v)
560  {
561         __asm__( "lock ; andl %1, %0"
562 -               : "=m"(*(int *)p) : "r"(v) : "memory" );
563 +               : "=m"(*p) : "r"(v) : "memory" );
564  }
565  
566  static inline int a_swap(volatile int *x, int v)
567 --- a/arch/microblaze/crt_arch.h
568 +++ b/arch/microblaze/crt_arch.h
569 @@ -1,4 +1,5 @@
570  __asm__(
571 +".text \n"
572  ".global " START " \n"
573  ".align  2 \n"
574  START ": \n"
575 --- a/arch/mips/crt_arch.h
576 +++ b/arch/mips/crt_arch.h
577 @@ -1,6 +1,7 @@
578  __asm__(
579  ".set push\n"
580  ".set noreorder\n"
581 +".text \n"
582  ".global _" START "\n"
583  ".global " START "\n"
584  ".type   _" START ", @function\n"
585 @@ -21,8 +22,8 @@ __asm__(
586  "      addu $5, $5, $gp \n"
587  "      lw $25, 4($ra) \n"
588  "      addu $25, $25, $gp \n"
589 -"      subu $sp, $sp, 16 \n"
590 +"      and $sp, $sp, -8 \n"
591  "      jalr $25 \n"
592 -"       and $sp, $sp, -8 \n"
593 +"       subu $sp, $sp, 16 \n"
594  ".set pop \n"
595  );
596 --- a/arch/or1k/crt_arch.h
597 +++ b/arch/or1k/crt_arch.h
598 @@ -1,4 +1,5 @@
599  __asm__(
600 +".text \n"
601  ".global " START " \n"
602  ".align  4 \n"
603  START ": \n"
604 --- a/arch/powerpc/crt_arch.h
605 +++ b/arch/powerpc/crt_arch.h
606 @@ -1,4 +1,5 @@
607  __asm__(
608 +".text \n"
609  ".global " START " \n"
610  ".type   " START ", %function \n"
611  START ": \n"
612 --- a/arch/sh/atomic.h
613 +++ b/arch/sh/atomic.h
614 @@ -22,6 +22,88 @@ static inline int a_ctz_64(uint64_t x)
615         return a_ctz_l(y);
616  }
617  
618 +#define LLSC_CLOBBERS "r0", "t", "memory"
619 +#define LLSC_START(mem) "synco\n"  \
620 +       "0:     movli.l @" mem ", r0\n"
621 +#define LLSC_END(mem)              \
622 +       "1:     movco.l r0, @" mem "\n"    \
623 +       "       bf 0b\n"                   \
624 +       "       synco\n"
625 +
626 +static inline int __sh_cas_llsc(volatile int *p, int t, int s)
627 +{
628 +       int old;
629 +       __asm__ __volatile__(
630 +               LLSC_START("%1")
631 +               "       mov r0, %0\n"
632 +               "       cmp/eq %0, %2\n"
633 +               "       bf 1f\n"
634 +               "       mov %3, r0\n"
635 +               LLSC_END("%1")
636 +               : "=&r"(old) : "r"(p), "r"(t), "r"(s) : LLSC_CLOBBERS);
637 +       return old;
638 +}
639 +
640 +static inline int __sh_swap_llsc(volatile int *x, int v)
641 +{
642 +       int old;
643 +       __asm__ __volatile__(
644 +               LLSC_START("%1")
645 +               "       mov r0, %0\n"
646 +               "       mov %2, r0\n"
647 +               LLSC_END("%1")
648 +               : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
649 +       return old;
650 +}
651 +
652 +static inline int __sh_fetch_add_llsc(volatile int *x, int v)
653 +{
654 +       int old;
655 +       __asm__ __volatile__(
656 +               LLSC_START("%1")
657 +               "       mov r0, %0\n"
658 +               "       add %2, r0\n"
659 +               LLSC_END("%1")
660 +               : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
661 +       return old;
662 +}
663 +
664 +static inline void __sh_store_llsc(volatile int *p, int x)
665 +{
666 +       __asm__ __volatile__(
667 +               "       synco\n"
668 +               "       mov.l %1, @%0\n"
669 +               "       synco\n"
670 +               : : "r"(p), "r"(x) : "memory");
671 +}
672 +
673 +static inline void __sh_and_llsc(volatile int *x, int v)
674 +{
675 +       __asm__ __volatile__(
676 +               LLSC_START("%0")
677 +               "       and %1, r0\n"
678 +               LLSC_END("%0")
679 +               : : "r"(x), "r"(v) : LLSC_CLOBBERS);
680 +}
681 +
682 +static inline void __sh_or_llsc(volatile int *x, int v)
683 +{
684 +       __asm__ __volatile__(
685 +               LLSC_START("%0")
686 +               "       or %1, r0\n"
687 +               LLSC_END("%0")
688 +               : : "r"(x), "r"(v) : LLSC_CLOBBERS);
689 +}
690 +
691 +#ifdef __SH4A__
692 +#define a_cas(p,t,s)     __sh_cas_llsc(p,t,s)
693 +#define a_swap(x,v)      __sh_swap_llsc(x,v)
694 +#define a_fetch_add(x,v) __sh_fetch_add_llsc(x, v)
695 +#define a_store(x,v)     __sh_store_llsc(x, v)
696 +#define a_and(x,v)       __sh_and_llsc(x, v)
697 +#define a_or(x,v)        __sh_or_llsc(x, v)
698 +#else
699 +
700  int  __sh_cas(volatile int *, int, int);
701  int  __sh_swap(volatile int *, int);
702  int  __sh_fetch_add(volatile int *, int);
703 @@ -35,6 +117,7 @@ void __sh_or(volatile int *, int);
704  #define a_store(x,v)     __sh_store(x, v)
705  #define a_and(x,v)       __sh_and(x, v)
706  #define a_or(x,v)        __sh_or(x, v)
707 +#endif
708  
709  static inline void *a_cas_p(volatile void *p, void *t, void *s)
710  {
711 --- a/arch/sh/crt_arch.h
712 +++ b/arch/sh/crt_arch.h
713 @@ -1,4 +1,5 @@
714  __asm__(
715 +".text \n"
716  ".global " START " \n"
717  START ": \n"
718  "      mova 1f, r0 \n"
719 --- a/arch/sh/src/atomic.c
720 +++ b/arch/sh/src/atomic.c
721 @@ -1,12 +1,7 @@
722 -#include "libc.h"
723 +#ifndef __SH4A__
724  
725 -#define LLSC_CLOBBERS   "r0", "t", "memory"
726 -#define LLSC_START(mem) "synco\n"  \
727 -       "0:     movli.l @" mem ", r0\n"
728 -#define LLSC_END(mem)              \
729 -       "1:     movco.l r0, @" mem "\n"    \
730 -       "       bf 0b\n"                   \
731 -       "       synco\n"
732 +#include "atomic.h"
733 +#include "libc.h"
734  
735  /* gusa is a hack in the kernel which lets you create a sequence of instructions
736   * which will be restarted if the process is preempted in the middle of the
737 @@ -34,114 +29,74 @@
738  
739  int __sh_cas(volatile int *p, int t, int s)
740  {
741 +       if (__hwcap & CPU_HAS_LLSC) return __sh_cas_llsc(p, t, s);
742 +
743         int old;
744 -       if (__hwcap & CPU_HAS_LLSC) {
745 -               __asm__ __volatile__(
746 -                       LLSC_START("%1")
747 -                       "       mov r0, %0\n"
748 -                       "       cmp/eq %0, %2\n"
749 -                       "       bf 1f\n"
750 -                       "       mov %3, r0\n"
751 -                       LLSC_END("%1")
752 -                       : "=&r"(old) : "r"(p), "r"(t), "r"(s) : LLSC_CLOBBERS);
753 -       } else {
754 -               __asm__ __volatile__(
755 -                       GUSA_START_EVEN("%1", "%0")
756 -                       "       cmp/eq %0, %2\n"
757 -                       "       bf 1f\n"
758 -                       GUSA_END("%1", "%3")
759 -                       : "=&r"(old) : "r"(p), "r"(t), "r"(s) : GUSA_CLOBBERS, "t");
760 -       }
761 +       __asm__ __volatile__(
762 +               GUSA_START_EVEN("%1", "%0")
763 +               "       cmp/eq %0, %2\n"
764 +               "       bf 1f\n"
765 +               GUSA_END("%1", "%3")
766 +               : "=&r"(old) : "r"(p), "r"(t), "r"(s) : GUSA_CLOBBERS, "t");
767         return old;
768  }
769  
770  int __sh_swap(volatile int *x, int v)
771  {
772 +       if (__hwcap & CPU_HAS_LLSC) return __sh_swap_llsc(x, v);
773 +
774         int old;
775 -       if (__hwcap & CPU_HAS_LLSC) {
776 -               __asm__ __volatile__(
777 -                       LLSC_START("%1")
778 -                       "       mov r0, %0\n"
779 -                       "       mov %2, r0\n"
780 -                       LLSC_END("%1")
781 -                       : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
782 -       } else {
783 -               __asm__ __volatile__(
784 -                       GUSA_START_EVEN("%1", "%0")
785 -                       GUSA_END("%1", "%2")
786 -                       : "=&r"(old) : "r"(x), "r"(v) : GUSA_CLOBBERS);
787 -       }
788 +       __asm__ __volatile__(
789 +               GUSA_START_EVEN("%1", "%0")
790 +               GUSA_END("%1", "%2")
791 +               : "=&r"(old) : "r"(x), "r"(v) : GUSA_CLOBBERS);
792         return old;
793  }
794  
795  int __sh_fetch_add(volatile int *x, int v)
796  {
797 +       if (__hwcap & CPU_HAS_LLSC) return __sh_fetch_add_llsc(x, v);
798 +
799         int old, dummy;
800 -       if (__hwcap & CPU_HAS_LLSC) {
801 -               __asm__ __volatile__(
802 -                       LLSC_START("%1")
803 -                       "       mov r0, %0\n"
804 -                       "       add %2, r0\n"
805 -                       LLSC_END("%1")
806 -                       : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
807 -       } else {
808 -               __asm__ __volatile__(
809 -                       GUSA_START_EVEN("%2", "%0")
810 -                       "       mov %0, %1\n"
811 -                       "       add %3, %1\n"
812 -                       GUSA_END("%2", "%1")
813 -                       : "=&r"(old), "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
814 -       }
815 +       __asm__ __volatile__(
816 +               GUSA_START_EVEN("%2", "%0")
817 +               "       mov %0, %1\n"
818 +               "       add %3, %1\n"
819 +               GUSA_END("%2", "%1")
820 +               : "=&r"(old), "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
821         return old;
822  }
823  
824  void __sh_store(volatile int *p, int x)
825  {
826 -       if (__hwcap & CPU_HAS_LLSC) {
827 -               __asm__ __volatile__(
828 -                       "       synco\n"
829 -                       "       mov.l %1, @%0\n"
830 -                       "       synco\n"
831 -                       : : "r"(p), "r"(x) : "memory");
832 -       } else {
833 -               __asm__ __volatile__(
834 -                       "       mov.l %1, @%0\n"
835 -                       : : "r"(p), "r"(x) : "memory");
836 -       }
837 +       if (__hwcap & CPU_HAS_LLSC) return __sh_store_llsc(p, x);
838 +       __asm__ __volatile__(
839 +               "       mov.l %1, @%0\n"
840 +               : : "r"(p), "r"(x) : "memory");
841  }
842  
843  void __sh_and(volatile int *x, int v)
844  {
845 +       if (__hwcap & CPU_HAS_LLSC) return __sh_and_llsc(x, v);
846 +
847         int dummy;
848 -       if (__hwcap & CPU_HAS_LLSC) {
849 -               __asm__ __volatile__(
850 -                       LLSC_START("%0")
851 -                       "       and %1, r0\n"
852 -                       LLSC_END("%0")
853 -                       : : "r"(x), "r"(v) : LLSC_CLOBBERS);
854 -       } else {
855 -               __asm__ __volatile__(
856 -                       GUSA_START_ODD("%1", "%0")
857 -                       "       and %2, %0\n"
858 -                       GUSA_END("%1", "%0")
859 -                       : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
860 -       }
861 +       __asm__ __volatile__(
862 +               GUSA_START_ODD("%1", "%0")
863 +               "       and %2, %0\n"
864 +               GUSA_END("%1", "%0")
865 +               : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
866  }
867  
868  void __sh_or(volatile int *x, int v)
869  {
870 +       if (__hwcap & CPU_HAS_LLSC) return __sh_or_llsc(x, v);
871 +
872         int dummy;
873 -       if (__hwcap & CPU_HAS_LLSC) {
874 -               __asm__ __volatile__(
875 -                       LLSC_START("%0")
876 -                       "       or %1, r0\n"
877 -                       LLSC_END("%0")
878 -                       : : "r"(x), "r"(v) : LLSC_CLOBBERS);
879 -       } else {
880 -               __asm__ __volatile__(
881 -                       GUSA_START_ODD("%1", "%0")
882 -                       "       or %2, %0\n"
883 -                       GUSA_END("%1", "%0")
884 -                       : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
885 -       }
886 +       __asm__ __volatile__(
887 +               GUSA_START_ODD("%1", "%0")
888 +               "       or %2, %0\n"
889 +               GUSA_END("%1", "%0")
890 +               : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
891  }
892 +
893 +#endif
894 --- a/arch/x32/atomic.h
895 +++ b/arch/x32/atomic.h
896 @@ -47,16 +47,16 @@ static inline int a_cas(volatile int *p,
897         return t;
898  }
899  
900 -static inline void a_or(volatile void *p, int v)
901 +static inline void a_or(volatile int *p, int v)
902  {
903         __asm__( "lock ; or %1, %0"
904 -               : "=m"(*(int *)p) : "r"(v) : "memory" );
905 +               : "=m"(*p) : "r"(v) : "memory" );
906  }
907  
908 -static inline void a_and(volatile void *p, int v)
909 +static inline void a_and(volatile int *p, int v)
910  {
911         __asm__( "lock ; and %1, %0"
912 -               : "=m"(*(int *)p) : "r"(v) : "memory" );
913 +               : "=m"(*p) : "r"(v) : "memory" );
914  }
915  
916  static inline int a_swap(volatile int *x, int v)
917 --- a/arch/x86_64/atomic.h
918 +++ b/arch/x86_64/atomic.h
919 @@ -47,16 +47,16 @@ static inline int a_cas(volatile int *p,
920         return t;
921  }
922  
923 -static inline void a_or(volatile void *p, int v)
924 +static inline void a_or(volatile int *p, int v)
925  {
926         __asm__( "lock ; or %1, %0"
927 -               : "=m"(*(int *)p) : "r"(v) : "memory" );
928 +               : "=m"(*p) : "r"(v) : "memory" );
929  }
930  
931 -static inline void a_and(volatile void *p, int v)
932 +static inline void a_and(volatile int *p, int v)
933  {
934         __asm__( "lock ; and %1, %0"
935 -               : "=m"(*(int *)p) : "r"(v) : "memory" );
936 +               : "=m"(*p) : "r"(v) : "memory" );
937  }
938  
939  static inline int a_swap(volatile int *x, int v)
940 --- a/configure
941 +++ b/configure
942 @@ -80,7 +80,7 @@ fi
943  tryflag () {
944  printf "checking whether compiler accepts %s... " "$2"
945  echo "typedef int x;" > "$tmpc"
946 -if $CC $2 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
947 +if $CC $CFLAGS_TRY $2 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
948  printf "yes\n"
949  eval "$1=\"\${$1} \$2\""
950  eval "$1=\${$1# }"
951 @@ -94,7 +94,7 @@ fi
952  tryldflag () {
953  printf "checking whether linker accepts %s... " "$2"
954  echo "typedef int x;" > "$tmpc"
955 -if $CC -nostdlib -shared "$2" -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
956 +if $CC $LDFLAGS_TRY -nostdlib -shared "$2" -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
957  printf "yes\n"
958  eval "$1=\"\${$1} \$2\""
959  eval "$1=\${$1# }"
960 @@ -113,7 +113,9 @@ CFLAGS_C99FSE=
961  CFLAGS_AUTO=
962  CFLAGS_MEMOPS=
963  CFLAGS_NOSSP=
964 +CFLAGS_TRY=
965  LDFLAGS_AUTO=
966 +LDFLAGS_TRY=
967  OPTIMIZE_GLOBS=
968  prefix=/usr/local/musl
969  exec_prefix='$(prefix)'
970 @@ -205,6 +207,14 @@ exit 1
971  fi
972  
973  #
974 +# Figure out options to force errors on unknown flags.
975 +#
976 +tryflag   CFLAGS_TRY  -Werror=unknown-warning-option
977 +tryflag   CFLAGS_TRY  -Werror=unused-command-line-argument
978 +tryldflag LDFLAGS_TRY -Werror=unknown-warning-option
979 +tryldflag LDFLAGS_TRY -Werror=unused-command-line-argument
980 +
981 +#
982  # Need to know if the compiler is gcc to decide whether to build the
983  # musl-gcc wrapper, and for critical bug detection in some gcc versions.
984  #
985 --- a/crt/mips/crt1.s
986 +++ b/crt/mips/crt1.s
987 @@ -4,6 +4,8 @@
988  .weak  _fini
989  .global __start
990  .global _start
991 +.type __start,@function
992 +.type _start,@function
993  __start:
994  _start:
995         subu    $fp, $fp, $fp            # Zero the frame pointer.
996 --- a/crt/mips/crti.s
997 +++ b/crt/mips/crti.s
998 @@ -2,6 +2,7 @@
999  
1000  .section .init
1001  .global _init
1002 +.type _init,@function
1003  .align 2
1004  _init:
1005         subu $sp,$sp,32
1006 @@ -10,6 +11,7 @@ _init:
1007  
1008  .section .fini
1009  .global _fini
1010 +.type _fini,@function
1011  .align 2
1012  _fini:
1013         subu $sp,$sp,32
1014 --- /dev/null
1015 +++ b/crt/rcrt1.c
1016 @@ -0,0 +1,15 @@
1017 +#define SHARED
1018 +#define START "_start"
1019 +#define _dlstart_c _start_c
1020 +#include "../src/ldso/dlstart.c"
1021 +
1022 +int main();
1023 +void _init() __attribute__((weak));
1024 +void _fini() __attribute__((weak));
1025 +_Noreturn int __libc_start_main(int (*)(), int, char **,
1026 +       void (*)(), void(*)(), void(*)());
1027 +
1028 +_Noreturn void __dls2(unsigned char *base, size_t *sp)
1029 +{
1030 +       __libc_start_main(main, *sp, (void *)(sp+1), _init, _fini, 0);
1031 +}
1032 --- a/include/sys/resource.h
1033 +++ b/include/sys/resource.h
1034 @@ -96,6 +96,9 @@ int prlimit(pid_t, int, const struct rli
1035  #define RLIM_NLIMITS RLIMIT_NLIMITS
1036  
1037  #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
1038 +#define RLIM64_INFINITY RLIM_INFINITY
1039 +#define RLIM64_SAVED_CUR RLIM_SAVED_CUR
1040 +#define RLIM64_SAVED_MAX RLIM_SAVED_MAX
1041  #define getrlimit64 getrlimit
1042  #define setrlimit64 setrlimit
1043  #define rlimit64 rlimit
1044 --- a/src/internal/dynlink.h
1045 +++ b/src/internal/dynlink.h
1046 @@ -51,7 +51,7 @@ enum {
1047  #define AUX_CNT 32
1048  #define DYN_CNT 32
1049  
1050 -typedef void (*stage2_func)(unsigned char *);
1051 +typedef void (*stage2_func)(unsigned char *, size_t *);
1052  typedef _Noreturn void (*stage3_func)(size_t *);
1053  
1054  #endif
1055 --- a/src/internal/libc.h
1056 +++ b/src/internal/libc.h
1057 @@ -8,9 +8,7 @@
1058  struct __locale_map;
1059  
1060  struct __locale_struct {
1061 -       volatile int ctype_utf8;
1062 -       char *messages_name;
1063 -       struct __locale_map *volatile cat[4];
1064 +       const struct __locale_map *volatile cat[6];
1065  };
1066  
1067  struct __libc {
1068 @@ -23,8 +21,6 @@ struct __libc {
1069         volatile int ofl_lock[2];
1070         size_t tls_size;
1071         size_t page_size;
1072 -       volatile int uselocale_cnt;
1073 -       volatile int bytelocale_cnt_minus_1;
1074         struct __locale_struct global_locale;
1075  };
1076  
1077 --- a/src/internal/locale_impl.h
1078 +++ b/src/internal/locale_impl.h
1079 @@ -9,22 +9,20 @@ struct __locale_map {
1080         const void *map;
1081         size_t map_size;
1082         char name[LOCALE_NAME_MAX+1];
1083 -       struct __locale_map *next;
1084 +       const struct __locale_map *next;
1085  };
1086  
1087 -int __setlocalecat(locale_t, int, const char *);
1088 +const struct __locale_map *__get_locale(int, const char *);
1089  const char *__mo_lookup(const void *, size_t, const char *);
1090  const char *__lctrans(const char *, const struct __locale_map *);
1091  const char *__lctrans_cur(const char *);
1092  
1093 -#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)-2])
1094 +#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])
1095  #define LCTRANS_CUR(msg) __lctrans_cur(msg)
1096  
1097 -#define CURRENT_LOCALE \
1098 -       (libc.uselocale_cnt ? __pthread_self()->locale : &libc.global_locale)
1099 +#define CURRENT_LOCALE (__pthread_self()->locale)
1100  
1101 -#define CURRENT_UTF8 \
1102 -       (libc.bytelocale_cnt_minus_1<0 || __pthread_self()->locale->ctype_utf8)
1103 +#define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
1104  
1105  #undef MB_CUR_MAX
1106  #define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
1107 --- a/src/ldso/dlstart.c
1108 +++ b/src/ldso/dlstart.c
1109 @@ -56,31 +56,22 @@ void _dlstart_c(size_t *sp, size_t *dynv
1110                 for (i=0; i<local_cnt; i++) got[i] += (size_t)base;
1111         }
1112  
1113 -       /* The use of the reloc_info structure and nested loops is a trick
1114 -        * to work around the fact that we can't necessarily make function
1115 -        * calls yet. Each struct in the array serves like the arguments
1116 -        * to a function call. */
1117 -       struct {
1118 -               void *rel;
1119 -               size_t size;
1120 -               size_t stride;
1121 -       } reloc_info[] = {
1122 -               { base+dyn[DT_JMPREL], dyn[DT_PLTRELSZ], 2+(dyn[DT_PLTREL]==DT_RELA) },
1123 -               { base+dyn[DT_REL], dyn[DT_RELSZ], 2 },
1124 -               { base+dyn[DT_RELA], dyn[DT_RELASZ], 3 },
1125 -               { 0, 0, 0 }
1126 -       };
1127 -
1128 -       for (i=0; reloc_info[i].stride; i++) {
1129 -               size_t *rel = reloc_info[i].rel;
1130 -               size_t rel_size = reloc_info[i].size;
1131 -               size_t stride = reloc_info[i].stride;
1132 -               for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
1133 -                       if (!IS_RELATIVE(rel[1])) continue;
1134 -                       size_t *rel_addr = (void *)(base + rel[0]);
1135 -                       size_t addend = stride==3 ? rel[2] : *rel_addr;
1136 -                       *rel_addr = (size_t)base + addend;
1137 -               }
1138 +       size_t *rel, rel_size;
1139 +
1140 +       rel = (void *)(base+dyn[DT_REL]);
1141 +       rel_size = dyn[DT_RELSZ];
1142 +       for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) {
1143 +               if (!IS_RELATIVE(rel[1])) continue;
1144 +               size_t *rel_addr = (void *)(base + rel[0]);
1145 +               *rel_addr += (size_t)base;
1146 +       }
1147 +
1148 +       rel = (void *)(base+dyn[DT_RELA]);
1149 +       rel_size = dyn[DT_RELASZ];
1150 +       for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
1151 +               if (!IS_RELATIVE(rel[1])) continue;
1152 +               size_t *rel_addr = (void *)(base + rel[0]);
1153 +               *rel_addr = (size_t)base + rel[2];
1154         }
1155  
1156         const char *strings = (void *)(base + dyn[DT_STRTAB]);
1157 @@ -93,16 +84,7 @@ void _dlstart_c(size_t *sp, size_t *dynv
1158                  && s[3]=='l' && s[4]=='s' && s[5]=='2' && !s[6])
1159                         break;
1160         }
1161 -       ((stage2_func)(base + syms[i].st_value))(base);
1162 -
1163 -       /* Call dynamic linker stage-3, __dls3 */
1164 -       for (i=0; ;i++) {
1165 -               const char *s = strings + syms[i].st_name;
1166 -               if (s[0]=='_' && s[1]=='_' && s[2]=='d'
1167 -                && s[3]=='l' && s[4]=='s' && s[5]=='3' && !s[6])
1168 -                       break;
1169 -       }
1170 -       ((stage3_func)(base + syms[i].st_value))(sp);
1171 +       ((stage2_func)(base + syms[i].st_value))(base, sp);
1172  }
1173  
1174  #endif
1175 --- a/src/ldso/dynlink.c
1176 +++ b/src/ldso/dynlink.c
1177 @@ -74,7 +74,6 @@ struct dso {
1178         volatile int new_dtv_idx, new_tls_idx;
1179         struct td_index *td_index;
1180         struct dso *fini_next;
1181 -       int rel_early_relative, rel_update_got;
1182         char *shortname;
1183         char buf[];
1184  };
1185 @@ -96,6 +95,9 @@ static struct builtin_tls {
1186  } builtin_tls[1];
1187  #define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
1188  
1189 +#define ADDEND_LIMIT 4096
1190 +static size_t *saved_addends, *apply_addends_to;
1191 +
1192  static struct dso ldso;
1193  static struct dso *head, *tail, *fini_head;
1194  static char *env_path, *sys_path;
1195 @@ -256,10 +258,19 @@ static void do_relocs(struct dso *dso, s
1196         size_t sym_val;
1197         size_t tls_val;
1198         size_t addend;
1199 +       int skip_relative = 0, reuse_addends = 0, save_slot = 0;
1200 +
1201 +       if (dso == &ldso) {
1202 +               /* Only ldso's REL table needs addend saving/reuse. */
1203 +               if (rel == apply_addends_to)
1204 +                       reuse_addends = 1;
1205 +               skip_relative = 1;
1206 +       }
1207  
1208         for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
1209 -               if (dso->rel_early_relative && IS_RELATIVE(rel[1])) continue;
1210 +               if (skip_relative && IS_RELATIVE(rel[1])) continue;
1211                 type = R_TYPE(rel[1]);
1212 +               if (type == REL_NONE) continue;
1213                 sym_index = R_SYM(rel[1]);
1214                 reloc_addr = (void *)(base + rel[0]);
1215                 if (sym_index) {
1216 @@ -280,12 +291,20 @@ static void do_relocs(struct dso *dso, s
1217                         def.dso = dso;
1218                 }
1219  
1220 -               int gotplt = (type == REL_GOT || type == REL_PLT);
1221 -               if (dso->rel_update_got && !gotplt) continue;
1222 -
1223 -               addend = stride>2 ? rel[2]
1224 -                       : gotplt || type==REL_COPY ? 0
1225 -                       : *reloc_addr;
1226 +               if (stride > 2) {
1227 +                       addend = rel[2];
1228 +               } else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {
1229 +                       addend = 0;
1230 +               } else if (reuse_addends) {
1231 +                       /* Save original addend in stage 2 where the dso
1232 +                        * chain consists of just ldso; otherwise read back
1233 +                        * saved addend since the inline one was clobbered. */
1234 +                       if (head==&ldso)
1235 +                               saved_addends[save_slot] = *reloc_addr;
1236 +                       addend = saved_addends[save_slot++];
1237 +               } else {
1238 +                       addend = *reloc_addr;
1239 +               }
1240  
1241                 sym_val = def.sym ? (size_t)def.dso->base+def.sym->st_value : 0;
1242                 tls_val = def.sym ? def.sym->st_value : 0;
1243 @@ -879,7 +898,7 @@ static void do_mips_relocs(struct dso *p
1244         size_t i, j, rel[2];
1245         unsigned char *base = p->base;
1246         i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);
1247 -       if (p->rel_early_relative) {
1248 +       if (p==&ldso) {
1249                 got += i;
1250         } else {
1251                 while (i--) *got++ += (size_t)base;
1252 @@ -1116,7 +1135,7 @@ static void update_tls_size()
1253   * linker itself, but some of the relocations performed may need to be
1254   * replaced later due to copy relocations in the main program. */
1255  
1256 -void __dls2(unsigned char *base)
1257 +void __dls2(unsigned char *base, size_t *sp)
1258  {
1259         Ehdr *ehdr = (void *)base;
1260         ldso.base = base;
1261 @@ -1125,15 +1144,35 @@ void __dls2(unsigned char *base)
1262         ldso.phnum = ehdr->e_phnum;
1263         ldso.phdr = (void *)(base + ehdr->e_phoff);
1264         ldso.phentsize = ehdr->e_phentsize;
1265 -       ldso.rel_early_relative = 1;
1266         kernel_mapped_dso(&ldso);
1267         decode_dyn(&ldso);
1268  
1269 +       /* Prepare storage for to save clobbered REL addends so they
1270 +        * can be reused in stage 3. There should be very few. If
1271 +        * something goes wrong and there are a huge number, abort
1272 +        * instead of risking stack overflow. */
1273 +       size_t dyn[DYN_CNT];
1274 +       decode_vec(ldso.dynv, dyn, DYN_CNT);
1275 +       size_t *rel = (void *)(base+dyn[DT_REL]);
1276 +       size_t rel_size = dyn[DT_RELSZ];
1277 +       size_t symbolic_rel_cnt = 0;
1278 +       apply_addends_to = rel;
1279 +       for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))
1280 +               if (!IS_RELATIVE(rel[1])) symbolic_rel_cnt++;
1281 +       if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();
1282 +       size_t addends[symbolic_rel_cnt+1];
1283 +       saved_addends = addends;
1284 +
1285         head = &ldso;
1286         reloc_all(&ldso);
1287  
1288         ldso.relocated = 0;
1289 -       ldso.rel_update_got = 1;
1290 +
1291 +       /* Call dynamic linker stage-3, __dls3, looking it up
1292 +        * symbolically as a barrier against moving the address
1293 +        * load across the above relocation processing. */
1294 +       struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
1295 +       ((stage3_func)(ldso.base+dls3_def.sym->st_value))(sp);
1296  }
1297  
1298  /* Stage 3 of the dynamic linker is called with the dynamic linker/libc
1299 --- a/src/locale/__lctrans.c
1300 +++ b/src/locale/__lctrans.c
1301 @@ -16,5 +16,5 @@ const char *__lctrans(const char *msg, c
1302  
1303  const char *__lctrans_cur(const char *msg)
1304  {
1305 -       return __lctrans_impl(msg, CURRENT_LOCALE->cat[LC_MESSAGES-2]);
1306 +       return __lctrans_impl(msg, CURRENT_LOCALE->cat[LC_MESSAGES]);
1307  }
1308 --- a/src/locale/__setlocalecat.c
1309 +++ /dev/null
1310 @@ -1,111 +0,0 @@
1311 -#include <locale.h>
1312 -#include <string.h>
1313 -#include "locale_impl.h"
1314 -#include "libc.h"
1315 -#include "atomic.h"
1316 -
1317 -const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
1318 -{
1319 -       const char *trans = 0;
1320 -       if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg);
1321 -       return trans ? trans : msg;
1322 -}
1323 -
1324 -const unsigned char *__map_file(const char *, size_t *);
1325 -int __munmap(void *, size_t);
1326 -char *__strchrnul(const char *, int);
1327 -
1328 -static struct __locale_map *findlocale(const char *name, size_t n)
1329 -{
1330 -       static void *volatile loc_head;
1331 -       struct __locale_map *p, *new, *old_head;
1332 -       const char *path = 0, *z;
1333 -       char buf[256];
1334 -       size_t l;
1335 -       const void *map;
1336 -       size_t map_size;
1337 -
1338 -       for (p=loc_head; p; p=p->next)
1339 -               if (!strcmp(name, p->name)) return p;
1340 -
1341 -       if (!libc.secure) path = getenv("MUSL_LOCPATH");
1342 -       /* FIXME: add a default path? */
1343 -       if (!path) return 0;
1344 -
1345 -       for (; *path; path=z+!!*z) {
1346 -               z = __strchrnul(path, ':');
1347 -               l = z - path - !!*z;
1348 -               if (l >= sizeof buf - n - 2) continue;
1349 -               memcpy(buf, path, l);
1350 -               buf[l] = '/';
1351 -               memcpy(buf+l+1, name, n);
1352 -               buf[l+1+n] = 0;
1353 -               map = __map_file(buf, &map_size);
1354 -               if (map) {
1355 -                       new = malloc(sizeof *new);
1356 -                       if (!new) {
1357 -                               __munmap((void *)map, map_size);
1358 -                               return 0;
1359 -                       }
1360 -                       new->map = map;
1361 -                       new->map_size = map_size;
1362 -                       memcpy(new->name, name, n);
1363 -                       new->name[n] = 0;
1364 -                       do {
1365 -                               old_head = loc_head;
1366 -                               new->next = old_head;
1367 -                       } while (a_cas_p(&loc_head, old_head, new) != old_head);
1368 -                       return new;
1369 -               }
1370 -       }
1371 -       return 0;
1372 -}
1373 -
1374 -static const char envvars[][12] = {
1375 -       "LC_CTYPE",
1376 -       "LC_NUMERIC",
1377 -       "LC_TIME",
1378 -       "LC_COLLATE",
1379 -       "LC_MONETARY",
1380 -       "LC_MESSAGES",
1381 -};
1382 -
1383 -int __setlocalecat(locale_t loc, int cat, const char *val)
1384 -{
1385 -       if (!*val) {
1386 -               (val = getenv("LC_ALL")) && *val ||
1387 -               (val = getenv(envvars[cat])) && *val ||
1388 -               (val = getenv("LANG")) && *val ||
1389 -               (val = "C.UTF-8");
1390 -       }
1391 -
1392 -       size_t n;
1393 -       for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);
1394 -       if (val[0]=='.' || val[n]) val = "C.UTF-8";
1395 -       int builtin = (val[0]=='C' && !val[1])
1396 -               || !strcmp(val, "C.UTF-8")
1397 -               || !strcmp(val, "POSIX");
1398 -       struct __locale_map *data, *old;
1399 -
1400 -       switch (cat) {
1401 -       case LC_CTYPE:
1402 -               a_store(&loc->ctype_utf8, !builtin || val[1]=='.');
1403 -               break;
1404 -       case LC_MESSAGES:
1405 -               if (builtin) {
1406 -                       loc->messages_name[0] = 0;
1407 -               } else {
1408 -                       memcpy(loc->messages_name, val, n);
1409 -                       loc->messages_name[n] = 0;
1410 -               }
1411 -               /* fall through */
1412 -       default:
1413 -               data = builtin ? 0 : findlocale(val, n);
1414 -               if (data == loc->cat[cat-2]) break;
1415 -               do old = loc->cat[cat-2];
1416 -               while (a_cas_p(&loc->cat[cat-2], old, data) != old);
1417 -       case LC_NUMERIC:
1418 -               break;
1419 -       }
1420 -       return 0;
1421 -}
1422 --- a/src/locale/dcngettext.c
1423 +++ b/src/locale/dcngettext.c
1424 @@ -84,13 +84,15 @@ char *bindtextdomain(const char *domainn
1425  }
1426  
1427  static const char catnames[][12] = {
1428 +       "LC_CTYPE",
1429 +       "LC_NUMERIC",
1430         "LC_TIME",
1431         "LC_COLLATE",
1432         "LC_MONETARY",
1433         "LC_MESSAGES",
1434  };
1435  
1436 -static const char catlens[] = { 7, 10, 11, 11 };
1437 +static const char catlens[] = { 8, 10, 7, 10, 11, 11 };
1438  
1439  struct msgcat {
1440         struct msgcat *next;
1441 @@ -117,10 +119,12 @@ char *dcngettext(const char *domainname,
1442         static struct msgcat *volatile cats;
1443         struct msgcat *p;
1444         struct __locale_struct *loc = CURRENT_LOCALE;
1445 -       struct __locale_map *lm;
1446 +       const struct __locale_map *lm;
1447         const char *dirname, *locname, *catname;
1448         size_t dirlen, loclen, catlen, domlen;
1449  
1450 +       if ((unsigned)category >= LC_ALL) goto notrans;
1451 +
1452         if (!domainname) domainname = __gettextdomain();
1453  
1454         domlen = strlen(domainname);
1455 @@ -129,25 +133,15 @@ char *dcngettext(const char *domainname,
1456         dirname = gettextdir(domainname, &dirlen);
1457         if (!dirname) goto notrans;
1458  
1459 -       switch (category) {
1460 -       case LC_MESSAGES:
1461 -               locname = loc->messages_name;
1462 -               if (!*locname) goto notrans;
1463 -               break;
1464 -       case LC_TIME:
1465 -       case LC_MONETARY:
1466 -       case LC_COLLATE:
1467 -               lm = loc->cat[category-2];
1468 -               if (!lm) goto notrans;
1469 -               locname = lm->name;
1470 -               break;
1471 -       default:
1472 +       lm = loc->cat[category];
1473 +       if (!lm) {
1474  notrans:
1475                 return (char *) ((n == 1) ? msgid1 : msgid2);
1476         }
1477 +       locname = lm->name;
1478  
1479 -       catname = catnames[category-2];
1480 -       catlen = catlens[category-2];
1481 +       catname = catnames[category];
1482 +       catlen = catlens[category];
1483         loclen = strlen(locname);
1484  
1485         size_t namelen = dirlen+1 + loclen+1 + catlen+1 + domlen+3;
1486 --- a/src/locale/duplocale.c
1487 +++ b/src/locale/duplocale.c
1488 @@ -5,17 +5,10 @@
1489  
1490  locale_t __duplocale(locale_t old)
1491  {
1492 -       locale_t new = calloc(1, sizeof *new + LOCALE_NAME_MAX + 1);
1493 +       locale_t new = malloc(sizeof *new);
1494         if (!new) return 0;
1495 -       new->messages_name = (void *)(new+1);
1496 -
1497         if (old == LC_GLOBAL_LOCALE) old = &libc.global_locale;
1498 -       new->ctype_utf8 = old->ctype_utf8;
1499 -       if (old->messages_name)
1500 -               strcpy(new->messages_name, old->messages_name);
1501 -
1502 -       for (size_t i=0; i<sizeof new->cat/sizeof new->cat[0]; i++)
1503 -               new->cat[i] = old->cat[i];
1504 +       *new = *old;
1505         return new;
1506  }
1507  
1508 --- a/src/locale/freelocale.c
1509 +++ b/src/locale/freelocale.c
1510 @@ -2,9 +2,11 @@
1511  #include "locale_impl.h"
1512  #include "libc.h"
1513  
1514 +int __loc_is_allocated(locale_t);
1515 +
1516  void freelocale(locale_t l)
1517  {
1518 -       free(l);
1519 +       if (__loc_is_allocated(l)) free(l);
1520  }
1521  
1522  weak_alias(freelocale, __freelocale);
1523 --- a/src/locale/iconv.c
1524 +++ b/src/locale/iconv.c
1525 @@ -23,19 +23,13 @@
1526  #define BIG5        0340
1527  #define EUC_KR      0350
1528  
1529 -/* FIXME: these are not implemented yet
1530 - * EUC:   A1-FE A1-FE
1531 - * GBK:   81-FE 40-7E,80-FE
1532 - * Big5:  A1-FE 40-7E,A1-FE
1533 - */
1534 -
1535  /* Definitions of charmaps. Each charmap consists of:
1536   * 1. Empty-string-terminated list of null-terminated aliases.
1537   * 2. Special type code or number of elided entries.
1538   * 3. Character table (size determined by field 2). */
1539  
1540  static const unsigned char charmaps[] =
1541 -"utf8\0\0\310"
1542 +"utf8\0char\0\0\310"
1543  "wchart\0\0\306"
1544  "ucs2\0ucs2be\0\0\304"
1545  "ucs2le\0\0\305"
1546 @@ -90,6 +84,7 @@ static int fuzzycmp(const unsigned char
1547  static size_t find_charmap(const void *name)
1548  {
1549         const unsigned char *s;
1550 +       if (!*(char *)name) name=charmaps; /* "utf8" */
1551         for (s=charmaps; *s; ) {
1552                 if (!fuzzycmp(name, s)) {
1553                         for (; *s; s+=strlen((void *)s)+1);
1554 --- /dev/null
1555 +++ b/src/locale/locale_map.c
1556 @@ -0,0 +1,124 @@
1557 +#include <locale.h>
1558 +#include <string.h>
1559 +#include "locale_impl.h"
1560 +#include "libc.h"
1561 +#include "atomic.h"
1562 +
1563 +const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
1564 +{
1565 +       const char *trans = 0;
1566 +       if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg);
1567 +       return trans ? trans : msg;
1568 +}
1569 +
1570 +const unsigned char *__map_file(const char *, size_t *);
1571 +int __munmap(void *, size_t);
1572 +char *__strchrnul(const char *, int);
1573 +
1574 +static const char envvars[][12] = {
1575 +       "LC_CTYPE",
1576 +       "LC_NUMERIC",
1577 +       "LC_TIME",
1578 +       "LC_COLLATE",
1579 +       "LC_MONETARY",
1580 +       "LC_MESSAGES",
1581 +};
1582 +
1583 +static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
1584 +
1585 +const struct __locale_map __c_dot_utf8 = {
1586 +       .map = empty_mo,
1587 +       .map_size = sizeof empty_mo,
1588 +       .name = "C.UTF-8"
1589 +};
1590 +
1591 +const struct __locale_map *__get_locale(int cat, const char *val)
1592 +{
1593 +       static int lock[2];
1594 +       static void *volatile loc_head;
1595 +       const struct __locale_map *p;
1596 +       struct __locale_map *new = 0;
1597 +       const char *path = 0, *z;
1598 +       char buf[256];
1599 +       size_t l, n;
1600 +
1601 +       if (!*val) {
1602 +               (val = getenv("LC_ALL")) && *val ||
1603 +               (val = getenv(envvars[cat])) && *val ||
1604 +               (val = getenv("LANG")) && *val ||
1605 +               (val = "C.UTF-8");
1606 +       }
1607 +
1608 +       /* Limit name length and forbid leading dot or any slashes. */
1609 +       for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);
1610 +       if (val[0]=='.' || val[n]) val = "C.UTF-8";
1611 +       int builtin = (val[0]=='C' && !val[1])
1612 +               || !strcmp(val, "C.UTF-8")
1613 +               || !strcmp(val, "POSIX");
1614 +
1615 +       if (builtin) {
1616 +               if (cat == LC_CTYPE && val[1]=='.')
1617 +                       return (void *)&__c_dot_utf8;
1618 +               return 0;
1619 +       }
1620 +
1621 +       for (p=loc_head; p; p=p->next)
1622 +               if (!strcmp(val, p->name)) return p;
1623 +
1624 +       LOCK(lock);
1625 +
1626 +       for (p=loc_head; p; p=p->next)
1627 +               if (!strcmp(val, p->name)) {
1628 +                       UNLOCK(lock);
1629 +                       return p;
1630 +               }
1631 +
1632 +       if (!libc.secure) path = getenv("MUSL_LOCPATH");
1633 +       /* FIXME: add a default path? */
1634 +
1635 +       if (path) for (; *path; path=z+!!*z) {
1636 +               z = __strchrnul(path, ':');
1637 +               l = z - path - !!*z;
1638 +               if (l >= sizeof buf - n - 2) continue;
1639 +               memcpy(buf, path, l);
1640 +               buf[l] = '/';
1641 +               memcpy(buf+l+1, val, n);
1642 +               buf[l+1+n] = 0;
1643 +               size_t map_size;
1644 +               const void *map = __map_file(buf, &map_size);
1645 +               if (map) {
1646 +                       new = malloc(sizeof *new);
1647 +                       if (!new) {
1648 +                               __munmap((void *)map, map_size);
1649 +                               break;
1650 +                       }
1651 +                       new->map = map;
1652 +                       new->map_size = map_size;
1653 +                       memcpy(new->name, val, n);
1654 +                       new->name[n] = 0;
1655 +                       new->next = loc_head;
1656 +                       loc_head = new;
1657 +                       break;
1658 +               }
1659 +       }
1660 +
1661 +       /* If no locale definition was found, make a locale map
1662 +        * object anyway to store the name, which is kept for the
1663 +        * sake of being able to do message translations at the
1664 +        * application level. */
1665 +       if (!new && (new = malloc(sizeof *new))) {
1666 +               new->map = empty_mo;
1667 +               new->map_size = sizeof empty_mo;
1668 +               memcpy(new->name, val, n);
1669 +               new->name[n] = 0;
1670 +               new->next = loc_head;
1671 +               loc_head = new;
1672 +       }
1673 +
1674 +       /* For LC_CTYPE, never return a null pointer unless the
1675 +        * requested name was "C" or "POSIX". */
1676 +       if (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8;
1677 +
1678 +       UNLOCK(lock);
1679 +       return new;
1680 +}
1681 --- a/src/locale/newlocale.c
1682 +++ b/src/locale/newlocale.c
1683 @@ -3,22 +3,52 @@
1684  #include "locale_impl.h"
1685  #include "libc.h"
1686  
1687 +extern const struct __locale_map __c_dot_utf8;
1688 +
1689 +static const struct __locale_struct c_locale = { 0 };
1690 +static const struct __locale_struct c_dot_utf8_locale = {
1691 +       .cat[LC_CTYPE] = &__c_dot_utf8
1692 +};
1693 +
1694 +int __loc_is_allocated(locale_t loc)
1695 +{
1696 +       return loc && loc != &c_locale && loc != &c_dot_utf8_locale;
1697 +}
1698 +
1699  locale_t __newlocale(int mask, const char *name, locale_t loc)
1700  {
1701 -       int i;
1702 +       int i, j;
1703 +       struct __locale_struct tmp;
1704 +       const struct __locale_map *lm;
1705  
1706 -       if (!loc) {
1707 -               loc = calloc(1, sizeof *loc + LOCALE_NAME_MAX + 1);
1708 -               if (!loc) return 0;
1709 -               loc->messages_name = (void *)(loc+1);
1710 +       /* For locales with allocated storage, modify in-place. */
1711 +       if (__loc_is_allocated(loc)) {
1712                 for (i=0; i<LC_ALL; i++)
1713 -                       if (!(mask & (1<<i)))
1714 -                               __setlocalecat(loc, i, "");
1715 +                       if (mask & (1<<i))
1716 +                               loc->cat[i] = __get_locale(i, name);
1717 +               return loc;
1718 +       }
1719 +
1720 +       /* Otherwise, build a temporary locale object, which will only
1721 +        * be instantiated in allocated storage if it does not match
1722 +        * one of the built-in static locales. This makes the common
1723 +        * usage case for newlocale, getting a C locale with predictable
1724 +        * behavior, very fast, and more importantly, fail-safe. */
1725 +       for (j=i=0; i<LC_ALL; i++) {
1726 +               if (loc && !(mask & (1<<i)))
1727 +                       lm = loc->cat[i];
1728 +               else
1729 +                       lm = __get_locale(i, mask & (1<<i) ? name : "");
1730 +               if (lm) j++;
1731 +               tmp.cat[i] = lm;
1732         }
1733  
1734 -       for (i=0; i<LC_ALL; i++)
1735 -               if (mask & (1<<i))
1736 -                       __setlocalecat(loc, i, name);
1737 +       if (!j)
1738 +               return (locale_t)&c_locale;
1739 +       if (j==1 && tmp.cat[LC_CTYPE]==c_dot_utf8_locale.cat[LC_CTYPE])
1740 +               return (locale_t)&c_dot_utf8_locale;
1741 +
1742 +       if ((loc = malloc(sizeof *loc))) *loc = tmp;
1743  
1744         return loc;
1745  }
1746 --- a/src/locale/setlocale.c
1747 +++ b/src/locale/setlocale.c
1748 @@ -5,73 +5,66 @@
1749  #include "libc.h"
1750  #include "atomic.h"
1751  
1752 -static char buf[2+4*(LOCALE_NAME_MAX+1)];
1753 +static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
1754  
1755 -char *setlocale(int cat, const char *name)
1756 +static char *setlocale_one_unlocked(int cat, const char *name)
1757  {
1758 -       struct __locale_map *lm;
1759 -       int i, j;
1760 +       const struct __locale_map *lm;
1761  
1762 -       if (!libc.global_locale.messages_name) {
1763 -               libc.global_locale.messages_name =
1764 -                       buf + 2 + 3*(LOCALE_NAME_MAX+1);
1765 -       }
1766 +       if (name) libc.global_locale.cat[cat] = lm = __get_locale(cat, name);
1767 +       else lm = libc.global_locale.cat[cat];
1768 +
1769 +       return lm ? (char *)lm->name : "C";
1770 +}
1771 +
1772 +char *__strchrnul(const char *, int);
1773 +
1774 +char *setlocale(int cat, const char *name)
1775 +{
1776 +       static volatile int lock[2];
1777  
1778         if ((unsigned)cat > LC_ALL) return 0;
1779  
1780 +       LOCK(lock);
1781 +
1782         /* For LC_ALL, setlocale is required to return a string which
1783          * encodes the current setting for all categories. The format of
1784          * this string is unspecified, and only the following code, which
1785          * performs both the serialization and deserialization, depends
1786          * on the format, so it can easily be changed if needed. */
1787         if (cat == LC_ALL) {
1788 +               int i;
1789                 if (name) {
1790 -                       char part[LOCALE_NAME_MAX+1];
1791 -                       if (name[0] && name[1]==';'
1792 -                           && strlen(name) > 2 + 3*(LOCALE_NAME_MAX+1)) {
1793 -                               part[0] = name[0];
1794 -                               part[1] = 0;
1795 -                               setlocale(LC_CTYPE, part);
1796 -                               part[LOCALE_NAME_MAX] = 0;
1797 -                               for (i=LC_TIME; i<LC_MESSAGES; i++) {
1798 -                                       memcpy(part, name + 2 + (i-2)*(LOCALE_NAME_MAX+1), LOCALE_NAME_MAX);
1799 -                                       for (j=LOCALE_NAME_MAX-1; j && part[j]==';'; j--)
1800 -                                               part[j] = 0;
1801 -                                       setlocale(i, part);
1802 +                       char part[LOCALE_NAME_MAX+1] = "C.UTF-8";
1803 +                       const char *p = name;
1804 +                       for (i=0; i<LC_ALL; i++) {
1805 +                               const char *z = __strchrnul(p, ';');
1806 +                               if (z-p <= LOCALE_NAME_MAX) {
1807 +                                       memcpy(part, p, z-p);
1808 +                                       part[z-p] = 0;
1809 +                                       if (*z) p = z+1;
1810                                 }
1811 -                               setlocale(LC_MESSAGES, name + 2 + 3*(LOCALE_NAME_MAX+1));
1812 -                       } else {
1813 -                               for (i=0; i<LC_ALL; i++)
1814 -                                       setlocale(i, name);
1815 +                               setlocale_one_unlocked(i, part);
1816                         }
1817                 }
1818 -               memset(buf, ';', 2 + 3*(LOCALE_NAME_MAX+1));
1819 -               buf[0] = libc.global_locale.ctype_utf8 ? 'U' : 'C';
1820 -               for (i=LC_TIME; i<LC_MESSAGES; i++) {
1821 -                       lm = libc.global_locale.cat[i-2];
1822 -                       if (lm) memcpy(buf + 2 + (i-2)*(LOCALE_NAME_MAX+1),
1823 -                               lm->name, strlen(lm->name));
1824 +               char *s = buf;
1825 +               for (i=0; i<LC_ALL; i++) {
1826 +                       const struct __locale_map *lm =
1827 +                               libc.global_locale.cat[i];
1828 +                       const char *part = lm ? lm->name : "C";
1829 +                       size_t l = strlen(part);
1830 +                       memcpy(s, part, l);
1831 +                       s[l] = ';';
1832 +                       s += l+1;
1833                 }
1834 +               *--s = 0;
1835 +               UNLOCK(lock);
1836                 return buf;
1837         }
1838  
1839 -       if (name) {
1840 -               int adj = libc.global_locale.ctype_utf8;
1841 -               __setlocalecat(&libc.global_locale, cat, name);
1842 -               adj -= libc.global_locale.ctype_utf8;
1843 -               if (adj) a_fetch_add(&libc.bytelocale_cnt_minus_1, adj);
1844 -       }
1845 +       char *ret = setlocale_one_unlocked(cat, name);
1846  
1847 -       switch (cat) {
1848 -       case LC_CTYPE:
1849 -               return libc.global_locale.ctype_utf8 ? "C.UTF-8" : "C";
1850 -       case LC_NUMERIC:
1851 -               return "C";
1852 -       case LC_MESSAGES:
1853 -               return libc.global_locale.messages_name[0]
1854 -                       ? libc.global_locale.messages_name : "C";
1855 -       default:
1856 -               lm = libc.global_locale.cat[cat-2];
1857 -               return lm ? lm->name : "C";
1858 -       }
1859 +       UNLOCK(lock);
1860 +
1861 +       return ret;
1862  }
1863 --- a/src/locale/uselocale.c
1864 +++ b/src/locale/uselocale.c
1865 @@ -10,15 +10,7 @@ locale_t __uselocale(locale_t new)
1866  
1867         if (new == LC_GLOBAL_LOCALE) new = global;
1868  
1869 -       if (new && new != old) {
1870 -               int adj = 0;
1871 -               if (new == global) a_dec(&libc.uselocale_cnt);
1872 -               else if (!new->ctype_utf8) adj++;
1873 -               if (old == global) a_inc(&libc.uselocale_cnt);
1874 -               else if (!old->ctype_utf8) adj--;
1875 -               a_fetch_add(&libc.bytelocale_cnt_minus_1, adj);
1876 -               self->locale = new;
1877 -       }
1878 +       self->locale = new;
1879  
1880         return old == global ? LC_GLOBAL_LOCALE : old;
1881  }
1882 --- a/src/stdio/__stdio_read.c
1883 +++ b/src/stdio/__stdio_read.c
1884 @@ -21,7 +21,6 @@ size_t __stdio_read(FILE *f, unsigned ch
1885         pthread_cleanup_pop(0);
1886         if (cnt <= 0) {
1887                 f->flags |= F_EOF ^ ((F_ERR^F_EOF) & cnt);
1888 -               f->rpos = f->rend = 0;
1889                 return cnt;
1890         }
1891         if (cnt <= iov[0].iov_len) return cnt;
1892 --- a/src/stdio/__toread.c
1893 +++ b/src/stdio/__toread.c
1894 @@ -5,12 +5,12 @@ int __toread(FILE *f)
1895         f->mode |= f->mode-1;
1896         if (f->wpos > f->buf) f->write(f, 0, 0);
1897         f->wpos = f->wbase = f->wend = 0;
1898 -       if (f->flags & (F_EOF|F_NORD)) {
1899 -               if (f->flags & F_NORD) f->flags |= F_ERR;
1900 +       if (f->flags & F_NORD) {
1901 +               f->flags |= F_ERR;
1902                 return EOF;
1903         }
1904 -       f->rpos = f->rend = f->buf;
1905 -       return 0;
1906 +       f->rpos = f->rend = f->buf + f->buf_size;
1907 +       return (f->flags & F_EOF) ? EOF : 0;
1908  }
1909  
1910  void __stdio_exit_needed(void);
1911 --- a/src/stdio/__uflow.c
1912 +++ b/src/stdio/__uflow.c
1913 @@ -1,11 +1,11 @@
1914  #include "stdio_impl.h"
1915  
1916 -/* This function will never be called if there is already data
1917 - * buffered for reading. Thus we can get by with very few branches. */
1918 +/* This function assumes it will never be called if there is already
1919 + * data buffered for reading. */
1920  
1921  int __uflow(FILE *f)
1922  {
1923         unsigned char c;
1924 -       if ((f->rend || !__toread(f)) && f->read(f, &c, 1)==1) return c;
1925 +       if (!__toread(f) && f->read(f, &c, 1)==1) return c;
1926         return EOF;
1927  }
1928 --- a/src/stdio/ungetc.c
1929 +++ b/src/stdio/ungetc.c
1930 @@ -6,7 +6,8 @@ int ungetc(int c, FILE *f)
1931  
1932         FLOCK(f);
1933  
1934 -       if ((!f->rend && __toread(f)) || f->rpos <= f->buf - UNGET) {
1935 +       if (!f->rpos) __toread(f);
1936 +       if (!f->rpos || f->rpos <= f->buf - UNGET) {
1937                 FUNLOCK(f);
1938                 return EOF;
1939         }
1940 --- a/src/stdio/ungetwc.c
1941 +++ b/src/stdio/ungetwc.c
1942 @@ -19,7 +19,8 @@ wint_t ungetwc(wint_t c, FILE *f)
1943  
1944         f->mode |= f->mode+1;
1945  
1946 -       if ((!f->rend && __toread(f)) || f->rpos < f->buf - UNGET + l) {
1947 +       if (!f->rpos) __toread(f);
1948 +       if (!f->rpos || f->rpos < f->buf - UNGET + l) {
1949                 FUNLOCK(f);
1950                 return EOF;
1951         }
1952 --- a/src/thread/i386/__set_thread_area.s
1953 +++ b/src/thread/i386/__set_thread_area.s
1954 @@ -6,10 +6,10 @@ __set_thread_area:
1955         push $0x51
1956         push $0xfffff
1957         push 16(%esp)
1958 -       xor %edx,%edx
1959 -       mov %gs,%dx
1960 -       sub $3,%edx
1961 -       sar $3,%edx
1962 +       call 1f
1963 +1:     addl $4f-1b,(%esp)
1964 +       pop %ecx
1965 +       mov (%ecx),%edx
1966         push %edx
1967         mov %esp,%ebx
1968         xor %eax,%eax
1969 @@ -18,6 +18,7 @@ __set_thread_area:
1970         testl %eax,%eax
1971         jnz 2f
1972         movl (%esp),%edx
1973 +       movl %edx,(%ecx)
1974         leal 3(,%edx,8),%edx
1975  3:     movw %dx,%gs
1976  1:
1977 @@ -38,3 +39,7 @@ __set_thread_area:
1978         mov $7,%dl
1979         inc %al
1980         jmp 3b
1981 +
1982 +.data
1983 +       .align 4
1984 +4:     .long -1
1985 --- a/src/thread/mips/syscall_cp.s
1986 +++ b/src/thread/mips/syscall_cp.s
1987 @@ -2,10 +2,13 @@
1988  
1989  .global __cp_begin
1990  .hidden __cp_begin
1991 +.type   __cp_begin,@function
1992  .global __cp_end
1993  .hidden __cp_end
1994 +.type   __cp_end,@function
1995  .global __cp_cancel
1996  .hidden __cp_cancel
1997 +.type   __cp_cancel,@function
1998  .hidden __cancel
1999  .global __syscall_cp_asm
2000  .hidden __syscall_cp_asm
2001 --- a/src/thread/pthread_create.c
2002 +++ b/src/thread/pthread_create.c
2003 @@ -67,12 +67,6 @@ _Noreturn void __pthread_exit(void *resu
2004                 exit(0);
2005         }
2006  
2007 -       if (self->locale != &libc.global_locale) {
2008 -               a_dec(&libc.uselocale_cnt);
2009 -               if (self->locale->ctype_utf8)
2010 -                       a_dec(&libc.bytelocale_cnt_minus_1);
2011 -       }
2012 -
2013         /* Process robust list in userspace to handle non-pshared mutexes
2014          * and the detached thread case where the robust list head will
2015          * be invalid when the kernel would process it. */