12 src/internal/version.h
17 # Do not make changes here.
21 exec_prefix = /usr/local
22 bindir = $(exec_prefix)/bin
24 @@ -16,31 +17,38 @@ includedir = $(prefix)/include
25 libdir = $(prefix)/lib
28 -SRCS = $(sort $(wildcard src/*/*.c arch/$(ARCH)/src/*.c))
30 +BASE_SRCS = $(sort $(wildcard $(srcdir)/src/*/*.c $(srcdir)/arch/$(ARCH)/src/*.[csS]))
31 +BASE_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(BASE_SRCS)))
32 +ARCH_SRCS = $(wildcard $(srcdir)/src/*/$(ARCH)/*.[csS])
33 +ARCH_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(ARCH_SRCS)))
34 +REPLACED_OBJS = $(sort $(subst /$(ARCH)/,/,$(ARCH_OBJS)))
35 +OBJS = $(addprefix obj/, $(filter-out $(REPLACED_OBJS), $(sort $(BASE_OBJS) $(ARCH_OBJS))))
36 LOBJS = $(OBJS:.o=.lo)
37 -GENH = include/bits/alltypes.h
38 -GENH_INT = src/internal/version.h
39 -IMPH = src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/libc.h
40 +GENH = obj/include/bits/alltypes.h
41 +GENH_INT = obj/src/internal/version.h
42 +IMPH = $(addprefix $(srcdir)/, src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/libc.h)
51 +CFLAGS_AUTO = -Os -pipe
52 CFLAGS_C99FSE = -std=c99 -ffreestanding -nostdinc
54 CFLAGS_ALL = $(CFLAGS_C99FSE)
55 -CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I./arch/$(ARCH) -I./src/internal -I./include
56 -CFLAGS_ALL += $(CPPFLAGS) $(CFLAGS)
57 -CFLAGS_ALL_STATIC = $(CFLAGS_ALL)
58 -CFLAGS_ALL_SHARED = $(CFLAGS_ALL) -fPIC -DSHARED
59 +CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I$(srcdir)/arch/$(ARCH) -Iobj/src/internal -I$(srcdir)/src/internal -Iobj/include -I$(srcdir)/include
60 +CFLAGS_ALL += $(CPPFLAGS) $(CFLAGS_AUTO) $(CFLAGS)
62 +LDFLAGS_ALL = $(LDFLAGS_AUTO) $(LDFLAGS)
64 AR = $(CROSS_COMPILE)ar
65 RANLIB = $(CROSS_COMPILE)ranlib
66 -INSTALL = ./tools/install.sh
67 +INSTALL = $(srcdir)/tools/install.sh
69 -ARCH_INCLUDES = $(wildcard arch/$(ARCH)/bits/*.h)
70 -ALL_INCLUDES = $(sort $(wildcard include/*.h include/*/*.h) $(GENH) $(ARCH_INCLUDES:arch/$(ARCH)/%=include/%))
71 +ARCH_INCLUDES = $(wildcard $(srcdir)/arch/$(ARCH)/bits/*.h)
72 +INCLUDES = $(wildcard $(srcdir)/include/*.h $(srcdir)/include/*/*.h)
73 +ALL_INCLUDES = $(sort $(INCLUDES:$(srcdir)/%=%) $(GENH:obj/%=%) $(ARCH_INCLUDES:$(srcdir)/arch/$(ARCH)/%=include/%))
75 EMPTY_LIB_NAMES = m rt pthread crypt util xnet resolv dl
76 EMPTY_LIBS = $(EMPTY_LIB_NAMES:%=lib/lib%.a)
77 @@ -49,7 +57,7 @@ STATIC_LIBS = lib/libc.a
78 SHARED_LIBS = lib/libc.so
79 TOOL_LIBS = lib/musl-gcc.specs
80 ALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS)
81 -ALL_TOOLS = tools/musl-gcc
82 +ALL_TOOLS = obj/musl-gcc
86 @@ -58,95 +66,93 @@ LDSO_PATHNAME = $(syslibdir)/ld-musl-$(A
91 +$(error Please set ARCH in config.mak before running make.)
94 all: $(ALL_LIBS) $(ALL_TOOLS)
96 +OBJ_DIRS = $(sort $(patsubst %/,%,$(dir $(ALL_LIBS) $(ALL_TOOLS) $(OBJS) $(GENH) $(GENH_INT))) $(addprefix obj/, crt crt/$(ARCH) include))
98 +$(ALL_LIBS) $(ALL_TOOLS) $(CRT_LIBS:lib/%=obj/crt/%) $(OBJS) $(LOBJS) $(GENH) $(GENH_INT): | $(OBJ_DIRS)
103 install: install-libs install-headers install-tools
109 - rm -f $(ALL_LIBS) lib/*.[ao] lib/*.so
111 - rm -f $(GENH) $(GENH_INT)
119 - @test "$(ARCH)" || { echo "Please set ARCH in config.mak before running make." ; exit 1 ; }
120 - ln -sf ../arch/$(ARCH)/bits $@
121 +obj/include/bits/alltypes.h: $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in $(srcdir)/tools/mkalltypes.sed
122 + sed -f $(srcdir)/tools/mkalltypes.sed $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in > $@
124 -include/bits/alltypes.h.in: include/bits
125 +obj/src/internal/version.h: $(wildcard $(srcdir)/VERSION $(srcdir)/.git)
126 + printf '#define VERSION "%s"\n' "$$(cd $(srcdir); sh tools/version.sh)" > $@
128 -include/bits/alltypes.h: include/bits/alltypes.h.in include/alltypes.h.in tools/mkalltypes.sed
129 - sed -f tools/mkalltypes.sed include/bits/alltypes.h.in include/alltypes.h.in > $@
130 +obj/src/internal/version.o obj/src/internal/version.lo: obj/src/internal/version.h
132 -src/internal/version.h: $(wildcard VERSION .git)
133 - printf '#define VERSION "%s"\n' "$$(sh tools/version.sh)" > $@
134 +obj/crt/rcrt1.o obj/src/ldso/dlstart.lo obj/src/ldso/dynlink.lo: $(srcdir)/src/internal/dynlink.h $(srcdir)/arch/$(ARCH)/reloc.h
136 -src/internal/version.lo: src/internal/version.h
137 +obj/crt/crt1.o obj/crt/scrt1.o obj/crt/rcrt1.o obj/src/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h
139 -crt/rcrt1.o src/ldso/dlstart.lo src/ldso/dynlink.lo: src/internal/dynlink.h arch/$(ARCH)/reloc.h
140 +obj/crt/rcrt1.o: $(srcdir)/src/ldso/dlstart.c
142 -crt/crt1.o crt/Scrt1.o crt/rcrt1.o src/ldso/dlstart.lo: $(wildcard arch/$(ARCH)/crt_arch.h)
143 +obj/crt/Scrt1.o obj/crt/rcrt1.o: CFLAGS_ALL += -fPIC
145 -crt/rcrt1.o: src/ldso/dlstart.c
146 +obj/crt/$(ARCH)/crti.o: $(srcdir)/crt/$(ARCH)/crti.s
148 -crt/Scrt1.o crt/rcrt1.o: CFLAGS += -fPIC
149 +obj/crt/$(ARCH)/crtn.o: $(srcdir)/crt/$(ARCH)/crtn.s
151 -OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=src/%))
152 -$(OPTIMIZE_SRCS:%.c=%.o) $(OPTIMIZE_SRCS:%.c=%.lo): CFLAGS += -O3
153 +OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=$(srcdir)/src/%))
154 +$(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.lo): CFLAGS += -O3
156 MEMOPS_SRCS = src/string/memcpy.c src/string/memmove.c src/string/memcmp.c src/string/memset.c
157 -$(MEMOPS_SRCS:%.c=%.o) $(MEMOPS_SRCS:%.c=%.lo): CFLAGS += $(CFLAGS_MEMOPS)
158 +$(MEMOPS_SRCS:%.c=obj/%.o) $(MEMOPS_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS)
160 NOSSP_SRCS = $(wildcard crt/*.c) \
161 src/env/__libc_start_main.c src/env/__init_tls.c \
162 src/thread/__set_thread_area.c src/env/__stack_chk_fail.c \
163 src/string/memset.c src/string/memcpy.c \
164 src/ldso/dlstart.c src/ldso/dynlink.c
165 -$(NOSSP_SRCS:%.c=%.o) $(NOSSP_SRCS:%.c=%.lo): CFLAGS += $(CFLAGS_NOSSP)
166 +$(NOSSP_SRCS:%.c=obj/%.o) $(NOSSP_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP)
168 +$(CRT_LIBS:lib/%=obj/crt/%): CFLAGS_ALL += -DCRT
170 -$(CRT_LIBS:lib/%=crt/%): CFLAGS += -DCRT
171 +$(LOBJS): CFLAGS_ALL += -fPIC -DSHARED
173 -# This incantation ensures that changes to any subarch asm files will
174 -# force the corresponding object file to be rebuilt, even if the implicit
175 -# rule below goes indirectly through a .sub file.
177 -$(dir $(patsubst %/,%,$(dir $(1))))$(notdir $(1:.s=.o)): $(1)
179 -$(foreach s,$(wildcard src/*/$(ARCH)*/*.s),$(eval $(call mkasmdep,$(s))))
180 +CC_CMD = $(CC) $(CFLAGS_ALL) -c -o $@ $<
182 # Choose invocation of assembler to be used
183 -# $(1) is input file, $(2) is output file, $(3) is assembler flags
184 ifeq ($(ADD_CFI),yes)
185 - AS_CMD = LC_ALL=C awk -f tools/add-cfi.common.awk -f tools/add-cfi.$(ARCH).awk $< | $(CC) -x assembler -c -o $@ -
186 + AS_CMD = LC_ALL=C awk -f $(srcdir)/tools/add-cfi.common.awk -f $(srcdir)/tools/add-cfi.$(ARCH).awk $< | $(CC) $(CFLAGS_ALL) -x assembler -c -o $@ -
188 - AS_CMD = $(CC) -c -o $@ $<
192 -%.o: $(ARCH)$(ASMSUBARCH)/%.sub
193 - $(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $(dir $<)$(shell cat $<)
194 +obj/%.o: $(srcdir)/%.s
198 - $(AS_CMD) $(CFLAGS_ALL_STATIC)
199 +obj/%.o: $(srcdir)/%.S
202 -%.o: %.c $(GENH) $(IMPH)
203 - $(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $<
204 +obj/%.o: $(srcdir)/%.c $(GENH) $(IMPH)
207 -%.lo: $(ARCH)$(ASMSUBARCH)/%.sub
208 - $(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $(dir $<)$(shell cat $<)
209 +obj/%.lo: $(srcdir)/%.s
213 - $(AS_CMD) $(CFLAGS_ALL_SHARED)
214 +obj/%.lo: $(srcdir)/%.S
217 -%.lo: %.c $(GENH) $(IMPH)
218 - $(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $<
219 +obj/%.lo: $(srcdir)/%.c $(GENH) $(IMPH)
222 lib/libc.so: $(LOBJS)
223 - $(CC) $(CFLAGS_ALL_SHARED) $(LDFLAGS) -nostdlib -shared \
224 + $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -nostdlib -shared \
225 -Wl,-e,_dlstart -Wl,-Bsymbolic-functions \
226 -o $@ $(LOBJS) $(LIBCC)
228 @@ -159,21 +165,27 @@ $(EMPTY_LIBS):
233 +lib/%.o: obj/crt/%.o
236 -lib/musl-gcc.specs: tools/musl-gcc.specs.sh config.mak
237 +lib/crti.o: obj/crt/$(ARCH)/crti.o
240 +lib/crtn.o: obj/crt/$(ARCH)/crtn.o
243 +lib/musl-gcc.specs: $(srcdir)/tools/musl-gcc.specs.sh config.mak
244 sh $< "$(includedir)" "$(libdir)" "$(LDSO_PATHNAME)" > $@
246 -tools/musl-gcc: config.mak
247 +obj/musl-gcc: config.mak
248 printf '#!/bin/sh\nexec "$${REALGCC:-$(WRAPCC_GCC)}" "$$@" -specs "%s/musl-gcc.specs"\n' "$(libdir)" > $@
251 -tools/%-clang: tools/%-clang.in config.mak
252 +obj/%-clang: $(srcdir)/tools/%-clang.in config.mak
253 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' $< > $@
256 -$(DESTDIR)$(bindir)/%: tools/%
257 +$(DESTDIR)$(bindir)/%: obj/%
260 $(DESTDIR)$(libdir)/%.so: lib/%.so
261 @@ -182,10 +194,13 @@ $(DESTDIR)$(libdir)/%.so: lib/%.so
262 $(DESTDIR)$(libdir)/%: lib/%
263 $(INSTALL) -D -m 644 $< $@
265 -$(DESTDIR)$(includedir)/bits/%: arch/$(ARCH)/bits/%
266 +$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/$(ARCH)/bits/%
267 + $(INSTALL) -D -m 644 $< $@
269 +$(DESTDIR)$(includedir)/bits/%: obj/include/bits/%
270 $(INSTALL) -D -m 644 $< $@
272 -$(DESTDIR)$(includedir)/%: include/%
273 +$(DESTDIR)$(includedir)/%: $(srcdir)/include/%
274 $(INSTALL) -D -m 644 $< $@
276 $(DESTDIR)$(LDSO_PATHNAME): $(DESTDIR)$(libdir)/libc.so
277 @@ -195,12 +210,12 @@ install-libs: $(ALL_LIBS:lib/%=$(DESTDIR
279 install-headers: $(ALL_INCLUDES:include/%=$(DESTDIR)$(includedir)/%)
281 -install-tools: $(ALL_TOOLS:tools/%=$(DESTDIR)$(bindir)/%)
282 +install-tools: $(ALL_TOOLS:obj/%=$(DESTDIR)$(bindir)/%)
284 musl-git-%.tar.gz: .git
285 - git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)
286 + git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)
289 - git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)
290 + git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)
292 .PHONY: all clean install install-libs install-headers install-tools
293 --- a/arch/aarch64/atomic.h
296 -#ifndef _INTERNAL_ATOMIC_H
297 -#define _INTERNAL_ATOMIC_H
301 -static inline int a_ctz_64(uint64_t x)
306 - : "=r"(x) : "r"(x));
310 -static inline int a_ctz_l(unsigned long x)
312 - return a_ctz_64(x);
315 -static inline void a_barrier()
317 - __asm__ __volatile__("dmb ish");
320 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
323 - __asm__ __volatile__(
328 - " stxr %w0,%2,%3\n"
333 - : "r"(t), "r"(s), "Q"(*(long*)p)
338 -static inline int a_cas(volatile int *p, int t, int s)
341 - __asm__ __volatile__(
346 - " stxr %w0,%w2,%3\n"
351 - : "r"(t), "r"(s), "Q"(*p)
356 -static inline int a_swap(volatile int *x, int v)
359 - __asm__ __volatile__(
362 - " stxr %w1,%w2,%3\n"
365 - : "=&r"(old), "=&r"(tmp)
367 - : "memory", "cc" );
371 -static inline int a_fetch_add(volatile int *x, int v)
374 - __asm__ __volatile__(
377 - " add %w0,%w0,%w2\n"
378 - " stxr %w1,%w0,%3\n"
381 - : "=&r"(old), "=&r"(tmp)
383 - : "memory", "cc" );
387 -static inline void a_inc(volatile int *x)
390 - __asm__ __volatile__(
393 - " add %w0,%w0,#1\n"
394 - " stxr %w1,%w0,%2\n"
397 - : "=&r"(tmp), "=&r"(tmp2)
399 - : "memory", "cc" );
402 -static inline void a_dec(volatile int *x)
405 - __asm__ __volatile__(
408 - " sub %w0,%w0,#1\n"
409 - " stxr %w1,%w0,%2\n"
412 - : "=&r"(tmp), "=&r"(tmp2)
414 - : "memory", "cc" );
417 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
420 - __asm__ __volatile__(
424 - " stxr %w1,%0,%3\n"
427 - : "=&r"(tmp), "=&r"(tmp2)
429 - : "memory", "cc" );
432 -static inline void a_and(volatile int *p, int v)
435 - __asm__ __volatile__(
438 - " and %w0,%w0,%w2\n"
439 - " stxr %w1,%w0,%3\n"
442 - : "=&r"(tmp), "=&r"(tmp2)
444 - : "memory", "cc" );
447 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
450 - __asm__ __volatile__(
454 - " stxr %w1,%0,%3\n"
457 - : "=&r"(tmp), "=&r"(tmp2)
459 - : "memory", "cc" );
462 -static inline void a_or_l(volatile void *p, long v)
464 - return a_or_64(p, v);
467 -static inline void a_or(volatile int *p, int v)
470 - __asm__ __volatile__(
473 - " orr %w0,%w0,%w2\n"
474 - " stxr %w1,%w0,%3\n"
477 - : "=&r"(tmp), "=&r"(tmp2)
479 - : "memory", "cc" );
482 -static inline void a_store(volatile int *p, int x)
484 - __asm__ __volatile__(
490 - : "memory", "cc" );
493 -#define a_spin a_barrier
495 -static inline void a_crash()
497 - *(volatile char *)0=0;
503 +++ b/arch/aarch64/atomic_arch.h
506 +static inline int a_ll(volatile int *p)
509 + __asm__ __volatile__ ("ldxr %0, %1" : "=r"(v) : "Q"(*p));
514 +static inline int a_sc(volatile int *p, int v)
517 + __asm__ __volatile__ ("stxr %w0,%1,%2" : "=&r"(r) : "r"(v), "Q"(*p) : "memory");
521 +#define a_barrier a_barrier
522 +static inline void a_barrier()
524 + __asm__ __volatile__ ("dmb ish" : : : "memory");
527 +#define a_pre_llsc a_barrier
528 +#define a_post_llsc a_barrier
530 +#define a_cas_p a_cas_p
531 +static inline void *a_cas_p(volatile void *p, void *t, void *s)
534 + __asm__ __volatile__(
539 + " stxr %w0,%2,%3\n"
544 + : "r"(t), "r"(s), "Q"(*(void *volatile *)p)
549 +#define a_ctz_64 a_ctz_64
550 +static inline int a_ctz_64(uint64_t x)
555 + : "=r"(x) : "r"(x));
558 --- a/arch/aarch64/pthread_arch.h
559 +++ b/arch/aarch64/pthread_arch.h
560 @@ -8,4 +8,4 @@ static inline struct pthread *__pthread_
562 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 16)
564 -#define CANCEL_REG_IP 33
566 --- a/arch/arm/atomic.h
569 -#ifndef _INTERNAL_ATOMIC_H
570 -#define _INTERNAL_ATOMIC_H
574 -static inline int a_ctz_l(unsigned long x)
576 - static const char debruijn32[32] = {
577 - 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
578 - 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
580 - return debruijn32[(x&-x)*0x076be629 >> 27];
583 -static inline int a_ctz_64(uint64_t x)
588 - return 32 + a_ctz_l(y);
593 -#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
595 -static inline void a_barrier()
597 - __asm__ __volatile__("dmb ish");
600 -static inline int a_cas(volatile int *p, int t, int s)
603 - __asm__ __volatile__(
608 - " strex %0,%2,%3\n"
614 - : "r"(t), "r"(s), "Q"(*p)
615 - : "memory", "cc" );
619 -static inline int a_swap(volatile int *x, int v)
622 - __asm__ __volatile__(
625 - " strex %1,%2,%3\n"
629 - : "=&r"(old), "=&r"(tmp)
631 - : "memory", "cc" );
635 -static inline int a_fetch_add(volatile int *x, int v)
638 - __asm__ __volatile__(
642 - " strex %1,%0,%3\n"
646 - : "=&r"(old), "=&r"(tmp)
648 - : "memory", "cc" );
652 -static inline void a_inc(volatile int *x)
655 - __asm__ __volatile__(
659 - " strex %1,%0,%2\n"
663 - : "=&r"(tmp), "=&r"(tmp2)
665 - : "memory", "cc" );
668 -static inline void a_dec(volatile int *x)
671 - __asm__ __volatile__(
675 - " strex %1,%0,%2\n"
679 - : "=&r"(tmp), "=&r"(tmp2)
681 - : "memory", "cc" );
684 -static inline void a_and(volatile int *x, int v)
687 - __asm__ __volatile__(
691 - " strex %1,%0,%3\n"
695 - : "=&r"(tmp), "=&r"(tmp2)
697 - : "memory", "cc" );
700 -static inline void a_or(volatile int *x, int v)
703 - __asm__ __volatile__(
707 - " strex %1,%0,%3\n"
711 - : "=&r"(tmp), "=&r"(tmp2)
713 - : "memory", "cc" );
716 -static inline void a_store(volatile int *p, int x)
718 - __asm__ __volatile__(
724 - : "memory", "cc" );
729 -int __a_cas(int, int, volatile int *) __attribute__((__visibility__("hidden")));
730 -#define __k_cas __a_cas
732 -static inline void a_barrier()
734 - __asm__ __volatile__("bl __a_barrier"
735 - : : : "memory", "cc", "ip", "lr" );
738 -static inline int a_cas(volatile int *p, int t, int s)
742 - if (!__k_cas(t, s, p))
749 -static inline int a_swap(volatile int *x, int v)
753 - while (__k_cas(old, v, x));
757 -static inline int a_fetch_add(volatile int *x, int v)
761 - while (__k_cas(old, old+v, x));
765 -static inline void a_inc(volatile int *x)
770 -static inline void a_dec(volatile int *x)
772 - a_fetch_add(x, -1);
775 -static inline void a_store(volatile int *p, int x)
782 -static inline void a_and(volatile int *p, int v)
786 - while (__k_cas(old, old&v, p));
789 -static inline void a_or(volatile int *p, int v)
793 - while (__k_cas(old, old|v, p));
798 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
800 - return (void *)a_cas(p, (int)t, (int)s);
803 -#define a_spin a_barrier
805 -static inline void a_crash()
807 - *(volatile char *)0=0;
810 -static inline void a_or_l(volatile void *p, long v)
815 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
817 - union { uint64_t v; uint32_t r[2]; } u = { v };
818 - a_and((int *)p, u.r[0]);
819 - a_and((int *)p+1, u.r[1]);
822 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
824 - union { uint64_t v; uint32_t r[2]; } u = { v };
825 - a_or((int *)p, u.r[0]);
826 - a_or((int *)p+1, u.r[1]);
831 +++ b/arch/arm/atomic_arch.h
833 +__attribute__((__visibility__("hidden")))
834 +extern const void *__arm_atomics[3]; /* gettp, cas, barrier */
836 +#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__) && !__thumb__) \
837 + || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
840 +static inline int a_ll(volatile int *p)
843 + __asm__ __volatile__ ("ldrex %0, %1" : "=r"(v) : "Q"(*p));
848 +static inline int a_sc(volatile int *p, int v)
851 + __asm__ __volatile__ ("strex %0,%1,%2" : "=&r"(r) : "r"(v), "Q"(*p) : "memory");
855 +#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
857 +#define a_barrier a_barrier
858 +static inline void a_barrier()
860 + __asm__ __volatile__ ("dmb ish" : : : "memory");
865 +#define a_pre_llsc a_barrier
866 +#define a_post_llsc a_barrier
871 +static inline int a_cas(volatile int *p, int t, int s)
874 + register int r0 __asm__("r0") = t;
875 + register int r1 __asm__("r1") = s;
876 + register volatile int *r2 __asm__("r2") = p;
878 + __asm__ __volatile__ (
880 + : "+r"(r0) : "r"(r1), "r"(r2)
881 + : "memory", "r3", "lr", "ip", "cc" );
883 + if ((old=*p)!=t) return old;
890 +#define a_barrier a_barrier
891 +static inline void a_barrier()
893 + __asm__ __volatile__("bl __a_barrier"
894 + : : : "memory", "cc", "ip", "lr" );
897 --- a/arch/arm/pthread_arch.h
898 +++ b/arch/arm/pthread_arch.h
899 @@ -27,4 +27,4 @@ static inline pthread_t __pthread_self()
901 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
903 -#define CANCEL_REG_IP 18
904 +#define MC_PC arm_pc
905 --- a/arch/arm/reloc.h
906 +++ b/arch/arm/reloc.h
908 #define ENDIAN_SUFFIX ""
912 -#define FP_SUFFIX ""
915 #define FP_SUFFIX "hf"
917 +#define FP_SUFFIX ""
920 #define LDSO_ARCH "arm" ENDIAN_SUFFIX FP_SUFFIX
922 #define REL_TPOFF R_ARM_TLS_TPOFF32
923 //#define REL_TLSDESC R_ARM_TLS_DESC
926 #define CRTJMP(pc,sp) __asm__ __volatile__( \
927 "mov sp,%1 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
929 -#define CRTJMP(pc,sp) __asm__ __volatile__( \
930 - "mov sp,%1 ; tst %0,#1 ; moveq pc,%0 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
932 --- a/arch/arm/src/__aeabi_atexit.c
935 -int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
937 -int __aeabi_atexit (void *obj, void (*func) (void *), void *d)
939 - return __cxa_atexit (func, obj, d);
941 --- a/arch/arm/src/__aeabi_memclr.c
947 -void __aeabi_memclr(void *dest, size_t n)
949 - memset(dest, 0, n);
951 -weak_alias(__aeabi_memclr, __aeabi_memclr4);
952 -weak_alias(__aeabi_memclr, __aeabi_memclr8);
953 --- a/arch/arm/src/__aeabi_memcpy.c
959 -void __aeabi_memcpy(void *restrict dest, const void *restrict src, size_t n)
961 - memcpy(dest, src, n);
963 -weak_alias(__aeabi_memcpy, __aeabi_memcpy4);
964 -weak_alias(__aeabi_memcpy, __aeabi_memcpy8);
965 --- a/arch/arm/src/__aeabi_memmove.c
971 -void __aeabi_memmove(void *dest, const void *src, size_t n)
973 - memmove(dest, src, n);
975 -weak_alias(__aeabi_memmove, __aeabi_memmove4);
976 -weak_alias(__aeabi_memmove, __aeabi_memmove8);
977 --- a/arch/arm/src/__aeabi_memset.c
983 -void __aeabi_memset(void *dest, size_t n, int c)
985 - memset(dest, c, n);
987 -weak_alias(__aeabi_memset, __aeabi_memset4);
988 -weak_alias(__aeabi_memset, __aeabi_memset8);
989 --- a/arch/arm/src/__set_thread_area.c
994 -#include "pthread_impl.h"
997 -#define HWCAP_TLS (1 << 15)
999 -extern const unsigned char __attribute__((__visibility__("hidden")))
1000 - __a_barrier_dummy[], __a_barrier_oldkuser[],
1001 - __a_barrier_v6[], __a_barrier_v7[],
1002 - __a_cas_dummy[], __a_cas_v6[], __a_cas_v7[],
1003 - __a_gettp_dummy[];
1005 -#define __a_barrier_kuser 0xffff0fa0
1006 -#define __a_cas_kuser 0xffff0fc0
1007 -#define __a_gettp_kuser 0xffff0fe0
1009 -extern uintptr_t __attribute__((__visibility__("hidden")))
1010 - __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;
1012 -#define SET(op,ver) (__a_##op##_ptr = \
1013 - (uintptr_t)__a_##op##_##ver - (uintptr_t)__a_##op##_dummy)
1015 -int __set_thread_area(void *p)
1017 -#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
1018 - if (__hwcap & HWCAP_TLS) {
1022 - for (aux=libc.auxv; *aux; aux+=2) {
1023 - if (*aux != AT_PLATFORM) continue;
1024 - const char *s = (void *)aux[1];
1025 - if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;
1031 - int ver = *(int *)0xffff0ffc;
1032 - SET(gettp, kuser);
1034 - SET(barrier, kuser);
1035 - if (ver < 2) a_crash();
1036 - if (ver < 3) SET(barrier, oldkuser);
1039 - return __syscall(0xf0005, p);
1041 --- a/arch/arm/src/arm/atomics.s
1046 -.global __a_barrier
1047 -.hidden __a_barrier
1048 -.type __a_barrier,%function
1053 -1: .word __a_barrier_ptr-1b
1054 -.global __a_barrier_dummy
1055 -.hidden __a_barrier_dummy
1060 -.global __a_barrier_oldkuser
1061 -.hidden __a_barrier_oldkuser
1062 -__a_barrier_oldkuser:
1063 - push {r0,r1,r2,r3,ip,lr}
1066 - ldr ip,=0xffff0fc0
1069 - pop {r0,r1,r2,r3,ip,lr}
1073 -.global __a_barrier_v6
1074 -.hidden __a_barrier_v6
1076 - mcr p15,0,r0,c7,c10,5
1078 -.global __a_barrier_v7
1079 -.hidden __a_barrier_v7
1081 - .word 0xf57ff05b /* dmb ish */
1086 -.type __a_cas,%function
1091 -1: .word __a_cas_ptr-1b
1092 -.global __a_cas_dummy
1093 -.hidden __a_cas_dummy
1106 - mcr p15,0,r0,c7,c10,5
1107 -1: .word 0xe1920f9f /* ldrex r0,[r2] */
1109 - .word 0x01820f91 /* strexeq r0,r1,[r2] */
1112 - mcr p15,0,r0,c7,c10,5
1118 - .word 0xf57ff05b /* dmb ish */
1119 -1: .word 0xe1920f9f /* ldrex r0,[r2] */
1121 - .word 0x01820f91 /* strexeq r0,r1,[r2] */
1124 - .word 0xf57ff05b /* dmb ish */
1127 -.global __aeabi_read_tp
1128 -.type __aeabi_read_tp,%function
1133 -.type __a_gettp,%function
1138 -1: .word __a_gettp_ptr-1b
1139 -.global __a_gettp_dummy
1140 -.hidden __a_gettp_dummy
1142 - mrc p15,0,r0,c13,c0,3
1146 -.global __a_barrier_ptr
1147 -.hidden __a_barrier_ptr
1151 -.global __a_cas_ptr
1152 -.hidden __a_cas_ptr
1156 -.global __a_gettp_ptr
1157 -.hidden __a_gettp_ptr
1160 --- a/arch/arm/src/find_exidx.c
1163 -#define _GNU_SOURCE
1165 -#include <stdint.h>
1167 -struct find_exidx_data {
1168 - uintptr_t pc, exidx_start;
1172 -static int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr)
1174 - struct find_exidx_data *data = ptr;
1175 - const ElfW(Phdr) *phdr = info->dlpi_phdr;
1176 - uintptr_t addr, exidx_start = 0;
1177 - int i, match = 0, exidx_len = 0;
1179 - for (i = info->dlpi_phnum; i > 0; i--, phdr++) {
1180 - addr = info->dlpi_addr + phdr->p_vaddr;
1181 - switch (phdr->p_type) {
1183 - match |= data->pc >= addr && data->pc < addr + phdr->p_memsz;
1185 - case PT_ARM_EXIDX:
1186 - exidx_start = addr;
1187 - exidx_len = phdr->p_memsz;
1191 - data->exidx_start = exidx_start;
1192 - data->exidx_len = exidx_len;
1196 -uintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount)
1198 - struct find_exidx_data data;
1200 - if (dl_iterate_phdr(find_exidx, &data) <= 0)
1202 - *pcount = data.exidx_len / 8;
1203 - return data.exidx_start;
1205 --- a/arch/i386/atomic.h
1208 -#ifndef _INTERNAL_ATOMIC_H
1209 -#define _INTERNAL_ATOMIC_H
1211 -#include <stdint.h>
1213 -static inline int a_ctz_64(uint64_t x)
1216 - __asm__( "bsf %1,%0 ; jnz 1f ; bsf %2,%0 ; addl $32,%0\n1:"
1217 - : "=&r"(r) : "r"((unsigned)x), "r"((unsigned)(x>>32)) );
1221 -static inline int a_ctz_l(unsigned long x)
1224 - __asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
1228 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
1230 - __asm__( "lock ; andl %1, (%0) ; lock ; andl %2, 4(%0)"
1231 - : : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) : "memory" );
1234 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
1236 - __asm__( "lock ; orl %1, (%0) ; lock ; orl %2, 4(%0)"
1237 - : : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) : "memory" );
1240 -static inline void a_or_l(volatile void *p, long v)
1242 - __asm__( "lock ; orl %1, %0"
1243 - : "=m"(*(long *)p) : "r"(v) : "memory" );
1246 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
1248 - __asm__( "lock ; cmpxchg %3, %1"
1249 - : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
1253 -static inline int a_cas(volatile int *p, int t, int s)
1255 - __asm__( "lock ; cmpxchg %3, %1"
1256 - : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
1260 -static inline void a_or(volatile int *p, int v)
1262 - __asm__( "lock ; orl %1, %0"
1263 - : "=m"(*p) : "r"(v) : "memory" );
1266 -static inline void a_and(volatile int *p, int v)
1268 - __asm__( "lock ; andl %1, %0"
1269 - : "=m"(*p) : "r"(v) : "memory" );
1272 -static inline int a_swap(volatile int *x, int v)
1274 - __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
1278 -#define a_xchg a_swap
1280 -static inline int a_fetch_add(volatile int *x, int v)
1282 - __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
1286 -static inline void a_inc(volatile int *x)
1288 - __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
1291 -static inline void a_dec(volatile int *x)
1293 - __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
1296 -static inline void a_store(volatile int *p, int x)
1298 - __asm__( "movl %1, %0 ; lock ; orl $0,(%%esp)" : "=m"(*p) : "r"(x) : "memory" );
1301 -static inline void a_spin()
1303 - __asm__ __volatile__( "pause" : : : "memory" );
1306 -static inline void a_barrier()
1308 - __asm__ __volatile__( "" : : : "memory" );
1311 -static inline void a_crash()
1313 - __asm__ __volatile__( "hlt" : : : "memory" );
1319 +++ b/arch/i386/atomic_arch.h
1321 +#define a_ctz_64 a_ctz_64
1322 +static inline int a_ctz_64(uint64_t x)
1325 + __asm__( "bsf %1,%0 ; jnz 1f ; bsf %2,%0 ; addl $32,%0\n1:"
1326 + : "=&r"(r) : "r"((unsigned)x), "r"((unsigned)(x>>32)) );
1330 +#define a_ctz_l a_ctz_l
1331 +static inline int a_ctz_l(unsigned long x)
1334 + __asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
1338 +#define a_and_64 a_and_64
1339 +static inline void a_and_64(volatile uint64_t *p, uint64_t v)
1341 + __asm__( "lock ; andl %1, (%0) ; lock ; andl %2, 4(%0)"
1342 + : : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) : "memory" );
1345 +#define a_or_64 a_or_64
1346 +static inline void a_or_64(volatile uint64_t *p, uint64_t v)
1348 + __asm__( "lock ; orl %1, (%0) ; lock ; orl %2, 4(%0)"
1349 + : : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) : "memory" );
1352 +#define a_or_l a_or_l
1353 +static inline void a_or_l(volatile void *p, long v)
1355 + __asm__( "lock ; orl %1, %0"
1356 + : "=m"(*(long *)p) : "r"(v) : "memory" );
1359 +#define a_cas a_cas
1360 +static inline int a_cas(volatile int *p, int t, int s)
1362 + __asm__( "lock ; cmpxchg %3, %1"
1363 + : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
1368 +static inline void a_or(volatile int *p, int v)
1370 + __asm__( "lock ; orl %1, %0"
1371 + : "=m"(*p) : "r"(v) : "memory" );
1374 +#define a_and a_and
1375 +static inline void a_and(volatile int *p, int v)
1377 + __asm__( "lock ; andl %1, %0"
1378 + : "=m"(*p) : "r"(v) : "memory" );
1381 +#define a_swap a_swap
1382 +static inline int a_swap(volatile int *x, int v)
1384 + __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
1388 +#define a_fetch_add a_fetch_add
1389 +static inline int a_fetch_add(volatile int *x, int v)
1391 + __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
1395 +#define a_inc a_inc
1396 +static inline void a_inc(volatile int *x)
1398 + __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
1401 +#define a_dec a_dec
1402 +static inline void a_dec(volatile int *x)
1404 + __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
1407 +#define a_store a_store
1408 +static inline void a_store(volatile int *p, int x)
1410 + __asm__( "movl %1, %0 ; lock ; orl $0,(%%esp)" : "=m"(*p) : "r"(x) : "memory" );
1413 +#define a_spin a_spin
1414 +static inline void a_spin()
1416 + __asm__ __volatile__( "pause" : : : "memory" );
1419 +#define a_barrier a_barrier
1420 +static inline void a_barrier()
1422 + __asm__ __volatile__( "" : : : "memory" );
1425 +#define a_crash a_crash
1426 +static inline void a_crash()
1428 + __asm__ __volatile__( "hlt" : : : "memory" );
1430 --- a/arch/i386/bits/alltypes.h.in
1431 +++ b/arch/i386/bits/alltypes.h.in
1432 @@ -26,10 +26,12 @@ TYPEDEF long double float_t;
1433 TYPEDEF long double double_t;
1437 -TYPEDEF struct { alignas(8) long long __ll; long double __ld; } max_align_t;
1439 +#if !defined(__cplusplus)
1440 TYPEDEF struct { _Alignas(8) long long __ll; long double __ld; } max_align_t;
1441 +#elif defined(__GNUC__)
1442 +TYPEDEF struct { __attribute__((__aligned__(8))) long long __ll; long double __ld; } max_align_t;
1444 +TYPEDEF struct { alignas(8) long long __ll; long double __ld; } max_align_t;
1447 TYPEDEF long time_t;
1448 --- a/arch/i386/pthread_arch.h
1449 +++ b/arch/i386/pthread_arch.h
1450 @@ -7,4 +7,4 @@ static inline struct pthread *__pthread_
1452 #define TP_ADJ(p) (p)
1454 -#define CANCEL_REG_IP 14
1455 +#define MC_PC gregs[REG_EIP]
1456 --- a/arch/microblaze/atomic.h
1459 -#ifndef _INTERNAL_ATOMIC_H
1460 -#define _INTERNAL_ATOMIC_H
1462 -#include <stdint.h>
1464 -static inline int a_ctz_l(unsigned long x)
1466 - static const char debruijn32[32] = {
1467 - 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
1468 - 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
1470 - return debruijn32[(x&-x)*0x076be629 >> 27];
1473 -static inline int a_ctz_64(uint64_t x)
1478 - return 32 + a_ctz_l(y);
1480 - return a_ctz_l(y);
1483 -static inline int a_cas(volatile int *p, int t, int s)
1485 - register int old, tmp;
1486 - __asm__ __volatile__ (
1487 - " addi %0, r0, 0\n"
1488 - "1: lwx %0, %2, r0\n"
1489 - " rsubk %1, %0, %3\n"
1491 - " swx %4, %2, r0\n"
1492 - " addic %1, r0, 0\n"
1495 - : "=&r"(old), "=&r"(tmp)
1496 - : "r"(p), "r"(t), "r"(s)
1497 - : "cc", "memory" );
1501 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
1503 - return (void *)a_cas(p, (int)t, (int)s);
1506 -static inline int a_swap(volatile int *x, int v)
1508 - register int old, tmp;
1509 - __asm__ __volatile__ (
1510 - " addi %0, r0, 0\n"
1511 - "1: lwx %0, %2, r0\n"
1512 - " swx %3, %2, r0\n"
1513 - " addic %1, r0, 0\n"
1516 - : "=&r"(old), "=&r"(tmp)
1518 - : "cc", "memory" );
1522 -static inline int a_fetch_add(volatile int *x, int v)
1524 - register int new, tmp;
1525 - __asm__ __volatile__ (
1526 - " addi %0, r0, 0\n"
1527 - "1: lwx %0, %2, r0\n"
1528 - " addk %0, %0, %3\n"
1529 - " swx %0, %2, r0\n"
1530 - " addic %1, r0, 0\n"
1533 - : "=&r"(new), "=&r"(tmp)
1535 - : "cc", "memory" );
1539 -static inline void a_inc(volatile int *x)
1541 - a_fetch_add(x, 1);
1544 -static inline void a_dec(volatile int *x)
1546 - a_fetch_add(x, -1);
1549 -static inline void a_store(volatile int *p, int x)
1551 - __asm__ __volatile__ (
1553 - : "=m"(*p) : "r"(x) : "memory" );
1556 -#define a_spin a_barrier
1558 -static inline void a_barrier()
1560 - a_cas(&(int){0}, 0, 0);
1563 -static inline void a_crash()
1565 - *(volatile char *)0=0;
1568 -static inline void a_and(volatile int *p, int v)
1572 - while (a_cas(p, old, old&v) != old);
1575 -static inline void a_or(volatile int *p, int v)
1579 - while (a_cas(p, old, old|v) != old);
1582 -static inline void a_or_l(volatile void *p, long v)
1587 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
1589 - union { uint64_t v; uint32_t r[2]; } u = { v };
1590 - a_and((int *)p, u.r[0]);
1591 - a_and((int *)p+1, u.r[1]);
1594 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
1596 - union { uint64_t v; uint32_t r[2]; } u = { v };
1597 - a_or((int *)p, u.r[0]);
1598 - a_or((int *)p+1, u.r[1]);
1603 +++ b/arch/microblaze/atomic_arch.h
1605 +#define a_cas a_cas
1606 +static inline int a_cas(volatile int *p, int t, int s)
1608 + register int old, tmp;
1609 + __asm__ __volatile__ (
1610 + " addi %0, r0, 0\n"
1611 + "1: lwx %0, %2, r0\n"
1612 + " rsubk %1, %0, %3\n"
1614 + " swx %4, %2, r0\n"
1615 + " addic %1, r0, 0\n"
1618 + : "=&r"(old), "=&r"(tmp)
1619 + : "r"(p), "r"(t), "r"(s)
1620 + : "cc", "memory" );
1624 +#define a_swap a_swap
1625 +static inline int a_swap(volatile int *x, int v)
1627 + register int old, tmp;
1628 + __asm__ __volatile__ (
1629 + " addi %0, r0, 0\n"
1630 + "1: lwx %0, %2, r0\n"
1631 + " swx %3, %2, r0\n"
1632 + " addic %1, r0, 0\n"
1635 + : "=&r"(old), "=&r"(tmp)
1637 + : "cc", "memory" );
1641 +#define a_fetch_add a_fetch_add
1642 +static inline int a_fetch_add(volatile int *x, int v)
1644 + register int new, tmp;
1645 + __asm__ __volatile__ (
1646 + " addi %0, r0, 0\n"
1647 + "1: lwx %0, %2, r0\n"
1648 + " addk %0, %0, %3\n"
1649 + " swx %0, %2, r0\n"
1650 + " addic %1, r0, 0\n"
1653 + : "=&r"(new), "=&r"(tmp)
1655 + : "cc", "memory" );
1658 --- a/arch/microblaze/pthread_arch.h
1659 +++ b/arch/microblaze/pthread_arch.h
1660 @@ -7,4 +7,4 @@ static inline struct pthread *__pthread_
1662 #define TP_ADJ(p) (p)
1664 -#define CANCEL_REG_IP 32
1665 +#define MC_PC regs.pc
1666 --- a/arch/mips/atomic.h
1669 -#ifndef _INTERNAL_ATOMIC_H
1670 -#define _INTERNAL_ATOMIC_H
1672 -#include <stdint.h>
1674 -static inline int a_ctz_l(unsigned long x)
1676 - static const char debruijn32[32] = {
1677 - 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
1678 - 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
1680 - return debruijn32[(x&-x)*0x076be629 >> 27];
1683 -static inline int a_ctz_64(uint64_t x)
1688 - return 32 + a_ctz_l(y);
1690 - return a_ctz_l(y);
1693 -static inline int a_cas(volatile int *p, int t, int s)
1696 - __asm__ __volatile__(
1699 - ".set noreorder\n"
1702 - " bne %0, %3, 1f\n"
1703 - " addu %1, %4, $0\n"
1705 - " beq %1, $0, 1b\n"
1710 - : "=&r"(t), "=&r"(dummy), "+m"(*p) : "r"(t), "r"(s) : "memory" );
1714 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
1716 - return (void *)a_cas(p, (int)t, (int)s);
1719 -static inline int a_swap(volatile int *x, int v)
1722 - __asm__ __volatile__(
1725 - ".set noreorder\n"
1728 - " addu %1, %3, $0\n"
1730 - " beq %1, $0, 1b\n"
1734 - : "=&r"(old), "=&r"(dummy), "+m"(*x) : "r"(v) : "memory" );
1738 -static inline int a_fetch_add(volatile int *x, int v)
1741 - __asm__ __volatile__(
1744 - ".set noreorder\n"
1747 - " addu %1, %0, %3\n"
1749 - " beq %1, $0, 1b\n"
1753 - : "=&r"(old), "=&r"(dummy), "+m"(*x) : "r"(v) : "memory" );
1757 -static inline void a_inc(volatile int *x)
1760 - __asm__ __volatile__(
1763 - ".set noreorder\n"
1766 - " addu %0, %0, 1\n"
1768 - " beq %0, $0, 1b\n"
1772 - : "=&r"(dummy), "+m"(*x) : : "memory" );
1775 -static inline void a_dec(volatile int *x)
1778 - __asm__ __volatile__(
1781 - ".set noreorder\n"
1784 - " subu %0, %0, 1\n"
1786 - " beq %0, $0, 1b\n"
1790 - : "=&r"(dummy), "+m"(*x) : : "memory" );
1793 -static inline void a_store(volatile int *p, int x)
1795 - __asm__ __volatile__(
1798 - ".set noreorder\n"
1803 - : "+m"(*p) : "r"(x) : "memory" );
1806 -#define a_spin a_barrier
1808 -static inline void a_barrier()
1810 - a_cas(&(int){0}, 0, 0);
1813 -static inline void a_crash()
1815 - *(volatile char *)0=0;
1818 -static inline void a_and(volatile int *p, int v)
1821 - __asm__ __volatile__(
1824 - ".set noreorder\n"
1827 - " and %0, %0, %2\n"
1829 - " beq %0, $0, 1b\n"
1833 - : "=&r"(dummy), "+m"(*p) : "r"(v) : "memory" );
1836 -static inline void a_or(volatile int *p, int v)
1839 - __asm__ __volatile__(
1842 - ".set noreorder\n"
1845 - " or %0, %0, %2\n"
1847 - " beq %0, $0, 1b\n"
1851 - : "=&r"(dummy), "+m"(*p) : "r"(v) : "memory" );
1854 -static inline void a_or_l(volatile void *p, long v)
1859 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
1861 - union { uint64_t v; uint32_t r[2]; } u = { v };
1862 - a_and((int *)p, u.r[0]);
1863 - a_and((int *)p+1, u.r[1]);
1866 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
1868 - union { uint64_t v; uint32_t r[2]; } u = { v };
1869 - a_or((int *)p, u.r[0]);
1870 - a_or((int *)p+1, u.r[1]);
1875 +++ b/arch/mips/atomic_arch.h
1878 +static inline int a_ll(volatile int *p)
1881 + __asm__ __volatile__ (
1882 + ".set push ; .set mips2\n\t"
1885 + : "=r"(v) : "m"(*p));
1890 +static inline int a_sc(volatile int *p, int v)
1893 + __asm__ __volatile__ (
1894 + ".set push ; .set mips2\n\t"
1897 + : "=r"(r), "=m"(*p) : "0"(v) : "memory");
1901 +#define a_barrier a_barrier
1902 +static inline void a_barrier()
1904 + /* mips2 sync, but using too many directives causes
1905 + * gcc not to inline it, so encode with .long instead. */
1906 + __asm__ __volatile__ (".long 0xf" : : : "memory");
1908 + __asm__ __volatile__ (
1909 + ".set push ; .set mips2 ; sync ; .set pop"
1914 +#define a_pre_llsc a_barrier
1915 +#define a_post_llsc a_barrier
1916 --- a/arch/mips/crt_arch.h
1917 +++ b/arch/mips/crt_arch.h
1918 @@ -4,13 +4,16 @@ __asm__(
1920 ".global _" START "\n"
1921 ".global " START "\n"
1922 +".global " START "_data\n"
1923 ".type _" START ", @function\n"
1924 ".type " START ", @function\n"
1925 +".type " START "_data, @function\n"
1931 +"" START "_data: \n"
1932 +" .gpword " START "_data \n"
1933 " .gpword " START "_c \n"
1935 ".hidden _DYNAMIC \n"
1936 --- a/arch/mips/pthread_arch.h
1937 +++ b/arch/mips/pthread_arch.h
1938 @@ -16,4 +16,4 @@ static inline struct pthread *__pthread_
1940 #define DTP_OFFSET 0x8000
1942 -#define CANCEL_REG_IP (3-(union {int __i; char __b;}){1}.__b)
1944 --- a/arch/mips/syscall_arch.h
1945 +++ b/arch/mips/syscall_arch.h
1947 ((union { long long ll; long l[2]; }){ .ll = x }).l[1]
1948 #define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
1951 __attribute__((visibility("hidden")))
1953 long (__syscall)(long, ...);
1955 #define SYSCALL_RLIM_INFINITY (-1UL/2)
1956 --- a/arch/or1k/atomic.h
1959 -#ifndef _INTERNAL_ATOMIC_H
1960 -#define _INTERNAL_ATOMIC_H
1962 -#include <stdint.h>
1964 -static inline int a_ctz_l(unsigned long x)
1966 - static const char debruijn32[32] = {
1967 - 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
1968 - 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
1970 - return debruijn32[(x&-x)*0x076be629 >> 27];
1973 -static inline int a_ctz_64(uint64_t x)
1978 - return 32 + a_ctz_l(y);
1980 - return a_ctz_l(y);
1983 -static inline int a_cas(volatile int *p, int t, int s)
1985 - __asm__("1: l.lwa %0, %1\n"
1986 - " l.sfeq %0, %2\n"
1993 - : "=&r"(t), "+m"(*p) : "r"(t), "r"(s) : "cc", "memory" );
1997 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
1999 - return (void *)a_cas(p, (int)t, (int)s);
2002 -static inline int a_swap(volatile int *x, int v)
2006 - while (a_cas(x, old, v) != old);
2010 -static inline int a_fetch_add(volatile int *x, int v)
2014 - while (a_cas(x, old, old+v) != old);
2018 -static inline void a_inc(volatile int *x)
2020 - a_fetch_add(x, 1);
2023 -static inline void a_dec(volatile int *x)
2025 - a_fetch_add(x, -1);
2028 -static inline void a_store(volatile int *p, int x)
2033 -#define a_spin a_barrier
2035 -static inline void a_barrier()
2037 - a_cas(&(int){0}, 0, 0);
2040 -static inline void a_crash()
2042 - *(volatile char *)0=0;
2045 -static inline void a_and(volatile int *p, int v)
2049 - while (a_cas(p, old, old&v) != old);
2052 -static inline void a_or(volatile int *p, int v)
2056 - while (a_cas(p, old, old|v) != old);
2059 -static inline void a_or_l(volatile void *p, long v)
2064 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
2066 - union { uint64_t v; uint32_t r[2]; } u = { v };
2067 - a_and((int *)p, u.r[0]);
2068 - a_and((int *)p+1, u.r[1]);
2071 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
2073 - union { uint64_t v; uint32_t r[2]; } u = { v };
2074 - a_or((int *)p, u.r[0]);
2075 - a_or((int *)p+1, u.r[1]);
2080 +++ b/arch/or1k/atomic_arch.h
2082 +#define a_cas a_cas
2083 +static inline int a_cas(volatile int *p, int t, int s)
2085 + __asm__("1: l.lwa %0, %1\n"
2086 + " l.sfeq %0, %2\n"
2093 + : "=&r"(t), "+m"(*p) : "r"(t), "r"(s) : "cc", "memory" );
2096 --- a/arch/or1k/pthread_arch.h
2097 +++ b/arch/or1k/pthread_arch.h
2098 @@ -14,5 +14,4 @@ static inline struct pthread *__pthread_
2099 #define TLS_ABOVE_TP
2100 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
2102 -/* word-offset to 'pc' in mcontext_t */
2103 -#define CANCEL_REG_IP 32
2104 +#define MC_PC regs.pc
2105 --- a/arch/powerpc/atomic.h
2108 -#ifndef _INTERNAL_ATOMIC_H
2109 -#define _INTERNAL_ATOMIC_H
2111 -#include <stdint.h>
2112 -#include <endian.h>
2114 -static inline int a_ctz_l(unsigned long x)
2116 - static const char debruijn32[32] = {
2117 - 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
2118 - 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
2120 - return debruijn32[(x&-x)*0x076be629 >> 27];
2123 -static inline int a_ctz_64(uint64_t x)
2128 - return 32 + a_ctz_l(y);
2130 - return a_ctz_l(y);
2133 -static inline int a_cas(volatile int *p, int t, int s)
2137 - "1: lwarx %0, 0, %4\n"
2140 - " stwcx. %3, 0, %4\n"
2144 - : "=&r"(t), "+m"(*p) : "r"(t), "r"(s), "r"(p) : "cc", "memory" );
2148 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
2150 - return (void *)a_cas(p, (int)t, (int)s);
2153 -static inline int a_swap(volatile int *x, int v)
2157 - while (a_cas(x, old, v) != old);
2161 -static inline int a_fetch_add(volatile int *x, int v)
2165 - while (a_cas(x, old, old+v) != old);
2169 -static inline void a_inc(volatile int *x)
2171 - a_fetch_add(x, 1);
2174 -static inline void a_dec(volatile int *x)
2176 - a_fetch_add(x, -1);
2179 -static inline void a_store(volatile int *p, int x)
2181 - __asm__ __volatile__ ("\n"
2185 - : "=m"(*p) : "r"(x) : "memory" );
2188 -#define a_spin a_barrier
2190 -static inline void a_barrier()
2192 - a_cas(&(int){0}, 0, 0);
2195 -static inline void a_crash()
2197 - *(volatile char *)0=0;
2200 -static inline void a_and(volatile int *p, int v)
2204 - while (a_cas(p, old, old&v) != old);
2207 -static inline void a_or(volatile int *p, int v)
2211 - while (a_cas(p, old, old|v) != old);
2214 -static inline void a_or_l(volatile void *p, long v)
2219 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
2221 - union { uint64_t v; uint32_t r[2]; } u = { v };
2222 - a_and((int *)p, u.r[0]);
2223 - a_and((int *)p+1, u.r[1]);
2226 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
2228 - union { uint64_t v; uint32_t r[2]; } u = { v };
2229 - a_or((int *)p, u.r[0]);
2230 - a_or((int *)p+1, u.r[1]);
2235 +++ b/arch/powerpc/atomic_arch.h
2237 +#define a_cas a_cas
2238 +static inline int a_cas(volatile int *p, int t, int s)
2242 + "1: lwarx %0, 0, %4\n"
2245 + " stwcx. %3, 0, %4\n"
2249 + : "=&r"(t), "+m"(*p) : "r"(t), "r"(s), "r"(p) : "cc", "memory" );
2252 --- a/arch/powerpc/pthread_arch.h
2253 +++ b/arch/powerpc/pthread_arch.h
2254 @@ -15,9 +15,8 @@ static inline struct pthread *__pthread_
2256 #define DTP_OFFSET 0x8000
2258 -// offset of the PC register in mcontext_t, divided by the system wordsize
2259 // the kernel calls the ip "nip", it's the first saved value after the 32
2261 -#define CANCEL_REG_IP 32
2262 +#define MC_PC gregs[32]
2264 #define CANARY canary_at_end
2265 --- a/arch/sh/atomic.h
2268 -#ifndef _INTERNAL_ATOMIC_H
2269 -#define _INTERNAL_ATOMIC_H
2271 -#include <stdint.h>
2273 -static inline int a_ctz_l(unsigned long x)
2275 - static const char debruijn32[32] = {
2276 - 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
2277 - 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
2279 - return debruijn32[(x&-x)*0x076be629 >> 27];
2282 -static inline int a_ctz_64(uint64_t x)
2287 - return 32 + a_ctz_l(y);
2289 - return a_ctz_l(y);
2292 -#define LLSC_CLOBBERS "r0", "t", "memory"
2293 -#define LLSC_START(mem) "synco\n" \
2294 - "0: movli.l @" mem ", r0\n"
2295 -#define LLSC_END(mem) \
2296 - "1: movco.l r0, @" mem "\n" \
2300 -static inline int __sh_cas_llsc(volatile int *p, int t, int s)
2303 - __asm__ __volatile__(
2306 - " cmp/eq %0, %2\n"
2310 - : "=&r"(old) : "r"(p), "r"(t), "r"(s) : LLSC_CLOBBERS);
2314 -static inline int __sh_swap_llsc(volatile int *x, int v)
2317 - __asm__ __volatile__(
2322 - : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
2326 -static inline int __sh_fetch_add_llsc(volatile int *x, int v)
2329 - __asm__ __volatile__(
2334 - : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
2338 -static inline void __sh_store_llsc(volatile int *p, int x)
2340 - __asm__ __volatile__(
2342 - " mov.l %1, @%0\n"
2344 - : : "r"(p), "r"(x) : "memory");
2347 -static inline void __sh_and_llsc(volatile int *x, int v)
2349 - __asm__ __volatile__(
2353 - : : "r"(x), "r"(v) : LLSC_CLOBBERS);
2356 -static inline void __sh_or_llsc(volatile int *x, int v)
2358 - __asm__ __volatile__(
2362 - : : "r"(x), "r"(v) : LLSC_CLOBBERS);
2366 -#define a_cas(p,t,s) __sh_cas_llsc(p,t,s)
2367 -#define a_swap(x,v) __sh_swap_llsc(x,v)
2368 -#define a_fetch_add(x,v) __sh_fetch_add_llsc(x, v)
2369 -#define a_store(x,v) __sh_store_llsc(x, v)
2370 -#define a_and(x,v) __sh_and_llsc(x, v)
2371 -#define a_or(x,v) __sh_or_llsc(x, v)
2374 -int __sh_cas(volatile int *, int, int);
2375 -int __sh_swap(volatile int *, int);
2376 -int __sh_fetch_add(volatile int *, int);
2377 -void __sh_store(volatile int *, int);
2378 -void __sh_and(volatile int *, int);
2379 -void __sh_or(volatile int *, int);
2381 -#define a_cas(p,t,s) __sh_cas(p,t,s)
2382 -#define a_swap(x,v) __sh_swap(x,v)
2383 -#define a_fetch_add(x,v) __sh_fetch_add(x, v)
2384 -#define a_store(x,v) __sh_store(x, v)
2385 -#define a_and(x,v) __sh_and(x, v)
2386 -#define a_or(x,v) __sh_or(x, v)
2389 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
2391 - return (void *)a_cas(p, (int)t, (int)s);
2394 -static inline void a_inc(volatile int *x)
2396 - a_fetch_add(x, 1);
2399 -static inline void a_dec(volatile int *x)
2401 - a_fetch_add(x, -1);
2404 -#define a_spin a_barrier
2406 -static inline void a_barrier()
2408 - a_cas(&(int){0}, 0, 0);
2411 -static inline void a_crash()
2413 - *(volatile char *)0=0;
2416 -static inline void a_or_l(volatile void *p, long v)
2421 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
2423 - union { uint64_t v; uint32_t r[2]; } u = { v };
2424 - a_and((int *)p, u.r[0]);
2425 - a_and((int *)p+1, u.r[1]);
2428 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
2430 - union { uint64_t v; uint32_t r[2]; } u = { v };
2431 - a_or((int *)p, u.r[0]);
2432 - a_or((int *)p+1, u.r[1]);
2437 +++ b/arch/sh/atomic_arch.h
2439 +#if defined(__SH4A__)
2442 +static inline int a_ll(volatile int *p)
2445 + __asm__ __volatile__ ("movli.l @%1, %0" : "=z"(v) : "r"(p), "m"(*p));
2450 +static inline int a_sc(volatile int *p, int v)
2453 + __asm__ __volatile__ (
2454 + "movco.l %2, @%3 ; movt %0"
2455 + : "=r"(r), "=m"(*p) : "z"(v), "r"(p) : "memory", "cc");
2459 +#define a_barrier a_barrier
2460 +static inline void a_barrier()
2462 + __asm__ __volatile__ ("synco" : : "memory");
2465 +#define a_pre_llsc a_barrier
2466 +#define a_post_llsc a_barrier
2470 +#define a_cas a_cas
2471 +__attribute__((__visibility__("hidden"))) extern const void *__sh_cas_ptr;
2472 +static inline int a_cas(volatile int *p, int t, int s)
2474 + register int r1 __asm__("r1");
2475 + register int r2 __asm__("r2") = t;
2476 + register int r3 __asm__("r3") = s;
2477 + __asm__ __volatile__ (
2479 + : "=r"(r1), "+r"(r3) : "z"(p), "r"(r2), "r"(__sh_cas_ptr)
2480 + : "memory", "pr", "cc");
2485 --- a/arch/sh/crt_arch.h
2486 +++ b/arch/sh/crt_arch.h
2487 @@ -22,7 +22,8 @@ START ": \n"
2489 " mov.l 1f+4, r6 \n"
2491 -" bsr __fdpic_fixup \n"
2497 @@ -31,11 +32,16 @@ START ": \n"
2498 " mov.l r9, @-r15 \n"
2499 " mov.l r8, @-r15 \n"
2501 -" bsr " START "_c \n"
2506 "1: .long __ROFIXUP_LIST__@PCREL \n"
2507 " .long __ROFIXUP_END__@PCREL + 4 \n"
2508 +"2: .long " START "_c@PCREL - (3b+4-.) \n"
2510 +"4: .long __fdpic_fixup@PCREL - (5b+4-.) \n"
2515 @@ -53,13 +59,14 @@ START ": \n"
2520 -" bsr " START "_c \n"
2527 ".hidden _DYNAMIC \n"
2528 "1: .long _DYNAMIC-. \n"
2529 +"2: .long " START "_c@PCREL - (3b+4-.) \n"
2533 --- a/arch/sh/pthread_arch.h
2534 +++ b/arch/sh/pthread_arch.h
2535 @@ -8,4 +8,4 @@ static inline struct pthread *__pthread_
2536 #define TLS_ABOVE_TP
2537 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
2539 -#define CANCEL_REG_IP 17
2540 +#define MC_PC sc_pc
2541 --- a/arch/sh/reloc.h
2542 +++ b/arch/sh/reloc.h
2544 #define REL_DTPOFF R_SH_TLS_DTPOFF32
2545 #define REL_TPOFF R_SH_TLS_TPOFF32
2547 +#define DL_NOMMU_SUPPORT 1
2550 #define REL_FUNCDESC R_SH_FUNCDESC
2551 #define REL_FUNCDESC_VAL R_SH_FUNCDESC_VALUE
2552 --- a/arch/sh/src/__set_thread_area.c
2555 -#include "pthread_impl.h"
2557 -#include "sh_atomic.h"
2560 -/* Also perform sh-specific init */
2562 -#define CPU_HAS_LLSC 0x0040
2564 -__attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model, __sh_nommu;
2566 -int __set_thread_area(void *p)
2569 - __asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
2571 - if (__hwcap & CPU_HAS_LLSC) {
2572 - __sh_atomic_model = SH_A_LLSC;
2575 -#if !defined(__SH3__) && !defined(__SH4__)
2576 - for (aux=libc.auxv; *aux; aux+=2) {
2577 - if (*aux != AT_PLATFORM) continue;
2578 - const char *s = (void *)aux[1];
2579 - if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
2580 - __sh_atomic_model = SH_A_IMASK;
2585 - /* __sh_atomic_model = SH_A_GUSA; */ /* 0, default */
2589 --- a/arch/sh/src/atomic.c
2594 -#include "sh_atomic.h"
2595 -#include "atomic.h"
2598 -static inline unsigned mask()
2601 - __asm__ __volatile__ ( "\n"
2606 - : "=&r"(sr) : : "memory", "r0" );
2610 -static inline void unmask(unsigned sr)
2612 - __asm__ __volatile__ ( "ldc %0,sr" : : "r"(sr) : "memory" );
2615 -/* gusa is a hack in the kernel which lets you create a sequence of instructions
2616 - * which will be restarted if the process is preempted in the middle of the
2617 - * sequence. It will do for implementing atomics on non-smp systems. ABI is:
2618 - * r0 = address of first instruction after the atomic sequence
2619 - * r1 = original stack pointer
2620 - * r15 = -1 * length of atomic sequence in bytes
2622 -#define GUSA_CLOBBERS "r0", "r1", "memory"
2623 -#define GUSA_START(mem,old,nop) \
2625 - " mova 1f, r0\n" \
2627 - " mov r15, r1\n" \
2628 - " mov #(0f-1f), r15\n" \
2629 - "0: mov.l @" mem ", " old "\n"
2630 -/* the target of mova must be 4 byte aligned, so we may need a nop */
2631 -#define GUSA_START_ODD(mem,old) GUSA_START(mem,old,"")
2632 -#define GUSA_START_EVEN(mem,old) GUSA_START(mem,old,"\tnop\n")
2633 -#define GUSA_END(mem,new) \
2634 - " mov.l " new ", @" mem "\n" \
2635 - "1: mov r1, r15\n"
2637 -int __sh_cas(volatile int *p, int t, int s)
2639 - if (__sh_atomic_model == SH_A_LLSC) return __sh_cas_llsc(p, t, s);
2641 - if (__sh_atomic_model == SH_A_IMASK) {
2642 - unsigned sr = mask();
2644 - if (old==t) *p = s;
2650 - __asm__ __volatile__(
2651 - GUSA_START_EVEN("%1", "%0")
2652 - " cmp/eq %0, %2\n"
2654 - GUSA_END("%1", "%3")
2655 - : "=&r"(old) : "r"(p), "r"(t), "r"(s) : GUSA_CLOBBERS, "t");
2659 -int __sh_swap(volatile int *x, int v)
2661 - if (__sh_atomic_model == SH_A_LLSC) return __sh_swap_llsc(x, v);
2663 - if (__sh_atomic_model == SH_A_IMASK) {
2664 - unsigned sr = mask();
2672 - __asm__ __volatile__(
2673 - GUSA_START_EVEN("%1", "%0")
2674 - GUSA_END("%1", "%2")
2675 - : "=&r"(old) : "r"(x), "r"(v) : GUSA_CLOBBERS);
2679 -int __sh_fetch_add(volatile int *x, int v)
2681 - if (__sh_atomic_model == SH_A_LLSC) return __sh_fetch_add_llsc(x, v);
2683 - if (__sh_atomic_model == SH_A_IMASK) {
2684 - unsigned sr = mask();
2692 - __asm__ __volatile__(
2693 - GUSA_START_EVEN("%2", "%0")
2696 - GUSA_END("%2", "%1")
2697 - : "=&r"(old), "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
2701 -void __sh_store(volatile int *p, int x)
2703 - if (__sh_atomic_model == SH_A_LLSC) return __sh_store_llsc(p, x);
2704 - __asm__ __volatile__(
2705 - " mov.l %1, @%0\n"
2706 - : : "r"(p), "r"(x) : "memory");
2709 -void __sh_and(volatile int *x, int v)
2711 - if (__sh_atomic_model == SH_A_LLSC) return __sh_and_llsc(x, v);
2713 - if (__sh_atomic_model == SH_A_IMASK) {
2714 - unsigned sr = mask();
2722 - __asm__ __volatile__(
2723 - GUSA_START_ODD("%1", "%0")
2725 - GUSA_END("%1", "%0")
2726 - : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
2729 -void __sh_or(volatile int *x, int v)
2731 - if (__sh_atomic_model == SH_A_LLSC) return __sh_or_llsc(x, v);
2733 - if (__sh_atomic_model == SH_A_IMASK) {
2734 - unsigned sr = mask();
2742 - __asm__ __volatile__(
2743 - GUSA_START_ODD("%1", "%0")
2745 - GUSA_END("%1", "%0")
2746 - : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
2750 --- a/arch/sh/src/sh_atomic.h
2753 -#ifndef _SH_ATOMIC_H
2754 -#define _SH_ATOMIC_H
2756 -#define SH_A_GUSA 0
2757 -#define SH_A_LLSC 1
2759 -#if !defined(__SH3__) && !defined(__SH4__)
2760 -#define SH_A_IMASK 3
2762 -#define SH_A_IMASK -1LL /* unmatchable by unsigned int */
2765 -extern __attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model;
2768 --- a/arch/x32/atomic.h
2771 -#ifndef _INTERNAL_ATOMIC_H
2772 -#define _INTERNAL_ATOMIC_H
2774 -#include <stdint.h>
2776 -static inline int a_ctz_64(uint64_t x)
2778 - __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
2782 -static inline int a_ctz_l(unsigned long x)
2784 - __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
2788 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
2790 - __asm__( "lock ; and %1, %0"
2791 - : "=m"(*p) : "r"(v) : "memory" );
2794 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
2796 - __asm__( "lock ; or %1, %0"
2797 - : "=m"(*p) : "r"(v) : "memory" );
2800 -static inline void a_or_l(volatile void *p, long v)
2802 - __asm__( "lock ; or %1, %0"
2803 - : "=m"(*(long *)p) : "r"(v) : "memory" );
2806 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
2808 - __asm__( "lock ; cmpxchg %3, %1"
2809 - : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
2813 -static inline int a_cas(volatile int *p, int t, int s)
2815 - __asm__( "lock ; cmpxchg %3, %1"
2816 - : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
2820 -static inline void a_or(volatile int *p, int v)
2822 - __asm__( "lock ; or %1, %0"
2823 - : "=m"(*p) : "r"(v) : "memory" );
2826 -static inline void a_and(volatile int *p, int v)
2828 - __asm__( "lock ; and %1, %0"
2829 - : "=m"(*p) : "r"(v) : "memory" );
2832 -static inline int a_swap(volatile int *x, int v)
2834 - __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
2838 -static inline int a_fetch_add(volatile int *x, int v)
2840 - __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
2844 -static inline void a_inc(volatile int *x)
2846 - __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
2849 -static inline void a_dec(volatile int *x)
2851 - __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
2854 -static inline void a_store(volatile int *p, int x)
2856 - __asm__( "mov %1, %0 ; lock ; orl $0,(%%rsp)" : "=m"(*p) : "r"(x) : "memory" );
2859 -static inline void a_spin()
2861 - __asm__ __volatile__( "pause" : : : "memory" );
2864 -static inline void a_barrier()
2866 - __asm__ __volatile__( "" : : : "memory" );
2869 -static inline void a_crash()
2871 - __asm__ __volatile__( "hlt" : : : "memory" );
2877 +++ b/arch/x32/atomic_arch.h
2879 +#define a_ctz_64 a_ctz_64
2880 +static inline int a_ctz_64(uint64_t x)
2882 + __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
2886 +#define a_ctz_l a_ctz_l
2887 +static inline int a_ctz_l(unsigned long x)
2889 + __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
2893 +#define a_and_64 a_and_64
2894 +static inline void a_and_64(volatile uint64_t *p, uint64_t v)
2896 + __asm__( "lock ; and %1, %0"
2897 + : "=m"(*p) : "r"(v) : "memory" );
2900 +#define a_or_64 a_or_64
2901 +static inline void a_or_64(volatile uint64_t *p, uint64_t v)
2903 + __asm__( "lock ; or %1, %0"
2904 + : "=m"(*p) : "r"(v) : "memory" );
2907 +#define a_or_l a_or_l
2908 +static inline void a_or_l(volatile void *p, long v)
2910 + __asm__( "lock ; or %1, %0"
2911 + : "=m"(*(long *)p) : "r"(v) : "memory" );
2914 +#define a_cas a_cas
2915 +static inline int a_cas(volatile int *p, int t, int s)
2917 + __asm__( "lock ; cmpxchg %3, %1"
2918 + : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
2923 +static inline void a_or(volatile int *p, int v)
2925 + __asm__( "lock ; or %1, %0"
2926 + : "=m"(*p) : "r"(v) : "memory" );
2929 +#define a_and a_and
2930 +static inline void a_and(volatile int *p, int v)
2932 + __asm__( "lock ; and %1, %0"
2933 + : "=m"(*p) : "r"(v) : "memory" );
2936 +#define a_swap a_swap
2937 +static inline int a_swap(volatile int *x, int v)
2939 + __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
2943 +#define a_fetch_add a_fetch_add
2944 +static inline int a_fetch_add(volatile int *x, int v)
2946 + __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
2950 +#define a_inc a_inc
2951 +static inline void a_inc(volatile int *x)
2953 + __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
2956 +#define a_dec a_dec
2957 +static inline void a_dec(volatile int *x)
2959 + __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
2962 +#define a_store a_store
2963 +static inline void a_store(volatile int *p, int x)
2965 + __asm__( "mov %1, %0 ; lock ; orl $0,(%%rsp)" : "=m"(*p) : "r"(x) : "memory" );
2968 +#define a_spin a_spin
2969 +static inline void a_spin()
2971 + __asm__ __volatile__( "pause" : : : "memory" );
2974 +#define a_barrier a_barrier
2975 +static inline void a_barrier()
2977 + __asm__ __volatile__( "" : : : "memory" );
2980 +#define a_crash a_crash
2981 +static inline void a_crash()
2983 + __asm__ __volatile__( "hlt" : : : "memory" );
2985 --- a/arch/x32/pthread_arch.h
2986 +++ b/arch/x32/pthread_arch.h
2987 @@ -7,6 +7,6 @@ static inline struct pthread *__pthread_
2989 #define TP_ADJ(p) (p)
2991 -#define CANCEL_REG_IP 32
2992 +#define MC_PC gregs[REG_RIP]
2994 #define CANARY canary2
2995 --- a/arch/x32/src/syscall_cp_fixup.c
2996 +++ b/arch/x32/src/syscall_cp_fixup.c
2998 #include <sys/syscall.h>
3001 __attribute__((__visibility__("hidden")))
3003 long __syscall_cp_internal(volatile void*, long long, long long, long long, long long,
3004 long long, long long, long long);
3006 @@ -14,9 +12,7 @@ struct __timespec_kernel { long long tv_
3007 ts->tv_nsec = __tsc(X)->tv_nsec; \
3008 (X) = (unsigned long)ts; } } while(0)
3011 __attribute__((__visibility__("hidden")))
3013 long __syscall_cp_asm (volatile void * foo, long long n, long long a1, long long a2, long long a3,
3014 long long a4, long long a5, long long a6)
3016 --- a/arch/x86_64/atomic.h
3019 -#ifndef _INTERNAL_ATOMIC_H
3020 -#define _INTERNAL_ATOMIC_H
3022 -#include <stdint.h>
3024 -static inline int a_ctz_64(uint64_t x)
3026 - __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
3030 -static inline int a_ctz_l(unsigned long x)
3032 - __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
3036 -static inline void a_and_64(volatile uint64_t *p, uint64_t v)
3038 - __asm__( "lock ; and %1, %0"
3039 - : "=m"(*p) : "r"(v) : "memory" );
3042 -static inline void a_or_64(volatile uint64_t *p, uint64_t v)
3044 - __asm__( "lock ; or %1, %0"
3045 - : "=m"(*p) : "r"(v) : "memory" );
3048 -static inline void a_or_l(volatile void *p, long v)
3050 - __asm__( "lock ; or %1, %0"
3051 - : "=m"(*(long *)p) : "r"(v) : "memory" );
3054 -static inline void *a_cas_p(volatile void *p, void *t, void *s)
3056 - __asm__( "lock ; cmpxchg %3, %1"
3057 - : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
3061 -static inline int a_cas(volatile int *p, int t, int s)
3063 - __asm__( "lock ; cmpxchg %3, %1"
3064 - : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
3068 -static inline void a_or(volatile int *p, int v)
3070 - __asm__( "lock ; or %1, %0"
3071 - : "=m"(*p) : "r"(v) : "memory" );
3074 -static inline void a_and(volatile int *p, int v)
3076 - __asm__( "lock ; and %1, %0"
3077 - : "=m"(*p) : "r"(v) : "memory" );
3080 -static inline int a_swap(volatile int *x, int v)
3082 - __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
3086 -static inline int a_fetch_add(volatile int *x, int v)
3088 - __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
3092 -static inline void a_inc(volatile int *x)
3094 - __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
3097 -static inline void a_dec(volatile int *x)
3099 - __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
3102 -static inline void a_store(volatile int *p, int x)
3104 - __asm__( "mov %1, %0 ; lock ; orl $0,(%%rsp)" : "=m"(*p) : "r"(x) : "memory" );
3107 -static inline void a_spin()
3109 - __asm__ __volatile__( "pause" : : : "memory" );
3112 -static inline void a_barrier()
3114 - __asm__ __volatile__( "" : : : "memory" );
3117 -static inline void a_crash()
3119 - __asm__ __volatile__( "hlt" : : : "memory" );
3125 +++ b/arch/x86_64/atomic_arch.h
3127 +#define a_ctz_64 a_ctz_64
3128 +static inline int a_ctz_64(uint64_t x)
3130 + __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
3134 +#define a_and_64 a_and_64
3135 +static inline void a_and_64(volatile uint64_t *p, uint64_t v)
3137 + __asm__( "lock ; and %1, %0"
3138 + : "=m"(*p) : "r"(v) : "memory" );
3141 +#define a_or_64 a_or_64
3142 +static inline void a_or_64(volatile uint64_t *p, uint64_t v)
3144 + __asm__( "lock ; or %1, %0"
3145 + : "=m"(*p) : "r"(v) : "memory" );
3148 +#define a_or_l a_or_l
3149 +static inline void a_or_l(volatile void *p, long v)
3151 + __asm__( "lock ; or %1, %0"
3152 + : "=m"(*(long *)p) : "r"(v) : "memory" );
3155 +#define a_cas_p a_cas_p
3156 +static inline void *a_cas_p(volatile void *p, void *t, void *s)
3158 + __asm__( "lock ; cmpxchg %3, %1"
3159 + : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
3163 +#define a_cas a_cas
3164 +static inline int a_cas(volatile int *p, int t, int s)
3166 + __asm__( "lock ; cmpxchg %3, %1"
3167 + : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
3172 +static inline void a_or(volatile int *p, int v)
3174 + __asm__( "lock ; or %1, %0"
3175 + : "=m"(*p) : "r"(v) : "memory" );
3178 +#define a_and a_and
3179 +static inline void a_and(volatile int *p, int v)
3181 + __asm__( "lock ; and %1, %0"
3182 + : "=m"(*p) : "r"(v) : "memory" );
3185 +#define a_swap a_swap
3186 +static inline int a_swap(volatile int *x, int v)
3188 + __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
3192 +#define a_fetch_add a_fetch_add
3193 +static inline int a_fetch_add(volatile int *x, int v)
3195 + __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
3199 +#define a_inc a_inc
3200 +static inline void a_inc(volatile int *x)
3202 + __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
3205 +#define a_dec a_dec
3206 +static inline void a_dec(volatile int *x)
3208 + __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
3211 +#define a_store a_store
3212 +static inline void a_store(volatile int *p, int x)
3214 + __asm__( "mov %1, %0 ; lock ; orl $0,(%%rsp)" : "=m"(*p) : "r"(x) : "memory" );
3217 +#define a_spin a_spin
3218 +static inline void a_spin()
3220 + __asm__ __volatile__( "pause" : : : "memory" );
3223 +#define a_barrier a_barrier
3224 +static inline void a_barrier()
3226 + __asm__ __volatile__( "" : : : "memory" );
3229 +#define a_crash a_crash
3230 +static inline void a_crash()
3232 + __asm__ __volatile__( "hlt" : : : "memory" );
3234 --- a/arch/x86_64/pthread_arch.h
3235 +++ b/arch/x86_64/pthread_arch.h
3236 @@ -7,4 +7,4 @@ static inline struct pthread *__pthread_
3238 #define TP_ADJ(p) (p)
3240 -#define CANCEL_REG_IP 16
3241 +#define MC_PC gregs[REG_RIP]
3244 @@ -9,6 +9,9 @@ VAR=VALUE. See below for descriptions o
3246 Defaults for the options are specified in brackets.
3249 + --srcdir=DIR source directory [detected]
3251 Installation directories:
3252 --prefix=PREFIX main installation prefix [/usr/local/musl]
3253 --exec-prefix=EPREFIX installation prefix for executable files [PREFIX]
3254 @@ -117,6 +120,7 @@ CFLAGS_TRY=
3259 prefix=/usr/local/musl
3260 exec_prefix='$(prefix)'
3261 bindir='$(exec_prefix)/bin'
3262 @@ -139,6 +143,7 @@ clang_wrapper=no
3266 +--srcdir=*) srcdir=${arg#*=} ;;
3267 --prefix=*) prefix=${arg#*=} ;;
3268 --exec-prefix=*) exec_prefix=${arg#*=} ;;
3269 --bindir=*) bindir=${arg#*=} ;;
3270 @@ -179,11 +184,23 @@ LIBCC=*) LIBCC=${arg#*=} ;;
3274 -for i in prefix exec_prefix bindir libdir includedir syslibdir ; do
3275 +for i in srcdir prefix exec_prefix bindir libdir includedir syslibdir ; do
3280 +# Get the source dir for out-of-tree builds
3282 +if test -z "$srcdir" ; then
3283 +srcdir="${0%/configure}"
3286 +abs_builddir="$(pwd)" || fail "$0: cannot determine working directory"
3287 +abs_srcdir="$(cd $srcdir && pwd)" || fail "$0: invalid source directory $srcdir"
3288 +test "$abs_srcdir" = "$abs_builddir" && srcdir=.
3289 +test "$srcdir" != "." -a -f Makefile -a ! -h Makefile && fail "$0: Makefile already exists in the working directory"
3292 # Get a temp filename we can use
3295 @@ -263,11 +280,11 @@ fi
3298 if test "$gcc_wrapper" = yes ; then
3299 -tools="$tools tools/musl-gcc"
3300 +tools="$tools obj/musl-gcc"
3301 tool_libs="$tool_libs lib/musl-gcc.specs"
3303 if test "$clang_wrapper" = yes ; then
3304 -tools="$tools tools/musl-clang tools/ld.musl-clang"
3305 +tools="$tools obj/musl-clang obj/ld.musl-clang"
3309 @@ -321,7 +338,7 @@ __attribute__((__may_alias__))
3313 -if $CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include $CPPFLAGS $CFLAGS \
3314 +if $CC $CFLAGS_C99FSE -I$srcdir/arch/$ARCH -I$srcdir/include $CPPFLAGS $CFLAGS \
3315 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
3318 @@ -330,6 +347,13 @@ CFLAGS_C99FSE="$CFLAGS_C99FSE -D__may_al
3322 +# The GNU toolchain defaults to assuming unmarked files need an
3323 +# executable stack, potentially exposing vulnerabilities in programs
3324 +# linked with such object files. Fix this.
3326 +tryflag CFLAGS_C99FSE -Wa,--noexecstack
3329 # Check for options to disable stack protector, which needs to be
3330 # disabled for a few early-bootstrap translation units. If not found,
3331 # this is not an error; we assume the toolchain does not do ssp.
3332 @@ -430,11 +454,15 @@ tryflag CFLAGS_AUTO -fno-unwind-tables
3333 tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables
3336 -# The GNU toolchain defaults to assuming unmarked files need an
3337 -# executable stack, potentially exposing vulnerabilities in programs
3338 -# linked with such object files. Fix this.
3339 +# Attempt to put each function and each data object in its own
3340 +# section. This both allows additional size optimizations at link
3341 +# time and works around a dangerous class of compiler/assembler bugs
3342 +# whereby relative address expressions are constant-folded by the
3343 +# assembler even when one or more of the symbols involved is
3344 +# replaceable. See gas pr 18561 and gcc pr 66609, 68178, etc.
3346 -tryflag CFLAGS_AUTO -Wa,--noexecstack
3347 +tryflag CFLAGS_AUTO -ffunction-sections
3348 +tryflag CFLAGS_AUTO -fdata-sections
3351 # On x86, make sure we don't have incompatible instruction set
3352 @@ -489,7 +517,7 @@ int foo(void) { }
3353 int bar(void) { fp = foo; return foo(); }
3355 if $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS \
3356 - -DSHARED -fPIC -I./src/internal -include vis.h \
3357 + -DSHARED -fPIC -I$srcdir/src/internal -include vis.h \
3358 -nostdlib -shared -Wl,-Bsymbolic-functions \
3359 -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
3361 @@ -504,6 +532,16 @@ CFLAGS_AUTO="$CFLAGS_AUTO -include vis.h
3362 CFLAGS_AUTO="${CFLAGS_AUTO# }"
3365 +# Reduce space lost to padding for alignment purposes by sorting data
3366 +# objects according to their alignment reqirements. This approximates
3368 +tryldflag LDFLAGS_AUTO -Wl,--sort-section,alignment
3369 +tryldflag LDFLAGS_AUTO -Wl,--sort-common
3371 +# When linking shared library, drop dummy weak definitions that were
3372 +# replaced by strong definitions from other translation units.
3373 +tryldflag LDFLAGS_AUTO -Wl,--gc-sections
3375 # Some patched GCC builds have these defaults messed up...
3376 tryldflag LDFLAGS_AUTO -Wl,--hash-style=both
3378 @@ -513,6 +551,11 @@ tryldflag LDFLAGS_AUTO -Wl,--hash-style=
3379 # runtime library; implementation error is also a possibility.
3380 tryldflag LDFLAGS_AUTO -Wl,--no-undefined
3382 +# Avoid exporting symbols from compiler runtime libraries. They
3383 +# should be hidden anyway, but some toolchains including old gcc
3384 +# versions built without shared library support and pcc are broken.
3385 +tryldflag LDFLAGS_AUTO -Wl,--exclude-libs=ALL
3387 test "$shared" = "no" || {
3388 # Disable dynamic linking if ld is broken and can't do -Bsymbolic-functions
3390 @@ -599,7 +642,7 @@ echo '#include <float.h>' > "$tmpc"
3391 echo '#if LDBL_MANT_DIG == 53' >> "$tmpc"
3392 echo 'typedef char ldcheck[9-(int)sizeof(long double)];' >> "$tmpc"
3393 echo '#endif' >> "$tmpc"
3394 -if $CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include $CPPFLAGS $CFLAGS \
3395 +if $CC $CFLAGS_C99FSE -I$srcdir/arch/$ARCH -I$srcdir/include $CPPFLAGS $CFLAGS \
3396 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
3399 @@ -622,6 +665,7 @@ cat << EOF
3402 ASMSUBARCH = $ASMSUBARCH
3405 exec_prefix = $exec_prefix
3407 @@ -629,12 +673,14 @@ libdir = $libdir
3408 includedir = $includedir
3409 syslibdir = $syslibdir
3411 -CFLAGS = $CFLAGS_AUTO $CFLAGS
3413 +CFLAGS_AUTO = $CFLAGS_AUTO
3414 CFLAGS_C99FSE = $CFLAGS_C99FSE
3415 CFLAGS_MEMOPS = $CFLAGS_MEMOPS
3416 CFLAGS_NOSSP = $CFLAGS_NOSSP
3417 CPPFLAGS = $CPPFLAGS
3418 -LDFLAGS = $LDFLAGS_AUTO $LDFLAGS
3420 +LDFLAGS_AUTO = $LDFLAGS_AUTO
3421 CROSS_COMPILE = $CROSS_COMPILE
3423 OPTIMIZE_GLOBS = $OPTIMIZE_GLOBS
3424 @@ -648,4 +694,6 @@ test "x$cc_family" = xgcc && echo 'WRAPC
3425 test "x$cc_family" = xclang && echo 'WRAPCC_CLANG = $(CC)'
3428 +test "$srcdir" = "." || ln -sf $srcdir/Makefile .
3431 --- a/crt/arm/crti.s
3432 +++ b/crt/arm/crti.s
3438 .type _init,%function
3439 --- a/crt/arm/crtn.s
3440 +++ b/crt/arm/crtn.s
3455 --- a/include/complex.h
3456 +++ b/include/complex.h
3457 @@ -116,7 +116,7 @@ long double creall(long double complex);
3459 #if __STDC_VERSION__ >= 201112L
3460 #if defined(_Imaginary_I)
3461 -#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y)))
3462 +#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y))
3463 #elif defined(__clang__)
3464 #define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) })
3466 --- a/include/netinet/tcp.h
3467 +++ b/include/netinet/tcp.h
3469 #define TCP_CLOSING 11
3471 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
3472 +#define TCPOPT_EOL 0
3473 +#define TCPOPT_NOP 1
3474 +#define TCPOPT_MAXSEG 2
3475 +#define TCPOPT_WINDOW 3
3476 +#define TCPOPT_SACK_PERMITTED 4
3477 +#define TCPOPT_SACK 5
3478 +#define TCPOPT_TIMESTAMP 8
3479 +#define TCPOLEN_SACK_PERMITTED 2
3480 +#define TCPOLEN_WINDOW 3
3481 +#define TCPOLEN_MAXSEG 4
3482 +#define TCPOLEN_TIMESTAMP 10
3486 #include <sys/types.h>
3487 #include <sys/socket.h>
3489 --- a/src/env/__init_tls.c
3490 +++ b/src/env/__init_tls.c
3493 #include "syscall.h"
3498 int __init_tp(void *p)
3501 @@ -24,8 +21,6 @@ int __init_tp(void *p)
3507 static struct builtin_tls {
3510 @@ -33,33 +28,40 @@ static struct builtin_tls {
3512 #define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
3516 - size_t len, size, align;
3519 -#define T __static_tls
3520 +static struct tls_module main_tls;
3522 void *__copy_tls(unsigned char *mem)
3525 - if (!T.image) return mem;
3526 - void **dtv = (void *)mem;
3527 - dtv[0] = (void *)1;
3528 + struct tls_module *p;
3533 - mem += sizeof(void *) * 2;
3534 - mem += -((uintptr_t)mem + sizeof(struct pthread)) & (T.align-1);
3535 + dtv = (void **)(mem + libc.tls_size) - (libc.tls_cnt + 1);
3537 + mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1);
3538 td = (pthread_t)mem;
3539 mem += sizeof(struct pthread);
3541 + for (i=1, p=libc.tls_head; p; i++, p=p->next) {
3542 + dtv[i] = mem + p->offset;
3543 + memcpy(dtv[i], p->image, p->len);
3546 + dtv = (void **)mem;
3548 mem += libc.tls_size - sizeof(struct pthread);
3549 - mem -= (uintptr_t)mem & (T.align-1);
3550 + mem -= (uintptr_t)mem & (libc.tls_align-1);
3551 td = (pthread_t)mem;
3554 + for (i=1, p=libc.tls_head; p; i++, p=p->next) {
3555 + dtv[i] = mem - p->offset;
3556 + memcpy(dtv[i], p->image, p->len);
3559 + dtv[0] = (void *)libc.tls_cnt;
3560 td->dtv = td->dtv_copy = dtv;
3562 - memcpy(mem, T.image, T.len);
3566 @@ -69,7 +71,7 @@ typedef Elf32_Phdr Phdr;
3567 typedef Elf64_Phdr Phdr;
3570 -void __init_tls(size_t *aux)
3571 +static void static_init_tls(size_t *aux)
3575 @@ -86,16 +88,24 @@ void __init_tls(size_t *aux)
3579 - T.image = (void *)(base + tls_phdr->p_vaddr);
3580 - T.len = tls_phdr->p_filesz;
3581 - T.size = tls_phdr->p_memsz;
3582 - T.align = tls_phdr->p_align;
3583 + main_tls.image = (void *)(base + tls_phdr->p_vaddr);
3584 + main_tls.len = tls_phdr->p_filesz;
3585 + main_tls.size = tls_phdr->p_memsz;
3586 + main_tls.align = tls_phdr->p_align;
3588 + libc.tls_head = &main_tls;
3591 - T.size += (-T.size - (uintptr_t)T.image) & (T.align-1);
3592 - if (T.align < MIN_TLS_ALIGN) T.align = MIN_TLS_ALIGN;
3593 + main_tls.size += (-main_tls.size - (uintptr_t)main_tls.image)
3594 + & (main_tls.align-1);
3595 + if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN;
3596 +#ifndef TLS_ABOVE_TP
3597 + main_tls.offset = main_tls.size;
3600 - libc.tls_size = 2*sizeof(void *)+T.size+T.align+sizeof(struct pthread)
3601 + libc.tls_align = main_tls.align;
3602 + libc.tls_size = 2*sizeof(void *) + sizeof(struct pthread)
3603 + + main_tls.size + main_tls.align
3604 + MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN;
3606 if (libc.tls_size > sizeof builtin_tls) {
3607 @@ -117,6 +127,5 @@ void __init_tls(size_t *aux)
3608 if (__init_tp(__copy_tls(mem)) < 0)
3612 -void __init_tls(size_t *auxv) { }
3615 +weak_alias(static_init_tls, __init_tls);
3616 --- a/src/env/__libc_start_main.c
3617 +++ b/src/env/__libc_start_main.c
3620 void __init_tls(size_t *);
3623 -static void dummy() {}
3624 +static void dummy(void) {}
3625 weak_alias(dummy, _init);
3626 -extern void (*const __init_array_start)() __attribute__((weak));
3627 -extern void (*const __init_array_end)() __attribute__((weak));
3630 +__attribute__((__weak__, __visibility__("hidden")))
3631 +extern void (*const __init_array_start)(void), (*const __init_array_end)(void);
3633 static void dummy1(void *p) {}
3634 weak_alias(dummy1, __init_ssp);
3641 void __init_libc(char **envp, char *pn)
3643 size_t i, *auxv, aux[AUX_CNT] = { 0 };
3644 @@ -57,20 +53,22 @@ void __init_libc(char **envp, char *pn)
3648 -int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
3649 +static void libc_start_init(void)
3651 - char **envp = argv+argc+1;
3654 - __init_libc(envp, argv[0]);
3656 uintptr_t a = (uintptr_t)&__init_array_start;
3657 for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
3658 (*(void (**)())a)();
3660 - void __libc_start_init(void);
3663 +weak_alias(libc_start_init, __libc_start_init);
3665 +int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
3667 + char **envp = argv+argc+1;
3669 + __init_libc(envp, argv[0]);
3670 __libc_start_init();
3673 /* Pass control to the application */
3674 exit(main(argc, argv, envp));
3675 --- a/src/env/__reset_tls.c
3676 +++ b/src/env/__reset_tls.c
3681 #include "pthread_impl.h"
3683 -extern struct tls_image {
3685 - size_t len, size, align;
3688 -#define T __static_tls
3693 - if (!T.size) return;
3694 pthread_t self = __pthread_self();
3695 - memcpy(self->dtv[1], T.image, T.len);
3696 - memset((char *)self->dtv[1]+T.len, 0, T.size-T.len);
3697 + struct tls_module *p;
3698 + size_t i, n = (size_t)self->dtv[0];
3699 + if (n) for (p=libc.tls_head, i=1; i<=n; i++, p=p->next) {
3700 + if (!self->dtv[i]) continue;
3701 + memcpy(self->dtv[i], p->image, p->len);
3702 + memset((char *)self->dtv[i]+p->len, 0,
3703 + p->size - p->len);
3708 --- a/src/env/__stack_chk_fail.c
3709 +++ b/src/env/__stack_chk_fail.c
3710 @@ -17,16 +17,7 @@ void __stack_chk_fail(void)
3716 __attribute__((__visibility__("hidden")))
3717 -void __stack_chk_fail_local(void)
3723 +void __stack_chk_fail_local(void);
3725 weak_alias(__stack_chk_fail, __stack_chk_fail_local);
3729 +++ b/src/exit/arm/__aeabi_atexit.c
3731 +int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
3733 +int __aeabi_atexit (void *obj, void (*func) (void *), void *d)
3735 + return __cxa_atexit (func, obj, d);
3737 --- a/src/exit/exit.c
3738 +++ b/src/exit/exit.c
3739 @@ -10,25 +10,25 @@ static void dummy()
3740 * as a consequence of linking either __toread.c or __towrite.c. */
3741 weak_alias(dummy, __funcs_on_exit);
3742 weak_alias(dummy, __stdio_exit);
3745 weak_alias(dummy, _fini);
3746 -extern void (*const __fini_array_start)() __attribute__((weak));
3747 -extern void (*const __fini_array_end)() __attribute__((weak));
3750 -_Noreturn void exit(int code)
3752 - __funcs_on_exit();
3753 +__attribute__((__weak__, __visibility__("hidden")))
3754 +extern void (*const __fini_array_start)(void), (*const __fini_array_end)(void);
3757 +static void libc_exit_fini(void)
3759 uintptr_t a = (uintptr_t)&__fini_array_end;
3760 for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)()))
3761 (*(void (**)())(a-sizeof(void(*)())))();
3767 +weak_alias(libc_exit_fini, __libc_exit_fini);
3769 +_Noreturn void exit(int code)
3771 + __funcs_on_exit();
3772 + __libc_exit_fini();
3777 +++ b/src/fenv/arm/fenv-hf.S
3785 +.type fegetround,%function
3788 + and r0, r0, #0xc00000
3791 +.global __fesetround
3792 +.type __fesetround,%function
3795 + bic r3, r3, #0xc00000
3801 +.global fetestexcept
3802 +.type fetestexcept,%function
3809 +.global feclearexcept
3810 +.type feclearexcept,%function
3819 +.global feraiseexcept
3820 +.type feraiseexcept,%function
3830 +.type fegetenv,%function
3838 +.type fesetenv,%function
3849 +++ b/src/fenv/arm/fenv.c
3852 +#include "../fenv.c"
3854 --- a/src/fenv/armebhf/fenv.sub
3858 --- a/src/fenv/armhf/fenv.s
3864 -.type fegetround,%function
3866 - mrc p10, 7, r0, cr1, cr0, 0
3867 - and r0, r0, #0xc00000
3870 -.global __fesetround
3871 -.type __fesetround,%function
3873 - mrc p10, 7, r3, cr1, cr0, 0
3874 - bic r3, r3, #0xc00000
3876 - mcr p10, 7, r3, cr1, cr0, 0
3880 -.global fetestexcept
3881 -.type fetestexcept,%function
3884 - mrc p10, 7, r3, cr1, cr0, 0
3888 -.global feclearexcept
3889 -.type feclearexcept,%function
3892 - mrc p10, 7, r3, cr1, cr0, 0
3894 - mcr p10, 7, r3, cr1, cr0, 0
3898 -.global feraiseexcept
3899 -.type feraiseexcept,%function
3902 - mrc p10, 7, r3, cr1, cr0, 0
3904 - mcr p10, 7, r3, cr1, cr0, 0
3909 -.type fegetenv,%function
3911 - mrc p10, 7, r3, cr1, cr0, 0
3917 -.type fesetenv,%function
3922 - mcr p10, 7, r3, cr1, cr0, 0
3925 --- a/src/fenv/armhf/fenv.sub
3929 --- a/src/fenv/mips-sf/fenv.sub
3934 +++ b/src/fenv/mips/fenv-sf.c
3936 +#ifdef __mips_soft_float
3937 +#include "../fenv.c"
3940 +++ b/src/fenv/mips/fenv.S
3942 +#ifndef __mips_soft_float
3946 +.global feclearexcept
3947 +.type feclearexcept,@function
3957 +.global feraiseexcept
3958 +.type feraiseexcept,@function
3967 +.global fetestexcept
3968 +.type fetestexcept,@function
3976 +.type fegetround,@function
3982 +.global __fesetround
3983 +.type __fesetround,@function
3994 +.type fegetenv,@function
4002 +.type fesetenv,@function
4013 --- a/src/fenv/mips/fenv.s
4018 -.global feclearexcept
4019 -.type feclearexcept,@function
4029 -.global feraiseexcept
4030 -.type feraiseexcept,@function
4039 -.global fetestexcept
4040 -.type fetestexcept,@function
4048 -.type fegetround,@function
4054 -.global __fesetround
4055 -.type __fesetround,@function
4066 -.type fegetenv,@function
4074 -.type fesetenv,@function
4083 --- a/src/fenv/mipsel-sf/fenv.sub
4087 --- a/src/fenv/sh-nofpu/fenv.sub
4092 +++ b/src/fenv/sh/fenv-nofpu.c
4094 +#if !__SH_FPU_ANY__ && !__SH4__
4095 +#include "../fenv.c"
4098 +++ b/src/fenv/sh/fenv.S
4100 +#if __SH_FPU_ANY__ || __SH4__
4103 +.type fegetround, @function
4109 +.global __fesetround
4110 +.type __fesetround, @function
4118 +.global fetestexcept
4119 +.type fetestexcept, @function
4126 +.global feclearexcept
4127 +.type feclearexcept, @function
4138 +.global feraiseexcept
4139 +.type feraiseexcept, @function
4150 +.type fegetenv, @function
4158 +.type fesetenv, @function
4164 + ! the default environment is complicated by the fact that we need to
4165 + ! preserve the current precision bit, which we do not know a priori
4172 +1: mov.l @r4, r0 ! non-default environment
4178 --- a/src/fenv/sh/fenv.s
4182 -.type fegetround, @function
4188 -.global __fesetround
4189 -.type __fesetround, @function
4197 -.global fetestexcept
4198 -.type fetestexcept, @function
4205 -.global feclearexcept
4206 -.type feclearexcept, @function
4217 -.global feraiseexcept
4218 -.type feraiseexcept, @function
4229 -.type fegetenv, @function
4237 -.type fesetenv, @function
4243 - ! the default environment is complicated by the fact that we need to
4244 - ! preserve the current precision bit, which we do not know a priori
4251 -1: mov.l @r4, r0 ! non-default environment
4255 --- a/src/fenv/sheb-nofpu/fenv.sub
4259 --- a/src/internal/arm/syscall.s
4260 +++ b/src/internal/arm/syscall.s
4265 .type __syscall,%function
4266 @@ -11,6 +12,4 @@ __syscall:
4267 ldmfd ip,{r3,r4,r5,r6}
4269 ldmfd sp!,{r4,r5,r6,r7}
4274 +++ b/src/internal/atomic.h
4279 +#include <stdint.h>
4281 +#include "atomic_arch.h"
4286 +#define a_pre_llsc()
4289 +#ifndef a_post_llsc
4290 +#define a_post_llsc()
4294 +#define a_cas a_cas
4295 +static inline int a_cas(volatile int *p, int t, int s)
4300 + while (old==t && !a_sc(p, s));
4307 +#define a_swap a_swap
4308 +static inline int a_swap(volatile int *p, int v)
4313 + while (!a_sc(p, v));
4319 +#ifndef a_fetch_add
4320 +#define a_fetch_add a_fetch_add
4321 +static inline int a_fetch_add(volatile int *p, int v)
4326 + while (!a_sc(p, (unsigned)old + v));
4332 +#ifndef a_fetch_and
4333 +#define a_fetch_and a_fetch_and
4334 +static inline int a_fetch_and(volatile int *p, int v)
4339 + while (!a_sc(p, old & v));
4346 +#define a_fetch_or a_fetch_or
4347 +static inline int a_fetch_or(volatile int *p, int v)
4352 + while (!a_sc(p, old | v));
4361 +#error missing definition of a_cas
4365 +#define a_swap a_swap
4366 +static inline int a_swap(volatile int *p, int v)
4370 + while (a_cas(p, old, v) != old);
4375 +#ifndef a_fetch_add
4376 +#define a_fetch_add a_fetch_add
4377 +static inline int a_fetch_add(volatile int *p, int v)
4381 + while (a_cas(p, old, (unsigned)old+v) != old);
4386 +#ifndef a_fetch_and
4387 +#define a_fetch_and a_fetch_and
4388 +static inline int a_fetch_and(volatile int *p, int v)
4392 + while (a_cas(p, old, old&v) != old);
4397 +#define a_fetch_or a_fetch_or
4398 +static inline int a_fetch_or(volatile int *p, int v)
4402 + while (a_cas(p, old, old|v) != old);
4408 +#define a_and a_and
4409 +static inline void a_and(volatile int *p, int v)
4411 + a_fetch_and(p, v);
4417 +static inline void a_or(volatile int *p, int v)
4424 +#define a_inc a_inc
4425 +static inline void a_inc(volatile int *p)
4427 + a_fetch_add(p, 1);
4432 +#define a_dec a_dec
4433 +static inline void a_dec(volatile int *p)
4435 + a_fetch_add(p, -1);
4440 +#define a_store a_store
4441 +static inline void a_store(volatile int *p, int v)
4454 +#define a_barrier a_barrier
4455 +static void a_barrier()
4457 + volatile int tmp = 0;
4458 + a_cas(&tmp, 0, 0);
4463 +#define a_spin a_barrier
4467 +#define a_and_64 a_and_64
4468 +static inline void a_and_64(volatile uint64_t *p, uint64_t v)
4470 + union { uint64_t v; uint32_t r[2]; } u = { v };
4471 + if (u.r[0]+1) a_and((int *)p, u.r[0]);
4472 + if (u.r[1]+1) a_and((int *)p+1, u.r[1]);
4477 +#define a_or_64 a_or_64
4478 +static inline void a_or_64(volatile uint64_t *p, uint64_t v)
4480 + union { uint64_t v; uint32_t r[2]; } u = { v };
4481 + if (u.r[0]) a_or((int *)p, u.r[0]);
4482 + if (u.r[1]) a_or((int *)p+1, u.r[1]);
4487 +#define a_cas_p a_cas_p
4488 +static inline void *a_cas_p(volatile void *p, void *t, void *s)
4490 + return (void *)a_cas((volatile int *)p, (int)t, (int)s);
4495 +#define a_or_l a_or_l
4496 +static inline void a_or_l(volatile void *p, long v)
4498 + if (sizeof(long) == sizeof(int)) a_or(p, v);
4499 + else a_or_64(p, v);
4504 +#define a_crash a_crash
4505 +static inline void a_crash()
4507 + *(volatile char *)0=0;
4512 +#define a_ctz_64 a_ctz_64
4513 +static inline int a_ctz_64(uint64_t x)
4515 + static const char debruijn64[64] = {
4516 + 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
4517 + 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
4518 + 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
4519 + 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
4521 + static const char debruijn32[32] = {
4522 + 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
4523 + 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
4525 + if (sizeof(long) < 8) {
4529 + return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
4531 + return debruijn32[(y&-y)*0x076be629 >> 27];
4533 + return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
4538 +#define a_ctz_l a_ctz_l
4539 +static inline int a_ctz_l(unsigned long x)
4541 + static const char debruijn32[32] = {
4542 + 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
4543 + 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
4545 + if (sizeof(long) == 8) return a_ctz_64(x);
4546 + return debruijn32[(x&-x)*0x076be629 >> 27];
4551 --- a/src/internal/dynlink.h
4552 +++ b/src/internal/dynlink.h
4553 @@ -64,6 +64,10 @@ struct fdpic_dummy_loadmap {
4557 +#ifndef DL_NOMMU_SUPPORT
4558 +#define DL_NOMMU_SUPPORT 0
4562 #define IS_RELATIVE(x,s) ( \
4563 (R_TYPE(x) == REL_RELATIVE) || \
4564 --- a/src/internal/libc.h
4565 +++ b/src/internal/libc.h
4566 @@ -11,13 +11,20 @@ struct __locale_struct {
4567 const struct __locale_map *volatile cat[6];
4570 +struct tls_module {
4571 + struct tls_module *next;
4573 + size_t len, size, align, offset;
4580 volatile int threads_minus_1;
4583 + struct tls_module *tls_head;
4584 + size_t tls_size, tls_align, tls_cnt;
4586 struct __locale_struct global_locale;
4588 --- a/src/internal/syscall.h
4589 +++ b/src/internal/syscall.h
4591 typedef long syscall_arg_t;
4595 __attribute__((visibility("hidden")))
4597 long __syscall_ret(unsigned long), __syscall(syscall_arg_t, ...),
4598 __syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t,
4599 syscall_arg_t, syscall_arg_t, syscall_arg_t);
4600 --- a/src/internal/version.c
4601 +++ b/src/internal/version.c
4605 #include "version.h"
4607 static const char version[] = VERSION;
4609 +__attribute__((__visibility__("hidden")))
4610 const char *__libc_get_version()
4616 --- a/src/internal/vis.h
4617 +++ b/src/internal/vis.h
4619 * override default visibilities to reduce the size and performance costs
4620 * of position-independent code. */
4624 +#if !defined(CRT) && !defined(__ASSEMBLER__)
4626 -/* For shared libc.so, all symbols should be protected, but some toolchains
4627 +/* Conceptually, all symbols should be protected, but some toolchains
4628 * fail to support copy relocations for protected data, so exclude all
4629 * exported data symbols. */
4631 @@ -25,16 +24,4 @@ extern char *optarg, **environ, **__envi
4633 #pragma GCC visibility push(protected)
4635 -#elif defined(__PIC__)
4637 -/* If building static libc.a as position-independent code, try to make
4638 - * everything hidden except possibly-undefined weak references. */
4640 -__attribute__((__visibility__("default")))
4641 -extern void (*const __init_array_start)(), (*const __init_array_end)(),
4642 - (*const __fini_array_start)(), (*const __fini_array_end)();
4644 -#pragma GCC visibility push(hidden)
4648 --- a/src/ldso/arm/dlsym.s
4649 +++ b/src/ldso/arm/dlsym.s
4656 +++ b/src/ldso/arm/find_exidx.c
4658 +#define _GNU_SOURCE
4660 +#include <stdint.h>
4662 +struct find_exidx_data {
4663 + uintptr_t pc, exidx_start;
4667 +static int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr)
4669 + struct find_exidx_data *data = ptr;
4670 + const ElfW(Phdr) *phdr = info->dlpi_phdr;
4671 + uintptr_t addr, exidx_start = 0;
4672 + int i, match = 0, exidx_len = 0;
4674 + for (i = info->dlpi_phnum; i > 0; i--, phdr++) {
4675 + addr = info->dlpi_addr + phdr->p_vaddr;
4676 + switch (phdr->p_type) {
4678 + match |= data->pc >= addr && data->pc < addr + phdr->p_memsz;
4680 + case PT_ARM_EXIDX:
4681 + exidx_start = addr;
4682 + exidx_len = phdr->p_memsz;
4686 + data->exidx_start = exidx_start;
4687 + data->exidx_len = exidx_len;
4691 +uintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount)
4693 + struct find_exidx_data data;
4695 + if (dl_iterate_phdr(find_exidx, &data) <= 0)
4697 + *pcount = data.exidx_len / 8;
4698 + return data.exidx_start;
4700 --- a/src/ldso/dynlink.c
4701 +++ b/src/ldso/dynlink.c
4702 @@ -70,8 +70,8 @@ struct dso {
4704 struct dso **deps, *needed_by;
4705 char *rpath_orig, *rpath;
4707 - size_t tls_len, tls_size, tls_align, tls_id, tls_offset;
4708 + struct tls_module tls;
4710 size_t relro_start, relro_end;
4712 unsigned char *new_tls;
4713 @@ -99,7 +99,9 @@ struct symdef {
4715 int __init_tp(void *);
4716 void __init_libc(char **, char *);
4717 +void *__copy_tls(unsigned char *);
4719 +__attribute__((__visibility__("hidden")))
4720 const char *__libc_get_version(void);
4722 static struct builtin_tls {
4723 @@ -123,6 +125,7 @@ static int noload;
4724 static jmp_buf *rtld_fail;
4725 static pthread_rwlock_t lock;
4726 static struct debug debug;
4727 +static struct tls_module *tls_tail;
4728 static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;
4729 static size_t static_tls_cnt;
4730 static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
4731 @@ -131,6 +134,15 @@ static struct fdpic_dummy_loadmap app_du
4733 struct debug *_dl_debug_addr = &debug;
4735 +__attribute__((__visibility__("hidden")))
4736 +void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;
4738 +__attribute__((__visibility__("hidden")))
4739 +extern void (*const __init_array_end)(void), (*const __fini_array_end)(void);
4741 +weak_alias(__init_array_start, __init_array_end);
4742 +weak_alias(__fini_array_start, __fini_array_end);
4744 static int dl_strcmp(const char *l, const char *r)
4746 for (; *l==*r && *l; l++, r++);
4747 @@ -397,14 +409,14 @@ static void do_relocs(struct dso *dso, s
4751 - *reloc_addr = tls_val + def.dso->tls_offset + TPOFF_K + addend;
4752 + *reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend;
4756 - *reloc_addr = tls_val - def.dso->tls_offset + addend;
4757 + *reloc_addr = tls_val - def.dso->tls.offset + addend;
4760 - *reloc_addr = def.dso->tls_offset - tls_val + addend;
4761 + *reloc_addr = def.dso->tls.offset - tls_val + addend;
4765 @@ -426,10 +438,10 @@ static void do_relocs(struct dso *dso, s
4767 reloc_addr[0] = (size_t)__tlsdesc_static;
4769 - reloc_addr[1] = tls_val + def.dso->tls_offset
4770 + reloc_addr[1] = tls_val + def.dso->tls.offset
4773 - reloc_addr[1] = tls_val - def.dso->tls_offset
4774 + reloc_addr[1] = tls_val - def.dso->tls.offset
4778 @@ -482,8 +494,14 @@ static void reclaim_gaps(struct dso *dso
4780 static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
4782 - char *q = mmap(p, n, prot, flags, fd, off);
4783 - if (q != MAP_FAILED || errno != EINVAL) return q;
4784 + static int no_map_fixed;
4786 + if (!no_map_fixed) {
4787 + q = mmap(p, n, prot, flags|MAP_FIXED, fd, off);
4788 + if (!DL_NOMMU_SUPPORT || q != MAP_FAILED || errno != EINVAL)
4792 /* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
4793 if (flags & MAP_ANONYMOUS) {
4795 @@ -561,9 +579,9 @@ static void *map_library(int fd, struct
4797 } else if (ph->p_type == PT_TLS) {
4798 tls_image = ph->p_vaddr;
4799 - dso->tls_align = ph->p_align;
4800 - dso->tls_len = ph->p_filesz;
4801 - dso->tls_size = ph->p_memsz;
4802 + dso->tls.align = ph->p_align;
4803 + dso->tls.len = ph->p_filesz;
4804 + dso->tls.size = ph->p_memsz;
4805 } else if (ph->p_type == PT_GNU_RELRO) {
4806 dso->relro_start = ph->p_vaddr & -PAGE_SIZE;
4807 dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
4808 @@ -593,7 +611,7 @@ static void *map_library(int fd, struct
4809 ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
4810 ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
4811 map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),
4812 - prot, (prot&PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED,
4813 + prot, MAP_PRIVATE,
4814 fd, ph->p_offset & -PAGE_SIZE);
4815 if (map == MAP_FAILED) {
4817 @@ -604,6 +622,19 @@ static void *map_library(int fd, struct
4818 dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
4819 dso->loadmap->segs[i].p_memsz = ph->p_memsz;
4821 + if (prot & PROT_WRITE) {
4822 + size_t brk = (ph->p_vaddr & PAGE_SIZE-1)
4824 + size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE;
4825 + size_t pgend = brk + ph->p_memsz - ph->p_filesz
4826 + + PAGE_SIZE-1 & -PAGE_SIZE;
4827 + if (pgend > pgbrk && mmap_fixed(map+pgbrk,
4828 + pgend-pgbrk, prot,
4829 + MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
4830 + -1, off_start) == MAP_FAILED)
4832 + memset(map + brk, 0, pgbrk-brk);
4835 map = (void *)dso->loadmap->segs[0].addr;
4837 @@ -618,7 +649,11 @@ static void *map_library(int fd, struct
4838 * the length of the file. This is okay because we will not
4839 * use the invalid part; we just need to reserve the right
4840 * amount of virtual address space to map over later. */
4841 - map = mmap((void *)addr_min, map_len, prot, MAP_PRIVATE, fd, off_start);
4842 + map = DL_NOMMU_SUPPORT
4843 + ? mmap((void *)addr_min, map_len, PROT_READ|PROT_WRITE|PROT_EXEC,
4844 + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
4845 + : mmap((void *)addr_min, map_len, prot,
4846 + MAP_PRIVATE, fd, off_start);
4847 if (map==MAP_FAILED) goto error;
4849 dso->map_len = map_len;
4850 @@ -643,7 +678,8 @@ static void *map_library(int fd, struct
4851 dso->phentsize = eh->e_phentsize;
4853 /* Reuse the existing mapping for the lowest-address LOAD */
4854 - if ((ph->p_vaddr & -PAGE_SIZE) == addr_min) continue;
4855 + if ((ph->p_vaddr & -PAGE_SIZE) == addr_min && !DL_NOMMU_SUPPORT)
4857 this_min = ph->p_vaddr & -PAGE_SIZE;
4858 this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
4859 off_start = ph->p_offset & -PAGE_SIZE;
4860 @@ -670,7 +706,7 @@ static void *map_library(int fd, struct
4863 dso->dynv = laddr(dso, dyn);
4864 - if (dso->tls_size) dso->tls_image = laddr(dso, tls_image);
4865 + if (dso->tls.size) dso->tls.image = laddr(dso, tls_image);
4866 if (!runtime) reclaim_gaps(dso);
4867 free(allocated_buf);
4869 @@ -987,8 +1023,8 @@ static struct dso *load_library(const ch
4870 * extended DTV capable of storing an additional slot for
4871 * the newly-loaded DSO. */
4872 alloc_size = sizeof *p + strlen(pathname) + 1;
4873 - if (runtime && temp_dso.tls_image) {
4874 - size_t per_th = temp_dso.tls_size + temp_dso.tls_align
4875 + if (runtime && temp_dso.tls.image) {
4876 + size_t per_th = temp_dso.tls.size + temp_dso.tls.align
4877 + sizeof(void *) * (tls_cnt+3);
4878 n_th = libc.threads_minus_1 + 1;
4879 if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
4880 @@ -1009,22 +1045,25 @@ static struct dso *load_library(const ch
4881 strcpy(p->name, pathname);
4882 /* Add a shortname only if name arg was not an explicit pathname. */
4883 if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
4884 - if (p->tls_image) {
4885 + if (p->tls.image) {
4886 p->tls_id = ++tls_cnt;
4887 - tls_align = MAXP2(tls_align, p->tls_align);
4888 + tls_align = MAXP2(tls_align, p->tls.align);
4890 - p->tls_offset = tls_offset + ( (tls_align-1) &
4891 - -(tls_offset + (uintptr_t)p->tls_image) );
4892 - tls_offset += p->tls_size;
4893 + p->tls.offset = tls_offset + ( (tls_align-1) &
4894 + -(tls_offset + (uintptr_t)p->tls.image) );
4895 + tls_offset += p->tls.size;
4897 - tls_offset += p->tls_size + p->tls_align - 1;
4898 - tls_offset -= (tls_offset + (uintptr_t)p->tls_image)
4899 - & (p->tls_align-1);
4900 - p->tls_offset = tls_offset;
4901 + tls_offset += p->tls.size + p->tls.align - 1;
4902 + tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
4903 + & (p->tls.align-1);
4904 + p->tls.offset = tls_offset;
4906 p->new_dtv = (void *)(-sizeof(size_t) &
4907 (uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
4908 p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
4909 + if (tls_tail) tls_tail->next = &p->tls;
4910 + else libc.tls_head = &p->tls;
4911 + tls_tail = &p->tls;
4915 @@ -1151,7 +1190,7 @@ static void kernel_mapped_dso(struct dso
4916 p->kernel_mapped = 1;
4919 -static void do_fini()
4920 +void __libc_exit_fini()
4923 size_t dyn[DYN_CNT];
4924 @@ -1214,53 +1253,8 @@ static void dl_debug_state(void)
4926 weak_alias(dl_debug_state, _dl_debug_state);
4929 +void __init_tls(size_t *auxv)
4931 - pthread_t self = __pthread_self();
4933 - for (p=head; p; p=p->next) {
4934 - if (!p->tls_id || !self->dtv[p->tls_id]) continue;
4935 - memcpy(self->dtv[p->tls_id], p->tls_image, p->tls_len);
4936 - memset((char *)self->dtv[p->tls_id]+p->tls_len, 0,
4937 - p->tls_size - p->tls_len);
4938 - if (p->tls_id == (size_t)self->dtv[0]) break;
4942 -void *__copy_tls(unsigned char *mem)
4948 -#ifdef TLS_ABOVE_TP
4949 - dtv = (void **)(mem + libc.tls_size) - (tls_cnt + 1);
4951 - mem += -((uintptr_t)mem + sizeof(struct pthread)) & (tls_align-1);
4952 - td = (pthread_t)mem;
4953 - mem += sizeof(struct pthread);
4955 - for (p=head; p; p=p->next) {
4956 - if (!p->tls_id) continue;
4957 - dtv[p->tls_id] = mem + p->tls_offset;
4958 - memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
4961 - dtv = (void **)mem;
4963 - mem += libc.tls_size - sizeof(struct pthread);
4964 - mem -= (uintptr_t)mem & (tls_align-1);
4965 - td = (pthread_t)mem;
4967 - for (p=head; p; p=p->next) {
4968 - if (!p->tls_id) continue;
4969 - dtv[p->tls_id] = mem - p->tls_offset;
4970 - memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
4973 - dtv[0] = (void *)tls_cnt;
4974 - td->dtv = td->dtv_copy = dtv;
4978 __attribute__((__visibility__("hidden")))
4979 @@ -1286,7 +1280,7 @@ void *__tls_get_new(size_t *v)
4980 /* Get new DTV space from new DSO if needed */
4981 if (v[0] > (size_t)self->dtv[0]) {
4982 void **newdtv = p->new_dtv +
4983 - (v[0]+1)*sizeof(void *)*a_fetch_add(&p->new_dtv_idx,1);
4984 + (v[0]+1)*a_fetch_add(&p->new_dtv_idx,1);
4985 memcpy(newdtv, self->dtv,
4986 ((size_t)self->dtv[0]+1) * sizeof(void *));
4987 newdtv[0] = (void *)v[0];
4988 @@ -1297,12 +1291,12 @@ void *__tls_get_new(size_t *v)
4990 for (p=head; ; p=p->next) {
4991 if (!p->tls_id || self->dtv[p->tls_id]) continue;
4992 - mem = p->new_tls + (p->tls_size + p->tls_align)
4993 + mem = p->new_tls + (p->tls.size + p->tls.align)
4994 * a_fetch_add(&p->new_tls_idx,1);
4995 - mem += ((uintptr_t)p->tls_image - (uintptr_t)mem)
4996 - & (p->tls_align-1);
4997 + mem += ((uintptr_t)p->tls.image - (uintptr_t)mem)
4998 + & (p->tls.align-1);
4999 self->dtv[p->tls_id] = mem;
5000 - memcpy(mem, p->tls_image, p->tls_len);
5001 + memcpy(mem, p->tls.image, p->tls.len);
5002 if (p->tls_id == v[0]) break;
5004 __restore_sigs(&set);
5005 @@ -1311,6 +1305,8 @@ void *__tls_get_new(size_t *v)
5007 static void update_tls_size()
5009 + libc.tls_cnt = tls_cnt;
5010 + libc.tls_align = tls_align;
5011 libc.tls_size = ALIGN(
5012 (1+tls_cnt) * sizeof(void *) +
5014 @@ -1421,6 +1417,7 @@ _Noreturn void __dls3(size_t *sp)
5015 * use during dynamic linking. If possible it will also serve as the
5016 * thread pointer at runtime. */
5017 libc.tls_size = sizeof builtin_tls;
5018 + libc.tls_align = tls_align;
5019 if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
5022 @@ -1448,13 +1445,13 @@ _Noreturn void __dls3(size_t *sp)
5023 interp_off = (size_t)phdr->p_vaddr;
5024 else if (phdr->p_type == PT_TLS) {
5025 tls_image = phdr->p_vaddr;
5026 - app.tls_len = phdr->p_filesz;
5027 - app.tls_size = phdr->p_memsz;
5028 - app.tls_align = phdr->p_align;
5029 + app.tls.len = phdr->p_filesz;
5030 + app.tls.size = phdr->p_memsz;
5031 + app.tls.align = phdr->p_align;
5034 if (DL_FDPIC) app.loadmap = app_loadmap;
5035 - if (app.tls_size) app.tls_image = laddr(&app, tls_image);
5036 + if (app.tls.size) app.tls.image = laddr(&app, tls_image);
5037 if (interp_off) ldso.name = laddr(&app, interp_off);
5038 if ((aux[0] & (1UL<<AT_EXECFN))
5039 && strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
5040 @@ -1523,19 +1520,20 @@ _Noreturn void __dls3(size_t *sp)
5041 dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
5044 - if (app.tls_size) {
5045 + if (app.tls.size) {
5046 + libc.tls_head = &app.tls;
5047 app.tls_id = tls_cnt = 1;
5049 - app.tls_offset = 0;
5050 - tls_offset = app.tls_size
5051 - + ( -((uintptr_t)app.tls_image + app.tls_size)
5052 - & (app.tls_align-1) );
5053 + app.tls.offset = 0;
5054 + tls_offset = app.tls.size
5055 + + ( -((uintptr_t)app.tls.image + app.tls.size)
5056 + & (app.tls.align-1) );
5058 - tls_offset = app.tls_offset = app.tls_size
5059 - + ( -((uintptr_t)app.tls_image + app.tls_size)
5060 - & (app.tls_align-1) );
5061 + tls_offset = app.tls.offset = app.tls.size
5062 + + ( -((uintptr_t)app.tls.image + app.tls.size)
5063 + & (app.tls.align-1) );
5065 - tls_align = MAXP2(tls_align, app.tls_align);
5066 + tls_align = MAXP2(tls_align, app.tls.align);
5070 @@ -1635,8 +1633,6 @@ _Noreturn void __dls3(size_t *sp)
5074 - __init_libc(envp, argv[0]);
5078 CRTJMP((void *)aux[AT_ENTRY], argv-1);
5079 @@ -1646,6 +1642,7 @@ _Noreturn void __dls3(size_t *sp)
5080 void *dlopen(const char *file, int mode)
5082 struct dso *volatile p, *orig_tail, *next;
5083 + struct tls_module *orig_tls_tail;
5084 size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
5087 @@ -1658,6 +1655,7 @@ void *dlopen(const char *file, int mode)
5091 + orig_tls_tail = tls_tail;
5092 orig_tls_cnt = tls_cnt;
5093 orig_tls_offset = tls_offset;
5094 orig_tls_align = tls_align;
5095 @@ -1684,6 +1682,8 @@ void *dlopen(const char *file, int mode)
5099 + if (!orig_tls_tail) libc.tls_head = 0;
5100 + tls_tail = orig_tls_tail;
5101 tls_cnt = orig_tls_cnt;
5102 tls_offset = orig_tls_offset;
5103 tls_align = orig_tls_align;
5104 @@ -1900,7 +1900,7 @@ int dl_iterate_phdr(int(*callback)(struc
5105 info.dlpi_adds = gencnt;
5107 info.dlpi_tls_modid = current->tls_id;
5108 - info.dlpi_tls_data = current->tls_image;
5109 + info.dlpi_tls_data = current->tls.image;
5111 ret = (callback)(&info, sizeof (info), data);
5113 --- a/src/locale/langinfo.c
5114 +++ b/src/locale/langinfo.c
5115 @@ -37,23 +37,23 @@ char *__nl_langinfo_l(nl_item item, loca
5119 - if (idx > 1) return NULL;
5120 + if (idx > 1) return "";
5124 - if (idx > 0x31) return NULL;
5125 + if (idx > 0x31) return "";
5129 - if (idx > 0) return NULL;
5130 + if (idx > 0) return "";
5134 - if (idx > 3) return NULL;
5135 + if (idx > 3) return "";
5143 for (; idx; idx--, str++) for (; *str; str++);
5144 --- a/src/malloc/lite_malloc.c
5145 +++ b/src/malloc/lite_malloc.c
5148 void *__expand_heap(size_t *);
5150 -void *__simple_malloc(size_t n)
5151 +static void *__simple_malloc(size_t n)
5153 static char *cur, *end;
5154 static volatile int lock[2];
5155 --- a/src/math/__rem_pio2.c
5156 +++ b/src/math/__rem_pio2.c
5157 @@ -118,7 +118,7 @@ int __rem_pio2(double x, double *y)
5158 if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */
5160 /* rint(x/(pi/2)), Assume round-to-nearest. */
5161 - fn = x*invpio2 + toint - toint;
5162 + fn = (double_t)x*invpio2 + toint - toint;
5165 w = fn*pio2_1t; /* 1st round, good to 85 bits */
5166 --- a/src/math/__rem_pio2f.c
5167 +++ b/src/math/__rem_pio2f.c
5168 @@ -51,7 +51,7 @@ int __rem_pio2f(float x, double *y)
5169 /* 25+53 bit pi is good enough for medium size */
5170 if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */
5171 /* Use a specialized rint() to get fn. Assume round-to-nearest. */
5172 - fn = x*invpio2 + toint - toint;
5173 + fn = (double_t)x*invpio2 + toint - toint;
5175 *y = x - fn*pio2_1 - fn*pio2_1t;
5178 +++ b/src/math/arm/fabs.c
5184 +double fabs(double x)
5186 + __asm__ ("vabs.f64 %P0, %P1" : "=w"(x) : "w"(x));
5192 +#include "../fabs.c"
5196 +++ b/src/math/arm/fabsf.c
5202 +float fabsf(float x)
5204 + __asm__ ("vabs.f32 %0, %1" : "=t"(x) : "t"(x));
5210 +#include "../fabsf.c"
5214 +++ b/src/math/arm/sqrt.c
5218 +#if __VFP_FP__ && !__SOFTFP__
5220 +double sqrt(double x)
5222 + __asm__ ("vsqrt.f64 %P0, %P1" : "=w"(x) : "w"(x));
5228 +#include "../sqrt.c"
5232 +++ b/src/math/arm/sqrtf.c
5236 +#if __VFP_FP__ && !__SOFTFP__
5238 +float sqrtf(float x)
5240 + __asm__ ("vsqrt.f32 %0, %1" : "=t"(x) : "t"(x));
5246 +#include "../sqrtf.c"
5249 --- a/src/math/armebhf/fabs.sub
5253 --- a/src/math/armebhf/fabsf.sub
5257 --- a/src/math/armebhf/sqrt.sub
5261 --- a/src/math/armebhf/sqrtf.sub
5265 --- a/src/math/armhf/fabs.s
5271 -.type fabs,%function
5275 --- a/src/math/armhf/fabs.sub
5279 --- a/src/math/armhf/fabsf.s
5285 -.type fabsf,%function
5289 --- a/src/math/armhf/fabsf.sub
5293 --- a/src/math/armhf/sqrt.s
5299 -.type sqrt,%function
5303 --- a/src/math/armhf/sqrt.sub
5307 --- a/src/math/armhf/sqrtf.s
5313 -.type sqrtf,%function
5317 --- a/src/math/armhf/sqrtf.sub
5321 --- a/src/math/hypot.c
5322 +++ b/src/math/hypot.c
5323 @@ -12,10 +12,10 @@ static void sq(double_t *hi, double_t *l
5325 double_t xh, xl, xc;
5328 + xc = (double_t)x*SPLIT;
5332 + *hi = (double_t)x*x;
5333 *lo = xh*xh - *hi + 2*xh*xl + xl*xl;
5336 --- a/src/mman/mremap.c
5337 +++ b/src/mman/mremap.c
5339 +#define _GNU_SOURCE
5341 #include <sys/mman.h>
5343 +#include <stdint.h>
5345 #include "syscall.h"
5348 +static void dummy(void) { }
5349 +weak_alias(dummy, __vm_wait);
5351 void *__mremap(void *old_addr, size_t old_len, size_t new_len, int flags, ...)
5356 - va_start(ap, flags);
5357 - new_addr = va_arg(ap, void *);
5359 + void *new_addr = 0;
5361 + if (new_len >= PTRDIFF_MAX) {
5363 + return MAP_FAILED;
5366 + if (flags & MREMAP_FIXED) {
5368 + va_start(ap, flags);
5369 + new_addr = va_arg(ap, void *);
5373 return (void *)syscall(SYS_mremap, old_addr, old_len, new_len, flags, new_addr);
5375 --- a/src/network/getifaddrs.c
5376 +++ b/src/network/getifaddrs.c
5377 @@ -162,13 +162,26 @@ static int netlink_msg_to_ifaddr(void *p
5378 for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
5379 switch (rta->rta_type) {
5381 - copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
5382 + /* If ifa_addr is already set we, received an IFA_LOCAL before
5383 + * so treat this as destination address */
5384 + if (ifs->ifa.ifa_addr)
5385 + copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
5387 + copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
5390 - /* For point-to-point links this is peer, but ifa_broadaddr
5391 - * and ifa_dstaddr are union, so this works for both. */
5392 copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
5395 + /* If ifa_addr is set and we get IFA_LOCAL, assume we have
5396 + * a point-to-point network. Move address to correct field. */
5397 + if (ifs->ifa.ifa_addr) {
5398 + ifs->ifu = ifs->addr;
5399 + ifs->ifa.ifa_dstaddr = &ifs->ifu.sa;
5400 + memset(&ifs->addr, 0, sizeof(ifs->addr));
5402 + copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
5405 if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
5406 memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
5407 --- a/src/network/getnameinfo.c
5408 +++ b/src/network/getnameinfo.c
5409 @@ -135,13 +135,13 @@ int getnameinfo(const struct sockaddr *r
5412 a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
5413 - if (sl != sizeof(struct sockaddr_in)) return EAI_FAMILY;
5414 + if (sl < sizeof(struct sockaddr_in)) return EAI_FAMILY;
5419 a = (void *)&((struct sockaddr_in6 *)sa)->sin6_addr;
5420 - if (sl != sizeof(struct sockaddr_in6)) return EAI_FAMILY;
5421 + if (sl < sizeof(struct sockaddr_in6)) return EAI_FAMILY;
5422 if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12))
5425 --- a/src/network/if_nametoindex.c
5426 +++ b/src/network/if_nametoindex.c
5427 @@ -10,7 +10,7 @@ unsigned if_nametoindex(const char *name
5431 - if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return -1;
5432 + if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
5433 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
5434 r = ioctl(fd, SIOCGIFINDEX, &ifr);
5435 __syscall(SYS_close, fd);
5436 --- a/src/network/lookup_name.c
5437 +++ b/src/network/lookup_name.c
5441 #include <pthread.h>
5444 #include "stdio_impl.h"
5445 #include "syscall.h"
5446 @@ -51,7 +52,14 @@ static int name_from_hosts(struct addres
5448 unsigned char _buf[1032];
5449 FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
5451 + if (!f) switch (errno) {
5457 + return EAI_SYSTEM;
5459 while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
5462 --- a/src/network/lookup_serv.c
5463 +++ b/src/network/lookup_serv.c
5470 #include "stdio_impl.h"
5472 @@ -69,7 +70,14 @@ int __lookup_serv(struct service buf[sta
5474 unsigned char _buf[1032];
5475 FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
5476 - if (!f) return EAI_SERVICE;
5477 + if (!f) switch (errno) {
5481 + return EAI_SERVICE;
5483 + return EAI_SYSTEM;
5486 while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
5487 if ((p=strchr(line, '#'))) *p++='\n', *p=0;
5488 --- a/src/network/proto.c
5489 +++ b/src/network/proto.c
5490 @@ -9,21 +9,36 @@ static const unsigned char protos[] = {
5528 --- a/src/network/res_msend.c
5529 +++ b/src/network/res_msend.c
5530 @@ -54,7 +54,15 @@ int __res_msend(int nqueries, const unsi
5532 /* Get nameservers from resolv.conf, fallback to localhost */
5533 f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
5534 - if (f) for (nns=0; nns<3 && fgets(line, sizeof line, f); ) {
5535 + if (!f) switch (errno) {
5539 + goto no_resolv_conf;
5543 + for (nns=0; nns<3 && fgets(line, sizeof line, f); ) {
5544 if (!strncmp(line, "options", 7) && isspace(line[7])) {
5547 @@ -92,7 +100,8 @@ int __res_msend(int nqueries, const unsi
5551 - if (f) __fclose_ca(f);
5555 ns[0].sin.sin_family = AF_INET;
5556 ns[0].sin.sin_port = htons(53);
5557 --- a/src/search/tsearch_avl.c
5558 +++ b/src/search/tsearch_avl.c
5559 @@ -77,38 +77,45 @@ static struct node *find(struct node *n,
5560 return find(n->right, k, cmp);
5563 -static struct node *insert(struct node **n, const void *k,
5564 - int (*cmp)(const void *, const void *), int *new)
5565 +static struct node *insert(struct node *n, const void *k,
5566 + int (*cmp)(const void *, const void *), struct node **found)
5568 - struct node *r = *n;
5573 - *n = r = malloc(sizeof **n);
5576 - r->left = r->right = 0;
5579 + n = malloc(sizeof *n);
5582 + n->left = n->right = 0;
5590 + c = cmp(k, n->key);
5595 + r = insert(c < 0 ? n->left : n->right, k, cmp, found);
5603 - c = cmp(k, r->key);
5607 - r = insert(&r->left, k, cmp, new);
5609 - r = insert(&r->right, k, cmp, new);
5615 -static struct node *movr(struct node *n, struct node *r) {
5618 - n->right = movr(n->right, r);
5619 +static struct node *remove_rightmost(struct node *n, struct node **rightmost)
5625 + n->right = remove_rightmost(n->right, rightmost);
5629 @@ -122,7 +129,13 @@ static struct node *remove(struct node *
5630 c = cmp(k, (*n)->key);
5632 struct node *r = *n;
5633 - *n = movr(r->left, r->right);
5635 + r->left = remove_rightmost(r->left, n);
5636 + (*n)->left = r->left;
5637 + (*n)->right = r->right;
5644 @@ -138,6 +151,8 @@ static struct node *remove(struct node *
5645 void *tdelete(const void *restrict key, void **restrict rootp,
5646 int(*compar)(const void *, const void *))
5650 struct node *n = *rootp;
5652 /* last argument is arbitrary non-null pointer
5653 @@ -150,17 +165,21 @@ void *tdelete(const void *restrict key,
5654 void *tfind(const void *key, void *const *rootp,
5655 int(*compar)(const void *, const void *))
5659 return find(*rootp, key, compar);
5662 void *tsearch(const void *key, void **rootp,
5663 int (*compar)(const void *, const void *))
5666 - struct node *n = *rootp;
5667 + struct node *update;
5669 - ret = insert(&n, key, compar, &new);
5673 + update = insert(*rootp, key, compar, &ret);
5679 --- a/src/setjmp/arm/longjmp.s
5680 +++ b/src/setjmp/arm/longjmp.s
5685 .type _longjmp,%function
5686 @@ -20,7 +21,11 @@ longjmp:
5687 ldc p2, cr4, [ip], #48
5690 - .word 0xecbc8b10 /* vldmia ip!, {d8-d15} */
5692 + vldmia ip!, {d8-d15}
5694 + .eabi_attribute 10, 0
5695 + .eabi_attribute 27, 0
5698 ldcl p1, cr10, [ip], #8
5699 @@ -29,9 +34,7 @@ longjmp:
5700 ldcl p1, cr13, [ip], #8
5701 ldcl p1, cr14, [ip], #8
5702 ldcl p1, cr15, [ip], #8
5710 --- a/src/setjmp/arm/setjmp.s
5711 +++ b/src/setjmp/arm/setjmp.s
5717 @@ -22,7 +23,11 @@ setjmp:
5718 stc p2, cr4, [ip], #48
5721 - .word 0xecac8b10 /* vstmia ip!, {d8-d15} */
5723 + vstmia ip!, {d8-d15}
5725 + .eabi_attribute 10, 0
5726 + .eabi_attribute 27, 0
5729 stcl p1, cr10, [ip], #8
5730 @@ -31,9 +36,7 @@ setjmp:
5731 stcl p1, cr13, [ip], #8
5732 stcl p1, cr14, [ip], #8
5733 stcl p1, cr15, [ip], #8
5741 --- a/src/setjmp/mips-sf/longjmp.s
5748 -.type _longjmp,@function
5749 -.type longjmp,@function
5769 --- a/src/setjmp/mips-sf/longjmp.sub
5773 --- a/src/setjmp/mips-sf/setjmp.s
5781 -.type __setjmp,@function
5782 -.type _setjmp,@function
5783 -.type setjmp,@function
5801 --- a/src/setjmp/mips-sf/setjmp.sub
5806 +++ b/src/setjmp/mips/longjmp.S
5812 +.type _longjmp,@function
5813 +.type longjmp,@function
5821 +#ifndef __mips_soft_float
5848 --- a/src/setjmp/mips/longjmp.s
5855 -.type _longjmp,@function
5856 -.type longjmp,@function
5863 -1: lwc1 $20, 56($4)
5889 +++ b/src/setjmp/mips/setjmp.S
5896 +.type __setjmp,@function
5897 +.type _setjmp,@function
5898 +.type setjmp,@function
5914 +#ifndef __mips_soft_float
5930 --- a/src/setjmp/mips/setjmp.s
5938 -.type __setjmp,@function
5939 -.type _setjmp,@function
5940 -.type setjmp,@function
5970 --- a/src/setjmp/mipsel-sf/longjmp.sub
5973 -../mips-sf/longjmp.s
5974 --- a/src/setjmp/mipsel-sf/setjmp.sub
5977 -../mips-sf/setjmp.s
5978 --- a/src/setjmp/sh-nofpu/longjmp.s
5983 -.type _longjmp, @function
5984 -.type longjmp, @function
6003 --- a/src/setjmp/sh-nofpu/longjmp.sub
6007 --- a/src/setjmp/sh-nofpu/setjmp.s
6015 -.type __setjmp, @function
6016 -.type _setjmp, @function
6017 -.type setjmp, @function
6034 --- a/src/setjmp/sh-nofpu/setjmp.sub
6039 +++ b/src/setjmp/sh/longjmp.S
6043 +.type _longjmp, @function
6044 +.type longjmp, @function
6056 +#if __SH_FPU_ANY__ || __SH4__
6069 --- a/src/setjmp/sh/longjmp.s
6074 -.type _longjmp, @function
6075 -.type longjmp, @function
6099 +++ b/src/setjmp/sh/setjmp.S
6106 +.type __setjmp, @function
6107 +.type _setjmp, @function
6108 +.type setjmp, @function
6113 +#if __SH_FPU_ANY__ || __SH4__
6133 --- a/src/setjmp/sh/setjmp.s
6141 -.type __setjmp, @function
6142 -.type _setjmp, @function
6143 -.type setjmp, @function
6164 --- a/src/setjmp/sheb-nofpu/longjmp.sub
6167 -../sh-nofpu/longjmp.s
6168 --- a/src/setjmp/sheb-nofpu/setjmp.sub
6171 -../sh-nofpu/setjmp.s
6172 --- a/src/signal/arm/restore.s
6173 +++ b/src/signal/arm/restore.s
6178 .type __restore,%function
6180 --- a/src/signal/arm/sigsetjmp.s
6181 +++ b/src/signal/arm/sigsetjmp.s
6186 .type sigsetjmp,%function
6187 --- a/src/signal/sigaction.c
6188 +++ b/src/signal/sigaction.c
6189 @@ -17,10 +17,6 @@ void __get_handler_set(sigset_t *set)
6190 int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
6192 struct k_sigaction ksa, ksa_old;
6193 - if (sig >= (unsigned)_NSIG) {
6198 if ((uintptr_t)sa->sa_handler > 1UL) {
6199 a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
6200 @@ -57,7 +53,7 @@ int __libc_sigaction(int sig, const stru
6202 int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
6204 - if (sig-32U < 3) {
6205 + if (sig-32U < 3 || sig-1U >= _NSIG-1) {
6209 --- a/src/signal/sigsetjmp_tail.c
6210 +++ b/src/signal/sigsetjmp_tail.c
6213 #include "syscall.h"
6216 __attribute__((__visibility__("hidden")))
6218 int __sigsetjmp_tail(sigjmp_buf jb, int ret)
6221 --- a/src/stdio/getdelim.c
6222 +++ b/src/stdio/getdelim.c
6223 @@ -27,17 +27,18 @@ ssize_t getdelim(char **restrict s, size
6225 z = memchr(f->rpos, delim, f->rend - f->rpos);
6226 k = z ? z - f->rpos + 1 : f->rend - f->rpos;
6228 + if (i+k+1 >= *n) {
6229 if (k >= SIZE_MAX/2-i) goto oom;
6231 - if (*n < SIZE_MAX/4) *n *= 2;
6232 - tmp = realloc(*s, *n);
6234 + if (!z && m < SIZE_MAX/4) m += m/2;
6235 + tmp = realloc(*s, m);
6238 - tmp = realloc(*s, *n);
6240 + tmp = realloc(*s, m);
6246 memcpy(*s+i, f->rpos, k);
6249 +++ b/src/string/arm/__aeabi_memclr.c
6251 +#include <string.h>
6254 +void __aeabi_memclr(void *dest, size_t n)
6256 + memset(dest, 0, n);
6258 +weak_alias(__aeabi_memclr, __aeabi_memclr4);
6259 +weak_alias(__aeabi_memclr, __aeabi_memclr8);
6261 +++ b/src/string/arm/__aeabi_memcpy.c
6263 +#include <string.h>
6266 +void __aeabi_memcpy(void *restrict dest, const void *restrict src, size_t n)
6268 + memcpy(dest, src, n);
6270 +weak_alias(__aeabi_memcpy, __aeabi_memcpy4);
6271 +weak_alias(__aeabi_memcpy, __aeabi_memcpy8);
6273 +++ b/src/string/arm/__aeabi_memmove.c
6275 +#include <string.h>
6278 +void __aeabi_memmove(void *dest, const void *src, size_t n)
6280 + memmove(dest, src, n);
6282 +weak_alias(__aeabi_memmove, __aeabi_memmove4);
6283 +weak_alias(__aeabi_memmove, __aeabi_memmove8);
6285 +++ b/src/string/arm/__aeabi_memset.c
6287 +#include <string.h>
6290 +void __aeabi_memset(void *dest, size_t n, int c)
6292 + memset(dest, c, n);
6294 +weak_alias(__aeabi_memset, __aeabi_memset4);
6295 +weak_alias(__aeabi_memset, __aeabi_memset8);
6297 +++ b/src/string/arm/memcpy.c
6300 +#include "../memcpy.c"
6303 +++ b/src/string/arm/memcpy_le.S
6308 + * Copyright (C) 2008 The Android Open Source Project
6309 + * All rights reserved.
6311 + * Redistribution and use in source and binary forms, with or without
6312 + * modification, are permitted provided that the following conditions
6314 + * * Redistributions of source code must retain the above copyright
6315 + * notice, this list of conditions and the following disclaimer.
6316 + * * Redistributions in binary form must reproduce the above copyright
6317 + * notice, this list of conditions and the following disclaimer in
6318 + * the documentation and/or other materials provided with the
6321 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6322 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6323 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
6324 + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
6325 + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
6326 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
6327 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
6328 + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
6329 + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
6330 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
6331 + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6337 + * Optimized memcpy() for ARM.
6339 + * note that memcpy() always returns the destination pointer,
6340 + * so we have to preserve R0.
6344 + * This file has been modified from the original for use in musl libc.
6345 + * The main changes are: addition of .type memcpy,%function to make the
6346 + * code safely callable from thumb mode, adjusting the return
6347 + * instructions to be compatible with pre-thumb ARM cpus, and removal
6348 + * of prefetch code that is not compatible with older cpus.
6354 +.type memcpy,%function
6356 + /* The stack must always be 64-bits aligned to be compliant with the
6357 + * ARM ABI. Since we have to save R0, we might as well save R4
6358 + * which we can use for better pipelining of the reads below
6361 + .save {r0, r4, lr}
6362 + stmfd sp!, {r0, r4, lr}
6363 + /* Making room for r5-r11 which will be spilled later */
6367 + /* it simplifies things to take care of len<4 early */
6369 + blo copy_last_3_and_return
6371 + /* compute the offset to align the source
6372 + * offset = (4-(src&3))&3 = -src & 3
6378 + /* align source to 32 bits. We need to insert 2 instructions between
6379 + * a ldr[b|h] and str[b|h] because byte and half-word instructions
6382 + movs r12, r3, lsl #31
6383 + sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
6384 + ldrbmi r3, [r1], #1
6385 + ldrbcs r4, [r1], #1
6386 + ldrbcs r12,[r1], #1
6387 + strbmi r3, [r0], #1
6388 + strbcs r4, [r0], #1
6389 + strbcs r12,[r0], #1
6393 + /* see if src and dst are aligned together (congruent) */
6398 + /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
6399 + * frame. Don't update sp.
6401 + stmea sp, {r5-r11}
6403 + /* align the destination to a cache-line */
6405 + ands r3, r3, #0x1C
6406 + beq congruent_aligned32
6408 + andhi r3, r2, #0x1C
6410 + /* conditionnaly copies 0 to 7 words (length in r3) */
6411 + movs r12, r3, lsl #28
6412 + ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
6413 + ldmmi r1!, {r8, r9} /* 8 bytes */
6414 + stmcs r0!, {r4, r5, r6, r7}
6415 + stmmi r0!, {r8, r9}
6417 + ldrne r10,[r1], #4 /* 4 bytes */
6418 + strne r10,[r0], #4
6421 +congruent_aligned32:
6423 + * here source is aligned to 32 bytes.
6428 + blo less_than_32_left
6431 + * We preload a cache-line up to 64 bytes ahead. On the 926, this will
6432 + * stall only until the requested world is fetched, but the linefill
6433 + * continues in the the background.
6434 + * While the linefill is going, we write our previous cache-line
6435 + * into the write-buffer (which should have some free space).
6436 + * When the linefill is done, the writebuffer will
6437 + * start dumping its content into memory
6439 + * While all this is going, we then load a full cache line into
6440 + * 8 registers, this cache line should be in the cache by now
6441 + * (or partly in the cache).
6443 + * This code should work well regardless of the source/dest alignment.
6447 + /* Align the preload register to a cache-line because the cpu does
6448 + * "critical word first" (the first word requested is loaded first).
6450 + @ bic r12, r1, #0x1F
6451 + @ add r12, r12, #64
6453 +1: ldmia r1!, { r4-r11 }
6457 + * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
6458 + * for ARM9 preload will not be safely guarded by the preceding subs.
6459 + * When it is safely guarded the only possibility to have SIGSEGV here
6460 + * is because the caller overstates the length.
6462 + @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */
6463 + stmia r0!, { r4-r11 }
6470 + * less than 32 bytes left at this point (length in r2)
6473 + /* skip all this if there is nothing to do, which should
6474 + * be a common case (if not executed the code below takes
6475 + * about 16 cycles)
6480 + /* conditionnaly copies 0 to 31 bytes */
6481 + movs r12, r2, lsl #28
6482 + ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
6483 + ldmmi r1!, {r8, r9} /* 8 bytes */
6484 + stmcs r0!, {r4, r5, r6, r7}
6485 + stmmi r0!, {r8, r9}
6486 + movs r12, r2, lsl #30
6487 + ldrcs r3, [r1], #4 /* 4 bytes */
6488 + ldrhmi r4, [r1], #2 /* 2 bytes */
6489 + strcs r3, [r0], #4
6490 + strhmi r4, [r0], #2
6492 + ldrbne r3, [r1] /* last byte */
6495 + /* we're done! restore everything and return */
6496 +1: ldmfd sp!, {r5-r11}
6497 + ldmfd sp!, {r0, r4, lr}
6500 + /********************************************************************/
6504 + * here source is aligned to 4 bytes
6505 + * but destination is not.
6507 + * in the code below r2 is the number of bytes read
6508 + * (the number of bytes written is always smaller, because we have
6509 + * partial words in the shift queue)
6512 + blo copy_last_3_and_return
6514 + /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
6515 + * frame. Don't update sp.
6517 + stmea sp, {r5-r11}
6519 + /* compute shifts needed to align src to dest */
6521 + and r5, r5, #3 /* r5 = # bytes in partial words */
6522 + mov r12, r5, lsl #3 /* r12 = right */
6523 + rsb lr, r12, #32 /* lr = left */
6525 + /* read the first word */
6529 + /* write a partial word (0 to 3 bytes), such that destination
6530 + * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
6532 + movs r5, r5, lsl #31
6533 + strbmi r3, [r0], #1
6534 + movmi r3, r3, lsr #8
6535 + strbcs r3, [r0], #1
6536 + movcs r3, r3, lsr #8
6537 + strbcs r3, [r0], #1
6538 + movcs r3, r3, lsr #8
6541 + blo partial_word_tail
6543 + /* Align destination to 32 bytes (cache line boundary) */
6548 + orr r4, r3, r5, lsl lr
6549 + mov r3, r5, lsr r12
6553 + blo partial_word_tail
6555 + /* copy 32 bytes at a time */
6556 +2: subs r2, r2, #32
6557 + blo less_than_thirtytwo
6559 + /* Use immediate mode for the shifts, because there is an extra cycle
6560 + * for register shifts, which could account for up to 50% of
6561 + * performance hit.
6572 + ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
6574 + ldrhs r12, [r1], #4
6575 + orr r3, r3, r4, lsl #16
6576 + mov r4, r4, lsr #16
6577 + orr r4, r4, r5, lsl #16
6578 + mov r5, r5, lsr #16
6579 + orr r5, r5, r6, lsl #16
6580 + mov r6, r6, lsr #16
6581 + orr r6, r6, r7, lsl #16
6582 + mov r7, r7, lsr #16
6583 + orr r7, r7, r8, lsl #16
6584 + mov r8, r8, lsr #16
6585 + orr r8, r8, r9, lsl #16
6586 + mov r9, r9, lsr #16
6587 + orr r9, r9, r10, lsl #16
6588 + mov r10, r10, lsr #16
6589 + orr r10, r10, r11, lsl #16
6590 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
6591 + mov r3, r11, lsr #16
6593 + b less_than_thirtytwo
6598 + ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
6600 + ldrhs r12, [r1], #4
6601 + orr r3, r3, r4, lsl #24
6602 + mov r4, r4, lsr #8
6603 + orr r4, r4, r5, lsl #24
6604 + mov r5, r5, lsr #8
6605 + orr r5, r5, r6, lsl #24
6606 + mov r6, r6, lsr #8
6607 + orr r6, r6, r7, lsl #24
6608 + mov r7, r7, lsr #8
6609 + orr r7, r7, r8, lsl #24
6610 + mov r8, r8, lsr #8
6611 + orr r8, r8, r9, lsl #24
6612 + mov r9, r9, lsr #8
6613 + orr r9, r9, r10, lsl #24
6614 + mov r10, r10, lsr #8
6615 + orr r10, r10, r11, lsl #24
6616 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
6617 + mov r3, r11, lsr #8
6619 + b less_than_thirtytwo
6624 + ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
6626 + ldrhs r12, [r1], #4
6627 + orr r3, r3, r4, lsl #8
6628 + mov r4, r4, lsr #24
6629 + orr r4, r4, r5, lsl #8
6630 + mov r5, r5, lsr #24
6631 + orr r5, r5, r6, lsl #8
6632 + mov r6, r6, lsr #24
6633 + orr r6, r6, r7, lsl #8
6634 + mov r7, r7, lsr #24
6635 + orr r7, r7, r8, lsl #8
6636 + mov r8, r8, lsr #24
6637 + orr r8, r8, r9, lsl #8
6638 + mov r9, r9, lsr #24
6639 + orr r9, r9, r10, lsl #8
6640 + mov r10, r10, lsr #24
6641 + orr r10, r10, r11, lsl #8
6642 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
6643 + mov r3, r11, lsr #24
6646 +less_than_thirtytwo:
6647 + /* copy the last 0 to 31 bytes of the source */
6648 + rsb r12, lr, #32 /* we corrupted r12, recompute it */
6651 + blo partial_word_tail
6653 +1: ldr r5, [r1], #4
6655 + orr r4, r3, r5, lsl lr
6656 + mov r3, r5, lsr r12
6662 + /* we have a partial word in the input buffer */
6663 + movs r5, lr, lsl #(31-3)
6664 + strbmi r3, [r0], #1
6665 + movmi r3, r3, lsr #8
6666 + strbcs r3, [r0], #1
6667 + movcs r3, r3, lsr #8
6668 + strbcs r3, [r0], #1
6670 + /* Refill spilled registers from the stack. Don't update sp. */
6671 + ldmfd sp, {r5-r11}
6673 +copy_last_3_and_return:
6674 + movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
6675 + ldrbmi r2, [r1], #1
6676 + ldrbcs r3, [r1], #1
6678 + strbmi r2, [r0], #1
6679 + strbcs r3, [r0], #1
6682 + /* we're done! restore sp and spilled registers and return */
6684 + ldmfd sp!, {r0, r4, lr}
6688 --- a/src/string/armel/memcpy.s
6692 - * Copyright (C) 2008 The Android Open Source Project
6693 - * All rights reserved.
6695 - * Redistribution and use in source and binary forms, with or without
6696 - * modification, are permitted provided that the following conditions
6698 - * * Redistributions of source code must retain the above copyright
6699 - * notice, this list of conditions and the following disclaimer.
6700 - * * Redistributions in binary form must reproduce the above copyright
6701 - * notice, this list of conditions and the following disclaimer in
6702 - * the documentation and/or other materials provided with the
6705 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6706 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6707 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
6708 - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
6709 - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
6710 - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
6711 - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
6712 - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
6713 - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
6714 - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
6715 - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6721 - * Optimized memcpy() for ARM.
6723 - * note that memcpy() always returns the destination pointer,
6724 - * so we have to preserve R0.
6728 - * This file has been modified from the original for use in musl libc.
6729 - * The main changes are: addition of .type memcpy,%function to make the
6730 - * code safely callable from thumb mode, adjusting the return
6731 - * instructions to be compatible with pre-thumb ARM cpus, and removal
6732 - * of prefetch code that is not compatible with older cpus.
6736 -.type memcpy,%function
6738 - /* The stack must always be 64-bits aligned to be compliant with the
6739 - * ARM ABI. Since we have to save R0, we might as well save R4
6740 - * which we can use for better pipelining of the reads below
6743 - .save {r0, r4, lr}
6744 - stmfd sp!, {r0, r4, lr}
6745 - /* Making room for r5-r11 which will be spilled later */
6749 - /* it simplifies things to take care of len<4 early */
6751 - blo copy_last_3_and_return
6753 - /* compute the offset to align the source
6754 - * offset = (4-(src&3))&3 = -src & 3
6760 - /* align source to 32 bits. We need to insert 2 instructions between
6761 - * a ldr[b|h] and str[b|h] because byte and half-word instructions
6764 - movs r12, r3, lsl #31
6765 - sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
6766 - .word 0x44d13001 /* ldrbmi r3, [r1], #1 */
6767 - .word 0x24d14001 /* ldrbcs r4, [r1], #1 */
6768 - .word 0x24d1c001 /* ldrbcs r12,[r1], #1 */
6769 - .word 0x44c03001 /* strbmi r3, [r0], #1 */
6770 - .word 0x24c04001 /* strbcs r4, [r0], #1 */
6771 - .word 0x24c0c001 /* strbcs r12,[r0], #1 */
6775 - /* see if src and dst are aligned together (congruent) */
6780 - /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
6781 - * frame. Don't update sp.
6783 - stmea sp, {r5-r11}
6785 - /* align the destination to a cache-line */
6787 - ands r3, r3, #0x1C
6788 - beq congruent_aligned32
6790 - andhi r3, r2, #0x1C
6792 - /* conditionnaly copies 0 to 7 words (length in r3) */
6793 - movs r12, r3, lsl #28
6794 - ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
6795 - ldmmi r1!, {r8, r9} /* 8 bytes */
6796 - stmcs r0!, {r4, r5, r6, r7}
6797 - stmmi r0!, {r8, r9}
6799 - ldrne r10,[r1], #4 /* 4 bytes */
6800 - strne r10,[r0], #4
6803 -congruent_aligned32:
6805 - * here source is aligned to 32 bytes.
6810 - blo less_than_32_left
6813 - * We preload a cache-line up to 64 bytes ahead. On the 926, this will
6814 - * stall only until the requested world is fetched, but the linefill
6815 - * continues in the the background.
6816 - * While the linefill is going, we write our previous cache-line
6817 - * into the write-buffer (which should have some free space).
6818 - * When the linefill is done, the writebuffer will
6819 - * start dumping its content into memory
6821 - * While all this is going, we then load a full cache line into
6822 - * 8 registers, this cache line should be in the cache by now
6823 - * (or partly in the cache).
6825 - * This code should work well regardless of the source/dest alignment.
6829 - /* Align the preload register to a cache-line because the cpu does
6830 - * "critical word first" (the first word requested is loaded first).
6832 - @ bic r12, r1, #0x1F
6833 - @ add r12, r12, #64
6835 -1: ldmia r1!, { r4-r11 }
6839 - * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
6840 - * for ARM9 preload will not be safely guarded by the preceding subs.
6841 - * When it is safely guarded the only possibility to have SIGSEGV here
6842 - * is because the caller overstates the length.
6844 - @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */
6845 - stmia r0!, { r4-r11 }
6852 - * less than 32 bytes left at this point (length in r2)
6855 - /* skip all this if there is nothing to do, which should
6856 - * be a common case (if not executed the code below takes
6857 - * about 16 cycles)
6862 - /* conditionnaly copies 0 to 31 bytes */
6863 - movs r12, r2, lsl #28
6864 - ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
6865 - ldmmi r1!, {r8, r9} /* 8 bytes */
6866 - stmcs r0!, {r4, r5, r6, r7}
6867 - stmmi r0!, {r8, r9}
6868 - movs r12, r2, lsl #30
6869 - ldrcs r3, [r1], #4 /* 4 bytes */
6870 - .word 0x40d140b2 /* ldrhmi r4, [r1], #2 */ /* 2 bytes */
6871 - strcs r3, [r0], #4
6872 - .word 0x40c040b2 /* strhmi r4, [r0], #2 */
6874 - .word 0x15d13000 /* ldrbne r3, [r1] */ /* last byte */
6875 - .word 0x15c03000 /* strbne r3, [r0] */
6877 - /* we're done! restore everything and return */
6878 -1: ldmfd sp!, {r5-r11}
6879 - ldmfd sp!, {r0, r4, lr}
6884 - /********************************************************************/
6888 - * here source is aligned to 4 bytes
6889 - * but destination is not.
6891 - * in the code below r2 is the number of bytes read
6892 - * (the number of bytes written is always smaller, because we have
6893 - * partial words in the shift queue)
6896 - blo copy_last_3_and_return
6898 - /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
6899 - * frame. Don't update sp.
6901 - stmea sp, {r5-r11}
6903 - /* compute shifts needed to align src to dest */
6905 - and r5, r5, #3 /* r5 = # bytes in partial words */
6906 - mov r12, r5, lsl #3 /* r12 = right */
6907 - rsb lr, r12, #32 /* lr = left */
6909 - /* read the first word */
6913 - /* write a partial word (0 to 3 bytes), such that destination
6914 - * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
6916 - movs r5, r5, lsl #31
6917 - .word 0x44c03001 /* strbmi r3, [r0], #1 */
6918 - movmi r3, r3, lsr #8
6919 - .word 0x24c03001 /* strbcs r3, [r0], #1 */
6920 - movcs r3, r3, lsr #8
6921 - .word 0x24c03001 /* strbcs r3, [r0], #1 */
6922 - movcs r3, r3, lsr #8
6925 - blo partial_word_tail
6927 - /* Align destination to 32 bytes (cache line boundary) */
6932 - orr r4, r3, r5, lsl lr
6933 - mov r3, r5, lsr r12
6937 - blo partial_word_tail
6939 - /* copy 32 bytes at a time */
6940 -2: subs r2, r2, #32
6941 - blo less_than_thirtytwo
6943 - /* Use immediate mode for the shifts, because there is an extra cycle
6944 - * for register shifts, which could account for up to 50% of
6945 - * performance hit.
6956 - ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
6958 - ldrhs r12, [r1], #4
6959 - orr r3, r3, r4, lsl #16
6960 - mov r4, r4, lsr #16
6961 - orr r4, r4, r5, lsl #16
6962 - mov r5, r5, lsr #16
6963 - orr r5, r5, r6, lsl #16
6964 - mov r6, r6, lsr #16
6965 - orr r6, r6, r7, lsl #16
6966 - mov r7, r7, lsr #16
6967 - orr r7, r7, r8, lsl #16
6968 - mov r8, r8, lsr #16
6969 - orr r8, r8, r9, lsl #16
6970 - mov r9, r9, lsr #16
6971 - orr r9, r9, r10, lsl #16
6972 - mov r10, r10, lsr #16
6973 - orr r10, r10, r11, lsl #16
6974 - stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
6975 - mov r3, r11, lsr #16
6977 - b less_than_thirtytwo
6982 - ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
6984 - ldrhs r12, [r1], #4
6985 - orr r3, r3, r4, lsl #24
6986 - mov r4, r4, lsr #8
6987 - orr r4, r4, r5, lsl #24
6988 - mov r5, r5, lsr #8
6989 - orr r5, r5, r6, lsl #24
6990 - mov r6, r6, lsr #8
6991 - orr r6, r6, r7, lsl #24
6992 - mov r7, r7, lsr #8
6993 - orr r7, r7, r8, lsl #24
6994 - mov r8, r8, lsr #8
6995 - orr r8, r8, r9, lsl #24
6996 - mov r9, r9, lsr #8
6997 - orr r9, r9, r10, lsl #24
6998 - mov r10, r10, lsr #8
6999 - orr r10, r10, r11, lsl #24
7000 - stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
7001 - mov r3, r11, lsr #8
7003 - b less_than_thirtytwo
7008 - ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
7010 - ldrhs r12, [r1], #4
7011 - orr r3, r3, r4, lsl #8
7012 - mov r4, r4, lsr #24
7013 - orr r4, r4, r5, lsl #8
7014 - mov r5, r5, lsr #24
7015 - orr r5, r5, r6, lsl #8
7016 - mov r6, r6, lsr #24
7017 - orr r6, r6, r7, lsl #8
7018 - mov r7, r7, lsr #24
7019 - orr r7, r7, r8, lsl #8
7020 - mov r8, r8, lsr #24
7021 - orr r8, r8, r9, lsl #8
7022 - mov r9, r9, lsr #24
7023 - orr r9, r9, r10, lsl #8
7024 - mov r10, r10, lsr #24
7025 - orr r10, r10, r11, lsl #8
7026 - stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
7027 - mov r3, r11, lsr #24
7030 -less_than_thirtytwo:
7031 - /* copy the last 0 to 31 bytes of the source */
7032 - rsb r12, lr, #32 /* we corrupted r12, recompute it */
7035 - blo partial_word_tail
7037 -1: ldr r5, [r1], #4
7039 - orr r4, r3, r5, lsl lr
7040 - mov r3, r5, lsr r12
7046 - /* we have a partial word in the input buffer */
7047 - movs r5, lr, lsl #(31-3)
7048 - .word 0x44c03001 /* strbmi r3, [r0], #1 */
7049 - movmi r3, r3, lsr #8
7050 - .word 0x24c03001 /* strbcs r3, [r0], #1 */
7051 - movcs r3, r3, lsr #8
7052 - .word 0x24c03001 /* strbcs r3, [r0], #1 */
7054 - /* Refill spilled registers from the stack. Don't update sp. */
7055 - ldmfd sp, {r5-r11}
7057 -copy_last_3_and_return:
7058 - movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
7059 - .word 0x44d12001 /* ldrbmi r2, [r1], #1 */
7060 - .word 0x24d13001 /* ldrbcs r3, [r1], #1 */
7061 - .word 0x25d1c000 /* ldrbcs r12,[r1] */
7062 - .word 0x44c02001 /* strbmi r2, [r0], #1 */
7063 - .word 0x24c03001 /* strbcs r3, [r0], #1 */
7064 - .word 0x25c0c000 /* strbcs r12,[r0] */
7066 - /* we're done! restore sp and spilled registers and return */
7068 - ldmfd sp!, {r0, r4, lr}
7072 --- a/src/string/armel/memcpy.sub
7076 --- a/src/string/armhf/memcpy.sub
7080 --- a/src/thread/__syscall_cp.c
7081 +++ b/src/thread/__syscall_cp.c
7083 #include "pthread_impl.h"
7084 #include "syscall.h"
7087 __attribute__((__visibility__("hidden")))
7089 long __syscall_cp_c();
7091 static long sccp(syscall_arg_t nr,
7092 --- a/src/thread/__tls_get_addr.c
7093 +++ b/src/thread/__tls_get_addr.c
7096 #include "pthread_impl.h"
7099 +__attribute__((__visibility__("hidden")))
7100 +void *__tls_get_new(size_t *);
7102 void *__tls_get_addr(size_t *v)
7104 pthread_t self = __pthread_self();
7106 - __attribute__((__visibility__("hidden")))
7107 - void *__tls_get_new(size_t *);
7108 if (v[0]<=(size_t)self->dtv[0])
7109 return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
7110 return __tls_get_new(v);
7112 - return (char *)self->dtv[1]+v[1]+DTP_OFFSET;
7116 +weak_alias(__tls_get_addr, __tls_get_new);
7117 --- a/src/thread/aarch64/syscall_cp.s
7118 +++ b/src/thread/aarch64/syscall_cp.s
7124 + cbnz w0,__cp_cancel
7128 @@ -28,6 +28,5 @@ __cp_begin:
7133 - // cbnz might not be able to jump far enough
7138 +++ b/src/thread/arm/__set_thread_area.c
7140 +#include <stdint.h>
7142 +#include "pthread_impl.h"
7145 +#define HWCAP_TLS (1 << 15)
7147 +extern const unsigned char __attribute__((__visibility__("hidden")))
7148 + __a_barrier_dummy[], __a_barrier_oldkuser[],
7149 + __a_barrier_v6[], __a_barrier_v7[],
7150 + __a_cas_dummy[], __a_cas_v6[], __a_cas_v7[],
7151 + __a_gettp_dummy[];
7153 +#define __a_barrier_kuser 0xffff0fa0
7154 +#define __a_cas_kuser 0xffff0fc0
7155 +#define __a_gettp_kuser 0xffff0fe0
7157 +extern uintptr_t __attribute__((__visibility__("hidden")))
7158 + __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;
7160 +#define SET(op,ver) (__a_##op##_ptr = \
7161 + (uintptr_t)__a_##op##_##ver - (uintptr_t)__a_##op##_dummy)
7163 +int __set_thread_area(void *p)
7165 +#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
7166 + if (__hwcap & HWCAP_TLS) {
7170 + for (aux=libc.auxv; *aux; aux+=2) {
7171 + if (*aux != AT_PLATFORM) continue;
7172 + const char *s = (void *)aux[1];
7173 + if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;
7179 + int ver = *(int *)0xffff0ffc;
7180 + SET(gettp, kuser);
7182 + SET(barrier, kuser);
7183 + if (ver < 2) a_crash();
7184 + if (ver < 3) SET(barrier, oldkuser);
7187 + return __syscall(0xf0005, p);
7189 --- a/src/thread/arm/__set_thread_area.s
7192 -/* Replaced by C code in arch/arm/src */
7193 --- a/src/thread/arm/__unmapself.s
7194 +++ b/src/thread/arm/__unmapself.s
7199 .type __unmapself,%function
7201 +++ b/src/thread/arm/atomics.s
7206 +.global __a_barrier
7207 +.hidden __a_barrier
7208 +.type __a_barrier,%function
7213 +1: .word __a_barrier_ptr-1b
7214 +.global __a_barrier_dummy
7215 +.hidden __a_barrier_dummy
7218 +.global __a_barrier_oldkuser
7219 +.hidden __a_barrier_oldkuser
7220 +__a_barrier_oldkuser:
7221 + push {r0,r1,r2,r3,ip,lr}
7224 + ldr ip,=0xffff0fc0
7227 + pop {r0,r1,r2,r3,ip,lr}
7229 +.global __a_barrier_v6
7230 +.hidden __a_barrier_v6
7232 + mcr p15,0,r0,c7,c10,5
7234 +.global __a_barrier_v7
7235 +.hidden __a_barrier_v7
7237 + .word 0xf57ff05b /* dmb ish */
7242 +.type __a_cas,%function
7247 +1: .word __a_cas_ptr-1b
7248 +.global __a_cas_dummy
7249 +.hidden __a_cas_dummy
7260 + mcr p15,0,r0,c7,c10,5
7261 +1: .word 0xe1920f9f /* ldrex r0,[r2] */
7263 + .word 0x01820f91 /* strexeq r0,r1,[r2] */
7266 + mcr p15,0,r0,c7,c10,5
7272 + .word 0xf57ff05b /* dmb ish */
7273 +1: .word 0xe1920f9f /* ldrex r0,[r2] */
7275 + .word 0x01820f91 /* strexeq r0,r1,[r2] */
7278 + .word 0xf57ff05b /* dmb ish */
7281 +.global __aeabi_read_tp
7282 +.type __aeabi_read_tp,%function
7287 +.type __a_gettp,%function
7292 +1: .word __a_gettp_ptr-1b
7293 +.global __a_gettp_dummy
7294 +.hidden __a_gettp_dummy
7296 + mrc p15,0,r0,c13,c0,3
7300 +.global __a_barrier_ptr
7301 +.hidden __a_barrier_ptr
7305 +.global __a_cas_ptr
7306 +.hidden __a_cas_ptr
7310 +.global __a_gettp_ptr
7311 +.hidden __a_gettp_ptr
7314 --- a/src/thread/arm/clone.s
7315 +++ b/src/thread/arm/clone.s
7320 .type __clone,%function
7321 @@ -15,8 +16,6 @@ __clone:
7324 ldmfd sp!,{r4,r5,r6,r7}
7330 --- a/src/thread/arm/syscall_cp.s
7331 +++ b/src/thread/arm/syscall_cp.s
7337 @@ -22,8 +23,6 @@ __cp_begin:
7340 ldmfd sp!,{r4,r5,r6,r7,lr}
7345 ldmfd sp!,{r4,r5,r6,r7,lr}
7346 --- a/src/thread/microblaze/syscall_cp.s
7347 +++ b/src/thread/microblaze/syscall_cp.s
7353 + bnei r5, __cp_cancel
7357 @@ -23,3 +23,5 @@ __cp_begin:
7363 --- a/src/thread/or1k/syscall_cp.s
7364 +++ b/src/thread/or1k/syscall_cp.s
7365 @@ -12,7 +12,7 @@ __syscall_cp_asm:
7374 @@ -24,3 +24,6 @@ __cp_begin:
7381 --- a/src/thread/powerpc/syscall_cp.s
7382 +++ b/src/thread/powerpc/syscall_cp.s
7383 @@ -38,7 +38,7 @@ __cp_begin:
7384 cmpwi cr7, 0, 0 #compare r0 with 0, store result in cr7.
7385 beq+ cr7, 1f #jump to label 1 if r0 was 0
7387 - b __cancel #else call cancel
7388 + b __cp_cancel #else call cancel
7390 #ok, the cancel flag was not set
7391 # syscall: number goes to r0, the rest 3-8
7392 @@ -55,3 +55,5 @@ __cp_end:
7393 #else negate result.
7398 --- a/src/thread/pthread_cancel.c
7399 +++ b/src/thread/pthread_cancel.c
7401 +#define _GNU_SOURCE
7403 #include "pthread_impl.h"
7404 #include "syscall.h"
7408 __attribute__((__visibility__("hidden")))
7410 -long __cancel(), __cp_cancel(), __syscall_cp_asm(), __syscall_cp_c();
7411 +long __cancel(), __syscall_cp_asm(), __syscall_cp_c();
7415 @@ -17,12 +16,6 @@ long __cancel()
7419 -/* If __syscall_cp_asm has adjusted the stack pointer, it must provide a
7420 - * definition of __cp_cancel to undo those adjustments and call __cancel.
7421 - * Otherwise, __cancel provides a definition for __cp_cancel. */
7423 -weak_alias(__cancel, __cp_cancel);
7425 long __syscall_cp_asm(volatile void *, syscall_arg_t,
7426 syscall_arg_t, syscall_arg_t, syscall_arg_t,
7427 syscall_arg_t, syscall_arg_t, syscall_arg_t);
7428 @@ -52,24 +45,22 @@ static void _sigaddset(sigset_t *set, in
7429 set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
7433 __attribute__((__visibility__("hidden")))
7435 -extern const char __cp_begin[1], __cp_end[1];
7436 +extern const char __cp_begin[1], __cp_end[1], __cp_cancel[1];
7438 static void cancel_handler(int sig, siginfo_t *si, void *ctx)
7440 pthread_t self = __pthread_self();
7441 ucontext_t *uc = ctx;
7442 - const char *ip = ((char **)&uc->uc_mcontext)[CANCEL_REG_IP];
7443 + uintptr_t pc = uc->uc_mcontext.MC_PC;
7446 if (!self->cancel || self->canceldisable == PTHREAD_CANCEL_DISABLE) return;
7448 _sigaddset(&uc->uc_sigmask, SIGCANCEL);
7450 - if (self->cancelasync || ip >= __cp_begin && ip < __cp_end) {
7451 - ((char **)&uc->uc_mcontext)[CANCEL_REG_IP] = (char *)__cp_cancel;
7452 + if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {
7453 + uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel;
7458 +++ b/src/thread/sh/__set_thread_area.c
7460 +#include "pthread_impl.h"
7464 +/* Also perform sh-specific init */
7466 +#define CPU_HAS_LLSC 0x0040
7467 +#define CPU_HAS_CAS_L 0x0400
7469 +__attribute__((__visibility__("hidden")))
7470 +extern const char __sh_cas_gusa[], __sh_cas_llsc[], __sh_cas_imask[], __sh_cas_cas_l[];
7472 +__attribute__((__visibility__("hidden")))
7473 +const void *__sh_cas_ptr;
7475 +__attribute__((__visibility__("hidden")))
7476 +unsigned __sh_nommu;
7478 +int __set_thread_area(void *p)
7481 + __asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
7483 + __sh_cas_ptr = __sh_cas_gusa;
7484 +#if !defined(__SH3__) && !defined(__SH4__)
7485 + for (aux=libc.auxv; *aux; aux+=2) {
7486 + if (*aux != AT_PLATFORM) continue;
7487 + const char *s = (void *)aux[1];
7488 + if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
7489 + __sh_cas_ptr = __sh_cas_imask;
7493 + if (__hwcap & CPU_HAS_CAS_L)
7494 + __sh_cas_ptr = __sh_cas_cas_l;
7495 + else if (__hwcap & CPU_HAS_LLSC)
7496 + __sh_cas_ptr = __sh_cas_llsc;
7501 +++ b/src/thread/sh/atomics.s
7503 +/* Contract for all versions is same as cas.l r2,r3,@r0
7504 + * pr and r1 are also clobbered (by jsr & r1 as temp).
7505 + * r0,r2,r4-r15 must be preserved.
7506 + * r3 contains result (==r2 iff cas succeeded). */
7509 +.global __sh_cas_gusa
7510 +.hidden __sh_cas_gusa
7529 +.global __sh_cas_llsc
7530 +.hidden __sh_cas_llsc
7546 +.global __sh_cas_imask
7547 +.hidden __sh_cas_imask
7563 +.global __sh_cas_cas_l
7564 +.hidden __sh_cas_cas_l
7567 + .word 0x2323 /* cas.l r2,r3,@r0 */
7568 --- a/src/thread/sh/syscall_cp.s
7569 +++ b/src/thread/sh/syscall_cp.s
7570 @@ -14,17 +14,8 @@ __syscall_cp_asm:
7582 -L1: .long __cancel@PLT-(1b-.)
7590 @@ -43,3 +34,12 @@ __cp_end:
7602 +2: .long __cancel@PCREL-(1b-.)
7603 --- a/src/thread/x32/syscall_cp.s
7604 +++ b/src/thread/x32/syscall_cp.s
7605 @@ -14,7 +14,7 @@ __syscall_cp_internal:
7614 @@ -27,3 +27,5 @@ __cp_begin:
7620 --- a/src/thread/x86_64/syscall_cp.s
7621 +++ b/src/thread/x86_64/syscall_cp.s
7622 @@ -14,7 +14,7 @@ __syscall_cp_asm:
7631 @@ -27,3 +27,5 @@ __cp_begin: