Merge release 1.1.13
diff --git a/.gitignore b/.gitignore
index c5d5c46..2cb88d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,9 +5,6 @@
 *.so.1
 arch/*/bits/alltypes.h
 config.mak
-include/bits
-tools/musl-gcc
-tools/musl-clang
-tools/ld.musl-clang
 lib/musl-gcc.specs
 src/internal/version.h
+/obj/
diff --git a/INSTALL b/INSTALL
index 5713cd4..9f33910 100644
--- a/INSTALL
+++ b/INSTALL
@@ -18,28 +18,18 @@
 
 The only build-time prerequisites for musl are GNU Make and a
 freestanding C99 compiler toolchain targeting the desired instruction
-set architecture and ABI, with support for gcc-style inline assembly,
-weak aliases, and stand-alone assembly source files.
+set architecture and ABI, with support for a minimal subset of "GNU C"
+extensions consisting mainly of gcc-style inline assembly, weak
+aliases, hidden visibility, and stand-alone assembly source files.
+
+GCC, LLVM/clang, Firm/cparser, and PCC have all successfully built
+musl, but GCC is the most widely used/tested. Recent compiler (and
+binutils) versions should be used if possible since some older
+versions have bugs which affect musl.
 
 The system used to build musl does not need to be Linux-based, nor do
 the Linux kernel headers need to be available.
 
-If support for dynamic linking is desired, some further requirements
-are placed on the compiler and linker. In particular, the linker must
-support the -Bsymbolic-functions option.
-
-At present, GCC 4.6 or later is the recommended compiler for building
-musl. Any earlier version of GCC with full C99 support should also
-work, but may be subject to minor floating point conformance issues on
-i386 targets. Sufficiently recent versions of PCC and LLVM/clang are
-also believed to work, but have not been tested as heavily; prior to
-Fall 2012, both had known bugs that affected musl. Firm/cparser is
-also believed to work but lacks support for producing shared
-libraries. GCC 4.9.0 and 4.9.1 are known to have a serious bug
-(#61144) which affects musl. Beginning with version 1.1.4 musl
-attempts to work around the bug, but these compiler versions are still
-considered unstable and unsupported.
-
 
 
 Supported Targets
@@ -53,12 +43,17 @@
       the `cmpxchg` instruction is added
 
 * x86_64
+    * ILP32 ABI (x32) is available as a separate arch but is still
+      experimental
 
 * ARM
     * EABI, standard or hard-float VFP variant
     * Little-endian default; big-endian variants also supported
     * Compiler toolchains only support armv4t and later
 
+* AArch64
+    * Little-endian default; big-endian variants also supported
+
 * MIPS
     * ABI is o32
     * Big-endian default; little-endian variants also supported
@@ -74,21 +69,18 @@
     * For dynamic linking, compiler toolchain must be configured for
       "secure PLT" variant
 
+* SuperH (SH)
+    * Standard ELF ABI or FDPIC ABI (shared-text without MMU)
+    * Little-endian by default; big-engian variant also supported
+    * Full FPU ABI or soft-float ABI is supported, but the
+      single-precision-only FPU ABI is not
+
 * Microblaze
     * Big-endian default; little-endian variants also supported
     * Soft-float
     * Requires support for lwx/swx instructions
 
-The following additional targets are available for build, but may not
-work correctly and may not yet have ABI stability:
-
-* SuperH (SH)
-    * Little-endian by default; big-engian variant also supported
-    * Full FPU ABI or soft-float ABI is supported, but the
-      single-precision-only FPU ABI is not supported (musl always
-      requires IEEE single and double to be supported)
-
-* x32 (x86_64 ILP32 ABI)
+* OpenRISC 1000 (or1k)
 
 
 
diff --git a/Makefile b/Makefile
index 844a017..b2a719d 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@
 # Do not make changes here.
 #
 
+srcdir = .
 exec_prefix = /usr/local
 bindir = $(exec_prefix)/bin
 
@@ -16,31 +17,42 @@
 libdir = $(prefix)/lib
 syslibdir = /lib
 
-SRCS = $(sort $(wildcard src/*/*.c arch/$(ARCH)/src/*.c))
-OBJS = $(SRCS:.c=.o)
+BASE_SRCS = $(sort $(wildcard $(srcdir)/src/*/*.c))
+BASE_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(BASE_SRCS)))
+ARCH_SRCS = $(wildcard $(srcdir)/src/*/$(ARCH)/*.[csS])
+ARCH_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(ARCH_SRCS)))
+REPLACED_OBJS = $(sort $(subst /$(ARCH)/,/,$(ARCH_OBJS)))
+LDSO_SRCS = $(sort $(wildcard $(srcdir)/ldso/*.c))
+LDSO_OBJS = $(patsubst $(srcdir)/%,obj/%.lo,$(basename $(LDSO_SRCS)))
+OBJS = $(addprefix obj/, $(filter-out $(REPLACED_OBJS), $(sort $(BASE_OBJS) $(ARCH_OBJS))))
+AOBJS = $(OBJS)
 LOBJS = $(OBJS:.o=.lo)
-GENH = include/bits/alltypes.h
-GENH_INT = src/internal/version.h
-IMPH = src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/libc.h
+GENH = obj/include/bits/alltypes.h
+GENH_INT = obj/src/internal/version.h
+IMPH = $(addprefix $(srcdir)/, src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/libc.h)
 
-LDFLAGS = 
+LDFLAGS =
+LDFLAGS_AUTO =
 LIBCC = -lgcc
 CPPFLAGS =
-CFLAGS = -Os -pipe
+CFLAGS =
+CFLAGS_AUTO = -Os -pipe
 CFLAGS_C99FSE = -std=c99 -ffreestanding -nostdinc 
 
 CFLAGS_ALL = $(CFLAGS_C99FSE)
-CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I./arch/$(ARCH) -I./src/internal -I./include
-CFLAGS_ALL += $(CPPFLAGS) $(CFLAGS)
-CFLAGS_ALL_STATIC = $(CFLAGS_ALL)
-CFLAGS_ALL_SHARED = $(CFLAGS_ALL) -fPIC -DSHARED
+CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I$(srcdir)/arch/$(ARCH) -I$(srcdir)/arch/generic -Iobj/src/internal -I$(srcdir)/src/internal -Iobj/include -I$(srcdir)/include
+CFLAGS_ALL += $(CPPFLAGS) $(CFLAGS_AUTO) $(CFLAGS)
+
+LDFLAGS_ALL = $(LDFLAGS_AUTO) $(LDFLAGS)
 
 AR      = $(CROSS_COMPILE)ar
 RANLIB  = $(CROSS_COMPILE)ranlib
-INSTALL = ./tools/install.sh
+INSTALL = $(srcdir)/tools/install.sh
 
-ARCH_INCLUDES = $(wildcard arch/$(ARCH)/bits/*.h)
-ALL_INCLUDES = $(sort $(wildcard include/*.h include/*/*.h) $(GENH) $(ARCH_INCLUDES:arch/$(ARCH)/%=include/%))
+ARCH_INCLUDES = $(wildcard $(srcdir)/arch/$(ARCH)/bits/*.h)
+GENERIC_INCLUDES = $(wildcard $(srcdir)/arch/generic/bits/*.h)
+INCLUDES = $(wildcard $(srcdir)/include/*.h $(srcdir)/include/*/*.h)
+ALL_INCLUDES = $(sort $(INCLUDES:$(srcdir)/%=%) $(GENH:obj/%=%) $(ARCH_INCLUDES:$(srcdir)/arch/$(ARCH)/%=include/%) $(GENERIC_INCLUDES:$(srcdir)/arch/generic/%=include/%))
 
 EMPTY_LIB_NAMES = m rt pthread crypt util xnet resolv dl
 EMPTY_LIBS = $(EMPTY_LIB_NAMES:%=lib/lib%.a)
@@ -49,7 +61,7 @@
 SHARED_LIBS = lib/libc.so
 TOOL_LIBS = lib/musl-gcc.specs
 ALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS)
-ALL_TOOLS = tools/musl-gcc
+ALL_TOOLS = obj/musl-gcc
 
 WRAPCC_GCC = gcc
 WRAPCC_CLANG = clang
@@ -58,122 +70,127 @@
 
 -include config.mak
 
+ifeq ($(ARCH),)
+$(error Please set ARCH in config.mak before running make.)
+endif
+
 all: $(ALL_LIBS) $(ALL_TOOLS)
 
+OBJ_DIRS = $(sort $(patsubst %/,%,$(dir $(ALL_LIBS) $(ALL_TOOLS) $(OBJS) $(LDSO_OBJS) $(GENH) $(GENH_INT))) $(addprefix obj/, crt crt/$(ARCH) include))
+
+$(ALL_LIBS) $(ALL_TOOLS) $(CRT_LIBS:lib/%=obj/crt/%) $(OBJS) $(LOBJS) $(GENH) $(GENH_INT): | $(OBJ_DIRS)
+
+$(OBJ_DIRS):
+	mkdir -p $@
+
 install: install-libs install-headers install-tools
 
 clean:
-	rm -f crt/*.o
-	rm -f $(OBJS)
-	rm -f $(LOBJS)
-	rm -f $(ALL_LIBS) lib/*.[ao] lib/*.so
-	rm -f $(ALL_TOOLS)
-	rm -f $(GENH) $(GENH_INT)
-	rm -f include/bits
+	rm -rf obj lib
 
 distclean: clean
 	rm -f config.mak
 
-include/bits:
-	@test "$(ARCH)" || { echo "Please set ARCH in config.mak before running make." ; exit 1 ; }
-	ln -sf ../arch/$(ARCH)/bits $@
+obj/include/bits/alltypes.h: $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in $(srcdir)/tools/mkalltypes.sed
+	sed -f $(srcdir)/tools/mkalltypes.sed $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in > $@
 
-include/bits/alltypes.h.in: include/bits
+obj/src/internal/version.h: $(wildcard $(srcdir)/VERSION $(srcdir)/.git)
+	printf '#define VERSION "%s"\n' "$$(cd $(srcdir); sh tools/version.sh)" > $@
 
-include/bits/alltypes.h: include/bits/alltypes.h.in include/alltypes.h.in tools/mkalltypes.sed
-	sed -f tools/mkalltypes.sed include/bits/alltypes.h.in include/alltypes.h.in > $@
+obj/src/internal/version.o obj/src/internal/version.lo: obj/src/internal/version.h
 
-src/internal/version.h: $(wildcard VERSION .git)
-	printf '#define VERSION "%s"\n' "$$(sh tools/version.sh)" > $@
+obj/crt/rcrt1.o obj/ldso/dlstart.lo obj/ldso/dynlink.lo: $(srcdir)/src/internal/dynlink.h $(srcdir)/arch/$(ARCH)/reloc.h
 
-src/internal/version.lo: src/internal/version.h
+obj/crt/crt1.o obj/crt/scrt1.o obj/crt/rcrt1.o obj/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h
 
-crt/rcrt1.o src/ldso/dlstart.lo src/ldso/dynlink.lo: src/internal/dynlink.h arch/$(ARCH)/reloc.h
+obj/crt/rcrt1.o: $(srcdir)/ldso/dlstart.c
 
-crt/crt1.o crt/Scrt1.o crt/rcrt1.o src/ldso/dlstart.lo: $(wildcard arch/$(ARCH)/crt_arch.h)
+obj/crt/Scrt1.o obj/crt/rcrt1.o: CFLAGS_ALL += -fPIC
 
-crt/rcrt1.o: src/ldso/dlstart.c
+obj/crt/$(ARCH)/crti.o: $(srcdir)/crt/$(ARCH)/crti.s
 
-crt/Scrt1.o crt/rcrt1.o: CFLAGS += -fPIC
+obj/crt/$(ARCH)/crtn.o: $(srcdir)/crt/$(ARCH)/crtn.s
 
-OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=src/%))
-$(OPTIMIZE_SRCS:%.c=%.o) $(OPTIMIZE_SRCS:%.c=%.lo): CFLAGS += -O3
+OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=$(srcdir)/src/%))
+$(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.lo): CFLAGS += -O3
 
 MEMOPS_SRCS = src/string/memcpy.c src/string/memmove.c src/string/memcmp.c src/string/memset.c
-$(MEMOPS_SRCS:%.c=%.o) $(MEMOPS_SRCS:%.c=%.lo): CFLAGS += $(CFLAGS_MEMOPS)
+$(MEMOPS_SRCS:%.c=obj/%.o) $(MEMOPS_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS)
 
 NOSSP_SRCS = $(wildcard crt/*.c) \
 	src/env/__libc_start_main.c src/env/__init_tls.c \
-	src/thread/__set_thread_area.c src/env/__stack_chk_fail.c \
-	src/string/memset.c src/string/memcpy.c \
-	src/ldso/dlstart.c src/ldso/dynlink.c
-$(NOSSP_SRCS:%.c=%.o) $(NOSSP_SRCS:%.c=%.lo): CFLAGS += $(CFLAGS_NOSSP)
+	src/env/__stack_chk_fail.c \
+	src/thread/__set_thread_area.c src/thread/$(ARCH)/__set_thread_area.c \
+	src/string/memset.c src/string/$(ARCH)/memset.c \
+	src/string/memcpy.c src/string/$(ARCH)/memcpy.c \
+	ldso/dlstart.c ldso/dynlink.c
+$(NOSSP_SRCS:%.c=obj/%.o) $(NOSSP_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP)
 
-$(CRT_LIBS:lib/%=crt/%): CFLAGS += -DCRT
+$(CRT_LIBS:lib/%=obj/crt/%): CFLAGS_ALL += -DCRT
 
-# This incantation ensures that changes to any subarch asm files will
-# force the corresponding object file to be rebuilt, even if the implicit
-# rule below goes indirectly through a .sub file.
-define mkasmdep
-$(dir $(patsubst %/,%,$(dir $(1))))$(notdir $(1:.s=.o)): $(1)
-endef
-$(foreach s,$(wildcard src/*/$(ARCH)*/*.s),$(eval $(call mkasmdep,$(s))))
+$(LOBJS) $(LDSO_OBJS): CFLAGS_ALL += -fPIC
+
+CC_CMD = $(CC) $(CFLAGS_ALL) -c -o $@ $<
 
 # Choose invocation of assembler to be used
-# $(1) is input file, $(2) is output file, $(3) is assembler flags
 ifeq ($(ADD_CFI),yes)
-	AS_CMD = LC_ALL=C awk -f tools/add-cfi.common.awk -f tools/add-cfi.$(ARCH).awk $< | $(CC) -x assembler -c -o $@ -
+	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 $@ -
 else
-	AS_CMD = $(CC) -c -o $@ $<
+	AS_CMD = $(CC_CMD)
 endif
 
-%.o: $(ARCH)$(ASMSUBARCH)/%.sub
-	$(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $(dir $<)$(shell cat $<)
+obj/%.o: $(srcdir)/%.s
+	$(AS_CMD)
 
-%.o: $(ARCH)/%.s
-	$(AS_CMD) $(CFLAGS_ALL_STATIC)
+obj/%.o: $(srcdir)/%.S
+	$(CC_CMD)
 
-%.o: %.c $(GENH) $(IMPH)
-	$(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $<
+obj/%.o: $(srcdir)/%.c $(GENH) $(IMPH)
+	$(CC_CMD)
 
-%.lo: $(ARCH)$(ASMSUBARCH)/%.sub
-	$(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $(dir $<)$(shell cat $<)
+obj/%.lo: $(srcdir)/%.s
+	$(AS_CMD)
 
-%.lo: $(ARCH)/%.s
-	$(AS_CMD) $(CFLAGS_ALL_SHARED)
+obj/%.lo: $(srcdir)/%.S
+	$(CC_CMD)
 
-%.lo: %.c $(GENH) $(IMPH)
-	$(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $<
+obj/%.lo: $(srcdir)/%.c $(GENH) $(IMPH)
+	$(CC_CMD)
 
-lib/libc.so: $(LOBJS)
-	$(CC) $(CFLAGS_ALL_SHARED) $(LDFLAGS) -nostdlib -shared \
-	-Wl,-e,_dlstart -Wl,-Bsymbolic-functions \
-	-o $@ $(LOBJS) $(LIBCC)
+lib/libc.so: $(LOBJS) $(LDSO_OBJS)
+	$(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -nostdlib -shared \
+	-Wl,-e,_dlstart -o $@ $(LOBJS) $(LDSO_OBJS) $(LIBCC)
 
-lib/libc.a: $(OBJS)
+lib/libc.a: $(AOBJS)
 	rm -f $@
-	$(AR) rc $@ $(OBJS)
+	$(AR) rc $@ $(AOBJS)
 	$(RANLIB) $@
 
 $(EMPTY_LIBS):
 	rm -f $@
 	$(AR) rc $@
 
-lib/%.o: crt/%.o
+lib/%.o: obj/crt/%.o
 	cp $< $@
 
-lib/musl-gcc.specs: tools/musl-gcc.specs.sh config.mak
+lib/crti.o: obj/crt/$(ARCH)/crti.o
+	cp $< $@
+
+lib/crtn.o: obj/crt/$(ARCH)/crtn.o
+	cp $< $@
+
+lib/musl-gcc.specs: $(srcdir)/tools/musl-gcc.specs.sh config.mak
 	sh $< "$(includedir)" "$(libdir)" "$(LDSO_PATHNAME)" > $@
 
-tools/musl-gcc: config.mak
+obj/musl-gcc: config.mak
 	printf '#!/bin/sh\nexec "$${REALGCC:-$(WRAPCC_GCC)}" "$$@" -specs "%s/musl-gcc.specs"\n' "$(libdir)" > $@
 	chmod +x $@
 
-tools/%-clang: tools/%-clang.in config.mak
+obj/%-clang: $(srcdir)/tools/%-clang.in config.mak
 	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' $< > $@
 	chmod +x $@
 
-$(DESTDIR)$(bindir)/%: tools/%
+$(DESTDIR)$(bindir)/%: obj/%
 	$(INSTALL) -D $< $@
 
 $(DESTDIR)$(libdir)/%.so: lib/%.so
@@ -182,10 +199,16 @@
 $(DESTDIR)$(libdir)/%: lib/%
 	$(INSTALL) -D -m 644 $< $@
 
-$(DESTDIR)$(includedir)/bits/%: arch/$(ARCH)/bits/%
+$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/$(ARCH)/bits/%
 	$(INSTALL) -D -m 644 $< $@
 
-$(DESTDIR)$(includedir)/%: include/%
+$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/generic/bits/%
+	$(INSTALL) -D -m 644 $< $@
+
+$(DESTDIR)$(includedir)/bits/%: obj/include/bits/%
+	$(INSTALL) -D -m 644 $< $@
+
+$(DESTDIR)$(includedir)/%: $(srcdir)/include/%
 	$(INSTALL) -D -m 644 $< $@
 
 $(DESTDIR)$(LDSO_PATHNAME): $(DESTDIR)$(libdir)/libc.so
@@ -195,12 +218,12 @@
 
 install-headers: $(ALL_INCLUDES:include/%=$(DESTDIR)$(includedir)/%)
 
-install-tools: $(ALL_TOOLS:tools/%=$(DESTDIR)$(bindir)/%)
+install-tools: $(ALL_TOOLS:obj/%=$(DESTDIR)$(bindir)/%)
 
 musl-git-%.tar.gz: .git
-	 git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)
+	 git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)
 
 musl-%.tar.gz: .git
-	 git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)
+	 git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)
 
 .PHONY: all clean install install-libs install-headers install-tools
diff --git a/VERSION b/VERSION
index ccad953..9ea63db 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.1.12
+1.1.13
diff --git a/WHATSNEW b/WHATSNEW
index 911a16d..935c0bb 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -1618,3 +1618,63 @@
 - arm crt1 entry point failed to align stack pointer in some cases
 - mips fesetround failed to actually set rounding mode
 - i386 asm source CFI generation had multiple bugs
+
+
+
+1.1.13 release notes
+
+new features:
+- out-of-tree builds
+- search domains in resolv.conf
+- sh arch supports j-core (j2) cas.l atomics
+- dynamic linker includes arch/abi in output when run as a command
+- header support for new kernel features through linux 4.4
+- mips vdso clock_gettime support
+- regex BRE extensions: \|, \+, \?
+
+performance:
+- improved atomics performance on all archs with ll/sc model
+- atomic instructions are now inlined on armv6
+- use fpu sqrt for arm softfp abi on targets with vfp
+
+compatibility:
+- getnameinfo now accepts sockaddr sizes larger than needed
+- new default CFLAGS/LDFLAGS avoid entire classes of toolchain bugs
+- explicit use of float_t/double_t avoids compiler float spill bugs
+- i386 max_align_t definition now works with g++ 4.7's pseudo-c++11
+- all known protocols are added to protoent functions
+- stub utmpname, utmpxname functions
+- linker support for -Bsymbolic-functions is no longer mandatory
+- regex parsing size limits increased
+- malloc_usable_size now accepts null pointer input
+
+bugs fixed:
+- potential single-byte heap overflow in getdelim
+- mishandling of transient failure opening hosts, services, resolv.conf
+- mremap was sometimes able to allocate objects larger than PTRDIFF_MAX
+- nl_langinfo wrongly returned NULL instead of "" for invalid items
+- out-of-bounds dynamic tls allocation due to pointer/index scaling error
+- getifaddrs misreported point-to-point interface addresses
+- tdelete left tsearch trees misbalanced
+- tsearch crashed on allocation failure
+- tsearch, tfind, and tdelete failed to handle null pointer input
+- passing signal number 0 to sigaction resulted in a crash
+- getdelim updated caller's size wrongly when realloc failed
+- getdelim realloc strategy was wasteful
+- if_nametoindex returned wrong value on failure
+- missing ssp-suppression for some source files called from early-init
+- various minor resolv.conf parsing bugs
+- fwrite wrongly reported success on write errors in line-buffered flush
+- fwrite and fread wrongly returned nmemb (not 0) when size was 0
+
+nommu-specific bugs fix:
+- failure to zero bss in FDPIC shared library loader
+- unsafe writes to read-only file mapping in non-FDPIC library loader
+
+arch-specific bugs fixed:
+- sh[eb]-nofpu-fdpic was using fpu-dependent setjmp/longjmp variants
+- dynamic linker path file name was wrong for arm "softfp" targets
+- mips siginfo_t and related macros were defined incorrectly
+- possibly misaligned pointer globals on arm (from an asm source file)
+- mips dynamic linker failed to provide info needed by debugger
+- mips cancellation asm wrongly assumed validity of $gp register value
diff --git a/arch/aarch64/atomic.h b/arch/aarch64/atomic.h
deleted file mode 100644
index e7c82c2..0000000
--- a/arch/aarch64/atomic.h
+++ /dev/null
@@ -1,206 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_64(uint64_t x)
-{
-	__asm__(
-		"	rbit %0, %1\n"
-		"	clz %0, %0\n"
-		: "=r"(x) : "r"(x));
-	return x;
-}
-
-static inline int a_ctz_l(unsigned long x)
-{
-	return a_ctz_64(x);
-}
-
-static inline void a_barrier()
-{
-	__asm__ __volatile__("dmb ish");
-}
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	void *old;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %0,%3\n"
-		"	cmp %0,%1\n"
-		"	b.ne 1f\n"
-		"	stxr %w0,%2,%3\n"
-		"	cbnz %w0,1b\n"
-		"	mov %0,%1\n"
-		"1:	dmb ish\n"
-		: "=&r"(old)
-		: "r"(t), "r"(s), "Q"(*(long*)p)
-		: "memory", "cc");
-	return old;
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	int old;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %w0,%3\n"
-		"	cmp %w0,%w1\n"
-		"	b.ne 1f\n"
-		"	stxr %w0,%w2,%3\n"
-		"	cbnz %w0,1b\n"
-		"	mov %w0,%w1\n"
-		"1:	dmb ish\n"
-		: "=&r"(old)
-		: "r"(t), "r"(s), "Q"(*p)
-		: "memory", "cc");
-	return old;
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	int old, tmp;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %w0,%3\n"
-		"	stxr %w1,%w2,%3\n"
-		"	cbnz %w1,1b\n"
-		"	dmb ish\n"
-		: "=&r"(old), "=&r"(tmp)
-		: "r"(v), "Q"(*x)
-		: "memory", "cc" );
-	return old;
-}
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	int old, tmp;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %w0,%3\n"
-		"	add %w0,%w0,%w2\n"
-		"	stxr %w1,%w0,%3\n"
-		"	cbnz %w1,1b\n"
-		"	dmb ish\n"
-		: "=&r"(old), "=&r"(tmp)
-		: "r"(v), "Q"(*x)
-		: "memory", "cc" );
-	return old-v;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %w0,%2\n"
-		"	add %w0,%w0,#1\n"
-		"	stxr %w1,%w0,%2\n"
-		"	cbnz %w1,1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "Q"(*x)
-		: "memory", "cc" );
-}
-
-static inline void a_dec(volatile int *x)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %w0,%2\n"
-		"	sub %w0,%w0,#1\n"
-		"	stxr %w1,%w0,%2\n"
-		"	cbnz %w1,1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "Q"(*x)
-		: "memory", "cc" );
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %0,%3\n"
-		"	and %0,%0,%2\n"
-		"	stxr %w1,%0,%3\n"
-		"	cbnz %w1,1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "r"(v), "Q"(*p)
-		: "memory", "cc" );
-}
-
-static inline void a_and(volatile int *p, int v)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %w0,%3\n"
-		"	and %w0,%w0,%w2\n"
-		"	stxr %w1,%w0,%3\n"
-		"	cbnz %w1,1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "r"(v), "Q"(*p)
-		: "memory", "cc" );
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %0,%3\n"
-		"	orr %0,%0,%2\n"
-		"	stxr %w1,%0,%3\n"
-		"	cbnz %w1,1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "r"(v), "Q"(*p)
-		: "memory", "cc" );
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	return a_or_64(p, v);
-}
-
-static inline void a_or(volatile int *p, int v)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldxr %w0,%3\n"
-		"	orr %w0,%w0,%w2\n"
-		"	stxr %w1,%w0,%3\n"
-		"	cbnz %w1,1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "r"(v), "Q"(*p)
-		: "memory", "cc" );
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"	str %w1,%0\n"
-		"	dmb ish\n"
-		: "=m"(*p)
-		: "r"(x)
-		: "memory", "cc" );
-}
-
-#define a_spin a_barrier
-
-static inline void a_crash()
-{
-	*(volatile char *)0=0;
-}
-
-
-#endif
diff --git a/arch/aarch64/atomic_arch.h b/arch/aarch64/atomic_arch.h
new file mode 100644
index 0000000..af93d87
--- /dev/null
+++ b/arch/aarch64/atomic_arch.h
@@ -0,0 +1,73 @@
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+	int v;
+	__asm__ __volatile__ ("ldaxr %w0,%1" : "=r"(v) : "Q"(*p));
+	return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+	int r;
+	__asm__ __volatile__ ("stlxr %w0,%w2,%1" : "=&r"(r), "=Q"(*p) : "r"(v) : "memory");
+	return !r;
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("dmb ish" : : : "memory");
+}
+
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	int old;
+	do {
+		old = a_ll(p);
+		if (old != t) {
+			a_barrier();
+			break;
+		}
+	} while (!a_sc(p, s));
+	return old;
+}
+
+static inline void *a_ll_p(volatile void *p)
+{
+	void *v;
+	__asm__ __volatile__ ("ldaxr %0, %1" : "=r"(v) : "Q"(*(void *volatile *)p));
+	return v;
+}
+
+static inline int a_sc_p(volatile int *p, void *v)
+{
+	int r;
+	__asm__ __volatile__ ("stlxr %w0,%2,%1" : "=&r"(r), "=Q"(*(void *volatile *)p) : "r"(v) : "memory");
+	return !r;
+}
+
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	void *old;
+	do {
+		old = a_ll_p(p);
+		if (old != t) {
+			a_barrier();
+			break;
+		}
+	} while (!a_sc_p(p, s));
+	return old;
+}
+
+#define a_ctz_64 a_ctz_64
+static inline int a_ctz_64(uint64_t x)
+{
+	__asm__(
+		"	rbit %0, %1\n"
+		"	clz %0, %0\n"
+		: "=r"(x) : "r"(x));
+	return x;
+}
diff --git a/arch/aarch64/bits/io.h b/arch/aarch64/bits/io.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/aarch64/bits/io.h
+++ /dev/null
diff --git a/arch/aarch64/bits/mman.h b/arch/aarch64/bits/mman.h
index ce5519f..31ece5b 100644
--- a/arch/aarch64/bits/mman.h
+++ b/arch/aarch64/bits/mman.h
@@ -36,6 +36,7 @@
 
 #define MCL_CURRENT     1
 #define MCL_FUTURE      2
+#define MCL_ONFAULT     4
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/aarch64/bits/poll.h b/arch/aarch64/bits/poll.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/aarch64/bits/poll.h
+++ /dev/null
diff --git a/arch/aarch64/bits/resource.h b/arch/aarch64/bits/resource.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/aarch64/bits/resource.h
+++ /dev/null
diff --git a/arch/aarch64/bits/statfs.h b/arch/aarch64/bits/statfs.h
deleted file mode 100644
index f103f4e..0000000
--- a/arch/aarch64/bits/statfs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct statfs {
-	unsigned long f_type, f_bsize;
-	fsblkcnt_t f_blocks, f_bfree, f_bavail;
-	fsfilcnt_t f_files, f_ffree;
-	fsid_t f_fsid;
-	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
-};
diff --git a/arch/aarch64/bits/stdarg.h b/arch/aarch64/bits/stdarg.h
deleted file mode 100644
index fde3781..0000000
--- a/arch/aarch64/bits/stdarg.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define va_start(v,l)   __builtin_va_start(v,l)
-#define va_end(v)       __builtin_va_end(v)
-#define va_arg(v,l)     __builtin_va_arg(v,l)
-#define va_copy(d,s)    __builtin_va_copy(d,s)
diff --git a/arch/aarch64/bits/syscall.h b/arch/aarch64/bits/syscall.h
index d7a1420..31bed73 100644
--- a/arch/aarch64/bits/syscall.h
+++ b/arch/aarch64/bits/syscall.h
@@ -265,6 +265,9 @@
 #define __NR_memfd_create 279
 #define __NR_bpf 280
 #define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
 
 #define SYS_io_setup __NR_io_setup
 #define SYS_io_destroy __NR_io_destroy
@@ -533,3 +536,6 @@
 #define SYS_memfd_create __NR_memfd_create
 #define SYS_bpf __NR_bpf
 #define SYS_execveat __NR_execveat
+#define SYS_userfaultfd __NR_userfaultfd
+#define SYS_membarrier __NR_membarrier
+#define SYS_mlock2 __NR_mlock2
diff --git a/arch/aarch64/pthread_arch.h b/arch/aarch64/pthread_arch.h
index 74276f4..b2e2d8f 100644
--- a/arch/aarch64/pthread_arch.h
+++ b/arch/aarch64/pthread_arch.h
@@ -8,4 +8,4 @@
 #define TLS_ABOVE_TP
 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 16)
 
-#define CANCEL_REG_IP 33
+#define MC_PC pc
diff --git a/arch/arm/atomic.h b/arch/arm/atomic.h
deleted file mode 100644
index 8ae35bb..0000000
--- a/arch/arm/atomic.h
+++ /dev/null
@@ -1,261 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_l(unsigned long x)
-{
-	static const char debruijn32[32] = {
-		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
-		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
-	};
-	return debruijn32[(x&-x)*0x076be629 >> 27];
-}
-
-static inline int a_ctz_64(uint64_t x)
-{
-	uint32_t y = x;
-	if (!y) {
-		y = x>>32;
-		return 32 + a_ctz_l(y);
-	}
-	return a_ctz_l(y);
-}
-
-#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ ||  __ARM_ARCH >= 7
-
-static inline void a_barrier()
-{
-	__asm__ __volatile__("dmb ish");
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	int old;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldrex %0,%3\n"
-		"	cmp %0,%1\n"
-		"	bne 1f\n"
-		"	strex %0,%2,%3\n"
-		"	cmp %0, #0\n"
-		"	bne 1b\n"
-		"	mov %0, %1\n"
-		"1:	dmb ish\n"
-		: "=&r"(old)
-		: "r"(t), "r"(s), "Q"(*p)
-		: "memory", "cc" );
-	return old;
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	int old, tmp;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldrex %0,%3\n"
-		"	strex %1,%2,%3\n"
-		"	cmp %1, #0\n"
-		"	bne 1b\n"
-		"	dmb ish\n"
-		: "=&r"(old), "=&r"(tmp)
-		: "r"(v), "Q"(*x)
-		: "memory", "cc" );
-	return old;
-}
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	int old, tmp;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldrex %0,%3\n"
-		"	add %0,%0,%2\n"
-		"	strex %1,%0,%3\n"
-		"	cmp %1, #0\n"
-		"	bne 1b\n"
-		"	dmb ish\n"
-		: "=&r"(old), "=&r"(tmp)
-		: "r"(v), "Q"(*x)
-		: "memory", "cc" );
-	return old-v;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldrex %0,%2\n"
-		"	add %0,%0,#1\n"
-		"	strex %1,%0,%2\n"
-		"	cmp %1, #0\n"
-		"	bne 1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "Q"(*x)
-		: "memory", "cc" );
-}
-
-static inline void a_dec(volatile int *x)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldrex %0,%2\n"
-		"	sub %0,%0,#1\n"
-		"	strex %1,%0,%2\n"
-		"	cmp %1, #0\n"
-		"	bne 1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "Q"(*x)
-		: "memory", "cc" );
-}
-
-static inline void a_and(volatile int *x, int v)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldrex %0,%3\n"
-		"	and %0,%0,%2\n"
-		"	strex %1,%0,%3\n"
-		"	cmp %1, #0\n"
-		"	bne 1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "r"(v), "Q"(*x)
-		: "memory", "cc" );
-}
-
-static inline void a_or(volatile int *x, int v)
-{
-	int tmp, tmp2;
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"1:	ldrex %0,%3\n"
-		"	orr %0,%0,%2\n"
-		"	strex %1,%0,%3\n"
-		"	cmp %1, #0\n"
-		"	bne 1b\n"
-		"	dmb ish\n"
-		: "=&r"(tmp), "=&r"(tmp2)
-		: "r"(v), "Q"(*x)
-		: "memory", "cc" );
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	__asm__ __volatile__(
-		"	dmb ish\n"
-		"	str %1,%0\n"
-		"	dmb ish\n"
-		: "=m"(*p)
-		: "r"(x)
-		: "memory", "cc" );
-}
-
-#else
-
-int __a_cas(int, int, volatile int *) __attribute__((__visibility__("hidden")));
-#define __k_cas __a_cas
-
-static inline void a_barrier()
-{
-	__asm__ __volatile__("bl __a_barrier"
-		: : : "memory", "cc", "ip", "lr" );
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	int old;
-	for (;;) {
-		if (!__k_cas(t, s, p))
-			return t;
-		if ((old=*p) != t)
-			return old;
-	}
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	int old;
-	do old = *x;
-	while (__k_cas(old, v, x));
-	return old;
-}
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	int old;
-	do old = *x;
-	while (__k_cas(old, old+v, x));
-	return old;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	a_fetch_add(x, 1);
-}
-
-static inline void a_dec(volatile int *x)
-{
-	a_fetch_add(x, -1);
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	a_barrier();
-	*p = x;
-	a_barrier();
-}
-
-static inline void a_and(volatile int *p, int v)
-{
-	int old;
-	do old = *p;
-	while (__k_cas(old, old&v, p));
-}
-
-static inline void a_or(volatile int *p, int v)
-{
-	int old;
-	do old = *p;
-	while (__k_cas(old, old|v, p));
-}
-
-#endif
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	return (void *)a_cas(p, (int)t, (int)s);
-}
-
-#define a_spin a_barrier
-
-static inline void a_crash()
-{
-	*(volatile char *)0=0;
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	a_or(p, v);
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_and((int *)p, u.r[0]);
-	a_and((int *)p+1, u.r[1]);
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_or((int *)p, u.r[0]);
-	a_or((int *)p+1, u.r[1]);
-}
-
-#endif
diff --git a/arch/arm/atomic_arch.h b/arch/arm/atomic_arch.h
new file mode 100644
index 0000000..706fa1f
--- /dev/null
+++ b/arch/arm/atomic_arch.h
@@ -0,0 +1,76 @@
+__attribute__((__visibility__("hidden")))
+extern const void *__arm_atomics[3]; /* gettp, cas, barrier */
+
+#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__) && !__thumb__) \
+ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ ||  __ARM_ARCH >= 7
+
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+	int v;
+	__asm__ __volatile__ ("ldrex %0, %1" : "=r"(v) : "Q"(*p));
+	return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+	int r;
+	__asm__ __volatile__ ("strex %0,%2,%1" : "=&r"(r), "=Q"(*p) : "r"(v) : "memory");
+	return !r;
+}
+
+#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ ||  __ARM_ARCH >= 7
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("dmb ish" : : : "memory");
+}
+
+#endif
+
+#define a_pre_llsc a_barrier
+#define a_post_llsc a_barrier
+
+#else
+
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	for (;;) {
+		register int r0 __asm__("r0") = t;
+		register int r1 __asm__("r1") = s;
+		register volatile int *r2 __asm__("r2") = p;
+		int old;
+		__asm__ __volatile__ (
+			"bl __a_cas"
+			: "+r"(r0) : "r"(r1), "r"(r2)
+			: "memory", "r3", "lr", "ip", "cc" );
+		if (!r0) return t;
+		if ((old=*p)!=t) return old;
+	}
+}
+
+#endif
+
+#ifndef a_barrier
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__("bl __a_barrier"
+		: : : "memory", "cc", "ip", "lr" );
+}
+#endif
+
+#define a_crash a_crash
+static inline void a_crash()
+{
+	__asm__ __volatile__(
+#ifndef __thumb__
+		".word 0xe7f000f0"
+#else
+		".short 0xdeff"
+#endif
+		: : : "memory");
+}
diff --git a/arch/arm/bits/errno.h b/arch/arm/bits/errno.h
deleted file mode 100644
index d2e1eee..0000000
--- a/arch/arm/bits/errno.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#define EPERM            1
-#define ENOENT           2
-#define ESRCH            3
-#define EINTR            4
-#define EIO              5
-#define ENXIO            6
-#define E2BIG            7
-#define ENOEXEC          8
-#define EBADF            9
-#define ECHILD          10
-#define EAGAIN          11
-#define ENOMEM          12
-#define EACCES          13
-#define EFAULT          14
-#define ENOTBLK         15
-#define EBUSY           16
-#define EEXIST          17
-#define EXDEV           18
-#define ENODEV          19
-#define ENOTDIR         20
-#define EISDIR          21
-#define EINVAL          22
-#define ENFILE          23
-#define EMFILE          24
-#define ENOTTY          25
-#define ETXTBSY         26
-#define EFBIG           27
-#define ENOSPC          28
-#define ESPIPE          29
-#define EROFS           30
-#define EMLINK          31
-#define EPIPE           32
-#define EDOM            33
-#define ERANGE          34
-#define EDEADLK         35
-#define ENAMETOOLONG    36
-#define ENOLCK          37
-#define ENOSYS          38
-#define ENOTEMPTY       39
-#define ELOOP           40
-#define EWOULDBLOCK     EAGAIN
-#define ENOMSG          42
-#define EIDRM           43
-#define ECHRNG          44
-#define EL2NSYNC        45
-#define EL3HLT          46
-#define EL3RST          47
-#define ELNRNG          48
-#define EUNATCH         49
-#define ENOCSI          50
-#define EL2HLT          51
-#define EBADE           52
-#define EBADR           53
-#define EXFULL          54
-#define ENOANO          55
-#define EBADRQC         56
-#define EBADSLT         57
-#define EDEADLOCK       EDEADLK
-#define EBFONT          59
-#define ENOSTR          60
-#define ENODATA         61
-#define ETIME           62
-#define ENOSR           63
-#define ENONET          64
-#define ENOPKG          65
-#define EREMOTE         66
-#define ENOLINK         67
-#define EADV            68
-#define ESRMNT          69
-#define ECOMM           70
-#define EPROTO          71
-#define EMULTIHOP       72
-#define EDOTDOT         73
-#define EBADMSG         74
-#define EOVERFLOW       75
-#define ENOTUNIQ        76
-#define EBADFD          77
-#define EREMCHG         78
-#define ELIBACC         79
-#define ELIBBAD         80
-#define ELIBSCN         81
-#define ELIBMAX         82
-#define ELIBEXEC        83
-#define EILSEQ          84
-#define ERESTART        85
-#define ESTRPIPE        86
-#define EUSERS          87
-#define ENOTSOCK        88
-#define EDESTADDRREQ    89
-#define EMSGSIZE        90
-#define EPROTOTYPE      91
-#define ENOPROTOOPT     92
-#define EPROTONOSUPPORT 93
-#define ESOCKTNOSUPPORT 94
-#define EOPNOTSUPP      95
-#define ENOTSUP         EOPNOTSUPP
-#define EPFNOSUPPORT    96
-#define EAFNOSUPPORT    97
-#define EADDRINUSE      98
-#define EADDRNOTAVAIL   99
-#define ENETDOWN        100
-#define ENETUNREACH     101
-#define ENETRESET       102
-#define ECONNABORTED    103
-#define ECONNRESET      104
-#define ENOBUFS         105
-#define EISCONN         106
-#define ENOTCONN        107
-#define ESHUTDOWN       108
-#define ETOOMANYREFS    109
-#define ETIMEDOUT       110
-#define ECONNREFUSED    111
-#define EHOSTDOWN       112
-#define EHOSTUNREACH    113
-#define EALREADY        114
-#define EINPROGRESS     115
-#define ESTALE          116
-#define EUCLEAN         117
-#define ENOTNAM         118
-#define ENAVAIL         119
-#define EISNAM          120
-#define EREMOTEIO       121
-#define EDQUOT          122
-#define ENOMEDIUM       123
-#define EMEDIUMTYPE     124
-#define ECANCELED       125
-#define ENOKEY          126
-#define EKEYEXPIRED     127
-#define EKEYREVOKED     128
-#define EKEYREJECTED    129
-#define EOWNERDEAD      130
-#define ENOTRECOVERABLE 131
-#define ERFKILL         132
-#define EHWPOISON       133
diff --git a/arch/arm/bits/io.h b/arch/arm/bits/io.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/arm/bits/io.h
+++ /dev/null
diff --git a/arch/arm/bits/mman.h b/arch/arm/bits/mman.h
index cc854aa..ea6f6a7 100644
--- a/arch/arm/bits/mman.h
+++ b/arch/arm/bits/mman.h
@@ -37,6 +37,7 @@
 
 #define MCL_CURRENT     1
 #define MCL_FUTURE      2
+#define MCL_ONFAULT     4
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/arm/bits/poll.h b/arch/arm/bits/poll.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/arm/bits/poll.h
+++ /dev/null
diff --git a/arch/arm/bits/resource.h b/arch/arm/bits/resource.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/arm/bits/resource.h
+++ /dev/null
diff --git a/arch/arm/bits/statfs.h b/arch/arm/bits/statfs.h
deleted file mode 100644
index f103f4e..0000000
--- a/arch/arm/bits/statfs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct statfs {
-	unsigned long f_type, f_bsize;
-	fsblkcnt_t f_blocks, f_bfree, f_bavail;
-	fsfilcnt_t f_files, f_ffree;
-	fsid_t f_fsid;
-	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
-};
diff --git a/arch/arm/bits/stdarg.h b/arch/arm/bits/stdarg.h
deleted file mode 100644
index fde3781..0000000
--- a/arch/arm/bits/stdarg.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define va_start(v,l)   __builtin_va_start(v,l)
-#define va_end(v)       __builtin_va_end(v)
-#define va_arg(v,l)     __builtin_va_arg(v,l)
-#define va_copy(d,s)    __builtin_va_copy(d,s)
diff --git a/arch/arm/bits/syscall.h b/arch/arm/bits/syscall.h
index df6cda0..036c562 100644
--- a/arch/arm/bits/syscall.h
+++ b/arch/arm/bits/syscall.h
@@ -341,6 +341,9 @@
 #define __NR_memfd_create	385
 #define __NR_bpf	386
 #define __NR_execveat	387
+#define __NR_userfaultfd	388
+#define __NR_membarrier		389
+#define __NR_mlock2		390
 
 #define __ARM_NR_breakpoint	0x0f0001
 #define __ARM_NR_cacheflush	0x0f0002
@@ -693,3 +696,6 @@
 #define SYS_memfd_create	385
 #define SYS_bpf	386
 #define SYS_execveat	387
+#define SYS_userfaultfd	388
+#define SYS_membarrier		389
+#define SYS_mlock2		390
diff --git a/arch/arm/bits/termios.h b/arch/arm/bits/termios.h
deleted file mode 100644
index f0d81b1..0000000
--- a/arch/arm/bits/termios.h
+++ /dev/null
@@ -1,160 +0,0 @@
-struct termios
-{
-	tcflag_t c_iflag;
-	tcflag_t c_oflag;
-	tcflag_t c_cflag;
-	tcflag_t c_lflag;
-	cc_t c_line;
-	cc_t c_cc[NCCS];
-	speed_t __c_ispeed;
-	speed_t __c_ospeed;
-};
-
-#define VINTR     0
-#define VQUIT     1
-#define VERASE    2
-#define VKILL     3
-#define VEOF      4
-#define VTIME     5
-#define VMIN      6
-#define VSWTC     7
-#define VSTART    8
-#define VSTOP     9
-#define VSUSP    10
-#define VEOL     11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE  14
-#define VLNEXT   15
-#define VEOL2    16
-
-#define IGNBRK  0000001
-#define BRKINT  0000002
-#define IGNPAR  0000004
-#define PARMRK  0000010
-#define INPCK   0000020
-#define ISTRIP  0000040
-#define INLCR   0000100
-#define IGNCR   0000200
-#define ICRNL   0000400
-#define IUCLC   0001000
-#define IXON    0002000
-#define IXANY   0004000
-#define IXOFF   0010000
-#define IMAXBEL 0020000
-#define IUTF8   0040000
-
-#define OPOST  0000001
-#define OLCUC  0000002
-#define ONLCR  0000004
-#define OCRNL  0000010
-#define ONOCR  0000020
-#define ONLRET 0000040
-#define OFILL  0000100
-#define OFDEL  0000200
-#define NLDLY  0000400
-#define NL0    0000000
-#define NL1    0000400
-#define CRDLY  0003000
-#define CR0    0000000
-#define CR1    0001000
-#define CR2    0002000
-#define CR3    0003000
-#define TABDLY 0014000
-#define TAB0   0000000
-#define TAB1   0004000
-#define TAB2   0010000
-#define TAB3   0014000
-#define BSDLY  0020000
-#define BS0    0000000
-#define BS1    0020000
-#define FFDLY  0100000
-#define FF0    0000000
-#define FF1    0100000
-
-#define VTDLY  0040000
-#define VT0    0000000
-#define VT1    0040000
-
-#define B0       0000000
-#define B50      0000001
-#define B75      0000002
-#define B110     0000003
-#define B134     0000004
-#define B150     0000005
-#define B200     0000006
-#define B300     0000007
-#define B600     0000010
-#define B1200    0000011
-#define B1800    0000012
-#define B2400    0000013
-#define B4800    0000014
-#define B9600    0000015
-#define B19200   0000016
-#define B38400   0000017
-
-#define B57600   0010001
-#define B115200  0010002
-#define B230400  0010003
-#define B460800  0010004
-#define B500000  0010005
-#define B576000  0010006
-#define B921600  0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-
-#define CBAUD    0010017
-
-#define CSIZE  0000060
-#define CS5    0000000
-#define CS6    0000020
-#define CS7    0000040
-#define CS8    0000060
-#define CSTOPB 0000100
-#define CREAD  0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL  0002000
-#define CLOCAL 0004000
-
-#define ISIG   0000001
-#define ICANON 0000002
-#define ECHO   0000010
-#define ECHOE  0000020
-#define ECHOK  0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define IEXTEN 0100000
-
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-
-#define TCOOFF 0
-#define TCOON  1
-#define TCIOFF 2
-#define TCION  3
-
-#define TCIFLUSH  0
-#define TCOFLUSH  1
-#define TCIOFLUSH 2
-
-#define TCSANOW   0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define CBAUDEX 0010000
-#define CRTSCTS  020000000000
-#define EXTPROC 0200000
-#define XTABS  0014000
-#endif
diff --git a/arch/arm/pthread_arch.h b/arch/arm/pthread_arch.h
index 4a4dd09..8b8a7fb 100644
--- a/arch/arm/pthread_arch.h
+++ b/arch/arm/pthread_arch.h
@@ -27,4 +27,4 @@
 #define TLS_ABOVE_TP
 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
 
-#define CANCEL_REG_IP 18
+#define MC_PC arm_pc
diff --git a/arch/arm/reloc.h b/arch/arm/reloc.h
index e1ef350..b175711 100644
--- a/arch/arm/reloc.h
+++ b/arch/arm/reloc.h
@@ -6,10 +6,10 @@
 #define ENDIAN_SUFFIX ""
 #endif
 
-#if __SOFTFP__
-#define FP_SUFFIX ""
-#else
+#if __ARM_PCS_VFP
 #define FP_SUFFIX "hf"
+#else
+#define FP_SUFFIX ""
 #endif
 
 #define LDSO_ARCH "arm" ENDIAN_SUFFIX FP_SUFFIX
@@ -28,10 +28,5 @@
 #define REL_TPOFF       R_ARM_TLS_TPOFF32
 //#define REL_TLSDESC     R_ARM_TLS_DESC
 
-#ifdef __thumb__
 #define CRTJMP(pc,sp) __asm__ __volatile__( \
 	"mov sp,%1 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
-#else
-#define CRTJMP(pc,sp) __asm__ __volatile__( \
-	"mov sp,%1 ; tst %0,#1 ; moveq pc,%0 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
-#endif
diff --git a/arch/arm/src/atomics.c b/arch/arm/src/atomics.c
deleted file mode 100644
index e69de29..0000000
--- a/arch/arm/src/atomics.c
+++ /dev/null
diff --git a/arch/aarch64/bits/errno.h b/arch/generic/bits/errno.h
similarity index 100%
rename from arch/aarch64/bits/errno.h
rename to arch/generic/bits/errno.h
diff --git a/arch/i386/bits/fcntl.h b/arch/generic/bits/fcntl.h
similarity index 100%
rename from arch/i386/bits/fcntl.h
rename to arch/generic/bits/fcntl.h
diff --git a/arch/or1k/bits/fenv.h b/arch/generic/bits/fenv.h
similarity index 100%
rename from arch/or1k/bits/fenv.h
rename to arch/generic/bits/fenv.h
diff --git a/arch/powerpc/bits/io.h b/arch/generic/bits/io.h
similarity index 100%
rename from arch/powerpc/bits/io.h
rename to arch/generic/bits/io.h
diff --git a/arch/arm/bits/ioctl.h b/arch/generic/bits/ioctl.h
similarity index 100%
rename from arch/arm/bits/ioctl.h
rename to arch/generic/bits/ioctl.h
diff --git a/arch/arm/bits/ipc.h b/arch/generic/bits/ipc.h
similarity index 100%
rename from arch/arm/bits/ipc.h
rename to arch/generic/bits/ipc.h
diff --git a/arch/arm/bits/msg.h b/arch/generic/bits/msg.h
similarity index 100%
rename from arch/arm/bits/msg.h
rename to arch/generic/bits/msg.h
diff --git a/arch/powerpc/bits/poll.h b/arch/generic/bits/poll.h
similarity index 100%
rename from arch/powerpc/bits/poll.h
rename to arch/generic/bits/poll.h
diff --git a/arch/powerpc/bits/resource.h b/arch/generic/bits/resource.h
similarity index 100%
rename from arch/powerpc/bits/resource.h
rename to arch/generic/bits/resource.h
diff --git a/arch/arm/bits/sem.h b/arch/generic/bits/sem.h
similarity index 100%
rename from arch/arm/bits/sem.h
rename to arch/generic/bits/sem.h
diff --git a/arch/arm/bits/shm.h b/arch/generic/bits/shm.h
similarity index 100%
rename from arch/arm/bits/shm.h
rename to arch/generic/bits/shm.h
diff --git a/arch/arm/bits/socket.h b/arch/generic/bits/socket.h
similarity index 100%
rename from arch/arm/bits/socket.h
rename to arch/generic/bits/socket.h
diff --git a/arch/powerpc/bits/statfs.h b/arch/generic/bits/statfs.h
similarity index 100%
rename from arch/powerpc/bits/statfs.h
rename to arch/generic/bits/statfs.h
diff --git a/arch/powerpc/bits/stdarg.h b/arch/generic/bits/stdarg.h
similarity index 100%
rename from arch/powerpc/bits/stdarg.h
rename to arch/generic/bits/stdarg.h
diff --git a/arch/aarch64/bits/termios.h b/arch/generic/bits/termios.h
similarity index 100%
rename from arch/aarch64/bits/termios.h
rename to arch/generic/bits/termios.h
diff --git a/arch/i386/atomic.h b/arch/i386/atomic.h
deleted file mode 100644
index fd222ea..0000000
--- a/arch/i386/atomic.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_64(uint64_t x)
-{
-	int r;
-	__asm__( "bsf %1,%0 ; jnz 1f ; bsf %2,%0 ; addl $32,%0\n1:"
-		: "=&r"(r) : "r"((unsigned)x), "r"((unsigned)(x>>32)) );
-	return r;
-}
-
-static inline int a_ctz_l(unsigned long x)
-{
-	long r;
-	__asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
-	return r;
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	__asm__( "lock ; andl %1, (%0) ; lock ; andl %2, 4(%0)"
-		: : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) : "memory" );
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	__asm__( "lock ; orl %1, (%0) ; lock ; orl %2, 4(%0)"
-		: : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) : "memory" );
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	__asm__( "lock ; orl %1, %0"
-		: "=m"(*(long *)p) : "r"(v) : "memory" );
-}
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	__asm__( "lock ; cmpxchg %3, %1"
-		: "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
-	return t;
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	__asm__( "lock ; cmpxchg %3, %1"
-		: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
-	return t;
-}
-
-static inline void a_or(volatile int *p, int v)
-{
-	__asm__( "lock ; orl %1, %0"
-		: "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline void a_and(volatile int *p, int v)
-{
-	__asm__( "lock ; andl %1, %0"
-		: "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	__asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
-	return v;
-}
-
-#define a_xchg a_swap
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	__asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
-	return v;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	__asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
-}
-
-static inline void a_dec(volatile int *x)
-{
-	__asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	__asm__( "movl %1, %0 ; lock ; orl $0,(%%esp)" : "=m"(*p) : "r"(x) : "memory" );
-}
-
-static inline void a_spin()
-{
-	__asm__ __volatile__( "pause" : : : "memory" );
-}
-
-static inline void a_barrier()
-{
-	__asm__ __volatile__( "" : : : "memory" );
-}
-
-static inline void a_crash()
-{
-	__asm__ __volatile__( "hlt" : : : "memory" );
-}
-
-
-#endif
diff --git a/arch/i386/atomic_arch.h b/arch/i386/atomic_arch.h
new file mode 100644
index 0000000..6e67c4c
--- /dev/null
+++ b/arch/i386/atomic_arch.h
@@ -0,0 +1,101 @@
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	__asm__ __volatile__ (
+		"lock ; cmpxchg %3, %1"
+		: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
+	return t;
+}
+
+#define a_swap a_swap
+static inline int a_swap(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"xchg %0, %1"
+		: "=r"(v), "=m"(*p) : "0"(v) : "memory" );
+	return v;
+}
+
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"lock ; xadd %0, %1"
+		: "=r"(v), "=m"(*p) : "0"(v) : "memory" );
+	return v;
+}
+
+#define a_and a_and
+static inline void a_and(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"lock ; and %1, %0"
+		: "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_or a_or
+static inline void a_or(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"lock ; or %1, %0"
+		: "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_inc a_inc
+static inline void a_inc(volatile int *p)
+{
+	__asm__ __volatile__(
+		"lock ; incl %0"
+		: "=m"(*p) : "m"(*p) : "memory" );
+}
+
+#define a_dec a_dec
+static inline void a_dec(volatile int *p)
+{
+	__asm__ __volatile__(
+		"lock ; decl %0"
+		: "=m"(*p) : "m"(*p) : "memory" );
+}
+
+#define a_store a_store
+static inline void a_store(volatile int *p, int x)
+{
+	__asm__ __volatile__(
+		"mov %1, %0 ; lock ; orl $0,(%%esp)"
+		: "=m"(*p) : "r"(x) : "memory" );
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__( "" : : : "memory" );
+}
+
+#define a_pause a_pause
+static inline void a_spin()
+{
+	__asm__ __volatile__( "pause" : : : "memory" );
+}
+
+#define a_crash a_crash
+static inline void a_crash()
+{
+	__asm__ __volatile__( "hlt" : : : "memory" );
+}
+
+#define a_ctz_64 a_ctz_64
+static inline int a_ctz_64(uint64_t x)
+{
+	int r;
+	__asm__( "bsf %1,%0 ; jnz 1f ; bsf %2,%0 ; add $32,%0\n1:"
+		: "=&r"(r) : "r"((unsigned)x), "r"((unsigned)(x>>32)) );
+	return r;
+}
+
+#define a_ctz_l a_ctz_l
+static inline int a_ctz_l(unsigned long x)
+{
+	long r;
+	__asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
+	return r;
+}
diff --git a/arch/i386/bits/alltypes.h.in b/arch/i386/bits/alltypes.h.in
index b8902db..1a8432d 100644
--- a/arch/i386/bits/alltypes.h.in
+++ b/arch/i386/bits/alltypes.h.in
@@ -26,10 +26,12 @@
 TYPEDEF long double double_t;
 #endif
 
-#ifdef __cplusplus
-TYPEDEF struct { alignas(8) long long __ll; long double __ld; } max_align_t;
-#else
+#if !defined(__cplusplus)
 TYPEDEF struct { _Alignas(8) long long __ll; long double __ld; } max_align_t;
+#elif defined(__GNUC__)
+TYPEDEF struct { __attribute__((__aligned__(8))) long long __ll; long double __ld; } max_align_t;
+#else
+TYPEDEF struct { alignas(8) long long __ll; long double __ld; } max_align_t;
 #endif
 
 TYPEDEF long time_t;
diff --git a/arch/i386/bits/errno.h b/arch/i386/bits/errno.h
deleted file mode 100644
index d2e1eee..0000000
--- a/arch/i386/bits/errno.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#define EPERM            1
-#define ENOENT           2
-#define ESRCH            3
-#define EINTR            4
-#define EIO              5
-#define ENXIO            6
-#define E2BIG            7
-#define ENOEXEC          8
-#define EBADF            9
-#define ECHILD          10
-#define EAGAIN          11
-#define ENOMEM          12
-#define EACCES          13
-#define EFAULT          14
-#define ENOTBLK         15
-#define EBUSY           16
-#define EEXIST          17
-#define EXDEV           18
-#define ENODEV          19
-#define ENOTDIR         20
-#define EISDIR          21
-#define EINVAL          22
-#define ENFILE          23
-#define EMFILE          24
-#define ENOTTY          25
-#define ETXTBSY         26
-#define EFBIG           27
-#define ENOSPC          28
-#define ESPIPE          29
-#define EROFS           30
-#define EMLINK          31
-#define EPIPE           32
-#define EDOM            33
-#define ERANGE          34
-#define EDEADLK         35
-#define ENAMETOOLONG    36
-#define ENOLCK          37
-#define ENOSYS          38
-#define ENOTEMPTY       39
-#define ELOOP           40
-#define EWOULDBLOCK     EAGAIN
-#define ENOMSG          42
-#define EIDRM           43
-#define ECHRNG          44
-#define EL2NSYNC        45
-#define EL3HLT          46
-#define EL3RST          47
-#define ELNRNG          48
-#define EUNATCH         49
-#define ENOCSI          50
-#define EL2HLT          51
-#define EBADE           52
-#define EBADR           53
-#define EXFULL          54
-#define ENOANO          55
-#define EBADRQC         56
-#define EBADSLT         57
-#define EDEADLOCK       EDEADLK
-#define EBFONT          59
-#define ENOSTR          60
-#define ENODATA         61
-#define ETIME           62
-#define ENOSR           63
-#define ENONET          64
-#define ENOPKG          65
-#define EREMOTE         66
-#define ENOLINK         67
-#define EADV            68
-#define ESRMNT          69
-#define ECOMM           70
-#define EPROTO          71
-#define EMULTIHOP       72
-#define EDOTDOT         73
-#define EBADMSG         74
-#define EOVERFLOW       75
-#define ENOTUNIQ        76
-#define EBADFD          77
-#define EREMCHG         78
-#define ELIBACC         79
-#define ELIBBAD         80
-#define ELIBSCN         81
-#define ELIBMAX         82
-#define ELIBEXEC        83
-#define EILSEQ          84
-#define ERESTART        85
-#define ESTRPIPE        86
-#define EUSERS          87
-#define ENOTSOCK        88
-#define EDESTADDRREQ    89
-#define EMSGSIZE        90
-#define EPROTOTYPE      91
-#define ENOPROTOOPT     92
-#define EPROTONOSUPPORT 93
-#define ESOCKTNOSUPPORT 94
-#define EOPNOTSUPP      95
-#define ENOTSUP         EOPNOTSUPP
-#define EPFNOSUPPORT    96
-#define EAFNOSUPPORT    97
-#define EADDRINUSE      98
-#define EADDRNOTAVAIL   99
-#define ENETDOWN        100
-#define ENETUNREACH     101
-#define ENETRESET       102
-#define ECONNABORTED    103
-#define ECONNRESET      104
-#define ENOBUFS         105
-#define EISCONN         106
-#define ENOTCONN        107
-#define ESHUTDOWN       108
-#define ETOOMANYREFS    109
-#define ETIMEDOUT       110
-#define ECONNREFUSED    111
-#define EHOSTDOWN       112
-#define EHOSTUNREACH    113
-#define EALREADY        114
-#define EINPROGRESS     115
-#define ESTALE          116
-#define EUCLEAN         117
-#define ENOTNAM         118
-#define ENAVAIL         119
-#define EISNAM          120
-#define EREMOTEIO       121
-#define EDQUOT          122
-#define ENOMEDIUM       123
-#define EMEDIUMTYPE     124
-#define ECANCELED       125
-#define ENOKEY          126
-#define EKEYEXPIRED     127
-#define EKEYREVOKED     128
-#define EKEYREJECTED    129
-#define EOWNERDEAD      130
-#define ENOTRECOVERABLE 131
-#define ERFKILL         132
-#define EHWPOISON       133
diff --git a/arch/i386/bits/ioctl.h b/arch/i386/bits/ioctl.h
deleted file mode 100644
index 9d75118..0000000
--- a/arch/i386/bits/ioctl.h
+++ /dev/null
@@ -1,197 +0,0 @@
-#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
-#define _IOC_NONE  0U
-#define _IOC_WRITE 1U
-#define _IOC_READ  2U
-
-#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
-#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
-#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
-#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
-
-#define TCGETS		0x5401
-#define TCSETS		0x5402
-#define TCSETSW		0x5403
-#define TCSETSF		0x5404
-#define TCGETA		0x5405
-#define TCSETA		0x5406
-#define TCSETAW		0x5407
-#define TCSETAF		0x5408
-#define TCSBRK		0x5409
-#define TCXONC		0x540A
-#define TCFLSH		0x540B
-#define TIOCEXCL	0x540C
-#define TIOCNXCL	0x540D
-#define TIOCSCTTY	0x540E
-#define TIOCGPGRP	0x540F
-#define TIOCSPGRP	0x5410
-#define TIOCOUTQ	0x5411
-#define TIOCSTI		0x5412
-#define TIOCGWINSZ	0x5413
-#define TIOCSWINSZ	0x5414
-#define TIOCMGET	0x5415
-#define TIOCMBIS	0x5416
-#define TIOCMBIC	0x5417
-#define TIOCMSET	0x5418
-#define TIOCGSOFTCAR	0x5419
-#define TIOCSSOFTCAR	0x541A
-#define FIONREAD	0x541B
-#define TIOCINQ		FIONREAD
-#define TIOCLINUX	0x541C
-#define TIOCCONS	0x541D
-#define TIOCGSERIAL	0x541E
-#define TIOCSSERIAL	0x541F
-#define TIOCPKT		0x5420
-#define FIONBIO		0x5421
-#define TIOCNOTTY	0x5422
-#define TIOCSETD	0x5423
-#define TIOCGETD	0x5424
-#define TCSBRKP		0x5425
-#define TIOCTTYGSTRUCT	0x5426
-#define TIOCSBRK	0x5427
-#define TIOCCBRK	0x5428
-#define TIOCGSID	0x5429
-#define TIOCGPTN	0x80045430
-#define TIOCSPTLCK	0x40045431
-#define TCGETX		0x5432
-#define TCSETX		0x5433
-#define TCSETXF		0x5434
-#define TCSETXW		0x5435
-
-#define FIONCLEX	0x5450
-#define FIOCLEX		0x5451
-#define FIOASYNC	0x5452
-#define TIOCSERCONFIG	0x5453
-#define TIOCSERGWILD	0x5454
-#define TIOCSERSWILD	0x5455
-#define TIOCGLCKTRMIOS	0x5456
-#define TIOCSLCKTRMIOS	0x5457
-#define TIOCSERGSTRUCT	0x5458
-#define TIOCSERGETLSR   0x5459
-#define TIOCSERGETMULTI 0x545A
-#define TIOCSERSETMULTI 0x545B
-
-#define TIOCMIWAIT	0x545C
-#define TIOCGICOUNT	0x545D
-#define TIOCGHAYESESP   0x545E
-#define TIOCSHAYESESP   0x545F
-#define FIOQSIZE	0x5460
-
-#define TIOCPKT_DATA		 0
-#define TIOCPKT_FLUSHREAD	 1
-#define TIOCPKT_FLUSHWRITE	 2
-#define TIOCPKT_STOP		 4
-#define TIOCPKT_START		 8
-#define TIOCPKT_NOSTOP		16
-#define TIOCPKT_DOSTOP		32
-#define TIOCPKT_IOCTL		64
-
-#define TIOCSER_TEMT    0x01
-
-struct winsize {
-	unsigned short ws_row;
-	unsigned short ws_col;
-	unsigned short ws_xpixel;
-	unsigned short ws_ypixel;
-};
-
-#define TIOCM_LE        0x001
-#define TIOCM_DTR       0x002
-#define TIOCM_RTS       0x004
-#define TIOCM_ST        0x008
-#define TIOCM_SR        0x010
-#define TIOCM_CTS       0x020
-#define TIOCM_CAR       0x040
-#define TIOCM_RNG       0x080
-#define TIOCM_DSR       0x100
-#define TIOCM_CD        TIOCM_CAR
-#define TIOCM_RI        TIOCM_RNG
-#define TIOCM_OUT1      0x2000
-#define TIOCM_OUT2      0x4000
-#define TIOCM_LOOP      0x8000
-#define TIOCM_MODEM_BITS TIOCM_OUT2
-
-#define N_TTY           0
-#define N_SLIP          1
-#define N_MOUSE         2
-#define N_PPP           3
-#define N_STRIP         4
-#define N_AX25          5
-#define N_X25           6
-#define N_6PACK         7
-#define N_MASC          8
-#define N_R3964         9
-#define N_PROFIBUS_FDL  10
-#define N_IRDA          11
-#define N_SMSBLOCK      12
-#define N_HDLC          13
-#define N_SYNC_PPP      14
-#define N_HCI           15
-
-#define FIOSETOWN       0x8901
-#define SIOCSPGRP       0x8902
-#define FIOGETOWN       0x8903
-#define SIOCGPGRP       0x8904
-#define SIOCATMARK      0x8905
-#define SIOCGSTAMP      0x8906
-
-#define SIOCADDRT       0x890B
-#define SIOCDELRT       0x890C
-#define SIOCRTMSG       0x890D
-
-#define SIOCGIFNAME     0x8910
-#define SIOCSIFLINK     0x8911
-#define SIOCGIFCONF     0x8912
-#define SIOCGIFFLAGS    0x8913
-#define SIOCSIFFLAGS    0x8914
-#define SIOCGIFADDR     0x8915
-#define SIOCSIFADDR     0x8916
-#define SIOCGIFDSTADDR  0x8917
-#define SIOCSIFDSTADDR  0x8918
-#define SIOCGIFBRDADDR  0x8919
-#define SIOCSIFBRDADDR  0x891a
-#define SIOCGIFNETMASK  0x891b
-#define SIOCSIFNETMASK  0x891c
-#define SIOCGIFMETRIC   0x891d
-#define SIOCSIFMETRIC   0x891e
-#define SIOCGIFMEM      0x891f
-#define SIOCSIFMEM      0x8920
-#define SIOCGIFMTU      0x8921
-#define SIOCSIFMTU      0x8922
-#define SIOCSIFHWADDR   0x8924
-#define SIOCGIFENCAP    0x8925
-#define SIOCSIFENCAP    0x8926
-#define SIOCGIFHWADDR   0x8927
-#define SIOCGIFSLAVE    0x8929
-#define SIOCSIFSLAVE    0x8930
-#define SIOCADDMULTI    0x8931
-#define SIOCDELMULTI    0x8932
-#define SIOCGIFINDEX    0x8933
-#define SIOGIFINDEX     SIOCGIFINDEX
-#define SIOCSIFPFLAGS   0x8934
-#define SIOCGIFPFLAGS   0x8935
-#define SIOCDIFADDR     0x8936
-#define SIOCSIFHWBROADCAST 0x8937
-#define SIOCGIFCOUNT    0x8938
-
-#define SIOCGIFBR       0x8940
-#define SIOCSIFBR       0x8941
-
-#define SIOCGIFTXQLEN   0x8942
-#define SIOCSIFTXQLEN   0x8943
-
-#define SIOCDARP        0x8953
-#define SIOCGARP        0x8954
-#define SIOCSARP        0x8955
-
-#define SIOCDRARP       0x8960
-#define SIOCGRARP       0x8961
-#define SIOCSRARP       0x8962
-
-#define SIOCGIFMAP      0x8970
-#define SIOCSIFMAP      0x8971
-
-#define SIOCADDDLCI     0x8980
-#define SIOCDELDLCI     0x8981
-
-#define SIOCDEVPRIVATE		0x89F0
-#define SIOCPROTOPRIVATE	0x89E0
diff --git a/arch/i386/bits/ipc.h b/arch/i386/bits/ipc.h
deleted file mode 100644
index b748d3b..0000000
--- a/arch/i386/bits/ipc.h
+++ /dev/null
@@ -1,14 +0,0 @@
-struct ipc_perm
-{
-	key_t __ipc_perm_key;
-	uid_t uid;
-	gid_t gid;
-	uid_t cuid;
-	gid_t cgid;
-	mode_t mode;
-	int __ipc_perm_seq;
-	long __pad1;
-	long __pad2;
-};
-
-#define IPC_64 0x100
diff --git a/arch/i386/bits/mman.h b/arch/i386/bits/mman.h
index 0f53acb..0c9022f 100644
--- a/arch/i386/bits/mman.h
+++ b/arch/i386/bits/mman.h
@@ -38,6 +38,7 @@
 
 #define MCL_CURRENT     1
 #define MCL_FUTURE      2
+#define MCL_ONFAULT     4
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/i386/bits/msg.h b/arch/i386/bits/msg.h
deleted file mode 100644
index 3db8576..0000000
--- a/arch/i386/bits/msg.h
+++ /dev/null
@@ -1,16 +0,0 @@
-struct msqid_ds
-{
-	struct ipc_perm msg_perm;
-	time_t msg_stime;
-	int __unused1;
-	time_t msg_rtime;
-	int __unused2;
-	time_t msg_ctime;
-	int __unused3;
-	unsigned long msg_cbytes;
-	msgqnum_t msg_qnum;
-	msglen_t msg_qbytes;
-	pid_t msg_lspid;
-	pid_t msg_lrpid;
-	unsigned long __unused[2];
-};
diff --git a/arch/i386/bits/poll.h b/arch/i386/bits/poll.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/i386/bits/poll.h
+++ /dev/null
diff --git a/arch/i386/bits/resource.h b/arch/i386/bits/resource.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/i386/bits/resource.h
+++ /dev/null
diff --git a/arch/i386/bits/sem.h b/arch/i386/bits/sem.h
deleted file mode 100644
index c629b81..0000000
--- a/arch/i386/bits/sem.h
+++ /dev/null
@@ -1,16 +0,0 @@
-struct semid_ds {
-	struct ipc_perm sem_perm;
-	time_t sem_otime;
-	time_t __unused1;
-	time_t sem_ctime;
-	time_t __unused2;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-	unsigned short sem_nsems;
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-#else
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-	unsigned short sem_nsems;
-#endif
-	time_t __unused3;
-	time_t __unused4;
-};
diff --git a/arch/i386/bits/shm.h b/arch/i386/bits/shm.h
deleted file mode 100644
index 547581f..0000000
--- a/arch/i386/bits/shm.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#define SHMLBA 4096
-
-struct shmid_ds
-{
-	struct ipc_perm shm_perm;
-	size_t shm_segsz;
-	time_t shm_atime;
-	int __unused1;
-	time_t shm_dtime;
-	int __unused2;
-	time_t shm_ctime;
-	int __unused3;
-	pid_t shm_cpid;
-	pid_t shm_lpid;
-	unsigned long shm_nattch;
-	unsigned long __pad1;
-	unsigned long __pad2;
-};
-
-struct shminfo {
-	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
-};
-
-struct shm_info {
-	int __used_ids;
-	unsigned long shm_tot, shm_rss, shm_swp;
-	unsigned long __swap_attempts, __swap_successes;
-};
-
diff --git a/arch/i386/bits/socket.h b/arch/i386/bits/socket.h
deleted file mode 100644
index 36febbc..0000000
--- a/arch/i386/bits/socket.h
+++ /dev/null
@@ -1,17 +0,0 @@
-struct msghdr
-{
-	void *msg_name;
-	socklen_t msg_namelen;
-	struct iovec *msg_iov;
-	int msg_iovlen;
-	void *msg_control;
-	socklen_t msg_controllen;
-	int msg_flags;
-};
-
-struct cmsghdr
-{
-	socklen_t cmsg_len;
-	int cmsg_level;
-	int cmsg_type;
-};
diff --git a/arch/i386/bits/statfs.h b/arch/i386/bits/statfs.h
deleted file mode 100644
index f103f4e..0000000
--- a/arch/i386/bits/statfs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct statfs {
-	unsigned long f_type, f_bsize;
-	fsblkcnt_t f_blocks, f_bfree, f_bavail;
-	fsfilcnt_t f_files, f_ffree;
-	fsid_t f_fsid;
-	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
-};
diff --git a/arch/i386/bits/syscall.h b/arch/i386/bits/syscall.h
index 2902f80..b1a389b 100644
--- a/arch/i386/bits/syscall.h
+++ b/arch/i386/bits/syscall.h
@@ -357,6 +357,24 @@
 #define __NR_memfd_create	356
 #define __NR_bpf		357
 #define __NR_execveat		358
+#define __NR_socket		359
+#define __NR_socketpair		360
+#define __NR_bind		361
+#define __NR_connect		362
+#define __NR_listen		363
+#define __NR_accept4		364
+#define __NR_getsockopt		365
+#define __NR_setsockopt		366
+#define __NR_getsockname	367
+#define __NR_getpeername	368
+#define __NR_sendto		369
+#define __NR_sendmsg		370
+#define __NR_recvfrom		371
+#define __NR_recvmsg		372
+#define __NR_shutdown		373
+#define __NR_userfaultfd	374
+#define __NR_membarrier		375
+#define __NR_mlock2		376
 
 
 /* Repeated with SYS_ prefix */
@@ -720,3 +738,21 @@
 #define SYS_memfd_create	356
 #define SYS_bpf			357
 #define SYS_execveat		358
+#define SYS_socket		359
+#define SYS_socketpair		360
+#define SYS_bind		361
+#define SYS_connect		362
+#define SYS_listen		363
+#define SYS_accept4		364
+#define SYS_getsockopt		365
+#define SYS_setsockopt		366
+#define SYS_getsockname		367
+#define SYS_getpeername		368
+#define SYS_sendto		369
+#define SYS_sendmsg		370
+#define SYS_recvfrom		371
+#define SYS_recvmsg		372
+#define SYS_shutdown		373
+#define SYS_userfaultfd		374
+#define SYS_membarrier		375
+#define SYS_mlock2		376
diff --git a/arch/i386/bits/termios.h b/arch/i386/bits/termios.h
deleted file mode 100644
index f0d81b1..0000000
--- a/arch/i386/bits/termios.h
+++ /dev/null
@@ -1,160 +0,0 @@
-struct termios
-{
-	tcflag_t c_iflag;
-	tcflag_t c_oflag;
-	tcflag_t c_cflag;
-	tcflag_t c_lflag;
-	cc_t c_line;
-	cc_t c_cc[NCCS];
-	speed_t __c_ispeed;
-	speed_t __c_ospeed;
-};
-
-#define VINTR     0
-#define VQUIT     1
-#define VERASE    2
-#define VKILL     3
-#define VEOF      4
-#define VTIME     5
-#define VMIN      6
-#define VSWTC     7
-#define VSTART    8
-#define VSTOP     9
-#define VSUSP    10
-#define VEOL     11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE  14
-#define VLNEXT   15
-#define VEOL2    16
-
-#define IGNBRK  0000001
-#define BRKINT  0000002
-#define IGNPAR  0000004
-#define PARMRK  0000010
-#define INPCK   0000020
-#define ISTRIP  0000040
-#define INLCR   0000100
-#define IGNCR   0000200
-#define ICRNL   0000400
-#define IUCLC   0001000
-#define IXON    0002000
-#define IXANY   0004000
-#define IXOFF   0010000
-#define IMAXBEL 0020000
-#define IUTF8   0040000
-
-#define OPOST  0000001
-#define OLCUC  0000002
-#define ONLCR  0000004
-#define OCRNL  0000010
-#define ONOCR  0000020
-#define ONLRET 0000040
-#define OFILL  0000100
-#define OFDEL  0000200
-#define NLDLY  0000400
-#define NL0    0000000
-#define NL1    0000400
-#define CRDLY  0003000
-#define CR0    0000000
-#define CR1    0001000
-#define CR2    0002000
-#define CR3    0003000
-#define TABDLY 0014000
-#define TAB0   0000000
-#define TAB1   0004000
-#define TAB2   0010000
-#define TAB3   0014000
-#define BSDLY  0020000
-#define BS0    0000000
-#define BS1    0020000
-#define FFDLY  0100000
-#define FF0    0000000
-#define FF1    0100000
-
-#define VTDLY  0040000
-#define VT0    0000000
-#define VT1    0040000
-
-#define B0       0000000
-#define B50      0000001
-#define B75      0000002
-#define B110     0000003
-#define B134     0000004
-#define B150     0000005
-#define B200     0000006
-#define B300     0000007
-#define B600     0000010
-#define B1200    0000011
-#define B1800    0000012
-#define B2400    0000013
-#define B4800    0000014
-#define B9600    0000015
-#define B19200   0000016
-#define B38400   0000017
-
-#define B57600   0010001
-#define B115200  0010002
-#define B230400  0010003
-#define B460800  0010004
-#define B500000  0010005
-#define B576000  0010006
-#define B921600  0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-
-#define CBAUD    0010017
-
-#define CSIZE  0000060
-#define CS5    0000000
-#define CS6    0000020
-#define CS7    0000040
-#define CS8    0000060
-#define CSTOPB 0000100
-#define CREAD  0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL  0002000
-#define CLOCAL 0004000
-
-#define ISIG   0000001
-#define ICANON 0000002
-#define ECHO   0000010
-#define ECHOE  0000020
-#define ECHOK  0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define IEXTEN 0100000
-
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-
-#define TCOOFF 0
-#define TCOON  1
-#define TCIOFF 2
-#define TCION  3
-
-#define TCIFLUSH  0
-#define TCOFLUSH  1
-#define TCIOFLUSH 2
-
-#define TCSANOW   0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define CBAUDEX 0010000
-#define CRTSCTS  020000000000
-#define EXTPROC 0200000
-#define XTABS  0014000
-#endif
diff --git a/arch/i386/pthread_arch.h b/arch/i386/pthread_arch.h
index 1c06c76..7f38a56 100644
--- a/arch/i386/pthread_arch.h
+++ b/arch/i386/pthread_arch.h
@@ -7,4 +7,4 @@
 
 #define TP_ADJ(p) (p)
 
-#define CANCEL_REG_IP 14
+#define MC_PC gregs[REG_EIP]
diff --git a/arch/i386/syscall_arch.h b/arch/i386/syscall_arch.h
index ca0ea7f..4c9d874 100644
--- a/arch/i386/syscall_arch.h
+++ b/arch/i386/syscall_arch.h
@@ -55,3 +55,5 @@
 #define VDSO_USEFUL
 #define VDSO_CGT_SYM "__vdso_clock_gettime"
 #define VDSO_CGT_VER "LINUX_2.6"
+
+#define SYSCALL_USE_SOCKETCALL
diff --git a/arch/microblaze/atomic.h b/arch/microblaze/atomic.h
deleted file mode 100644
index 93404b9..0000000
--- a/arch/microblaze/atomic.h
+++ /dev/null
@@ -1,143 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_l(unsigned long x)
-{
-	static const char debruijn32[32] = {
-		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
-		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
-	};
-	return debruijn32[(x&-x)*0x076be629 >> 27];
-}
-
-static inline int a_ctz_64(uint64_t x)
-{
-	uint32_t y = x;
-	if (!y) {
-		y = x>>32;
-		return 32 + a_ctz_l(y);
-	}
-	return a_ctz_l(y);
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	register int old, tmp;
-	__asm__ __volatile__ (
-		"	addi %0, r0, 0\n"
-		"1:	lwx %0, %2, r0\n"
-		"	rsubk %1, %0, %3\n"
-		"	bnei %1, 1f\n"
-		"	swx %4, %2, r0\n"
-		"	addic %1, r0, 0\n"
-		"	bnei %1, 1b\n"
-		"1:	"
-		: "=&r"(old), "=&r"(tmp)
-		: "r"(p), "r"(t), "r"(s)
-		: "cc", "memory" );
-	return old;
-}
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	return (void *)a_cas(p, (int)t, (int)s);
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	register int old, tmp;
-	__asm__ __volatile__ (
-		"	addi %0, r0, 0\n"
-		"1:	lwx %0, %2, r0\n"
-		"	swx %3, %2, r0\n"
-		"	addic %1, r0, 0\n"
-		"	bnei %1, 1b\n"
-		"1:	"
-		: "=&r"(old), "=&r"(tmp)
-		: "r"(x), "r"(v)
-		: "cc", "memory" );
-	return old;
-}
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	register int new, tmp;
-	__asm__ __volatile__ (
-		"	addi %0, r0, 0\n"
-		"1:	lwx %0, %2, r0\n"
-		"	addk %0, %0, %3\n"
-		"	swx %0, %2, r0\n"
-		"	addic %1, r0, 0\n"
-		"	bnei %1, 1b\n"
-		"1:	"
-		: "=&r"(new), "=&r"(tmp)
-		: "r"(x), "r"(v)
-		: "cc", "memory" );
-	return new-v;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	a_fetch_add(x, 1);
-}
-
-static inline void a_dec(volatile int *x)
-{
-	a_fetch_add(x, -1);
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	__asm__ __volatile__ (
-		"swi %1, %0"
-		: "=m"(*p) : "r"(x) : "memory" );
-}
-
-#define a_spin a_barrier
-
-static inline void a_barrier()
-{
-	a_cas(&(int){0}, 0, 0);
-}
-
-static inline void a_crash()
-{
-	*(volatile char *)0=0;
-}
-
-static inline void a_and(volatile int *p, int v)
-{
-	int old;
-	do old = *p;
-	while (a_cas(p, old, old&v) != old);
-}
-
-static inline void a_or(volatile int *p, int v)
-{
-	int old;
-	do old = *p;
-	while (a_cas(p, old, old|v) != old);
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	a_or(p, v);
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_and((int *)p, u.r[0]);
-	a_and((int *)p+1, u.r[1]);
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_or((int *)p, u.r[0]);
-	a_or((int *)p+1, u.r[1]);
-}
-
-#endif
diff --git a/arch/microblaze/atomic_arch.h b/arch/microblaze/atomic_arch.h
new file mode 100644
index 0000000..1152e8c
--- /dev/null
+++ b/arch/microblaze/atomic_arch.h
@@ -0,0 +1,53 @@
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	register int old, tmp;
+	__asm__ __volatile__ (
+		"	addi %0, r0, 0\n"
+		"1:	lwx %0, %2, r0\n"
+		"	rsubk %1, %0, %3\n"
+		"	bnei %1, 1f\n"
+		"	swx %4, %2, r0\n"
+		"	addic %1, r0, 0\n"
+		"	bnei %1, 1b\n"
+		"1:	"
+		: "=&r"(old), "=&r"(tmp)
+		: "r"(p), "r"(t), "r"(s)
+		: "cc", "memory" );
+	return old;
+}
+
+#define a_swap a_swap
+static inline int a_swap(volatile int *x, int v)
+{
+	register int old, tmp;
+	__asm__ __volatile__ (
+		"	addi %0, r0, 0\n"
+		"1:	lwx %0, %2, r0\n"
+		"	swx %3, %2, r0\n"
+		"	addic %1, r0, 0\n"
+		"	bnei %1, 1b\n"
+		"1:	"
+		: "=&r"(old), "=&r"(tmp)
+		: "r"(x), "r"(v)
+		: "cc", "memory" );
+	return old;
+}
+
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *x, int v)
+{
+	register int new, tmp;
+	__asm__ __volatile__ (
+		"	addi %0, r0, 0\n"
+		"1:	lwx %0, %2, r0\n"
+		"	addk %0, %0, %3\n"
+		"	swx %0, %2, r0\n"
+		"	addic %1, r0, 0\n"
+		"	bnei %1, 1b\n"
+		"1:	"
+		: "=&r"(new), "=&r"(tmp)
+		: "r"(x), "r"(v)
+		: "cc", "memory" );
+	return new-v;
+}
diff --git a/arch/microblaze/bits/errno.h b/arch/microblaze/bits/errno.h
deleted file mode 100644
index d2e1eee..0000000
--- a/arch/microblaze/bits/errno.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#define EPERM            1
-#define ENOENT           2
-#define ESRCH            3
-#define EINTR            4
-#define EIO              5
-#define ENXIO            6
-#define E2BIG            7
-#define ENOEXEC          8
-#define EBADF            9
-#define ECHILD          10
-#define EAGAIN          11
-#define ENOMEM          12
-#define EACCES          13
-#define EFAULT          14
-#define ENOTBLK         15
-#define EBUSY           16
-#define EEXIST          17
-#define EXDEV           18
-#define ENODEV          19
-#define ENOTDIR         20
-#define EISDIR          21
-#define EINVAL          22
-#define ENFILE          23
-#define EMFILE          24
-#define ENOTTY          25
-#define ETXTBSY         26
-#define EFBIG           27
-#define ENOSPC          28
-#define ESPIPE          29
-#define EROFS           30
-#define EMLINK          31
-#define EPIPE           32
-#define EDOM            33
-#define ERANGE          34
-#define EDEADLK         35
-#define ENAMETOOLONG    36
-#define ENOLCK          37
-#define ENOSYS          38
-#define ENOTEMPTY       39
-#define ELOOP           40
-#define EWOULDBLOCK     EAGAIN
-#define ENOMSG          42
-#define EIDRM           43
-#define ECHRNG          44
-#define EL2NSYNC        45
-#define EL3HLT          46
-#define EL3RST          47
-#define ELNRNG          48
-#define EUNATCH         49
-#define ENOCSI          50
-#define EL2HLT          51
-#define EBADE           52
-#define EBADR           53
-#define EXFULL          54
-#define ENOANO          55
-#define EBADRQC         56
-#define EBADSLT         57
-#define EDEADLOCK       EDEADLK
-#define EBFONT          59
-#define ENOSTR          60
-#define ENODATA         61
-#define ETIME           62
-#define ENOSR           63
-#define ENONET          64
-#define ENOPKG          65
-#define EREMOTE         66
-#define ENOLINK         67
-#define EADV            68
-#define ESRMNT          69
-#define ECOMM           70
-#define EPROTO          71
-#define EMULTIHOP       72
-#define EDOTDOT         73
-#define EBADMSG         74
-#define EOVERFLOW       75
-#define ENOTUNIQ        76
-#define EBADFD          77
-#define EREMCHG         78
-#define ELIBACC         79
-#define ELIBBAD         80
-#define ELIBSCN         81
-#define ELIBMAX         82
-#define ELIBEXEC        83
-#define EILSEQ          84
-#define ERESTART        85
-#define ESTRPIPE        86
-#define EUSERS          87
-#define ENOTSOCK        88
-#define EDESTADDRREQ    89
-#define EMSGSIZE        90
-#define EPROTOTYPE      91
-#define ENOPROTOOPT     92
-#define EPROTONOSUPPORT 93
-#define ESOCKTNOSUPPORT 94
-#define EOPNOTSUPP      95
-#define ENOTSUP         EOPNOTSUPP
-#define EPFNOSUPPORT    96
-#define EAFNOSUPPORT    97
-#define EADDRINUSE      98
-#define EADDRNOTAVAIL   99
-#define ENETDOWN        100
-#define ENETUNREACH     101
-#define ENETRESET       102
-#define ECONNABORTED    103
-#define ECONNRESET      104
-#define ENOBUFS         105
-#define EISCONN         106
-#define ENOTCONN        107
-#define ESHUTDOWN       108
-#define ETOOMANYREFS    109
-#define ETIMEDOUT       110
-#define ECONNREFUSED    111
-#define EHOSTDOWN       112
-#define EHOSTUNREACH    113
-#define EALREADY        114
-#define EINPROGRESS     115
-#define ESTALE          116
-#define EUCLEAN         117
-#define ENOTNAM         118
-#define ENAVAIL         119
-#define EISNAM          120
-#define EREMOTEIO       121
-#define EDQUOT          122
-#define ENOMEDIUM       123
-#define EMEDIUMTYPE     124
-#define ECANCELED       125
-#define ENOKEY          126
-#define EKEYEXPIRED     127
-#define EKEYREVOKED     128
-#define EKEYREJECTED    129
-#define EOWNERDEAD      130
-#define ENOTRECOVERABLE 131
-#define ERFKILL         132
-#define EHWPOISON       133
diff --git a/arch/microblaze/bits/fcntl.h b/arch/microblaze/bits/fcntl.h
deleted file mode 100644
index ae233cc..0000000
--- a/arch/microblaze/bits/fcntl.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#define O_CREAT        0100
-#define O_EXCL         0200
-#define O_NOCTTY       0400
-#define O_TRUNC       01000
-#define O_APPEND      02000
-#define O_NONBLOCK    04000
-#define O_DSYNC      010000
-#define O_SYNC     04010000
-#define O_RSYNC    04010000
-#define O_DIRECTORY 0200000
-#define O_NOFOLLOW  0400000
-#define O_CLOEXEC  02000000
-
-#define O_ASYNC      020000
-#define O_DIRECT     040000
-#define O_LARGEFILE 0100000
-#define O_NOATIME  01000000
-#define O_PATH    010000000
-#define O_TMPFILE 020200000
-#define O_NDELAY O_NONBLOCK
-
-#define F_DUPFD  0
-#define F_GETFD  1
-#define F_SETFD  2
-#define F_GETFL  3
-#define F_SETFL  4
-
-#define F_SETOWN 8
-#define F_GETOWN 9
-#define F_SETSIG 10
-#define F_GETSIG 11
-
-#define F_GETLK 12
-#define F_SETLK 13
-#define F_SETLKW 14
-
-#define F_SETOWN_EX 15
-#define F_GETOWN_EX 16
-
-#define F_GETOWNER_UIDS 17
diff --git a/arch/microblaze/bits/fenv.h b/arch/microblaze/bits/fenv.h
deleted file mode 100644
index edbdea2..0000000
--- a/arch/microblaze/bits/fenv.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#define FE_ALL_EXCEPT 0
-#define FE_TONEAREST  0
-
-typedef unsigned long fexcept_t;
-
-typedef struct {
-	unsigned long __cw;
-} fenv_t;
-
-#define FE_DFL_ENV      ((const fenv_t *) -1)
diff --git a/arch/microblaze/bits/io.h b/arch/microblaze/bits/io.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/microblaze/bits/io.h
+++ /dev/null
diff --git a/arch/microblaze/bits/ioctl.h b/arch/microblaze/bits/ioctl.h
deleted file mode 100644
index 9d75118..0000000
--- a/arch/microblaze/bits/ioctl.h
+++ /dev/null
@@ -1,197 +0,0 @@
-#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
-#define _IOC_NONE  0U
-#define _IOC_WRITE 1U
-#define _IOC_READ  2U
-
-#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
-#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
-#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
-#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
-
-#define TCGETS		0x5401
-#define TCSETS		0x5402
-#define TCSETSW		0x5403
-#define TCSETSF		0x5404
-#define TCGETA		0x5405
-#define TCSETA		0x5406
-#define TCSETAW		0x5407
-#define TCSETAF		0x5408
-#define TCSBRK		0x5409
-#define TCXONC		0x540A
-#define TCFLSH		0x540B
-#define TIOCEXCL	0x540C
-#define TIOCNXCL	0x540D
-#define TIOCSCTTY	0x540E
-#define TIOCGPGRP	0x540F
-#define TIOCSPGRP	0x5410
-#define TIOCOUTQ	0x5411
-#define TIOCSTI		0x5412
-#define TIOCGWINSZ	0x5413
-#define TIOCSWINSZ	0x5414
-#define TIOCMGET	0x5415
-#define TIOCMBIS	0x5416
-#define TIOCMBIC	0x5417
-#define TIOCMSET	0x5418
-#define TIOCGSOFTCAR	0x5419
-#define TIOCSSOFTCAR	0x541A
-#define FIONREAD	0x541B
-#define TIOCINQ		FIONREAD
-#define TIOCLINUX	0x541C
-#define TIOCCONS	0x541D
-#define TIOCGSERIAL	0x541E
-#define TIOCSSERIAL	0x541F
-#define TIOCPKT		0x5420
-#define FIONBIO		0x5421
-#define TIOCNOTTY	0x5422
-#define TIOCSETD	0x5423
-#define TIOCGETD	0x5424
-#define TCSBRKP		0x5425
-#define TIOCTTYGSTRUCT	0x5426
-#define TIOCSBRK	0x5427
-#define TIOCCBRK	0x5428
-#define TIOCGSID	0x5429
-#define TIOCGPTN	0x80045430
-#define TIOCSPTLCK	0x40045431
-#define TCGETX		0x5432
-#define TCSETX		0x5433
-#define TCSETXF		0x5434
-#define TCSETXW		0x5435
-
-#define FIONCLEX	0x5450
-#define FIOCLEX		0x5451
-#define FIOASYNC	0x5452
-#define TIOCSERCONFIG	0x5453
-#define TIOCSERGWILD	0x5454
-#define TIOCSERSWILD	0x5455
-#define TIOCGLCKTRMIOS	0x5456
-#define TIOCSLCKTRMIOS	0x5457
-#define TIOCSERGSTRUCT	0x5458
-#define TIOCSERGETLSR   0x5459
-#define TIOCSERGETMULTI 0x545A
-#define TIOCSERSETMULTI 0x545B
-
-#define TIOCMIWAIT	0x545C
-#define TIOCGICOUNT	0x545D
-#define TIOCGHAYESESP   0x545E
-#define TIOCSHAYESESP   0x545F
-#define FIOQSIZE	0x5460
-
-#define TIOCPKT_DATA		 0
-#define TIOCPKT_FLUSHREAD	 1
-#define TIOCPKT_FLUSHWRITE	 2
-#define TIOCPKT_STOP		 4
-#define TIOCPKT_START		 8
-#define TIOCPKT_NOSTOP		16
-#define TIOCPKT_DOSTOP		32
-#define TIOCPKT_IOCTL		64
-
-#define TIOCSER_TEMT    0x01
-
-struct winsize {
-	unsigned short ws_row;
-	unsigned short ws_col;
-	unsigned short ws_xpixel;
-	unsigned short ws_ypixel;
-};
-
-#define TIOCM_LE        0x001
-#define TIOCM_DTR       0x002
-#define TIOCM_RTS       0x004
-#define TIOCM_ST        0x008
-#define TIOCM_SR        0x010
-#define TIOCM_CTS       0x020
-#define TIOCM_CAR       0x040
-#define TIOCM_RNG       0x080
-#define TIOCM_DSR       0x100
-#define TIOCM_CD        TIOCM_CAR
-#define TIOCM_RI        TIOCM_RNG
-#define TIOCM_OUT1      0x2000
-#define TIOCM_OUT2      0x4000
-#define TIOCM_LOOP      0x8000
-#define TIOCM_MODEM_BITS TIOCM_OUT2
-
-#define N_TTY           0
-#define N_SLIP          1
-#define N_MOUSE         2
-#define N_PPP           3
-#define N_STRIP         4
-#define N_AX25          5
-#define N_X25           6
-#define N_6PACK         7
-#define N_MASC          8
-#define N_R3964         9
-#define N_PROFIBUS_FDL  10
-#define N_IRDA          11
-#define N_SMSBLOCK      12
-#define N_HDLC          13
-#define N_SYNC_PPP      14
-#define N_HCI           15
-
-#define FIOSETOWN       0x8901
-#define SIOCSPGRP       0x8902
-#define FIOGETOWN       0x8903
-#define SIOCGPGRP       0x8904
-#define SIOCATMARK      0x8905
-#define SIOCGSTAMP      0x8906
-
-#define SIOCADDRT       0x890B
-#define SIOCDELRT       0x890C
-#define SIOCRTMSG       0x890D
-
-#define SIOCGIFNAME     0x8910
-#define SIOCSIFLINK     0x8911
-#define SIOCGIFCONF     0x8912
-#define SIOCGIFFLAGS    0x8913
-#define SIOCSIFFLAGS    0x8914
-#define SIOCGIFADDR     0x8915
-#define SIOCSIFADDR     0x8916
-#define SIOCGIFDSTADDR  0x8917
-#define SIOCSIFDSTADDR  0x8918
-#define SIOCGIFBRDADDR  0x8919
-#define SIOCSIFBRDADDR  0x891a
-#define SIOCGIFNETMASK  0x891b
-#define SIOCSIFNETMASK  0x891c
-#define SIOCGIFMETRIC   0x891d
-#define SIOCSIFMETRIC   0x891e
-#define SIOCGIFMEM      0x891f
-#define SIOCSIFMEM      0x8920
-#define SIOCGIFMTU      0x8921
-#define SIOCSIFMTU      0x8922
-#define SIOCSIFHWADDR   0x8924
-#define SIOCGIFENCAP    0x8925
-#define SIOCSIFENCAP    0x8926
-#define SIOCGIFHWADDR   0x8927
-#define SIOCGIFSLAVE    0x8929
-#define SIOCSIFSLAVE    0x8930
-#define SIOCADDMULTI    0x8931
-#define SIOCDELMULTI    0x8932
-#define SIOCGIFINDEX    0x8933
-#define SIOGIFINDEX     SIOCGIFINDEX
-#define SIOCSIFPFLAGS   0x8934
-#define SIOCGIFPFLAGS   0x8935
-#define SIOCDIFADDR     0x8936
-#define SIOCSIFHWBROADCAST 0x8937
-#define SIOCGIFCOUNT    0x8938
-
-#define SIOCGIFBR       0x8940
-#define SIOCSIFBR       0x8941
-
-#define SIOCGIFTXQLEN   0x8942
-#define SIOCSIFTXQLEN   0x8943
-
-#define SIOCDARP        0x8953
-#define SIOCGARP        0x8954
-#define SIOCSARP        0x8955
-
-#define SIOCDRARP       0x8960
-#define SIOCGRARP       0x8961
-#define SIOCSRARP       0x8962
-
-#define SIOCGIFMAP      0x8970
-#define SIOCSIFMAP      0x8971
-
-#define SIOCADDDLCI     0x8980
-#define SIOCDELDLCI     0x8981
-
-#define SIOCDEVPRIVATE		0x89F0
-#define SIOCPROTOPRIVATE	0x89E0
diff --git a/arch/microblaze/bits/ipc.h b/arch/microblaze/bits/ipc.h
deleted file mode 100644
index b748d3b..0000000
--- a/arch/microblaze/bits/ipc.h
+++ /dev/null
@@ -1,14 +0,0 @@
-struct ipc_perm
-{
-	key_t __ipc_perm_key;
-	uid_t uid;
-	gid_t gid;
-	uid_t cuid;
-	gid_t cgid;
-	mode_t mode;
-	int __ipc_perm_seq;
-	long __pad1;
-	long __pad2;
-};
-
-#define IPC_64 0x100
diff --git a/arch/microblaze/bits/mman.h b/arch/microblaze/bits/mman.h
index cc854aa..ea6f6a7 100644
--- a/arch/microblaze/bits/mman.h
+++ b/arch/microblaze/bits/mman.h
@@ -37,6 +37,7 @@
 
 #define MCL_CURRENT     1
 #define MCL_FUTURE      2
+#define MCL_ONFAULT     4
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/microblaze/bits/msg.h b/arch/microblaze/bits/msg.h
deleted file mode 100644
index 3db8576..0000000
--- a/arch/microblaze/bits/msg.h
+++ /dev/null
@@ -1,16 +0,0 @@
-struct msqid_ds
-{
-	struct ipc_perm msg_perm;
-	time_t msg_stime;
-	int __unused1;
-	time_t msg_rtime;
-	int __unused2;
-	time_t msg_ctime;
-	int __unused3;
-	unsigned long msg_cbytes;
-	msgqnum_t msg_qnum;
-	msglen_t msg_qbytes;
-	pid_t msg_lspid;
-	pid_t msg_lrpid;
-	unsigned long __unused[2];
-};
diff --git a/arch/microblaze/bits/poll.h b/arch/microblaze/bits/poll.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/microblaze/bits/poll.h
+++ /dev/null
diff --git a/arch/microblaze/bits/resource.h b/arch/microblaze/bits/resource.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/microblaze/bits/resource.h
+++ /dev/null
diff --git a/arch/microblaze/bits/sem.h b/arch/microblaze/bits/sem.h
deleted file mode 100644
index c629b81..0000000
--- a/arch/microblaze/bits/sem.h
+++ /dev/null
@@ -1,16 +0,0 @@
-struct semid_ds {
-	struct ipc_perm sem_perm;
-	time_t sem_otime;
-	time_t __unused1;
-	time_t sem_ctime;
-	time_t __unused2;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-	unsigned short sem_nsems;
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-#else
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-	unsigned short sem_nsems;
-#endif
-	time_t __unused3;
-	time_t __unused4;
-};
diff --git a/arch/microblaze/bits/shm.h b/arch/microblaze/bits/shm.h
deleted file mode 100644
index 547581f..0000000
--- a/arch/microblaze/bits/shm.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#define SHMLBA 4096
-
-struct shmid_ds
-{
-	struct ipc_perm shm_perm;
-	size_t shm_segsz;
-	time_t shm_atime;
-	int __unused1;
-	time_t shm_dtime;
-	int __unused2;
-	time_t shm_ctime;
-	int __unused3;
-	pid_t shm_cpid;
-	pid_t shm_lpid;
-	unsigned long shm_nattch;
-	unsigned long __pad1;
-	unsigned long __pad2;
-};
-
-struct shminfo {
-	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
-};
-
-struct shm_info {
-	int __used_ids;
-	unsigned long shm_tot, shm_rss, shm_swp;
-	unsigned long __swap_attempts, __swap_successes;
-};
-
diff --git a/arch/microblaze/bits/socket.h b/arch/microblaze/bits/socket.h
deleted file mode 100644
index 36febbc..0000000
--- a/arch/microblaze/bits/socket.h
+++ /dev/null
@@ -1,17 +0,0 @@
-struct msghdr
-{
-	void *msg_name;
-	socklen_t msg_namelen;
-	struct iovec *msg_iov;
-	int msg_iovlen;
-	void *msg_control;
-	socklen_t msg_controllen;
-	int msg_flags;
-};
-
-struct cmsghdr
-{
-	socklen_t cmsg_len;
-	int cmsg_level;
-	int cmsg_type;
-};
diff --git a/arch/microblaze/bits/statfs.h b/arch/microblaze/bits/statfs.h
deleted file mode 100644
index f103f4e..0000000
--- a/arch/microblaze/bits/statfs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct statfs {
-	unsigned long f_type, f_bsize;
-	fsblkcnt_t f_blocks, f_bfree, f_bavail;
-	fsfilcnt_t f_files, f_ffree;
-	fsid_t f_fsid;
-	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
-};
diff --git a/arch/microblaze/bits/stdarg.h b/arch/microblaze/bits/stdarg.h
deleted file mode 100644
index fde3781..0000000
--- a/arch/microblaze/bits/stdarg.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define va_start(v,l)   __builtin_va_start(v,l)
-#define va_end(v)       __builtin_va_end(v)
-#define va_arg(v,l)     __builtin_va_arg(v,l)
-#define va_copy(d,s)    __builtin_va_copy(d,s)
diff --git a/arch/microblaze/bits/termios.h b/arch/microblaze/bits/termios.h
deleted file mode 100644
index f0d81b1..0000000
--- a/arch/microblaze/bits/termios.h
+++ /dev/null
@@ -1,160 +0,0 @@
-struct termios
-{
-	tcflag_t c_iflag;
-	tcflag_t c_oflag;
-	tcflag_t c_cflag;
-	tcflag_t c_lflag;
-	cc_t c_line;
-	cc_t c_cc[NCCS];
-	speed_t __c_ispeed;
-	speed_t __c_ospeed;
-};
-
-#define VINTR     0
-#define VQUIT     1
-#define VERASE    2
-#define VKILL     3
-#define VEOF      4
-#define VTIME     5
-#define VMIN      6
-#define VSWTC     7
-#define VSTART    8
-#define VSTOP     9
-#define VSUSP    10
-#define VEOL     11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE  14
-#define VLNEXT   15
-#define VEOL2    16
-
-#define IGNBRK  0000001
-#define BRKINT  0000002
-#define IGNPAR  0000004
-#define PARMRK  0000010
-#define INPCK   0000020
-#define ISTRIP  0000040
-#define INLCR   0000100
-#define IGNCR   0000200
-#define ICRNL   0000400
-#define IUCLC   0001000
-#define IXON    0002000
-#define IXANY   0004000
-#define IXOFF   0010000
-#define IMAXBEL 0020000
-#define IUTF8   0040000
-
-#define OPOST  0000001
-#define OLCUC  0000002
-#define ONLCR  0000004
-#define OCRNL  0000010
-#define ONOCR  0000020
-#define ONLRET 0000040
-#define OFILL  0000100
-#define OFDEL  0000200
-#define NLDLY  0000400
-#define NL0    0000000
-#define NL1    0000400
-#define CRDLY  0003000
-#define CR0    0000000
-#define CR1    0001000
-#define CR2    0002000
-#define CR3    0003000
-#define TABDLY 0014000
-#define TAB0   0000000
-#define TAB1   0004000
-#define TAB2   0010000
-#define TAB3   0014000
-#define BSDLY  0020000
-#define BS0    0000000
-#define BS1    0020000
-#define FFDLY  0100000
-#define FF0    0000000
-#define FF1    0100000
-
-#define VTDLY  0040000
-#define VT0    0000000
-#define VT1    0040000
-
-#define B0       0000000
-#define B50      0000001
-#define B75      0000002
-#define B110     0000003
-#define B134     0000004
-#define B150     0000005
-#define B200     0000006
-#define B300     0000007
-#define B600     0000010
-#define B1200    0000011
-#define B1800    0000012
-#define B2400    0000013
-#define B4800    0000014
-#define B9600    0000015
-#define B19200   0000016
-#define B38400   0000017
-
-#define B57600   0010001
-#define B115200  0010002
-#define B230400  0010003
-#define B460800  0010004
-#define B500000  0010005
-#define B576000  0010006
-#define B921600  0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-
-#define CBAUD    0010017
-
-#define CSIZE  0000060
-#define CS5    0000000
-#define CS6    0000020
-#define CS7    0000040
-#define CS8    0000060
-#define CSTOPB 0000100
-#define CREAD  0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL  0002000
-#define CLOCAL 0004000
-
-#define ISIG   0000001
-#define ICANON 0000002
-#define ECHO   0000010
-#define ECHOE  0000020
-#define ECHOK  0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define IEXTEN 0100000
-
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-
-#define TCOOFF 0
-#define TCOON  1
-#define TCIOFF 2
-#define TCION  3
-
-#define TCIFLUSH  0
-#define TCOFLUSH  1
-#define TCIOFLUSH 2
-
-#define TCSANOW   0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define CBAUDEX 0010000
-#define CRTSCTS  020000000000
-#define EXTPROC 0200000
-#define XTABS  0014000
-#endif
diff --git a/arch/microblaze/pthread_arch.h b/arch/microblaze/pthread_arch.h
index 259d3d6..08d1ba7 100644
--- a/arch/microblaze/pthread_arch.h
+++ b/arch/microblaze/pthread_arch.h
@@ -7,4 +7,4 @@
 
 #define TP_ADJ(p) (p)
 
-#define CANCEL_REG_IP 32
+#define MC_PC regs.pc
diff --git a/arch/mips/atomic.h b/arch/mips/atomic.h
deleted file mode 100644
index c82046a..0000000
--- a/arch/mips/atomic.h
+++ /dev/null
@@ -1,205 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_l(unsigned long x)
-{
-	static const char debruijn32[32] = {
-		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
-		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
-	};
-	return debruijn32[(x&-x)*0x076be629 >> 27];
-}
-
-static inline int a_ctz_64(uint64_t x)
-{
-	uint32_t y = x;
-	if (!y) {
-		y = x>>32;
-		return 32 + a_ctz_l(y);
-	}
-	return a_ctz_l(y);
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	int dummy;
-	__asm__ __volatile__(
-		".set push\n"
-		".set mips2\n"
-		".set noreorder\n"
-		"	sync\n"
-		"1:	ll %0, %2\n"
-		"	bne %0, %3, 1f\n"
-		"	addu %1, %4, $0\n"
-		"	sc %1, %2\n"
-		"	beq %1, $0, 1b\n"
-		"	nop\n"
-		"	sync\n"
-		"1:	\n"
-		".set pop\n"
-		: "=&r"(t), "=&r"(dummy), "+m"(*p) : "r"(t), "r"(s) : "memory" );
-        return t;
-}
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	return (void *)a_cas(p, (int)t, (int)s);
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	int old, dummy;
-	__asm__ __volatile__(
-		".set push\n"
-		".set mips2\n"
-		".set noreorder\n"
-		"	sync\n"
-		"1:	ll %0, %2\n"
-		"	addu %1, %3, $0\n"
-		"	sc %1, %2\n"
-		"	beq %1, $0, 1b\n"
-		"	nop\n"
-		"	sync\n"
-		".set pop\n"
-		: "=&r"(old), "=&r"(dummy), "+m"(*x) : "r"(v) : "memory" );
-        return old;
-}
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	int old, dummy;
-	__asm__ __volatile__(
-		".set push\n"
-		".set mips2\n"
-		".set noreorder\n"
-		"	sync\n"
-		"1:	ll %0, %2\n"
-		"	addu %1, %0, %3\n"
-		"	sc %1, %2\n"
-		"	beq %1, $0, 1b\n"
-		"	nop\n"
-		"	sync\n"
-		".set pop\n"
-		: "=&r"(old), "=&r"(dummy), "+m"(*x) : "r"(v) : "memory" );
-        return old;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	int dummy;
-	__asm__ __volatile__(
-		".set push\n"
-		".set mips2\n"
-		".set noreorder\n"
-		"	sync\n"
-		"1:	ll %0, %1\n"
-		"	addu %0, %0, 1\n"
-		"	sc %0, %1\n"
-		"	beq %0, $0, 1b\n"
-		"	nop\n"
-		"	sync\n"
-		".set pop\n"
-		: "=&r"(dummy), "+m"(*x) : : "memory" );
-}
-
-static inline void a_dec(volatile int *x)
-{
-	int dummy;
-	__asm__ __volatile__(
-		".set push\n"
-		".set mips2\n"
-		".set noreorder\n"
-		"	sync\n"
-		"1:	ll %0, %1\n"
-		"	subu %0, %0, 1\n"
-		"	sc %0, %1\n"
-		"	beq %0, $0, 1b\n"
-		"	nop\n"
-		"	sync\n"
-		".set pop\n"
-		: "=&r"(dummy), "+m"(*x) : : "memory" );
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	__asm__ __volatile__(
-		".set push\n"
-		".set mips2\n"
-		".set noreorder\n"
-		"	sync\n"
-		"	sw %1, %0\n"
-		"	sync\n"
-		".set pop\n"
-		: "+m"(*p) : "r"(x) : "memory" );
-}
-
-#define a_spin a_barrier
-
-static inline void a_barrier()
-{
-	a_cas(&(int){0}, 0, 0);
-}
-
-static inline void a_crash()
-{
-	*(volatile char *)0=0;
-}
-
-static inline void a_and(volatile int *p, int v)
-{
-	int dummy;
-	__asm__ __volatile__(
-		".set push\n"
-		".set mips2\n"
-		".set noreorder\n"
-		"	sync\n"
-		"1:	ll %0, %1\n"
-		"	and %0, %0, %2\n"
-		"	sc %0, %1\n"
-		"	beq %0, $0, 1b\n"
-		"	nop\n"
-		"	sync\n"
-		".set pop\n"
-		: "=&r"(dummy), "+m"(*p) : "r"(v) : "memory" );
-}
-
-static inline void a_or(volatile int *p, int v)
-{
-	int dummy;
-	__asm__ __volatile__(
-		".set push\n"
-		".set mips2\n"
-		".set noreorder\n"
-		"	sync\n"
-		"1:	ll %0, %1\n"
-		"	or %0, %0, %2\n"
-		"	sc %0, %1\n"
-		"	beq %0, $0, 1b\n"
-		"	nop\n"
-		"	sync\n"
-		".set pop\n"
-		: "=&r"(dummy), "+m"(*p) : "r"(v) : "memory" );
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	a_or(p, v);
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_and((int *)p, u.r[0]);
-	a_and((int *)p+1, u.r[1]);
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_or((int *)p, u.r[0]);
-	a_or((int *)p+1, u.r[1]);
-}
-
-#endif
diff --git a/arch/mips/atomic_arch.h b/arch/mips/atomic_arch.h
new file mode 100644
index 0000000..ce2823b
--- /dev/null
+++ b/arch/mips/atomic_arch.h
@@ -0,0 +1,39 @@
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+	int v;
+	__asm__ __volatile__ (
+		".set push ; .set mips2\n\t"
+		"ll %0, %1"
+		"\n\t.set pop"
+		: "=r"(v) : "m"(*p));
+	return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+	int r;
+	__asm__ __volatile__ (
+		".set push ; .set mips2\n\t"
+		"sc %0, %1"
+		"\n\t.set pop"
+		: "=r"(r), "=m"(*p) : "0"(v) : "memory");
+	return r;
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	/* mips2 sync, but using too many directives causes
+	 * gcc not to inline it, so encode with .long instead. */
+	__asm__ __volatile__ (".long 0xf" : : : "memory");
+#if 0
+	__asm__ __volatile__ (
+		".set push ; .set mips2 ; sync ; .set pop"
+		: : : "memory");
+#endif
+}
+
+#define a_pre_llsc a_barrier
+#define a_post_llsc a_barrier
diff --git a/arch/mips/bits/io.h b/arch/mips/bits/io.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/mips/bits/io.h
+++ /dev/null
diff --git a/arch/mips/bits/ipc.h b/arch/mips/bits/ipc.h
deleted file mode 100644
index b748d3b..0000000
--- a/arch/mips/bits/ipc.h
+++ /dev/null
@@ -1,14 +0,0 @@
-struct ipc_perm
-{
-	key_t __ipc_perm_key;
-	uid_t uid;
-	gid_t gid;
-	uid_t cuid;
-	gid_t cgid;
-	mode_t mode;
-	int __ipc_perm_seq;
-	long __pad1;
-	long __pad2;
-};
-
-#define IPC_64 0x100
diff --git a/arch/mips/bits/mman.h b/arch/mips/bits/mman.h
index 3125fc2..cb9ac53 100644
--- a/arch/mips/bits/mman.h
+++ b/arch/mips/bits/mman.h
@@ -37,6 +37,7 @@
 
 #define MCL_CURRENT     1
 #define MCL_FUTURE      2
+#define MCL_ONFAULT     4
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/mips/bits/signal.h b/arch/mips/bits/signal.h
index 818e0a7..889f77e 100644
--- a/arch/mips/bits/signal.h
+++ b/arch/mips/bits/signal.h
@@ -73,6 +73,15 @@
 #define SIG_UNBLOCK   2
 #define SIG_SETMASK   3
 
+#undef SI_ASYNCIO
+#undef SI_MESGQ
+#undef SI_TIMER
+#define SI_ASYNCIO (-2)
+#define SI_MESGQ (-4)
+#define SI_TIMER (-3)
+
+#define __SI_SWAP_ERRNO_CODE
+
 #endif
 
 #define SIGHUP    1
diff --git a/arch/mips/bits/stdarg.h b/arch/mips/bits/stdarg.h
deleted file mode 100644
index fde3781..0000000
--- a/arch/mips/bits/stdarg.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define va_start(v,l)   __builtin_va_start(v,l)
-#define va_end(v)       __builtin_va_end(v)
-#define va_arg(v,l)     __builtin_va_arg(v,l)
-#define va_copy(d,s)    __builtin_va_copy(d,s)
diff --git a/arch/mips/bits/syscall.h b/arch/mips/bits/syscall.h
index 06761ed..340c587 100644
--- a/arch/mips/bits/syscall.h
+++ b/arch/mips/bits/syscall.h
@@ -354,6 +354,9 @@
 #define __NR_memfd_create            4354
 #define __NR_bpf                     4355
 #define __NR_execveat                4356
+#define __NR_userfaultfd             4357
+#define __NR_membarrier              4358
+#define __NR_mlock2                  4359
 
 
 /* Repeated with SYS_ prefix */
@@ -713,3 +716,6 @@
 #define SYS_memfd_create            4354
 #define SYS_bpf                     4355
 #define SYS_execveat                4356
+#define SYS_userfaultfd             4357
+#define SYS_membarrier              4358
+#define SYS_mlock2                  4359
diff --git a/arch/mips/crt_arch.h b/arch/mips/crt_arch.h
index 21e139b..9fc50d7 100644
--- a/arch/mips/crt_arch.h
+++ b/arch/mips/crt_arch.h
@@ -10,7 +10,7 @@
 "" START ":\n"
 "	bal 1f \n"
 "	 move $fp, $0 \n"
-"2:	.gpword 2b \n"
+"	.gpword . \n"
 "	.gpword " START "_c \n"
 ".weak _DYNAMIC \n"
 ".hidden _DYNAMIC \n"
diff --git a/arch/mips/pthread_arch.h b/arch/mips/pthread_arch.h
index 93edbd4..8a49965 100644
--- a/arch/mips/pthread_arch.h
+++ b/arch/mips/pthread_arch.h
@@ -16,4 +16,4 @@
 
 #define DTP_OFFSET 0x8000
 
-#define CANCEL_REG_IP (3-(union {int __i; char __b;}){1}.__b)
+#define MC_PC pc
diff --git a/arch/mips/reloc.h b/arch/mips/reloc.h
index 9b40e3d..8c52df0 100644
--- a/arch/mips/reloc.h
+++ b/arch/mips/reloc.h
@@ -24,7 +24,7 @@
 #define REL_TPOFF       R_MIPS_TLS_TPREL32
 
 #define NEED_MIPS_GOT_RELOCS 1
-#define DYNAMIC_IS_RO 1
+#define DT_DEBUG_INDIRECT DT_MIPS_RLD_MAP
 #define ARCH_SYM_REJECT_UND(s) (!((s)->st_other & STO_MIPS_PLT))
 
 #define CRTJMP(pc,sp) __asm__ __volatile__( \
diff --git a/arch/mips/syscall_arch.h b/arch/mips/syscall_arch.h
index 1b1179c..39c0ea3 100644
--- a/arch/mips/syscall_arch.h
+++ b/arch/mips/syscall_arch.h
@@ -3,9 +3,7 @@
 ((union { long long ll; long l[2]; }){ .ll = x }).l[1]
 #define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
 
-#ifdef SHARED
 __attribute__((visibility("hidden")))
-#endif
 long (__syscall)(long, ...);
 
 #define SYSCALL_RLIM_INFINITY (-1UL/2)
@@ -163,3 +161,7 @@
 	if (n == SYS_fstatat) __stat_fix(c);
 	return r2;
 }
+
+#define VDSO_USEFUL
+#define VDSO_CGT_SYM "__vdso_clock_gettime"
+#define VDSO_CGT_VER "LINUX_2.6"
diff --git a/arch/or1k/atomic.h b/arch/or1k/atomic.h
deleted file mode 100644
index 640ff43..0000000
--- a/arch/or1k/atomic.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_l(unsigned long x)
-{
-	static const char debruijn32[32] = {
-		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
-		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
-	};
-	return debruijn32[(x&-x)*0x076be629 >> 27];
-}
-
-static inline int a_ctz_64(uint64_t x)
-{
-	uint32_t y = x;
-	if (!y) {
-		y = x>>32;
-		return 32 + a_ctz_l(y);
-	}
-	return a_ctz_l(y);
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	__asm__("1:	l.lwa %0, %1\n"
-		"	l.sfeq %0, %2\n"
-		"	l.bnf 1f\n"
-		"	 l.nop\n"
-		"	l.swa %1, %3\n"
-		"	l.bnf 1b\n"
-		"	 l.nop\n"
-		"1:	\n"
-		: "=&r"(t), "+m"(*p) : "r"(t), "r"(s) : "cc", "memory" );
-        return t;
-}
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	return (void *)a_cas(p, (int)t, (int)s);
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	int old;
-	do old = *x;
-	while (a_cas(x, old, v) != old);
-	return old;
-}
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	int old;
-	do old = *x;
-	while (a_cas(x, old, old+v) != old);
-	return old;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	a_fetch_add(x, 1);
-}
-
-static inline void a_dec(volatile int *x)
-{
-	a_fetch_add(x, -1);
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	a_swap(p, x);
-}
-
-#define a_spin a_barrier
-
-static inline void a_barrier()
-{
-	a_cas(&(int){0}, 0, 0);
-}
-
-static inline void a_crash()
-{
-	*(volatile char *)0=0;
-}
-
-static inline void a_and(volatile int *p, int v)
-{
-	int old;
-	do old = *p;
-	while (a_cas(p, old, old&v) != old);
-}
-
-static inline void a_or(volatile int *p, int v)
-{
-	int old;
-	do old = *p;
-	while (a_cas(p, old, old|v) != old);
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	a_or(p, v);
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_and((int *)p, u.r[0]);
-	a_and((int *)p+1, u.r[1]);
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_or((int *)p, u.r[0]);
-	a_or((int *)p+1, u.r[1]);
-}
-
-#endif
diff --git a/arch/or1k/atomic_arch.h b/arch/or1k/atomic_arch.h
new file mode 100644
index 0000000..11a5429
--- /dev/null
+++ b/arch/or1k/atomic_arch.h
@@ -0,0 +1,14 @@
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	__asm__("1:	l.lwa %0, %1\n"
+		"	l.sfeq %0, %2\n"
+		"	l.bnf 1f\n"
+		"	 l.nop\n"
+		"	l.swa %1, %3\n"
+		"	l.bnf 1b\n"
+		"	 l.nop\n"
+		"1:	\n"
+		: "=&r"(t), "+m"(*p) : "r"(t), "r"(s) : "cc", "memory" );
+        return t;
+}
diff --git a/arch/or1k/bits/errno.h b/arch/or1k/bits/errno.h
deleted file mode 100644
index d2e1eee..0000000
--- a/arch/or1k/bits/errno.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#define EPERM            1
-#define ENOENT           2
-#define ESRCH            3
-#define EINTR            4
-#define EIO              5
-#define ENXIO            6
-#define E2BIG            7
-#define ENOEXEC          8
-#define EBADF            9
-#define ECHILD          10
-#define EAGAIN          11
-#define ENOMEM          12
-#define EACCES          13
-#define EFAULT          14
-#define ENOTBLK         15
-#define EBUSY           16
-#define EEXIST          17
-#define EXDEV           18
-#define ENODEV          19
-#define ENOTDIR         20
-#define EISDIR          21
-#define EINVAL          22
-#define ENFILE          23
-#define EMFILE          24
-#define ENOTTY          25
-#define ETXTBSY         26
-#define EFBIG           27
-#define ENOSPC          28
-#define ESPIPE          29
-#define EROFS           30
-#define EMLINK          31
-#define EPIPE           32
-#define EDOM            33
-#define ERANGE          34
-#define EDEADLK         35
-#define ENAMETOOLONG    36
-#define ENOLCK          37
-#define ENOSYS          38
-#define ENOTEMPTY       39
-#define ELOOP           40
-#define EWOULDBLOCK     EAGAIN
-#define ENOMSG          42
-#define EIDRM           43
-#define ECHRNG          44
-#define EL2NSYNC        45
-#define EL3HLT          46
-#define EL3RST          47
-#define ELNRNG          48
-#define EUNATCH         49
-#define ENOCSI          50
-#define EL2HLT          51
-#define EBADE           52
-#define EBADR           53
-#define EXFULL          54
-#define ENOANO          55
-#define EBADRQC         56
-#define EBADSLT         57
-#define EDEADLOCK       EDEADLK
-#define EBFONT          59
-#define ENOSTR          60
-#define ENODATA         61
-#define ETIME           62
-#define ENOSR           63
-#define ENONET          64
-#define ENOPKG          65
-#define EREMOTE         66
-#define ENOLINK         67
-#define EADV            68
-#define ESRMNT          69
-#define ECOMM           70
-#define EPROTO          71
-#define EMULTIHOP       72
-#define EDOTDOT         73
-#define EBADMSG         74
-#define EOVERFLOW       75
-#define ENOTUNIQ        76
-#define EBADFD          77
-#define EREMCHG         78
-#define ELIBACC         79
-#define ELIBBAD         80
-#define ELIBSCN         81
-#define ELIBMAX         82
-#define ELIBEXEC        83
-#define EILSEQ          84
-#define ERESTART        85
-#define ESTRPIPE        86
-#define EUSERS          87
-#define ENOTSOCK        88
-#define EDESTADDRREQ    89
-#define EMSGSIZE        90
-#define EPROTOTYPE      91
-#define ENOPROTOOPT     92
-#define EPROTONOSUPPORT 93
-#define ESOCKTNOSUPPORT 94
-#define EOPNOTSUPP      95
-#define ENOTSUP         EOPNOTSUPP
-#define EPFNOSUPPORT    96
-#define EAFNOSUPPORT    97
-#define EADDRINUSE      98
-#define EADDRNOTAVAIL   99
-#define ENETDOWN        100
-#define ENETUNREACH     101
-#define ENETRESET       102
-#define ECONNABORTED    103
-#define ECONNRESET      104
-#define ENOBUFS         105
-#define EISCONN         106
-#define ENOTCONN        107
-#define ESHUTDOWN       108
-#define ETOOMANYREFS    109
-#define ETIMEDOUT       110
-#define ECONNREFUSED    111
-#define EHOSTDOWN       112
-#define EHOSTUNREACH    113
-#define EALREADY        114
-#define EINPROGRESS     115
-#define ESTALE          116
-#define EUCLEAN         117
-#define ENOTNAM         118
-#define ENAVAIL         119
-#define EISNAM          120
-#define EREMOTEIO       121
-#define EDQUOT          122
-#define ENOMEDIUM       123
-#define EMEDIUMTYPE     124
-#define ECANCELED       125
-#define ENOKEY          126
-#define EKEYEXPIRED     127
-#define EKEYREVOKED     128
-#define EKEYREJECTED    129
-#define EOWNERDEAD      130
-#define ENOTRECOVERABLE 131
-#define ERFKILL         132
-#define EHWPOISON       133
diff --git a/arch/or1k/bits/fcntl.h b/arch/or1k/bits/fcntl.h
deleted file mode 100644
index ae233cc..0000000
--- a/arch/or1k/bits/fcntl.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#define O_CREAT        0100
-#define O_EXCL         0200
-#define O_NOCTTY       0400
-#define O_TRUNC       01000
-#define O_APPEND      02000
-#define O_NONBLOCK    04000
-#define O_DSYNC      010000
-#define O_SYNC     04010000
-#define O_RSYNC    04010000
-#define O_DIRECTORY 0200000
-#define O_NOFOLLOW  0400000
-#define O_CLOEXEC  02000000
-
-#define O_ASYNC      020000
-#define O_DIRECT     040000
-#define O_LARGEFILE 0100000
-#define O_NOATIME  01000000
-#define O_PATH    010000000
-#define O_TMPFILE 020200000
-#define O_NDELAY O_NONBLOCK
-
-#define F_DUPFD  0
-#define F_GETFD  1
-#define F_SETFD  2
-#define F_GETFL  3
-#define F_SETFL  4
-
-#define F_SETOWN 8
-#define F_GETOWN 9
-#define F_SETSIG 10
-#define F_GETSIG 11
-
-#define F_GETLK 12
-#define F_SETLK 13
-#define F_SETLKW 14
-
-#define F_SETOWN_EX 15
-#define F_GETOWN_EX 16
-
-#define F_GETOWNER_UIDS 17
diff --git a/arch/or1k/bits/io.h b/arch/or1k/bits/io.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/or1k/bits/io.h
+++ /dev/null
diff --git a/arch/or1k/bits/ioctl.h b/arch/or1k/bits/ioctl.h
deleted file mode 100644
index 9d75118..0000000
--- a/arch/or1k/bits/ioctl.h
+++ /dev/null
@@ -1,197 +0,0 @@
-#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
-#define _IOC_NONE  0U
-#define _IOC_WRITE 1U
-#define _IOC_READ  2U
-
-#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
-#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
-#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
-#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
-
-#define TCGETS		0x5401
-#define TCSETS		0x5402
-#define TCSETSW		0x5403
-#define TCSETSF		0x5404
-#define TCGETA		0x5405
-#define TCSETA		0x5406
-#define TCSETAW		0x5407
-#define TCSETAF		0x5408
-#define TCSBRK		0x5409
-#define TCXONC		0x540A
-#define TCFLSH		0x540B
-#define TIOCEXCL	0x540C
-#define TIOCNXCL	0x540D
-#define TIOCSCTTY	0x540E
-#define TIOCGPGRP	0x540F
-#define TIOCSPGRP	0x5410
-#define TIOCOUTQ	0x5411
-#define TIOCSTI		0x5412
-#define TIOCGWINSZ	0x5413
-#define TIOCSWINSZ	0x5414
-#define TIOCMGET	0x5415
-#define TIOCMBIS	0x5416
-#define TIOCMBIC	0x5417
-#define TIOCMSET	0x5418
-#define TIOCGSOFTCAR	0x5419
-#define TIOCSSOFTCAR	0x541A
-#define FIONREAD	0x541B
-#define TIOCINQ		FIONREAD
-#define TIOCLINUX	0x541C
-#define TIOCCONS	0x541D
-#define TIOCGSERIAL	0x541E
-#define TIOCSSERIAL	0x541F
-#define TIOCPKT		0x5420
-#define FIONBIO		0x5421
-#define TIOCNOTTY	0x5422
-#define TIOCSETD	0x5423
-#define TIOCGETD	0x5424
-#define TCSBRKP		0x5425
-#define TIOCTTYGSTRUCT	0x5426
-#define TIOCSBRK	0x5427
-#define TIOCCBRK	0x5428
-#define TIOCGSID	0x5429
-#define TIOCGPTN	0x80045430
-#define TIOCSPTLCK	0x40045431
-#define TCGETX		0x5432
-#define TCSETX		0x5433
-#define TCSETXF		0x5434
-#define TCSETXW		0x5435
-
-#define FIONCLEX	0x5450
-#define FIOCLEX		0x5451
-#define FIOASYNC	0x5452
-#define TIOCSERCONFIG	0x5453
-#define TIOCSERGWILD	0x5454
-#define TIOCSERSWILD	0x5455
-#define TIOCGLCKTRMIOS	0x5456
-#define TIOCSLCKTRMIOS	0x5457
-#define TIOCSERGSTRUCT	0x5458
-#define TIOCSERGETLSR   0x5459
-#define TIOCSERGETMULTI 0x545A
-#define TIOCSERSETMULTI 0x545B
-
-#define TIOCMIWAIT	0x545C
-#define TIOCGICOUNT	0x545D
-#define TIOCGHAYESESP   0x545E
-#define TIOCSHAYESESP   0x545F
-#define FIOQSIZE	0x5460
-
-#define TIOCPKT_DATA		 0
-#define TIOCPKT_FLUSHREAD	 1
-#define TIOCPKT_FLUSHWRITE	 2
-#define TIOCPKT_STOP		 4
-#define TIOCPKT_START		 8
-#define TIOCPKT_NOSTOP		16
-#define TIOCPKT_DOSTOP		32
-#define TIOCPKT_IOCTL		64
-
-#define TIOCSER_TEMT    0x01
-
-struct winsize {
-	unsigned short ws_row;
-	unsigned short ws_col;
-	unsigned short ws_xpixel;
-	unsigned short ws_ypixel;
-};
-
-#define TIOCM_LE        0x001
-#define TIOCM_DTR       0x002
-#define TIOCM_RTS       0x004
-#define TIOCM_ST        0x008
-#define TIOCM_SR        0x010
-#define TIOCM_CTS       0x020
-#define TIOCM_CAR       0x040
-#define TIOCM_RNG       0x080
-#define TIOCM_DSR       0x100
-#define TIOCM_CD        TIOCM_CAR
-#define TIOCM_RI        TIOCM_RNG
-#define TIOCM_OUT1      0x2000
-#define TIOCM_OUT2      0x4000
-#define TIOCM_LOOP      0x8000
-#define TIOCM_MODEM_BITS TIOCM_OUT2
-
-#define N_TTY           0
-#define N_SLIP          1
-#define N_MOUSE         2
-#define N_PPP           3
-#define N_STRIP         4
-#define N_AX25          5
-#define N_X25           6
-#define N_6PACK         7
-#define N_MASC          8
-#define N_R3964         9
-#define N_PROFIBUS_FDL  10
-#define N_IRDA          11
-#define N_SMSBLOCK      12
-#define N_HDLC          13
-#define N_SYNC_PPP      14
-#define N_HCI           15
-
-#define FIOSETOWN       0x8901
-#define SIOCSPGRP       0x8902
-#define FIOGETOWN       0x8903
-#define SIOCGPGRP       0x8904
-#define SIOCATMARK      0x8905
-#define SIOCGSTAMP      0x8906
-
-#define SIOCADDRT       0x890B
-#define SIOCDELRT       0x890C
-#define SIOCRTMSG       0x890D
-
-#define SIOCGIFNAME     0x8910
-#define SIOCSIFLINK     0x8911
-#define SIOCGIFCONF     0x8912
-#define SIOCGIFFLAGS    0x8913
-#define SIOCSIFFLAGS    0x8914
-#define SIOCGIFADDR     0x8915
-#define SIOCSIFADDR     0x8916
-#define SIOCGIFDSTADDR  0x8917
-#define SIOCSIFDSTADDR  0x8918
-#define SIOCGIFBRDADDR  0x8919
-#define SIOCSIFBRDADDR  0x891a
-#define SIOCGIFNETMASK  0x891b
-#define SIOCSIFNETMASK  0x891c
-#define SIOCGIFMETRIC   0x891d
-#define SIOCSIFMETRIC   0x891e
-#define SIOCGIFMEM      0x891f
-#define SIOCSIFMEM      0x8920
-#define SIOCGIFMTU      0x8921
-#define SIOCSIFMTU      0x8922
-#define SIOCSIFHWADDR   0x8924
-#define SIOCGIFENCAP    0x8925
-#define SIOCSIFENCAP    0x8926
-#define SIOCGIFHWADDR   0x8927
-#define SIOCGIFSLAVE    0x8929
-#define SIOCSIFSLAVE    0x8930
-#define SIOCADDMULTI    0x8931
-#define SIOCDELMULTI    0x8932
-#define SIOCGIFINDEX    0x8933
-#define SIOGIFINDEX     SIOCGIFINDEX
-#define SIOCSIFPFLAGS   0x8934
-#define SIOCGIFPFLAGS   0x8935
-#define SIOCDIFADDR     0x8936
-#define SIOCSIFHWBROADCAST 0x8937
-#define SIOCGIFCOUNT    0x8938
-
-#define SIOCGIFBR       0x8940
-#define SIOCSIFBR       0x8941
-
-#define SIOCGIFTXQLEN   0x8942
-#define SIOCSIFTXQLEN   0x8943
-
-#define SIOCDARP        0x8953
-#define SIOCGARP        0x8954
-#define SIOCSARP        0x8955
-
-#define SIOCDRARP       0x8960
-#define SIOCGRARP       0x8961
-#define SIOCSRARP       0x8962
-
-#define SIOCGIFMAP      0x8970
-#define SIOCSIFMAP      0x8971
-
-#define SIOCADDDLCI     0x8980
-#define SIOCDELDLCI     0x8981
-
-#define SIOCDEVPRIVATE		0x89F0
-#define SIOCPROTOPRIVATE	0x89E0
diff --git a/arch/or1k/bits/mman.h b/arch/or1k/bits/mman.h
index cc854aa..ea6f6a7 100644
--- a/arch/or1k/bits/mman.h
+++ b/arch/or1k/bits/mman.h
@@ -37,6 +37,7 @@
 
 #define MCL_CURRENT     1
 #define MCL_FUTURE      2
+#define MCL_ONFAULT     4
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/or1k/bits/poll.h b/arch/or1k/bits/poll.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/or1k/bits/poll.h
+++ /dev/null
diff --git a/arch/or1k/bits/resource.h b/arch/or1k/bits/resource.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/or1k/bits/resource.h
+++ /dev/null
diff --git a/arch/or1k/bits/shm.h b/arch/or1k/bits/shm.h
deleted file mode 100644
index 81b2a29..0000000
--- a/arch/or1k/bits/shm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#define SHMLBA 4096
-
-struct shmid_ds {
-	struct ipc_perm shm_perm;
-	size_t shm_segsz;
-	time_t shm_atime;
-	int __unused1;
-	time_t shm_dtime;
-	int __unused2;
-	time_t shm_ctime;
-	int __unused3;
-	pid_t shm_cpid;
-	pid_t shm_lpid;
-	unsigned long shm_nattch;
-	unsigned long __pad1;
-	unsigned long __pad2;
-};
-
-struct shminfo {
-	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
-};
-
-struct shm_info {
-	int __used_ids;
-	unsigned long shm_tot, shm_rss, shm_swp;
-	unsigned long __swap_attempts, __swap_successes;
-};
diff --git a/arch/or1k/bits/socket.h b/arch/or1k/bits/socket.h
deleted file mode 100644
index 1f73b99..0000000
--- a/arch/or1k/bits/socket.h
+++ /dev/null
@@ -1,15 +0,0 @@
-struct msghdr {
-	void *msg_name;
-	socklen_t msg_namelen;
-	struct iovec *msg_iov;
-	int msg_iovlen;
-	void *msg_control;
-	socklen_t msg_controllen;
-	int msg_flags;
-};
-
-struct cmsghdr {
-	socklen_t cmsg_len;
-	int cmsg_level;
-	int cmsg_type;
-};
diff --git a/arch/or1k/bits/statfs.h b/arch/or1k/bits/statfs.h
deleted file mode 100644
index f103f4e..0000000
--- a/arch/or1k/bits/statfs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct statfs {
-	unsigned long f_type, f_bsize;
-	fsblkcnt_t f_blocks, f_bfree, f_bavail;
-	fsfilcnt_t f_files, f_ffree;
-	fsid_t f_fsid;
-	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
-};
diff --git a/arch/or1k/bits/stdarg.h b/arch/or1k/bits/stdarg.h
deleted file mode 100644
index fde3781..0000000
--- a/arch/or1k/bits/stdarg.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define va_start(v,l)   __builtin_va_start(v,l)
-#define va_end(v)       __builtin_va_end(v)
-#define va_arg(v,l)     __builtin_va_arg(v,l)
-#define va_copy(d,s)    __builtin_va_copy(d,s)
diff --git a/arch/or1k/bits/syscall.h b/arch/or1k/bits/syscall.h
index 967db72..a73b232 100644
--- a/arch/or1k/bits/syscall.h
+++ b/arch/or1k/bits/syscall.h
@@ -265,6 +265,9 @@
 #define __NR_memfd_create 279
 #define __NR_bpf 280
 #define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
 
 #define SYS_io_setup __NR_io_setup
 #define SYS_io_destroy __NR_io_destroy
@@ -533,3 +536,6 @@
 #define SYS_memfd_create __NR_memfd_create
 #define SYS_bpf __NR_bpf
 #define SYS_execveat __NR_execveat
+#define SYS_userfaultfd __NR_userfaultfd
+#define SYS_membarrier __NR_membarrier
+#define SYS_mlock2 __NR_mlock2
diff --git a/arch/or1k/bits/termios.h b/arch/or1k/bits/termios.h
deleted file mode 100644
index da26644..0000000
--- a/arch/or1k/bits/termios.h
+++ /dev/null
@@ -1,159 +0,0 @@
-struct termios {
-	tcflag_t c_iflag;
-	tcflag_t c_oflag;
-	tcflag_t c_cflag;
-	tcflag_t c_lflag;
-	cc_t c_line;
-	cc_t c_cc[NCCS];
-	speed_t __c_ispeed;
-	speed_t __c_ospeed;
-};
-
-#define VINTR     0
-#define VQUIT     1
-#define VERASE    2
-#define VKILL     3
-#define VEOF      4
-#define VTIME     5
-#define VMIN      6
-#define VSWTC     7
-#define VSTART    8
-#define VSTOP     9
-#define VSUSP    10
-#define VEOL     11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE  14
-#define VLNEXT   15
-#define VEOL2    16
-
-#define IGNBRK  0000001
-#define BRKINT  0000002
-#define IGNPAR  0000004
-#define PARMRK  0000010
-#define INPCK   0000020
-#define ISTRIP  0000040
-#define INLCR   0000100
-#define IGNCR   0000200
-#define ICRNL   0000400
-#define IUCLC   0001000
-#define IXON    0002000
-#define IXANY   0004000
-#define IXOFF   0010000
-#define IMAXBEL 0020000
-#define IUTF8   0040000
-
-#define OPOST  0000001
-#define OLCUC  0000002
-#define ONLCR  0000004
-#define OCRNL  0000010
-#define ONOCR  0000020
-#define ONLRET 0000040
-#define OFILL  0000100
-#define OFDEL  0000200
-#define NLDLY  0000400
-#define NL0    0000000
-#define NL1    0000400
-#define CRDLY  0003000
-#define CR0    0000000
-#define CR1    0001000
-#define CR2    0002000
-#define CR3    0003000
-#define TABDLY 0014000
-#define TAB0   0000000
-#define TAB1   0004000
-#define TAB2   0010000
-#define TAB3   0014000
-#define BSDLY  0020000
-#define BS0    0000000
-#define BS1    0020000
-#define FFDLY  0100000
-#define FF0    0000000
-#define FF1    0100000
-
-#define VTDLY  0040000
-#define VT0    0000000
-#define VT1    0040000
-
-#define B0       0000000
-#define B50      0000001
-#define B75      0000002
-#define B110     0000003
-#define B134     0000004
-#define B150     0000005
-#define B200     0000006
-#define B300     0000007
-#define B600     0000010
-#define B1200    0000011
-#define B1800    0000012
-#define B2400    0000013
-#define B4800    0000014
-#define B9600    0000015
-#define B19200   0000016
-#define B38400   0000017
-
-#define B57600   0010001
-#define B115200  0010002
-#define B230400  0010003
-#define B460800  0010004
-#define B500000  0010005
-#define B576000  0010006
-#define B921600  0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-
-#define CBAUD    0010017
-
-#define CSIZE  0000060
-#define CS5    0000000
-#define CS6    0000020
-#define CS7    0000040
-#define CS8    0000060
-#define CSTOPB 0000100
-#define CREAD  0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL  0002000
-#define CLOCAL 0004000
-
-#define ISIG   0000001
-#define ICANON 0000002
-#define ECHO   0000010
-#define ECHOE  0000020
-#define ECHOK  0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define IEXTEN 0100000
-
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-
-#define TCOOFF 0
-#define TCOON  1
-#define TCIOFF 2
-#define TCION  3
-
-#define TCIFLUSH  0
-#define TCOFLUSH  1
-#define TCIOFLUSH 2
-
-#define TCSANOW   0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define CBAUDEX 0010000
-#define CRTSCTS  020000000000
-#define EXTPROC 0200000
-#define XTABS  0014000
-#endif
diff --git a/arch/or1k/pthread_arch.h b/arch/or1k/pthread_arch.h
index ad63169..7decd76 100644
--- a/arch/or1k/pthread_arch.h
+++ b/arch/or1k/pthread_arch.h
@@ -14,5 +14,4 @@
 #define TLS_ABOVE_TP
 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
 
-/* word-offset to 'pc' in mcontext_t */
-#define CANCEL_REG_IP 32
+#define MC_PC regs.pc
diff --git a/arch/powerpc/atomic.h b/arch/powerpc/atomic.h
deleted file mode 100644
index f706543..0000000
--- a/arch/powerpc/atomic.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-#include <endian.h>
-
-static inline int a_ctz_l(unsigned long x)
-{
-	static const char debruijn32[32] = {
-		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
-		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
-	};
-	return debruijn32[(x&-x)*0x076be629 >> 27];
-}
-
-static inline int a_ctz_64(uint64_t x)
-{
-	uint32_t y = x;
-	if (!y) {
-		y = x>>32;
-		return 32 + a_ctz_l(y);
-	}
-	return a_ctz_l(y);
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	__asm__("\n"
-		"	sync\n"
-		"1:	lwarx %0, 0, %4\n"
-		"	cmpw %0, %2\n"
-		"	bne 1f\n"
-		"	stwcx. %3, 0, %4\n"
-		"	bne- 1b\n"
-		"	isync\n"
-		"1:	\n"
-		: "=&r"(t), "+m"(*p) : "r"(t), "r"(s), "r"(p) : "cc", "memory" );
-        return t;
-}
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	return (void *)a_cas(p, (int)t, (int)s);
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	int old;
-	do old = *x;
-	while (a_cas(x, old, v) != old);
-	return old;
-}
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	int old;
-	do old = *x;
-	while (a_cas(x, old, old+v) != old);
-	return old;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	a_fetch_add(x, 1);
-}
-
-static inline void a_dec(volatile int *x)
-{
-	a_fetch_add(x, -1);
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	__asm__ __volatile__ ("\n"
-		"	sync\n"
-		"	stw %1, %0\n"
-		"	isync\n"
-		: "=m"(*p) : "r"(x) : "memory" );
-}
-
-#define a_spin a_barrier
-
-static inline void a_barrier()
-{
-	a_cas(&(int){0}, 0, 0);
-}
-
-static inline void a_crash()
-{
-	*(volatile char *)0=0;
-}
-
-static inline void a_and(volatile int *p, int v)
-{
-	int old;
-	do old = *p;
-	while (a_cas(p, old, old&v) != old);
-}
-
-static inline void a_or(volatile int *p, int v)
-{
-	int old;
-	do old = *p;
-	while (a_cas(p, old, old|v) != old);
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	a_or(p, v);
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_and((int *)p, u.r[0]);
-	a_and((int *)p+1, u.r[1]);
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_or((int *)p, u.r[0]);
-	a_or((int *)p+1, u.r[1]);
-}
-
-#endif
diff --git a/arch/powerpc/atomic_arch.h b/arch/powerpc/atomic_arch.h
new file mode 100644
index 0000000..f31566b
--- /dev/null
+++ b/arch/powerpc/atomic_arch.h
@@ -0,0 +1,39 @@
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+	int v;
+	__asm__ __volatile__ ("lwarx %0, 0, %2" : "=r"(v) : "m"(*p), "r"(p));
+	return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+	int r;
+	__asm__ __volatile__ (
+		"stwcx. %2, 0, %3 ; mfcr %0"
+		: "=r"(r), "=m"(*p) : "r"(v), "r"(p) : "memory", "cc");
+	return r & 0x20000000; /* "bit 2" of "cr0" (backwards bit order) */
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("sync" : : : "memory");
+}
+
+#define a_pre_llsc a_barrier
+
+#define a_post_llsc a_post_llsc
+static inline void a_post_llsc()
+{
+	__asm__ __volatile__ ("isync" : : : "memory");
+}
+
+#define a_store a_store
+static inline void a_store(volatile int *p, int v)
+{
+	a_pre_llsc();
+	*p = v;
+	a_post_llsc();
+}
diff --git a/arch/powerpc/bits/mman.h b/arch/powerpc/bits/mman.h
index fe8de2b..6581edc 100644
--- a/arch/powerpc/bits/mman.h
+++ b/arch/powerpc/bits/mman.h
@@ -4,6 +4,7 @@
 #define	PROT_READ      1
 #define	PROT_WRITE     2
 #define	PROT_EXEC      4
+#define	PROT_SAO       0x10
 #define	PROT_GROWSDOWN 0x01000000
 #define	PROT_GROWSUP   0x02000000
 
@@ -35,8 +36,9 @@
 #define MS_INVALIDATE   2
 #define MS_SYNC         4
 
-#define MCL_CURRENT     1
-#define MCL_FUTURE      2
+#define MCL_CURRENT     0x2000
+#define MCL_FUTURE      0x4000
+#define MCL_ONFAULT     0x8000
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/powerpc/bits/syscall.h b/arch/powerpc/bits/syscall.h
index acd825a..e02f56f 100644
--- a/arch/powerpc/bits/syscall.h
+++ b/arch/powerpc/bits/syscall.h
@@ -194,23 +194,19 @@
 #define __NR_vfork                  189
 #define __NR_ugetrlimit             190
 #define __NR_readahead              191
-#if !defined(__PPC64) || defined(__ABI32)
 #define __NR_mmap2                  192
 #define __NR_truncate64             193
 #define __NR_ftruncate64            194
 #define __NR_stat64                 195
 #define __NR_lstat64                196
 #define __NR_fstat64                197
-#endif
 #define __NR_pciconfig_read         198
 #define __NR_pciconfig_write        199
 #define __NR_pciconfig_iobase       200
 #define __NR_multiplexer            201
 #define __NR_getdents64             202
 #define __NR_pivot_root             203
-#if !defined(__PPC64) || defined(__ABI32)
 #define __NR_fcntl64                204
-#endif
 #define __NR_madvise                205
 #define __NR_mincore                206
 #define __NR_gettid                 207
@@ -231,9 +227,7 @@
 #define __NR_sched_setaffinity      222
 #define __NR_sched_getaffinity      223
 #define __NR_tuxcall                225
-#if !defined(__PPC64) || defined(__ABI32)
 #define __NR_sendfile64             226
-#endif
 #define __NR_io_setup               227
 #define __NR_io_destroy             228
 #define __NR_io_getevents           229
@@ -261,9 +255,7 @@
 #define __NR_utimes                 251
 #define __NR_statfs64               252
 #define __NR_fstatfs64              253
-#if !defined(__PPC64) || defined(__ABI32)
 #define __NR_fadvise64_64           254
-#endif
 #define __NR_rtas		255
 #define __NR_sys_debug_setcontext 256
 #define __NR_migrate_pages	258
@@ -299,11 +291,7 @@
 #define __NR_mknodat		288
 #define __NR_fchownat		289
 #define __NR_futimesat		290
-#if defined(__PPC64) && !defined(__ABI32)
-#define __NR_newfstatat		291
-#else
 #define __NR_fstatat64		291
-#endif
 #define __NR_unlinkat		292
 #define __NR_renameat		293
 #define __NR_linkat		294
@@ -376,6 +364,10 @@
 #define __NR_memfd_create          360
 #define __NR_bpf                   361
 #define __NR_execveat              362
+#define __NR_switch_endian         363
+#define __NR_userfaultfd           364
+#define __NR_membarrier            365
+#define __NR_mlock2                378
 
 /*
  * repeated with SYS prefix
@@ -576,23 +568,19 @@
 #define SYS_vfork                  189
 #define SYS_ugetrlimit             190
 #define SYS_readahead              191
-#if !defined(__PPC64) || defined(__ABI32)
 #define SYS_mmap2                  192
 #define SYS_truncate64             193
 #define SYS_ftruncate64            194
 #define SYS_stat64                 195
 #define SYS_lstat64                196
 #define SYS_fstat64                197
-#endif
 #define SYS_pciconfig_read         198
 #define SYS_pciconfig_write        199
 #define SYS_pciconfig_iobase       200
 #define SYS_multiplexer            201
 #define SYS_getdents64             202
 #define SYS_pivot_root             203
-#if !defined(__PPC64) || defined(__ABI32)
 #define SYS_fcntl64                204
-#endif
 #define SYS_madvise                205
 #define SYS_mincore                206
 #define SYS_gettid                 207
@@ -613,9 +601,7 @@
 #define SYS_sched_setaffinity      222
 #define SYS_sched_getaffinity      223
 #define SYS_tuxcall                225
-#if !defined(__PPC64) || defined(__ABI32)
 #define SYS_sendfile64             226
-#endif
 #define SYS_io_setup               227
 #define SYS_io_destroy             228
 #define SYS_io_getevents           229
@@ -643,9 +629,7 @@
 #define SYS_utimes                 251
 #define SYS_statfs64               252
 #define SYS_fstatfs64              253
-#if !defined(__PPC64) || defined(__ABI32)
 #define SYS_fadvise64_64           254
-#endif
 #define SYS_rtas		255
 #define SYS_sys_debug_setcontext 256
 #define SYS_migrate_pages	258
@@ -681,11 +665,7 @@
 #define SYS_mknodat		288
 #define SYS_fchownat		289
 #define SYS_futimesat		290
-#if defined(__PPC64) && !defined(__ABI32)
-#define SYS_newfstatat		291
-#else
 #define SYS_fstatat64		291
-#endif
 #define SYS_unlinkat		292
 #define SYS_renameat		293
 #define SYS_linkat		294
@@ -758,3 +738,7 @@
 #define SYS_memfd_create          360
 #define SYS_bpf                   361
 #define SYS_execveat              362
+#define SYS_switch_endian         363
+#define SYS_userfaultfd           364
+#define SYS_membarrier            365
+#define SYS_mlock2                378
diff --git a/arch/powerpc/pthread_arch.h b/arch/powerpc/pthread_arch.h
index bb7405d..7c5c4fa 100644
--- a/arch/powerpc/pthread_arch.h
+++ b/arch/powerpc/pthread_arch.h
@@ -15,9 +15,8 @@
 
 #define DTP_OFFSET 0x8000
 
-// offset of the PC register in mcontext_t, divided by the system wordsize
 // the kernel calls the ip "nip", it's the first saved value after the 32
 // GPRs.
-#define CANCEL_REG_IP 32
+#define MC_PC gregs[32]
 
 #define CANARY canary_at_end
diff --git a/arch/sh/atomic.h b/arch/sh/atomic.h
deleted file mode 100644
index f2e6dac..0000000
--- a/arch/sh/atomic.h
+++ /dev/null
@@ -1,168 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_l(unsigned long x)
-{
-	static const char debruijn32[32] = {
-		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
-		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
-	};
-	return debruijn32[(x&-x)*0x076be629 >> 27];
-}
-
-static inline int a_ctz_64(uint64_t x)
-{
-	uint32_t y = x;
-	if (!y) {
-		y = x>>32;
-		return 32 + a_ctz_l(y);
-	}
-	return a_ctz_l(y);
-}
-
-#define LLSC_CLOBBERS "r0", "t", "memory"
-#define LLSC_START(mem) "synco\n"  \
-	"0:	movli.l @" mem ", r0\n"
-#define LLSC_END(mem)              \
-	"1:	movco.l r0, @" mem "\n"    \
-	"	bf 0b\n"                   \
-	"	synco\n"
-
-static inline int __sh_cas_llsc(volatile int *p, int t, int s)
-{
-	int old;
-	__asm__ __volatile__(
-		LLSC_START("%1")
-		"	mov r0, %0\n"
-		"	cmp/eq %0, %2\n"
-		"	bf 1f\n"
-		"	mov %3, r0\n"
-		LLSC_END("%1")
-		: "=&r"(old) : "r"(p), "r"(t), "r"(s) : LLSC_CLOBBERS);
-	return old;
-}
-
-static inline int __sh_swap_llsc(volatile int *x, int v)
-{
-	int old;
-	__asm__ __volatile__(
-		LLSC_START("%1")
-		"	mov r0, %0\n"
-		"	mov %2, r0\n"
-		LLSC_END("%1")
-		: "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
-	return old;
-}
-
-static inline int __sh_fetch_add_llsc(volatile int *x, int v)
-{
-	int old;
-	__asm__ __volatile__(
-		LLSC_START("%1")
-		"	mov r0, %0\n"
-		"	add %2, r0\n"
-		LLSC_END("%1")
-		: "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
-	return old;
-}
-
-static inline void __sh_store_llsc(volatile int *p, int x)
-{
-	__asm__ __volatile__(
-		"	synco\n"
-		"	mov.l %1, @%0\n"
-		"	synco\n"
-		: : "r"(p), "r"(x) : "memory");
-}
-
-static inline void __sh_and_llsc(volatile int *x, int v)
-{
-	__asm__ __volatile__(
-		LLSC_START("%0")
-		"	and %1, r0\n"
-		LLSC_END("%0")
-		: : "r"(x), "r"(v) : LLSC_CLOBBERS);
-}
-
-static inline void __sh_or_llsc(volatile int *x, int v)
-{
-	__asm__ __volatile__(
-		LLSC_START("%0")
-		"	or %1, r0\n"
-		LLSC_END("%0")
-		: : "r"(x), "r"(v) : LLSC_CLOBBERS);
-}
-
-#ifdef __SH4A__
-#define a_cas(p,t,s)     __sh_cas_llsc(p,t,s)
-#define a_swap(x,v)      __sh_swap_llsc(x,v)
-#define a_fetch_add(x,v) __sh_fetch_add_llsc(x, v)
-#define a_store(x,v)     __sh_store_llsc(x, v)
-#define a_and(x,v)       __sh_and_llsc(x, v)
-#define a_or(x,v)        __sh_or_llsc(x, v)
-#else
-
-int  __sh_cas(volatile int *, int, int);
-int  __sh_swap(volatile int *, int);
-int  __sh_fetch_add(volatile int *, int);
-void __sh_store(volatile int *, int);
-void __sh_and(volatile int *, int);
-void __sh_or(volatile int *, int);
-
-#define a_cas(p,t,s)     __sh_cas(p,t,s)
-#define a_swap(x,v)      __sh_swap(x,v)
-#define a_fetch_add(x,v) __sh_fetch_add(x, v)
-#define a_store(x,v)     __sh_store(x, v)
-#define a_and(x,v)       __sh_and(x, v)
-#define a_or(x,v)        __sh_or(x, v)
-#endif
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	return (void *)a_cas(p, (int)t, (int)s);
-}
-
-static inline void a_inc(volatile int *x)
-{
-	a_fetch_add(x, 1);
-}
-
-static inline void a_dec(volatile int *x)
-{
-	a_fetch_add(x, -1);
-}
-
-#define a_spin a_barrier
-
-static inline void a_barrier()
-{
-	a_cas(&(int){0}, 0, 0);
-}
-
-static inline void a_crash()
-{
-	*(volatile char *)0=0;
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	a_or(p, v);
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_and((int *)p,   u.r[0]);
-	a_and((int *)p+1, u.r[1]);
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	union { uint64_t v; uint32_t r[2]; } u = { v };
-	a_or((int *)p,   u.r[0]);
-	a_or((int *)p+1, u.r[1]);
-}
-
-#endif
diff --git a/arch/sh/atomic_arch.h b/arch/sh/atomic_arch.h
new file mode 100644
index 0000000..74444d5
--- /dev/null
+++ b/arch/sh/atomic_arch.h
@@ -0,0 +1,46 @@
+#if defined(__SH4A__)
+
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+	int v;
+	__asm__ __volatile__ ("movli.l @%1, %0" : "=z"(v) : "r"(p), "m"(*p));
+	return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+	int r;
+	__asm__ __volatile__ (
+		"movco.l %2, @%3 ; movt %0"
+		: "=r"(r), "=m"(*p) : "z"(v), "r"(p) : "memory", "cc");
+	return r;
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("synco" : : "memory");
+}
+
+#define a_pre_llsc a_barrier
+#define a_post_llsc a_barrier
+
+#else
+
+#define a_cas a_cas
+__attribute__((__visibility__("hidden"))) extern const void *__sh_cas_ptr;
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	register int r1 __asm__("r1");
+	register int r2 __asm__("r2") = t;
+	register int r3 __asm__("r3") = s;
+	__asm__ __volatile__ (
+		"jsr @%4 ; nop"
+		: "=r"(r1), "+r"(r3) : "z"(p), "r"(r2), "r"(__sh_cas_ptr)
+		: "memory", "pr", "cc");
+	return r3;
+}
+
+#endif
diff --git a/arch/sh/bits/errno.h b/arch/sh/bits/errno.h
deleted file mode 100644
index d2e1eee..0000000
--- a/arch/sh/bits/errno.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#define EPERM            1
-#define ENOENT           2
-#define ESRCH            3
-#define EINTR            4
-#define EIO              5
-#define ENXIO            6
-#define E2BIG            7
-#define ENOEXEC          8
-#define EBADF            9
-#define ECHILD          10
-#define EAGAIN          11
-#define ENOMEM          12
-#define EACCES          13
-#define EFAULT          14
-#define ENOTBLK         15
-#define EBUSY           16
-#define EEXIST          17
-#define EXDEV           18
-#define ENODEV          19
-#define ENOTDIR         20
-#define EISDIR          21
-#define EINVAL          22
-#define ENFILE          23
-#define EMFILE          24
-#define ENOTTY          25
-#define ETXTBSY         26
-#define EFBIG           27
-#define ENOSPC          28
-#define ESPIPE          29
-#define EROFS           30
-#define EMLINK          31
-#define EPIPE           32
-#define EDOM            33
-#define ERANGE          34
-#define EDEADLK         35
-#define ENAMETOOLONG    36
-#define ENOLCK          37
-#define ENOSYS          38
-#define ENOTEMPTY       39
-#define ELOOP           40
-#define EWOULDBLOCK     EAGAIN
-#define ENOMSG          42
-#define EIDRM           43
-#define ECHRNG          44
-#define EL2NSYNC        45
-#define EL3HLT          46
-#define EL3RST          47
-#define ELNRNG          48
-#define EUNATCH         49
-#define ENOCSI          50
-#define EL2HLT          51
-#define EBADE           52
-#define EBADR           53
-#define EXFULL          54
-#define ENOANO          55
-#define EBADRQC         56
-#define EBADSLT         57
-#define EDEADLOCK       EDEADLK
-#define EBFONT          59
-#define ENOSTR          60
-#define ENODATA         61
-#define ETIME           62
-#define ENOSR           63
-#define ENONET          64
-#define ENOPKG          65
-#define EREMOTE         66
-#define ENOLINK         67
-#define EADV            68
-#define ESRMNT          69
-#define ECOMM           70
-#define EPROTO          71
-#define EMULTIHOP       72
-#define EDOTDOT         73
-#define EBADMSG         74
-#define EOVERFLOW       75
-#define ENOTUNIQ        76
-#define EBADFD          77
-#define EREMCHG         78
-#define ELIBACC         79
-#define ELIBBAD         80
-#define ELIBSCN         81
-#define ELIBMAX         82
-#define ELIBEXEC        83
-#define EILSEQ          84
-#define ERESTART        85
-#define ESTRPIPE        86
-#define EUSERS          87
-#define ENOTSOCK        88
-#define EDESTADDRREQ    89
-#define EMSGSIZE        90
-#define EPROTOTYPE      91
-#define ENOPROTOOPT     92
-#define EPROTONOSUPPORT 93
-#define ESOCKTNOSUPPORT 94
-#define EOPNOTSUPP      95
-#define ENOTSUP         EOPNOTSUPP
-#define EPFNOSUPPORT    96
-#define EAFNOSUPPORT    97
-#define EADDRINUSE      98
-#define EADDRNOTAVAIL   99
-#define ENETDOWN        100
-#define ENETUNREACH     101
-#define ENETRESET       102
-#define ECONNABORTED    103
-#define ECONNRESET      104
-#define ENOBUFS         105
-#define EISCONN         106
-#define ENOTCONN        107
-#define ESHUTDOWN       108
-#define ETOOMANYREFS    109
-#define ETIMEDOUT       110
-#define ECONNREFUSED    111
-#define EHOSTDOWN       112
-#define EHOSTUNREACH    113
-#define EALREADY        114
-#define EINPROGRESS     115
-#define ESTALE          116
-#define EUCLEAN         117
-#define ENOTNAM         118
-#define ENAVAIL         119
-#define EISNAM          120
-#define EREMOTEIO       121
-#define EDQUOT          122
-#define ENOMEDIUM       123
-#define EMEDIUMTYPE     124
-#define ECANCELED       125
-#define ENOKEY          126
-#define EKEYEXPIRED     127
-#define EKEYREVOKED     128
-#define EKEYREJECTED    129
-#define EOWNERDEAD      130
-#define ENOTRECOVERABLE 131
-#define ERFKILL         132
-#define EHWPOISON       133
diff --git a/arch/sh/bits/fcntl.h b/arch/sh/bits/fcntl.h
deleted file mode 100644
index ae233cc..0000000
--- a/arch/sh/bits/fcntl.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#define O_CREAT        0100
-#define O_EXCL         0200
-#define O_NOCTTY       0400
-#define O_TRUNC       01000
-#define O_APPEND      02000
-#define O_NONBLOCK    04000
-#define O_DSYNC      010000
-#define O_SYNC     04010000
-#define O_RSYNC    04010000
-#define O_DIRECTORY 0200000
-#define O_NOFOLLOW  0400000
-#define O_CLOEXEC  02000000
-
-#define O_ASYNC      020000
-#define O_DIRECT     040000
-#define O_LARGEFILE 0100000
-#define O_NOATIME  01000000
-#define O_PATH    010000000
-#define O_TMPFILE 020200000
-#define O_NDELAY O_NONBLOCK
-
-#define F_DUPFD  0
-#define F_GETFD  1
-#define F_SETFD  2
-#define F_GETFL  3
-#define F_SETFL  4
-
-#define F_SETOWN 8
-#define F_GETOWN 9
-#define F_SETSIG 10
-#define F_GETSIG 11
-
-#define F_GETLK 12
-#define F_SETLK 13
-#define F_SETLKW 14
-
-#define F_SETOWN_EX 15
-#define F_GETOWN_EX 16
-
-#define F_GETOWNER_UIDS 17
diff --git a/arch/sh/bits/io.h b/arch/sh/bits/io.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/sh/bits/io.h
+++ /dev/null
diff --git a/arch/sh/bits/ipc.h b/arch/sh/bits/ipc.h
deleted file mode 100644
index b748d3b..0000000
--- a/arch/sh/bits/ipc.h
+++ /dev/null
@@ -1,14 +0,0 @@
-struct ipc_perm
-{
-	key_t __ipc_perm_key;
-	uid_t uid;
-	gid_t gid;
-	uid_t cuid;
-	gid_t cgid;
-	mode_t mode;
-	int __ipc_perm_seq;
-	long __pad1;
-	long __pad2;
-};
-
-#define IPC_64 0x100
diff --git a/arch/sh/bits/mman.h b/arch/sh/bits/mman.h
index f6fc98f..3a25df1 100644
--- a/arch/sh/bits/mman.h
+++ b/arch/sh/bits/mman.h
@@ -38,6 +38,7 @@
 
 #define MCL_CURRENT     1
 #define MCL_FUTURE      2
+#define MCL_ONFAULT     4
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/sh/bits/msg.h b/arch/sh/bits/msg.h
deleted file mode 100644
index 3db8576..0000000
--- a/arch/sh/bits/msg.h
+++ /dev/null
@@ -1,16 +0,0 @@
-struct msqid_ds
-{
-	struct ipc_perm msg_perm;
-	time_t msg_stime;
-	int __unused1;
-	time_t msg_rtime;
-	int __unused2;
-	time_t msg_ctime;
-	int __unused3;
-	unsigned long msg_cbytes;
-	msgqnum_t msg_qnum;
-	msglen_t msg_qbytes;
-	pid_t msg_lspid;
-	pid_t msg_lrpid;
-	unsigned long __unused[2];
-};
diff --git a/arch/sh/bits/poll.h b/arch/sh/bits/poll.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/sh/bits/poll.h
+++ /dev/null
diff --git a/arch/sh/bits/resource.h b/arch/sh/bits/resource.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/sh/bits/resource.h
+++ /dev/null
diff --git a/arch/sh/bits/sem.h b/arch/sh/bits/sem.h
deleted file mode 100644
index c629b81..0000000
--- a/arch/sh/bits/sem.h
+++ /dev/null
@@ -1,16 +0,0 @@
-struct semid_ds {
-	struct ipc_perm sem_perm;
-	time_t sem_otime;
-	time_t __unused1;
-	time_t sem_ctime;
-	time_t __unused2;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-	unsigned short sem_nsems;
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-#else
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-	unsigned short sem_nsems;
-#endif
-	time_t __unused3;
-	time_t __unused4;
-};
diff --git a/arch/sh/bits/socket.h b/arch/sh/bits/socket.h
deleted file mode 100644
index 36febbc..0000000
--- a/arch/sh/bits/socket.h
+++ /dev/null
@@ -1,17 +0,0 @@
-struct msghdr
-{
-	void *msg_name;
-	socklen_t msg_namelen;
-	struct iovec *msg_iov;
-	int msg_iovlen;
-	void *msg_control;
-	socklen_t msg_controllen;
-	int msg_flags;
-};
-
-struct cmsghdr
-{
-	socklen_t cmsg_len;
-	int cmsg_level;
-	int cmsg_type;
-};
diff --git a/arch/sh/bits/statfs.h b/arch/sh/bits/statfs.h
deleted file mode 100644
index f103f4e..0000000
--- a/arch/sh/bits/statfs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct statfs {
-	unsigned long f_type, f_bsize;
-	fsblkcnt_t f_blocks, f_bfree, f_bavail;
-	fsfilcnt_t f_files, f_ffree;
-	fsid_t f_fsid;
-	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
-};
diff --git a/arch/sh/bits/stdarg.h b/arch/sh/bits/stdarg.h
deleted file mode 100644
index fde3781..0000000
--- a/arch/sh/bits/stdarg.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define va_start(v,l)   __builtin_va_start(v,l)
-#define va_end(v)       __builtin_va_end(v)
-#define va_arg(v,l)     __builtin_va_arg(v,l)
-#define va_copy(d,s)    __builtin_va_copy(d,s)
diff --git a/arch/sh/bits/termios.h b/arch/sh/bits/termios.h
deleted file mode 100644
index f0d81b1..0000000
--- a/arch/sh/bits/termios.h
+++ /dev/null
@@ -1,160 +0,0 @@
-struct termios
-{
-	tcflag_t c_iflag;
-	tcflag_t c_oflag;
-	tcflag_t c_cflag;
-	tcflag_t c_lflag;
-	cc_t c_line;
-	cc_t c_cc[NCCS];
-	speed_t __c_ispeed;
-	speed_t __c_ospeed;
-};
-
-#define VINTR     0
-#define VQUIT     1
-#define VERASE    2
-#define VKILL     3
-#define VEOF      4
-#define VTIME     5
-#define VMIN      6
-#define VSWTC     7
-#define VSTART    8
-#define VSTOP     9
-#define VSUSP    10
-#define VEOL     11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE  14
-#define VLNEXT   15
-#define VEOL2    16
-
-#define IGNBRK  0000001
-#define BRKINT  0000002
-#define IGNPAR  0000004
-#define PARMRK  0000010
-#define INPCK   0000020
-#define ISTRIP  0000040
-#define INLCR   0000100
-#define IGNCR   0000200
-#define ICRNL   0000400
-#define IUCLC   0001000
-#define IXON    0002000
-#define IXANY   0004000
-#define IXOFF   0010000
-#define IMAXBEL 0020000
-#define IUTF8   0040000
-
-#define OPOST  0000001
-#define OLCUC  0000002
-#define ONLCR  0000004
-#define OCRNL  0000010
-#define ONOCR  0000020
-#define ONLRET 0000040
-#define OFILL  0000100
-#define OFDEL  0000200
-#define NLDLY  0000400
-#define NL0    0000000
-#define NL1    0000400
-#define CRDLY  0003000
-#define CR0    0000000
-#define CR1    0001000
-#define CR2    0002000
-#define CR3    0003000
-#define TABDLY 0014000
-#define TAB0   0000000
-#define TAB1   0004000
-#define TAB2   0010000
-#define TAB3   0014000
-#define BSDLY  0020000
-#define BS0    0000000
-#define BS1    0020000
-#define FFDLY  0100000
-#define FF0    0000000
-#define FF1    0100000
-
-#define VTDLY  0040000
-#define VT0    0000000
-#define VT1    0040000
-
-#define B0       0000000
-#define B50      0000001
-#define B75      0000002
-#define B110     0000003
-#define B134     0000004
-#define B150     0000005
-#define B200     0000006
-#define B300     0000007
-#define B600     0000010
-#define B1200    0000011
-#define B1800    0000012
-#define B2400    0000013
-#define B4800    0000014
-#define B9600    0000015
-#define B19200   0000016
-#define B38400   0000017
-
-#define B57600   0010001
-#define B115200  0010002
-#define B230400  0010003
-#define B460800  0010004
-#define B500000  0010005
-#define B576000  0010006
-#define B921600  0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-
-#define CBAUD    0010017
-
-#define CSIZE  0000060
-#define CS5    0000000
-#define CS6    0000020
-#define CS7    0000040
-#define CS8    0000060
-#define CSTOPB 0000100
-#define CREAD  0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL  0002000
-#define CLOCAL 0004000
-
-#define ISIG   0000001
-#define ICANON 0000002
-#define ECHO   0000010
-#define ECHOE  0000020
-#define ECHOK  0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define IEXTEN 0100000
-
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-
-#define TCOOFF 0
-#define TCOON  1
-#define TCIOFF 2
-#define TCION  3
-
-#define TCIFLUSH  0
-#define TCOFLUSH  1
-#define TCIOFLUSH 2
-
-#define TCSANOW   0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define CBAUDEX 0010000
-#define CRTSCTS  020000000000
-#define EXTPROC 0200000
-#define XTABS  0014000
-#endif
diff --git a/arch/sh/crt_arch.h b/arch/sh/crt_arch.h
index 948bcb7..f341c8f 100644
--- a/arch/sh/crt_arch.h
+++ b/arch/sh/crt_arch.h
@@ -22,7 +22,8 @@
 "	mov.l 1f, r5 \n"
 "	mov.l 1f+4, r6 \n"
 "	add r0, r5 \n"
-"	bsr __fdpic_fixup \n"
+"	mov.l 4f, r1 \n"
+"5:	bsrf r1 \n"
 "	 add r0, r6 \n"
 "	mov r0, r12 \n"
 #endif
@@ -31,11 +32,16 @@
 "	mov.l r9, @-r15 \n"
 "	mov.l r8, @-r15 \n"
 "	mov #-16, r0 \n"
-"	bsr " START "_c \n"
+"	mov.l 2f, r1 \n"
+"3:	bsrf r1 \n"
 "	 and r0, r15 \n"
 ".align 2 \n"
 "1:	.long __ROFIXUP_LIST__@PCREL \n"
 "	.long __ROFIXUP_END__@PCREL + 4 \n"
+"2:	.long " START "_c@PCREL - (3b+4-.) \n"
+#ifndef SHARED
+"4:	.long __fdpic_fixup@PCREL - (5b+4-.) \n"
+#endif
 );
 
 #ifndef SHARED
@@ -53,13 +59,14 @@
 "	add r0, r5 \n"
 "	mov r15, r4 \n"
 "	mov #-16, r0 \n"
-"	and r0, r15 \n"
-"	bsr " START "_c \n"
-"	nop \n"
+"	mov.l 2f, r1 \n"
+"3:	bsrf r1 \n"
+"	 and r0, r15 \n"
 ".align 2 \n"
 ".weak _DYNAMIC \n"
 ".hidden _DYNAMIC \n"
 "1:	.long _DYNAMIC-. \n"
+"2:	.long " START "_c@PCREL - (3b+4-.) \n"
 );
 
 #endif
diff --git a/arch/sh/pthread_arch.h b/arch/sh/pthread_arch.h
index 65c389f..2756e7e 100644
--- a/arch/sh/pthread_arch.h
+++ b/arch/sh/pthread_arch.h
@@ -8,4 +8,4 @@
 #define TLS_ABOVE_TP
 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
 
-#define CANCEL_REG_IP 17
+#define MC_PC sc_pc
diff --git a/arch/sh/reloc.h b/arch/sh/reloc.h
index d4fe348..0238ce0 100644
--- a/arch/sh/reloc.h
+++ b/arch/sh/reloc.h
@@ -32,6 +32,8 @@
 #define REL_DTPOFF      R_SH_TLS_DTPOFF32
 #define REL_TPOFF       R_SH_TLS_TPOFF32
 
+#define DL_NOMMU_SUPPORT 1
+
 #if __SH_FDPIC__
 #define REL_FUNCDESC    R_SH_FUNCDESC
 #define REL_FUNCDESC_VAL R_SH_FUNCDESC_VALUE
diff --git a/arch/sh/src/__fpscr_values.c b/arch/sh/src/__fpscr_values.c
deleted file mode 100644
index 374df30..0000000
--- a/arch/sh/src/__fpscr_values.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "libc.h"
-
-/* used by gcc for switching the FPU between single and double precision */
-//const unsigned long __fpscr_values[2] ATTR_LIBC_VISIBILITY = { 0, 0x80000 };
-
diff --git a/arch/sh/src/__set_thread_area.c b/arch/sh/src/__set_thread_area.c
deleted file mode 100644
index 1d3e022..0000000
--- a/arch/sh/src/__set_thread_area.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "pthread_impl.h"
-#include "libc.h"
-#include "sh_atomic.h"
-#include <elf.h>
-
-/* Also perform sh-specific init */
-
-#define CPU_HAS_LLSC 0x0040
-
-__attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model, __sh_nommu;
-
-int __set_thread_area(void *p)
-{
-	size_t *aux;
-	__asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
-#ifndef __SH4A__
-	if (__hwcap & CPU_HAS_LLSC) {
-		__sh_atomic_model = SH_A_LLSC;
-		return 0;
-	}
-#if !defined(__SH3__) && !defined(__SH4__)
-	for (aux=libc.auxv; *aux; aux+=2) {
-		if (*aux != AT_PLATFORM) continue;
-		const char *s = (void *)aux[1];
-		if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
-		__sh_atomic_model = SH_A_IMASK;
-		__sh_nommu = 1;
-		return 0;
-	}
-#endif
-	/* __sh_atomic_model = SH_A_GUSA; */ /* 0, default */
-#endif
-	return 0;
-}
diff --git a/arch/sh/src/atomic.c b/arch/sh/src/atomic.c
deleted file mode 100644
index 7fd7307..0000000
--- a/arch/sh/src/atomic.c
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef __SH4A__
-
-#include "sh_atomic.h"
-#include "atomic.h"
-#include "libc.h"
-
-static inline unsigned mask()
-{
-	unsigned sr;
-	__asm__ __volatile__ ( "\n"
-	"	stc sr,r0 \n"
-	"	mov r0,%0 \n"
-	"	or #0xf0,r0 \n"
-	"	ldc r0,sr \n"
-	: "=&r"(sr) : : "memory", "r0" );
-	return sr;
-}
-
-static inline void unmask(unsigned sr)
-{
-	__asm__ __volatile__ ( "ldc %0,sr" : : "r"(sr) : "memory" );
-}
-
-/* gusa is a hack in the kernel which lets you create a sequence of instructions
- * which will be restarted if the process is preempted in the middle of the
- * sequence. It will do for implementing atomics on non-smp systems. ABI is:
- * r0  = address of first instruction after the atomic sequence
- * r1  = original stack pointer
- * r15 = -1 * length of atomic sequence in bytes
- */
-#define GUSA_CLOBBERS   "r0", "r1", "memory"
-#define GUSA_START(mem,old,nop)    \
-	"	.align 2\n"                \
-	"	mova 1f, r0\n"             \
-	nop                            \
-	"	mov r15, r1\n"             \
-	"	mov #(0f-1f), r15\n"       \
-	"0:	mov.l @" mem ", " old "\n"
-/* the target of mova must be 4 byte aligned, so we may need a nop */
-#define GUSA_START_ODD(mem,old)  GUSA_START(mem,old,"")
-#define GUSA_START_EVEN(mem,old) GUSA_START(mem,old,"\tnop\n")
-#define GUSA_END(mem,new)          \
-	"	mov.l " new ", @" mem "\n" \
-	"1:	mov r1, r15\n"
-
-int __sh_cas(volatile int *p, int t, int s)
-{
-	if (__sh_atomic_model == SH_A_LLSC) return __sh_cas_llsc(p, t, s);
-
-	if (__sh_atomic_model == SH_A_IMASK) {
-		unsigned sr = mask();
-		int old = *p;
-		if (old==t) *p = s;
-		unmask(sr);
-		return old;
-	}
-
-	int old;
-	__asm__ __volatile__(
-		GUSA_START_EVEN("%1", "%0")
-		"	cmp/eq %0, %2\n"
-		"	bf 1f\n"
-		GUSA_END("%1", "%3")
-		: "=&r"(old) : "r"(p), "r"(t), "r"(s) : GUSA_CLOBBERS, "t");
-	return old;
-}
-
-int __sh_swap(volatile int *x, int v)
-{
-	if (__sh_atomic_model == SH_A_LLSC) return __sh_swap_llsc(x, v);
-
-	if (__sh_atomic_model == SH_A_IMASK) {
-		unsigned sr = mask();
-		int old = *x;
-		*x = v;
-		unmask(sr);
-		return old;
-	}
-
-	int old;
-	__asm__ __volatile__(
-		GUSA_START_EVEN("%1", "%0")
-		GUSA_END("%1", "%2")
-		: "=&r"(old) : "r"(x), "r"(v) : GUSA_CLOBBERS);
-	return old;
-}
-
-int __sh_fetch_add(volatile int *x, int v)
-{
-	if (__sh_atomic_model == SH_A_LLSC) return __sh_fetch_add_llsc(x, v);
-
-	if (__sh_atomic_model == SH_A_IMASK) {
-		unsigned sr = mask();
-		int old = *x;
-		*x = old + v;
-		unmask(sr);
-		return old;
-	}
-
-	int old, dummy;
-	__asm__ __volatile__(
-		GUSA_START_EVEN("%2", "%0")
-		"	mov %0, %1\n"
-		"	add %3, %1\n"
-		GUSA_END("%2", "%1")
-		: "=&r"(old), "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
-	return old;
-}
-
-void __sh_store(volatile int *p, int x)
-{
-	if (__sh_atomic_model == SH_A_LLSC) return __sh_store_llsc(p, x);
-	__asm__ __volatile__(
-		"	mov.l %1, @%0\n"
-		: : "r"(p), "r"(x) : "memory");
-}
-
-void __sh_and(volatile int *x, int v)
-{
-	if (__sh_atomic_model == SH_A_LLSC) return __sh_and_llsc(x, v);
-
-	if (__sh_atomic_model == SH_A_IMASK) {
-		unsigned sr = mask();
-		int old = *x;
-		*x = old & v;
-		unmask(sr);
-		return;
-	}
-
-	int dummy;
-	__asm__ __volatile__(
-		GUSA_START_ODD("%1", "%0")
-		"	and %2, %0\n"
-		GUSA_END("%1", "%0")
-		: "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
-}
-
-void __sh_or(volatile int *x, int v)
-{
-	if (__sh_atomic_model == SH_A_LLSC) return __sh_or_llsc(x, v);
-
-	if (__sh_atomic_model == SH_A_IMASK) {
-		unsigned sr = mask();
-		int old = *x;
-		*x = old | v;
-		unmask(sr);
-		return;
-	}
-
-	int dummy;
-	__asm__ __volatile__(
-		GUSA_START_ODD("%1", "%0")
-		"	or %2, %0\n"
-		GUSA_END("%1", "%0")
-		: "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
-}
-
-#endif
diff --git a/arch/sh/src/sh_atomic.h b/arch/sh/src/sh_atomic.h
deleted file mode 100644
index 054c2a3..0000000
--- a/arch/sh/src/sh_atomic.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _SH_ATOMIC_H
-#define _SH_ATOMIC_H
-
-#define SH_A_GUSA 0
-#define SH_A_LLSC 1
-#define SH_A_CAS 2
-#if !defined(__SH3__) && !defined(__SH4__)
-#define SH_A_IMASK 3
-#else
-#define SH_A_IMASK -1LL /* unmatchable by unsigned int */
-#endif
-
-extern __attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model;
-
-#endif
diff --git a/arch/x32/atomic.h b/arch/x32/atomic.h
deleted file mode 100644
index 7690183..0000000
--- a/arch/x32/atomic.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_64(uint64_t x)
-{
-	__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
-	return x;
-}
-
-static inline int a_ctz_l(unsigned long x)
-{
-	__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
-	return x;
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	__asm__( "lock ; and %1, %0"
-			 : "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	__asm__( "lock ; or %1, %0"
-			 : "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	__asm__( "lock ; or %1, %0"
-		: "=m"(*(long *)p) : "r"(v) : "memory" );
-}
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	__asm__( "lock ; cmpxchg %3, %1"
-		: "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
-	return t;
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	__asm__( "lock ; cmpxchg %3, %1"
-		: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
-	return t;
-}
-
-static inline void a_or(volatile int *p, int v)
-{
-	__asm__( "lock ; or %1, %0"
-		: "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline void a_and(volatile int *p, int v)
-{
-	__asm__( "lock ; and %1, %0"
-		: "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	__asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
-	return v;
-}
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	__asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
-	return v;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	__asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
-}
-
-static inline void a_dec(volatile int *x)
-{
-	__asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	__asm__( "mov %1, %0 ; lock ; orl $0,(%%rsp)" : "=m"(*p) : "r"(x) : "memory" );
-}
-
-static inline void a_spin()
-{
-	__asm__ __volatile__( "pause" : : : "memory" );
-}
-
-static inline void a_barrier()
-{
-	__asm__ __volatile__( "" : : : "memory" );
-}
-
-static inline void a_crash()
-{
-	__asm__ __volatile__( "hlt" : : : "memory" );
-}
-
-
-#endif
diff --git a/arch/x32/atomic_arch.h b/arch/x32/atomic_arch.h
new file mode 100644
index 0000000..26098d3
--- /dev/null
+++ b/arch/x32/atomic_arch.h
@@ -0,0 +1,114 @@
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	__asm__ __volatile__ (
+		"lock ; cmpxchg %3, %1"
+		: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
+	return t;
+}
+
+#define a_swap a_swap
+static inline int a_swap(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"xchg %0, %1"
+		: "=r"(v), "=m"(*p) : "0"(v) : "memory" );
+	return v;
+}
+
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"lock ; xadd %0, %1"
+		: "=r"(v), "=m"(*p) : "0"(v) : "memory" );
+	return v;
+}
+
+#define a_and a_and
+static inline void a_and(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"lock ; and %1, %0"
+		: "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_or a_or
+static inline void a_or(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"lock ; or %1, %0"
+		: "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_and_64 a_and_64
+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
+{
+	__asm__ __volatile(
+		"lock ; and %1, %0"
+		 : "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_or_64 a_or_64
+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
+{
+	__asm__ __volatile__(
+		"lock ; or %1, %0"
+		 : "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_inc a_inc
+static inline void a_inc(volatile int *p)
+{
+	__asm__ __volatile__(
+		"lock ; incl %0"
+		: "=m"(*p) : "m"(*p) : "memory" );
+}
+
+#define a_dec a_dec
+static inline void a_dec(volatile int *p)
+{
+	__asm__ __volatile__(
+		"lock ; decl %0"
+		: "=m"(*p) : "m"(*p) : "memory" );
+}
+
+#define a_store a_store
+static inline void a_store(volatile int *p, int x)
+{
+	__asm__ __volatile__(
+		"mov %1, %0 ; lock ; orl $0,(%%rsp)"
+		: "=m"(*p) : "r"(x) : "memory" );
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__( "" : : : "memory" );
+}
+
+#define a_pause a_pause
+static inline void a_spin()
+{
+	__asm__ __volatile__( "pause" : : : "memory" );
+}
+
+#define a_crash a_crash
+static inline void a_crash()
+{
+	__asm__ __volatile__( "hlt" : : : "memory" );
+}
+
+#define a_ctz_64 a_ctz_64
+static inline int a_ctz_64(uint64_t x)
+{
+	__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
+	return x;
+}
+
+#define a_ctz_l a_ctz_l
+static inline int a_ctz_l(unsigned long x)
+{
+	__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
+	return x;
+}
diff --git a/arch/x32/bits/errno.h b/arch/x32/bits/errno.h
deleted file mode 100644
index d2e1eee..0000000
--- a/arch/x32/bits/errno.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#define EPERM            1
-#define ENOENT           2
-#define ESRCH            3
-#define EINTR            4
-#define EIO              5
-#define ENXIO            6
-#define E2BIG            7
-#define ENOEXEC          8
-#define EBADF            9
-#define ECHILD          10
-#define EAGAIN          11
-#define ENOMEM          12
-#define EACCES          13
-#define EFAULT          14
-#define ENOTBLK         15
-#define EBUSY           16
-#define EEXIST          17
-#define EXDEV           18
-#define ENODEV          19
-#define ENOTDIR         20
-#define EISDIR          21
-#define EINVAL          22
-#define ENFILE          23
-#define EMFILE          24
-#define ENOTTY          25
-#define ETXTBSY         26
-#define EFBIG           27
-#define ENOSPC          28
-#define ESPIPE          29
-#define EROFS           30
-#define EMLINK          31
-#define EPIPE           32
-#define EDOM            33
-#define ERANGE          34
-#define EDEADLK         35
-#define ENAMETOOLONG    36
-#define ENOLCK          37
-#define ENOSYS          38
-#define ENOTEMPTY       39
-#define ELOOP           40
-#define EWOULDBLOCK     EAGAIN
-#define ENOMSG          42
-#define EIDRM           43
-#define ECHRNG          44
-#define EL2NSYNC        45
-#define EL3HLT          46
-#define EL3RST          47
-#define ELNRNG          48
-#define EUNATCH         49
-#define ENOCSI          50
-#define EL2HLT          51
-#define EBADE           52
-#define EBADR           53
-#define EXFULL          54
-#define ENOANO          55
-#define EBADRQC         56
-#define EBADSLT         57
-#define EDEADLOCK       EDEADLK
-#define EBFONT          59
-#define ENOSTR          60
-#define ENODATA         61
-#define ETIME           62
-#define ENOSR           63
-#define ENONET          64
-#define ENOPKG          65
-#define EREMOTE         66
-#define ENOLINK         67
-#define EADV            68
-#define ESRMNT          69
-#define ECOMM           70
-#define EPROTO          71
-#define EMULTIHOP       72
-#define EDOTDOT         73
-#define EBADMSG         74
-#define EOVERFLOW       75
-#define ENOTUNIQ        76
-#define EBADFD          77
-#define EREMCHG         78
-#define ELIBACC         79
-#define ELIBBAD         80
-#define ELIBSCN         81
-#define ELIBMAX         82
-#define ELIBEXEC        83
-#define EILSEQ          84
-#define ERESTART        85
-#define ESTRPIPE        86
-#define EUSERS          87
-#define ENOTSOCK        88
-#define EDESTADDRREQ    89
-#define EMSGSIZE        90
-#define EPROTOTYPE      91
-#define ENOPROTOOPT     92
-#define EPROTONOSUPPORT 93
-#define ESOCKTNOSUPPORT 94
-#define EOPNOTSUPP      95
-#define ENOTSUP         EOPNOTSUPP
-#define EPFNOSUPPORT    96
-#define EAFNOSUPPORT    97
-#define EADDRINUSE      98
-#define EADDRNOTAVAIL   99
-#define ENETDOWN        100
-#define ENETUNREACH     101
-#define ENETRESET       102
-#define ECONNABORTED    103
-#define ECONNRESET      104
-#define ENOBUFS         105
-#define EISCONN         106
-#define ENOTCONN        107
-#define ESHUTDOWN       108
-#define ETOOMANYREFS    109
-#define ETIMEDOUT       110
-#define ECONNREFUSED    111
-#define EHOSTDOWN       112
-#define EHOSTUNREACH    113
-#define EALREADY        114
-#define EINPROGRESS     115
-#define ESTALE          116
-#define EUCLEAN         117
-#define ENOTNAM         118
-#define ENAVAIL         119
-#define EISNAM          120
-#define EREMOTEIO       121
-#define EDQUOT          122
-#define ENOMEDIUM       123
-#define EMEDIUMTYPE     124
-#define ECANCELED       125
-#define ENOKEY          126
-#define EKEYEXPIRED     127
-#define EKEYREVOKED     128
-#define EKEYREJECTED    129
-#define EOWNERDEAD      130
-#define ENOTRECOVERABLE 131
-#define ERFKILL         132
-#define EHWPOISON       133
diff --git a/arch/x32/bits/mman.h b/arch/x32/bits/mman.h
index 846b7ea..f3235f4 100644
--- a/arch/x32/bits/mman.h
+++ b/arch/x32/bits/mman.h
@@ -38,6 +38,7 @@
 
 #define MCL_CURRENT     1
 #define MCL_FUTURE      2
+#define MCL_ONFAULT     4
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/x32/bits/poll.h b/arch/x32/bits/poll.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/x32/bits/poll.h
+++ /dev/null
diff --git a/arch/x32/bits/resource.h b/arch/x32/bits/resource.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/x32/bits/resource.h
+++ /dev/null
diff --git a/arch/x32/bits/sem.h b/arch/x32/bits/sem.h
deleted file mode 100644
index c629b81..0000000
--- a/arch/x32/bits/sem.h
+++ /dev/null
@@ -1,16 +0,0 @@
-struct semid_ds {
-	struct ipc_perm sem_perm;
-	time_t sem_otime;
-	time_t __unused1;
-	time_t sem_ctime;
-	time_t __unused2;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-	unsigned short sem_nsems;
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-#else
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-	unsigned short sem_nsems;
-#endif
-	time_t __unused3;
-	time_t __unused4;
-};
diff --git a/arch/x32/bits/stdarg.h b/arch/x32/bits/stdarg.h
deleted file mode 100644
index fde3781..0000000
--- a/arch/x32/bits/stdarg.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define va_start(v,l)   __builtin_va_start(v,l)
-#define va_end(v)       __builtin_va_end(v)
-#define va_arg(v,l)     __builtin_va_arg(v,l)
-#define va_copy(d,s)    __builtin_va_copy(d,s)
diff --git a/arch/x32/bits/syscall.h b/arch/x32/bits/syscall.h
index 5a6d4d1..4a1099d 100644
--- a/arch/x32/bits/syscall.h
+++ b/arch/x32/bits/syscall.h
@@ -277,6 +277,9 @@
 #define __NR_memfd_create (__X32_SYSCALL_BIT + 319)
 #define __NR_kexec_file_load (__X32_SYSCALL_BIT + 320)
 #define __NR_bpf (__X32_SYSCALL_BIT + 321)
+#define __NR_userfaultfd (__X32_SYSCALL_BIT + 323)
+#define __NR_membarrier (__X32_SYSCALL_BIT + 324)
+#define __NR_mlock2 (__X32_SYSCALL_BIT + 325)
 
 #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
 #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
@@ -607,6 +610,9 @@
 #define SYS_memfd_create __NR_memfd_create
 #define SYS_kexec_file_load __NR_kexec_file_load
 #define SYS_bpf __NR_bpf
+#define SYS_userfaultfd __NR_userfaultfd
+#define SYS_membarrier __NR_membarrier
+#define SYS_mlock2 __NR_mlock2
 
 
 #define SYS_rt_sigaction __NR_rt_sigaction
diff --git a/arch/x32/bits/termios.h b/arch/x32/bits/termios.h
deleted file mode 100644
index f0d81b1..0000000
--- a/arch/x32/bits/termios.h
+++ /dev/null
@@ -1,160 +0,0 @@
-struct termios
-{
-	tcflag_t c_iflag;
-	tcflag_t c_oflag;
-	tcflag_t c_cflag;
-	tcflag_t c_lflag;
-	cc_t c_line;
-	cc_t c_cc[NCCS];
-	speed_t __c_ispeed;
-	speed_t __c_ospeed;
-};
-
-#define VINTR     0
-#define VQUIT     1
-#define VERASE    2
-#define VKILL     3
-#define VEOF      4
-#define VTIME     5
-#define VMIN      6
-#define VSWTC     7
-#define VSTART    8
-#define VSTOP     9
-#define VSUSP    10
-#define VEOL     11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE  14
-#define VLNEXT   15
-#define VEOL2    16
-
-#define IGNBRK  0000001
-#define BRKINT  0000002
-#define IGNPAR  0000004
-#define PARMRK  0000010
-#define INPCK   0000020
-#define ISTRIP  0000040
-#define INLCR   0000100
-#define IGNCR   0000200
-#define ICRNL   0000400
-#define IUCLC   0001000
-#define IXON    0002000
-#define IXANY   0004000
-#define IXOFF   0010000
-#define IMAXBEL 0020000
-#define IUTF8   0040000
-
-#define OPOST  0000001
-#define OLCUC  0000002
-#define ONLCR  0000004
-#define OCRNL  0000010
-#define ONOCR  0000020
-#define ONLRET 0000040
-#define OFILL  0000100
-#define OFDEL  0000200
-#define NLDLY  0000400
-#define NL0    0000000
-#define NL1    0000400
-#define CRDLY  0003000
-#define CR0    0000000
-#define CR1    0001000
-#define CR2    0002000
-#define CR3    0003000
-#define TABDLY 0014000
-#define TAB0   0000000
-#define TAB1   0004000
-#define TAB2   0010000
-#define TAB3   0014000
-#define BSDLY  0020000
-#define BS0    0000000
-#define BS1    0020000
-#define FFDLY  0100000
-#define FF0    0000000
-#define FF1    0100000
-
-#define VTDLY  0040000
-#define VT0    0000000
-#define VT1    0040000
-
-#define B0       0000000
-#define B50      0000001
-#define B75      0000002
-#define B110     0000003
-#define B134     0000004
-#define B150     0000005
-#define B200     0000006
-#define B300     0000007
-#define B600     0000010
-#define B1200    0000011
-#define B1800    0000012
-#define B2400    0000013
-#define B4800    0000014
-#define B9600    0000015
-#define B19200   0000016
-#define B38400   0000017
-
-#define B57600   0010001
-#define B115200  0010002
-#define B230400  0010003
-#define B460800  0010004
-#define B500000  0010005
-#define B576000  0010006
-#define B921600  0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-
-#define CBAUD    0010017
-
-#define CSIZE  0000060
-#define CS5    0000000
-#define CS6    0000020
-#define CS7    0000040
-#define CS8    0000060
-#define CSTOPB 0000100
-#define CREAD  0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL  0002000
-#define CLOCAL 0004000
-
-#define ISIG   0000001
-#define ICANON 0000002
-#define ECHO   0000010
-#define ECHOE  0000020
-#define ECHOK  0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define IEXTEN 0100000
-
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-
-#define TCOOFF 0
-#define TCOON  1
-#define TCIOFF 2
-#define TCION  3
-
-#define TCIFLUSH  0
-#define TCOFLUSH  1
-#define TCIOFLUSH 2
-
-#define TCSANOW   0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define CBAUDEX 0010000
-#define CRTSCTS  020000000000
-#define EXTPROC 0200000
-#define XTABS  0014000
-#endif
diff --git a/arch/x32/pthread_arch.h b/arch/x32/pthread_arch.h
index 033bfd6..ecb0bbf 100644
--- a/arch/x32/pthread_arch.h
+++ b/arch/x32/pthread_arch.h
@@ -7,6 +7,6 @@
 
 #define TP_ADJ(p) (p)
 
-#define CANCEL_REG_IP 32
+#define MC_PC gregs[REG_RIP]
 
 #define CANARY canary2
diff --git a/arch/x86_64/atomic.h b/arch/x86_64/atomic.h
deleted file mode 100644
index 7690183..0000000
--- a/arch/x86_64/atomic.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef _INTERNAL_ATOMIC_H
-#define _INTERNAL_ATOMIC_H
-
-#include <stdint.h>
-
-static inline int a_ctz_64(uint64_t x)
-{
-	__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
-	return x;
-}
-
-static inline int a_ctz_l(unsigned long x)
-{
-	__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
-	return x;
-}
-
-static inline void a_and_64(volatile uint64_t *p, uint64_t v)
-{
-	__asm__( "lock ; and %1, %0"
-			 : "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline void a_or_64(volatile uint64_t *p, uint64_t v)
-{
-	__asm__( "lock ; or %1, %0"
-			 : "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline void a_or_l(volatile void *p, long v)
-{
-	__asm__( "lock ; or %1, %0"
-		: "=m"(*(long *)p) : "r"(v) : "memory" );
-}
-
-static inline void *a_cas_p(volatile void *p, void *t, void *s)
-{
-	__asm__( "lock ; cmpxchg %3, %1"
-		: "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
-	return t;
-}
-
-static inline int a_cas(volatile int *p, int t, int s)
-{
-	__asm__( "lock ; cmpxchg %3, %1"
-		: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
-	return t;
-}
-
-static inline void a_or(volatile int *p, int v)
-{
-	__asm__( "lock ; or %1, %0"
-		: "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline void a_and(volatile int *p, int v)
-{
-	__asm__( "lock ; and %1, %0"
-		: "=m"(*p) : "r"(v) : "memory" );
-}
-
-static inline int a_swap(volatile int *x, int v)
-{
-	__asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
-	return v;
-}
-
-static inline int a_fetch_add(volatile int *x, int v)
-{
-	__asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
-	return v;
-}
-
-static inline void a_inc(volatile int *x)
-{
-	__asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
-}
-
-static inline void a_dec(volatile int *x)
-{
-	__asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
-}
-
-static inline void a_store(volatile int *p, int x)
-{
-	__asm__( "mov %1, %0 ; lock ; orl $0,(%%rsp)" : "=m"(*p) : "r"(x) : "memory" );
-}
-
-static inline void a_spin()
-{
-	__asm__ __volatile__( "pause" : : : "memory" );
-}
-
-static inline void a_barrier()
-{
-	__asm__ __volatile__( "" : : : "memory" );
-}
-
-static inline void a_crash()
-{
-	__asm__ __volatile__( "hlt" : : : "memory" );
-}
-
-
-#endif
diff --git a/arch/x86_64/atomic_arch.h b/arch/x86_64/atomic_arch.h
new file mode 100644
index 0000000..9f47f80
--- /dev/null
+++ b/arch/x86_64/atomic_arch.h
@@ -0,0 +1,116 @@
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	__asm__ __volatile__ (
+		"lock ; cmpxchg %3, %1"
+		: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
+	return t;
+}
+
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	__asm__( "lock ; cmpxchg %3, %1"
+		: "=a"(t), "=m"(*(void *volatile *)p)
+		: "a"(t), "r"(s) : "memory" );
+	return t;
+}
+
+#define a_swap a_swap
+static inline int a_swap(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"xchg %0, %1"
+		: "=r"(v), "=m"(*p) : "0"(v) : "memory" );
+	return v;
+}
+
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"lock ; xadd %0, %1"
+		: "=r"(v), "=m"(*p) : "0"(v) : "memory" );
+	return v;
+}
+
+#define a_and a_and
+static inline void a_and(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"lock ; and %1, %0"
+		: "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_or a_or
+static inline void a_or(volatile int *p, int v)
+{
+	__asm__ __volatile__(
+		"lock ; or %1, %0"
+		: "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_and_64 a_and_64
+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
+{
+	__asm__ __volatile(
+		"lock ; and %1, %0"
+		 : "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_or_64 a_or_64
+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
+{
+	__asm__ __volatile__(
+		"lock ; or %1, %0"
+		 : "=m"(*p) : "r"(v) : "memory" );
+}
+
+#define a_inc a_inc
+static inline void a_inc(volatile int *p)
+{
+	__asm__ __volatile__(
+		"lock ; incl %0"
+		: "=m"(*p) : "m"(*p) : "memory" );
+}
+
+#define a_dec a_dec
+static inline void a_dec(volatile int *p)
+{
+	__asm__ __volatile__(
+		"lock ; decl %0"
+		: "=m"(*p) : "m"(*p) : "memory" );
+}
+
+#define a_store a_store
+static inline void a_store(volatile int *p, int x)
+{
+	__asm__ __volatile__(
+		"mov %1, %0 ; lock ; orl $0,(%%rsp)"
+		: "=m"(*p) : "r"(x) : "memory" );
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__( "" : : : "memory" );
+}
+
+#define a_pause a_pause
+static inline void a_spin()
+{
+	__asm__ __volatile__( "pause" : : : "memory" );
+}
+
+#define a_crash a_crash
+static inline void a_crash()
+{
+	__asm__ __volatile__( "hlt" : : : "memory" );
+}
+
+#define a_ctz_64 a_ctz_64
+static inline int a_ctz_64(uint64_t x)
+{
+	__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
+	return x;
+}
diff --git a/arch/x86_64/bits/errno.h b/arch/x86_64/bits/errno.h
deleted file mode 100644
index d2e1eee..0000000
--- a/arch/x86_64/bits/errno.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#define EPERM            1
-#define ENOENT           2
-#define ESRCH            3
-#define EINTR            4
-#define EIO              5
-#define ENXIO            6
-#define E2BIG            7
-#define ENOEXEC          8
-#define EBADF            9
-#define ECHILD          10
-#define EAGAIN          11
-#define ENOMEM          12
-#define EACCES          13
-#define EFAULT          14
-#define ENOTBLK         15
-#define EBUSY           16
-#define EEXIST          17
-#define EXDEV           18
-#define ENODEV          19
-#define ENOTDIR         20
-#define EISDIR          21
-#define EINVAL          22
-#define ENFILE          23
-#define EMFILE          24
-#define ENOTTY          25
-#define ETXTBSY         26
-#define EFBIG           27
-#define ENOSPC          28
-#define ESPIPE          29
-#define EROFS           30
-#define EMLINK          31
-#define EPIPE           32
-#define EDOM            33
-#define ERANGE          34
-#define EDEADLK         35
-#define ENAMETOOLONG    36
-#define ENOLCK          37
-#define ENOSYS          38
-#define ENOTEMPTY       39
-#define ELOOP           40
-#define EWOULDBLOCK     EAGAIN
-#define ENOMSG          42
-#define EIDRM           43
-#define ECHRNG          44
-#define EL2NSYNC        45
-#define EL3HLT          46
-#define EL3RST          47
-#define ELNRNG          48
-#define EUNATCH         49
-#define ENOCSI          50
-#define EL2HLT          51
-#define EBADE           52
-#define EBADR           53
-#define EXFULL          54
-#define ENOANO          55
-#define EBADRQC         56
-#define EBADSLT         57
-#define EDEADLOCK       EDEADLK
-#define EBFONT          59
-#define ENOSTR          60
-#define ENODATA         61
-#define ETIME           62
-#define ENOSR           63
-#define ENONET          64
-#define ENOPKG          65
-#define EREMOTE         66
-#define ENOLINK         67
-#define EADV            68
-#define ESRMNT          69
-#define ECOMM           70
-#define EPROTO          71
-#define EMULTIHOP       72
-#define EDOTDOT         73
-#define EBADMSG         74
-#define EOVERFLOW       75
-#define ENOTUNIQ        76
-#define EBADFD          77
-#define EREMCHG         78
-#define ELIBACC         79
-#define ELIBBAD         80
-#define ELIBSCN         81
-#define ELIBMAX         82
-#define ELIBEXEC        83
-#define EILSEQ          84
-#define ERESTART        85
-#define ESTRPIPE        86
-#define EUSERS          87
-#define ENOTSOCK        88
-#define EDESTADDRREQ    89
-#define EMSGSIZE        90
-#define EPROTOTYPE      91
-#define ENOPROTOOPT     92
-#define EPROTONOSUPPORT 93
-#define ESOCKTNOSUPPORT 94
-#define EOPNOTSUPP      95
-#define ENOTSUP         EOPNOTSUPP
-#define EPFNOSUPPORT    96
-#define EAFNOSUPPORT    97
-#define EADDRINUSE      98
-#define EADDRNOTAVAIL   99
-#define ENETDOWN        100
-#define ENETUNREACH     101
-#define ENETRESET       102
-#define ECONNABORTED    103
-#define ECONNRESET      104
-#define ENOBUFS         105
-#define EISCONN         106
-#define ENOTCONN        107
-#define ESHUTDOWN       108
-#define ETOOMANYREFS    109
-#define ETIMEDOUT       110
-#define ECONNREFUSED    111
-#define EHOSTDOWN       112
-#define EHOSTUNREACH    113
-#define EALREADY        114
-#define EINPROGRESS     115
-#define ESTALE          116
-#define EUCLEAN         117
-#define ENOTNAM         118
-#define ENAVAIL         119
-#define EISNAM          120
-#define EREMOTEIO       121
-#define EDQUOT          122
-#define ENOMEDIUM       123
-#define EMEDIUMTYPE     124
-#define ECANCELED       125
-#define ENOKEY          126
-#define EKEYEXPIRED     127
-#define EKEYREVOKED     128
-#define EKEYREJECTED    129
-#define EOWNERDEAD      130
-#define ENOTRECOVERABLE 131
-#define ERFKILL         132
-#define EHWPOISON       133
diff --git a/arch/x86_64/bits/mman.h b/arch/x86_64/bits/mman.h
index 846b7ea..f3235f4 100644
--- a/arch/x86_64/bits/mman.h
+++ b/arch/x86_64/bits/mman.h
@@ -38,6 +38,7 @@
 
 #define MCL_CURRENT     1
 #define MCL_FUTURE      2
+#define MCL_ONFAULT     4
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define MADV_NORMAL      0
diff --git a/arch/x86_64/bits/poll.h b/arch/x86_64/bits/poll.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/x86_64/bits/poll.h
+++ /dev/null
diff --git a/arch/x86_64/bits/resource.h b/arch/x86_64/bits/resource.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/x86_64/bits/resource.h
+++ /dev/null
diff --git a/arch/x86_64/bits/sem.h b/arch/x86_64/bits/sem.h
deleted file mode 100644
index c629b81..0000000
--- a/arch/x86_64/bits/sem.h
+++ /dev/null
@@ -1,16 +0,0 @@
-struct semid_ds {
-	struct ipc_perm sem_perm;
-	time_t sem_otime;
-	time_t __unused1;
-	time_t sem_ctime;
-	time_t __unused2;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-	unsigned short sem_nsems;
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-#else
-	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
-	unsigned short sem_nsems;
-#endif
-	time_t __unused3;
-	time_t __unused4;
-};
diff --git a/arch/x86_64/bits/statfs.h b/arch/x86_64/bits/statfs.h
deleted file mode 100644
index f103f4e..0000000
--- a/arch/x86_64/bits/statfs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct statfs {
-	unsigned long f_type, f_bsize;
-	fsblkcnt_t f_blocks, f_bfree, f_bavail;
-	fsfilcnt_t f_files, f_ffree;
-	fsid_t f_fsid;
-	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
-};
diff --git a/arch/x86_64/bits/stdarg.h b/arch/x86_64/bits/stdarg.h
deleted file mode 100644
index fde3781..0000000
--- a/arch/x86_64/bits/stdarg.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define va_start(v,l)   __builtin_va_start(v,l)
-#define va_end(v)       __builtin_va_end(v)
-#define va_arg(v,l)     __builtin_va_arg(v,l)
-#define va_copy(d,s)    __builtin_va_copy(d,s)
diff --git a/arch/x86_64/bits/syscall.h b/arch/x86_64/bits/syscall.h
index 96ec51f..22aa716 100644
--- a/arch/x86_64/bits/syscall.h
+++ b/arch/x86_64/bits/syscall.h
@@ -321,6 +321,9 @@
 #define __NR_kexec_file_load			320
 #define __NR_bpf				321
 #define __NR_execveat				322
+#define __NR_userfaultfd			323
+#define __NR_membarrier				324
+#define __NR_mlock2				325
 
 
 
@@ -649,3 +652,6 @@
 #define SYS_kexec_file_load			320
 #define SYS_bpf					321
 #define SYS_execveat				322
+#define SYS_userfaultfd				323
+#define SYS_membarrier				324
+#define SYS_mlock2				325
diff --git a/arch/x86_64/bits/termios.h b/arch/x86_64/bits/termios.h
deleted file mode 100644
index f0d81b1..0000000
--- a/arch/x86_64/bits/termios.h
+++ /dev/null
@@ -1,160 +0,0 @@
-struct termios
-{
-	tcflag_t c_iflag;
-	tcflag_t c_oflag;
-	tcflag_t c_cflag;
-	tcflag_t c_lflag;
-	cc_t c_line;
-	cc_t c_cc[NCCS];
-	speed_t __c_ispeed;
-	speed_t __c_ospeed;
-};
-
-#define VINTR     0
-#define VQUIT     1
-#define VERASE    2
-#define VKILL     3
-#define VEOF      4
-#define VTIME     5
-#define VMIN      6
-#define VSWTC     7
-#define VSTART    8
-#define VSTOP     9
-#define VSUSP    10
-#define VEOL     11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE  14
-#define VLNEXT   15
-#define VEOL2    16
-
-#define IGNBRK  0000001
-#define BRKINT  0000002
-#define IGNPAR  0000004
-#define PARMRK  0000010
-#define INPCK   0000020
-#define ISTRIP  0000040
-#define INLCR   0000100
-#define IGNCR   0000200
-#define ICRNL   0000400
-#define IUCLC   0001000
-#define IXON    0002000
-#define IXANY   0004000
-#define IXOFF   0010000
-#define IMAXBEL 0020000
-#define IUTF8   0040000
-
-#define OPOST  0000001
-#define OLCUC  0000002
-#define ONLCR  0000004
-#define OCRNL  0000010
-#define ONOCR  0000020
-#define ONLRET 0000040
-#define OFILL  0000100
-#define OFDEL  0000200
-#define NLDLY  0000400
-#define NL0    0000000
-#define NL1    0000400
-#define CRDLY  0003000
-#define CR0    0000000
-#define CR1    0001000
-#define CR2    0002000
-#define CR3    0003000
-#define TABDLY 0014000
-#define TAB0   0000000
-#define TAB1   0004000
-#define TAB2   0010000
-#define TAB3   0014000
-#define BSDLY  0020000
-#define BS0    0000000
-#define BS1    0020000
-#define FFDLY  0100000
-#define FF0    0000000
-#define FF1    0100000
-
-#define VTDLY  0040000
-#define VT0    0000000
-#define VT1    0040000
-
-#define B0       0000000
-#define B50      0000001
-#define B75      0000002
-#define B110     0000003
-#define B134     0000004
-#define B150     0000005
-#define B200     0000006
-#define B300     0000007
-#define B600     0000010
-#define B1200    0000011
-#define B1800    0000012
-#define B2400    0000013
-#define B4800    0000014
-#define B9600    0000015
-#define B19200   0000016
-#define B38400   0000017
-
-#define B57600   0010001
-#define B115200  0010002
-#define B230400  0010003
-#define B460800  0010004
-#define B500000  0010005
-#define B576000  0010006
-#define B921600  0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-
-#define CBAUD    0010017
-
-#define CSIZE  0000060
-#define CS5    0000000
-#define CS6    0000020
-#define CS7    0000040
-#define CS8    0000060
-#define CSTOPB 0000100
-#define CREAD  0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL  0002000
-#define CLOCAL 0004000
-
-#define ISIG   0000001
-#define ICANON 0000002
-#define ECHO   0000010
-#define ECHOE  0000020
-#define ECHOK  0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define IEXTEN 0100000
-
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-
-#define TCOOFF 0
-#define TCOON  1
-#define TCIOFF 2
-#define TCION  3
-
-#define TCIFLUSH  0
-#define TCOFLUSH  1
-#define TCIOFLUSH 2
-
-#define TCSANOW   0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-#define CBAUDEX 0010000
-#define CRTSCTS  020000000000
-#define EXTPROC 0200000
-#define XTABS  0014000
-#endif
diff --git a/arch/x86_64/pthread_arch.h b/arch/x86_64/pthread_arch.h
index 29e4590..c61509c 100644
--- a/arch/x86_64/pthread_arch.h
+++ b/arch/x86_64/pthread_arch.h
@@ -7,4 +7,4 @@
 
 #define TP_ADJ(p) (p)
 
-#define CANCEL_REG_IP 16
+#define MC_PC gregs[REG_RIP]
diff --git a/configure b/configure
index 03c0ebe..248c450 100755
--- a/configure
+++ b/configure
@@ -9,6 +9,9 @@
 
 Defaults for the options are specified in brackets.
 
+Configuration:
+  --srcdir=DIR            source directory [detected]
+
 Installation directories:
   --prefix=PREFIX         main installation prefix [/usr/local/musl]
   --exec-prefix=EPREFIX   installation prefix for executable files [PREFIX]
@@ -117,6 +120,7 @@
 LDFLAGS_AUTO=
 LDFLAGS_TRY=
 OPTIMIZE_GLOBS=
+srcdir=
 prefix=/usr/local/musl
 exec_prefix='$(prefix)'
 bindir='$(exec_prefix)/bin'
@@ -138,7 +142,8 @@
 
 for arg ; do
 case "$arg" in
---help) usage ;;
+--help|-h) usage ;;
+--srcdir=*) srcdir=${arg#*=} ;;
 --prefix=*) prefix=${arg#*=} ;;
 --exec-prefix=*) exec_prefix=${arg#*=} ;;
 --bindir=*) bindir=${arg#*=} ;;
@@ -179,11 +184,23 @@
 esac
 done
 
-for i in prefix exec_prefix bindir libdir includedir syslibdir ; do
+for i in srcdir prefix exec_prefix bindir libdir includedir syslibdir ; do
 stripdir $i
 done
 
 #
+# Get the source dir for out-of-tree builds
+#
+if test -z "$srcdir" ; then
+srcdir="${0%/configure}"
+stripdir srcdir
+fi
+abs_builddir="$(pwd)" || fail "$0: cannot determine working directory"
+abs_srcdir="$(cd $srcdir && pwd)" || fail "$0: invalid source directory $srcdir"
+test "$abs_srcdir" = "$abs_builddir" && srcdir=.
+test "$srcdir" != "." -a -f Makefile -a ! -h Makefile && fail "$0: Makefile already exists in the working directory"
+
+#
 # Get a temp filename we can use
 #
 i=0
@@ -263,11 +280,11 @@
 fi
 
 if test "$gcc_wrapper" = yes ; then
-tools="$tools tools/musl-gcc"
+tools="$tools obj/musl-gcc"
 tool_libs="$tool_libs lib/musl-gcc.specs"
 fi
 if test "$clang_wrapper" = yes ; then
-tools="$tools tools/musl-clang tools/ld.musl-clang"
+tools="$tools obj/musl-clang obj/ld.musl-clang"
 fi
 
 #
@@ -321,7 +338,7 @@
 #endif
 x;
 EOF
-if $CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include $CPPFLAGS $CFLAGS \
+if $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS \
   -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
 printf "no\n"
 else
@@ -330,6 +347,13 @@
 fi
 
 #
+# The GNU toolchain defaults to assuming unmarked files need an
+# executable stack, potentially exposing vulnerabilities in programs
+# linked with such object files. Fix this.
+#
+tryflag CFLAGS_C99FSE -Wa,--noexecstack
+
+#
 # Check for options to disable stack protector, which needs to be
 # disabled for a few early-bootstrap translation units. If not found,
 # this is not an error; we assume the toolchain does not do ssp.
@@ -430,11 +454,15 @@
 tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables
 
 #
-# The GNU toolchain defaults to assuming unmarked files need an
-# executable stack, potentially exposing vulnerabilities in programs
-# linked with such object files. Fix this.
+# Attempt to put each function and each data object in its own
+# section. This both allows additional size optimizations at link
+# time and works around a dangerous class of compiler/assembler bugs
+# whereby relative address expressions are constant-folded by the
+# assembler even when one or more of the symbols involved is
+# replaceable. See gas pr 18561 and gcc pr 66609, 68178, etc.
 #
-tryflag CFLAGS_AUTO -Wa,--noexecstack
+tryflag CFLAGS_AUTO -ffunction-sections
+tryflag CFLAGS_AUTO -fdata-sections
 
 #
 # On x86, make sure we don't have incompatible instruction set
@@ -489,7 +517,7 @@
 int bar(void) { fp = foo; return foo(); }
 EOF
 if $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS \
-  -DSHARED -fPIC -I./src/internal -include vis.h \
+  -DSHARED -fPIC -I$srcdir/src/internal -include vis.h \
   -nostdlib -shared -Wl,-Bsymbolic-functions \
   -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
 visibility=yes
@@ -504,6 +532,25 @@
 CFLAGS_AUTO="${CFLAGS_AUTO# }"
 fi
 
+# Determine if the compiler produces position-independent code (PIC)
+# by default. If so, we don't need to compile separate object files
+# for libc.a and libc.so.
+if trycppif __PIC__ "$CFLAGS_C99FSE $CPPFLAGS $CFLAGS" ; then
+pic_default=yes
+else
+pic_default=no
+fi
+
+# Reduce space lost to padding for alignment purposes by sorting data
+# objects according to their alignment reqirements. This approximates
+# optimal packing.
+tryldflag LDFLAGS_AUTO -Wl,--sort-section,alignment
+tryldflag LDFLAGS_AUTO -Wl,--sort-common
+
+# When linking shared library, drop dummy weak definitions that were
+# replaced by strong definitions from other translation units.
+tryldflag LDFLAGS_AUTO -Wl,--gc-sections
+
 # Some patched GCC builds have these defaults messed up...
 tryldflag LDFLAGS_AUTO -Wl,--hash-style=both
 
@@ -513,15 +560,15 @@
 # runtime library; implementation error is also a possibility.
 tryldflag LDFLAGS_AUTO -Wl,--no-undefined
 
-test "$shared" = "no" || {
-# Disable dynamic linking if ld is broken and can't do -Bsymbolic-functions
-LDFLAGS_DUMMY=
-tryldflag LDFLAGS_DUMMY -Wl,-Bsymbolic-functions || {
-test "$shared" = "yes" && fail "$0: error: linker cannot build shared library"
-printf "warning: disabling dynamic linking support\n"
-shared=no
-}
-}
+# Avoid exporting symbols from compiler runtime libraries. They
+# should be hidden anyway, but some toolchains including old gcc
+# versions built without shared library support and pcc are broken.
+tryldflag LDFLAGS_AUTO -Wl,--exclude-libs=ALL
+
+# Linking with -Bsymbolic-functions is no longer mandatory for
+# the dynamic linker to work, but enable it if it works as
+# a linking optimization.
+tryldflag LDFLAGS_AUTO -Wl,-Bsymbolic-functions
 
 # Find compiler runtime library
 test -z "$LIBCC" && tryldflag LIBCC -lgcc && tryldflag LIBCC -lgcc_eh
@@ -599,8 +646,9 @@
 echo '#if LDBL_MANT_DIG == 53' >> "$tmpc"
 echo 'typedef char ldcheck[9-(int)sizeof(long double)];' >> "$tmpc"
 echo '#endif' >> "$tmpc"
-if $CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include $CPPFLAGS $CFLAGS \
-  -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
+if $CC $CFLAGS_C99FSE \
+  -I$srcdir/arch/$ARCH -I$srcdir/arch/generic -I$srcdir/include \
+  $CPPFLAGS $CFLAGS -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
 printf "yes\n"
 else
 printf "no\n"
@@ -622,6 +670,7 @@
 ARCH = $ARCH
 SUBARCH = $SUBARCH
 ASMSUBARCH = $ASMSUBARCH
+srcdir = $srcdir
 prefix = $prefix
 exec_prefix = $exec_prefix
 bindir = $bindir
@@ -629,12 +678,14 @@
 includedir = $includedir
 syslibdir = $syslibdir
 CC = $CC
-CFLAGS = $CFLAGS_AUTO $CFLAGS
+CFLAGS = $CFLAGS
+CFLAGS_AUTO = $CFLAGS_AUTO
 CFLAGS_C99FSE = $CFLAGS_C99FSE
 CFLAGS_MEMOPS = $CFLAGS_MEMOPS
 CFLAGS_NOSSP = $CFLAGS_NOSSP
 CPPFLAGS = $CPPFLAGS
-LDFLAGS = $LDFLAGS_AUTO $LDFLAGS
+LDFLAGS = $LDFLAGS
+LDFLAGS_AUTO = $LDFLAGS_AUTO
 CROSS_COMPILE = $CROSS_COMPILE
 LIBCC = $LIBCC
 OPTIMIZE_GLOBS = $OPTIMIZE_GLOBS
@@ -646,6 +697,9 @@
 test "x$shared" = xno && echo "SHARED_LIBS ="
 test "x$cc_family" = xgcc && echo 'WRAPCC_GCC = $(CC)'
 test "x$cc_family" = xclang && echo 'WRAPCC_CLANG = $(CC)'
+test "x$pic_default" = xyes && echo 'AOBJS = $(LOBJS)'
 exec 1>&3 3>&-
 
+test "$srcdir" = "." || ln -sf $srcdir/Makefile .
+
 printf "done\n"
diff --git a/crt/arm/crti.s b/crt/arm/crti.s
index 1ba165c..18dc1e4 100644
--- a/crt/arm/crti.s
+++ b/crt/arm/crti.s
@@ -1,3 +1,5 @@
+.syntax unified
+
 .section .init
 .global _init
 .type _init,%function
diff --git a/crt/arm/crtn.s b/crt/arm/crtn.s
index 1b626c0..dc020f9 100644
--- a/crt/arm/crtn.s
+++ b/crt/arm/crtn.s
@@ -1,11 +1,9 @@
+.syntax unified
+
 .section .init
 	pop {r0,lr}
-	tst lr,#1
-	moveq pc,lr
 	bx lr
 
 .section .fini
 	pop {r0,lr}
-	tst lr,#1
-	moveq pc,lr
 	bx lr
diff --git a/crt/rcrt1.c b/crt/rcrt1.c
index 9be117f..e763d0a 100644
--- a/crt/rcrt1.c
+++ b/crt/rcrt1.c
@@ -1,7 +1,7 @@
 #define SHARED
 #define START "_start"
 #define _dlstart_c _start_c
-#include "../src/ldso/dlstart.c"
+#include "../ldso/dlstart.c"
 
 int main();
 void _init() __attribute__((weak));
diff --git a/include/assert.h b/include/assert.h
index 1ee02a4..e679adb 100644
--- a/include/assert.h
+++ b/include/assert.h
@@ -8,7 +8,7 @@
 #define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__),0)))
 #endif
 
-#ifndef __cplusplus
+#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
 #define static_assert _Static_assert
 #endif
 
diff --git a/include/complex.h b/include/complex.h
index 4d21728..008b3c7 100644
--- a/include/complex.h
+++ b/include/complex.h
@@ -116,7 +116,7 @@
 
 #if __STDC_VERSION__ >= 201112L
 #if defined(_Imaginary_I)
-#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y)))
+#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y))
 #elif defined(__clang__)
 #define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) })
 #else
diff --git a/include/netinet/in.h b/include/netinet/in.h
index 1ed3e6f..622bdfe 100644
--- a/include/netinet/in.h
+++ b/include/netinet/in.h
@@ -103,6 +103,7 @@
 #define IPPROTO_SCTP     132
 #define IPPROTO_MH       135
 #define IPPROTO_UDPLITE  136
+#define IPPROTO_MPLS     137
 #define IPPROTO_RAW      255
 #define IPPROTO_MAX      256
 
@@ -200,6 +201,7 @@
 #define IP_MINTTL          21
 #define IP_NODEFRAG        22
 #define IP_CHECKSUM        23
+#define IP_BIND_ADDRESS_NO_PORT 24
 #define IP_MULTICAST_IF    32
 #define IP_MULTICAST_TTL   33
 #define IP_MULTICAST_LOOP  34
diff --git a/include/netinet/tcp.h b/include/netinet/tcp.h
index 52358c7..244a21e 100644
--- a/include/netinet/tcp.h
+++ b/include/netinet/tcp.h
@@ -27,6 +27,9 @@
 #define TCP_FASTOPEN     23
 #define TCP_TIMESTAMP    24
 #define TCP_NOTSENT_LOWAT 25
+#define TCP_CC_INFO      26
+#define TCP_SAVE_SYN     27
+#define TCP_SAVED_SYN    28
 
 #define TCP_ESTABLISHED  1
 #define TCP_SYN_SENT     2
@@ -41,7 +44,20 @@
 #define TCP_CLOSING      11
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define TCPOPT_EOL              0
+#define TCPOPT_NOP              1
+#define TCPOPT_MAXSEG           2
+#define TCPOPT_WINDOW           3
+#define TCPOPT_SACK_PERMITTED   4
+#define TCPOPT_SACK             5
+#define TCPOPT_TIMESTAMP        8
+#define TCPOLEN_SACK_PERMITTED  2
+#define TCPOLEN_WINDOW          3
+#define TCPOLEN_MAXSEG          4
+#define TCPOLEN_TIMESTAMP       10
+
 #define SOL_TCP 6
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <stdint.h>
@@ -164,6 +180,10 @@
 	uint32_t tcpi_total_retrans;
 	uint64_t tcpi_pacing_rate;
 	uint64_t tcpi_max_pacing_rate;
+	uint64_t tcpi_bytes_acked;
+	uint64_t tcpi_bytes_received;
+	uint32_t tcpi_segs_out;
+	uint32_t tcpi_segs_in;
 };
 
 #define TCP_MD5SIG_MAXKEYLEN    80
diff --git a/include/netpacket/packet.h b/include/netpacket/packet.h
index fa53712..f2210ce 100644
--- a/include/netpacket/packet.h
+++ b/include/netpacket/packet.h
@@ -32,10 +32,27 @@
 #define	PACKET_RECV_OUTPUT		3
 #define	PACKET_RX_RING			5
 #define	PACKET_STATISTICS		6
+#define PACKET_COPY_THRESH		7
+#define PACKET_AUXDATA			8
+#define PACKET_ORIGDEV			9
+#define PACKET_VERSION			10
+#define PACKET_HDRLEN			11
+#define PACKET_RESERVE			12
+#define PACKET_TX_RING			13
+#define PACKET_LOSS			14
+#define PACKET_VNET_HDR			15
+#define PACKET_TX_TIMESTAMP		16
+#define PACKET_TIMESTAMP		17
+#define PACKET_FANOUT			18
+#define PACKET_TX_HAS_OFF		19
+#define PACKET_QDISC_BYPASS		20
+#define PACKET_ROLLOVER_STATS		21
+#define PACKET_FANOUT_DATA		22
 
 #define PACKET_MR_MULTICAST	0
 #define PACKET_MR_PROMISC	1
 #define PACKET_MR_ALLMULTI	2
+#define PACKET_MR_UNICAST	3
 
 #ifdef __cplusplus
 }
diff --git a/include/signal.h b/include/signal.h
index 559362f..c6323c6 100644
--- a/include/signal.h
+++ b/include/signal.h
@@ -27,8 +27,6 @@
 
 #include <bits/alltypes.h>
 
-#define SIG_HOLD ((void (*)(int)) 2)
-
 #define SIG_BLOCK     0
 #define SIG_UNBLOCK   1
 #define SIG_SETMASK   2
@@ -43,6 +41,18 @@
 #define SI_USER 0
 #define SI_KERNEL 128
 
+typedef struct sigaltstack stack_t;
+
+#endif
+
+#include <bits/signal.h>
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#define SIG_HOLD ((void (*)(int)) 2)
+
 #define FPE_INTDIV 1
 #define FPE_INTOVF 2
 #define FPE_FLTDIV 3
@@ -78,15 +88,17 @@
 #define CLD_STOPPED 5
 #define CLD_CONTINUED 6
 
-typedef struct sigaltstack stack_t;
-
 union sigval {
 	int sival_int;
 	void *sival_ptr;
 };
 
 typedef struct {
+#ifdef __SI_SWAP_ERRNO_CODE
+	int si_signo, si_code, si_errno;
+#else
 	int si_signo, si_errno, si_code;
+#endif
 	union {
 		char __pad[128 - 2*sizeof(int) - sizeof(long)];
 		struct {
@@ -240,8 +252,6 @@
 #define SA_ONESHOT SA_RESETHAND
 #endif
 
-#include <bits/signal.h>
-
 #define SIG_ERR  ((void (*)(int))-1)
 #define SIG_DFL  ((void (*)(int)) 0)
 #define SIG_IGN  ((void (*)(int)) 1)
diff --git a/include/sys/mman.h b/include/sys/mman.h
index 9fc2db5..a1864ec 100644
--- a/include/sys/mman.h
+++ b/include/sys/mman.h
@@ -39,6 +39,7 @@
 #endif
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MLOCK_ONFAULT   0x01
 int madvise (void *, size_t, int);
 int mincore (void *, size_t, unsigned char *);
 #endif
diff --git a/include/sys/mount.h b/include/sys/mount.h
index 1e1907f..6674e65 100644
--- a/include/sys/mount.h
+++ b/include/sys/mount.h
@@ -46,12 +46,13 @@
 #define MS_KERNMOUNT   (1<<22)
 #define MS_I_VERSION   (1<<23)
 #define MS_STRICTATIME (1<<24)
+#define MS_LAZYTIME    (1<<25)
 #define MS_NOSEC       (1<<28)
 #define MS_BORN        (1<<29)
 #define MS_ACTIVE      (1<<30)
 #define MS_NOUSER      (1U<<31)
 
-#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|MS_LAZYTIME)
 
 #define MS_MGC_VAL 0xc0ed0000
 #define MS_MGC_MSK 0xffff0000
diff --git a/include/sys/prctl.h b/include/sys/prctl.h
index ec92053..24f4f8b 100644
--- a/include/sys/prctl.h
+++ b/include/sys/prctl.h
@@ -124,6 +124,12 @@
 #define PR_FP_MODE_FR (1 << 0)
 #define PR_FP_MODE_FRE (1 << 1)
 
+#define PR_CAP_AMBIENT          47
+#define PR_CAP_AMBIENT_IS_SET   1
+#define PR_CAP_AMBIENT_RAISE    2
+#define PR_CAP_AMBIENT_LOWER    3
+#define PR_CAP_AMBIENT_CLEAR_ALL 4
+
 int prctl (int, ...);
 
 #ifdef __cplusplus
diff --git a/include/sys/ptrace.h b/include/sys/ptrace.h
index a133e66..d9d4540 100644
--- a/include/sys/ptrace.h
+++ b/include/sys/ptrace.h
@@ -39,6 +39,7 @@
 #define PTRACE_PEEKSIGINFO 0x4209
 #define PTRACE_GETSIGMASK 0x420a
 #define PTRACE_SETSIGMASK 0x420b
+#define PTRACE_SECCOMP_GET_FILTER 0x420c
 
 #define PT_READ_I PTRACE_PEEKTEXT
 #define PT_READ_D PTRACE_PEEKDATA
@@ -72,7 +73,8 @@
 #define PTRACE_O_TRACEEXIT      0x00000040
 #define PTRACE_O_TRACESECCOMP   0x00000080
 #define PTRACE_O_EXITKILL       0x00100000
-#define PTRACE_O_MASK           0x001000ff
+#define PTRACE_O_SUSPEND_SECCOMP 0x00200000
+#define PTRACE_O_MASK           0x003000ff
 
 #define PTRACE_EVENT_FORK 1
 #define PTRACE_EVENT_VFORK 2
diff --git a/include/sys/socket.h b/include/sys/socket.h
index 40de336..a4db940 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -96,6 +96,7 @@
 #define PF_WANPIPE      25
 #define PF_LLC          26
 #define PF_IB           27
+#define PF_MPLS         28
 #define PF_CAN          29
 #define PF_TIPC         30
 #define PF_BLUETOOTH    31
@@ -141,6 +142,7 @@
 #define AF_WANPIPE      PF_WANPIPE
 #define AF_LLC          PF_LLC
 #define AF_IB           PF_IB
+#define AF_MPLS         PF_MPLS
 #define AF_CAN          PF_CAN
 #define AF_TIPC         PF_TIPC
 #define AF_BLUETOOTH    PF_BLUETOOTH
@@ -255,6 +257,7 @@
 #define MSG_NOSIGNAL  0x4000
 #define MSG_MORE      0x8000
 #define MSG_WAITFORONE 0x10000
+#define MSG_FASTOPEN  0x20000000
 #define MSG_CMSG_CLOEXEC 0x40000000
 
 #define __CMSG_LEN(cmsg) (((cmsg)->cmsg_len + sizeof(long) - 1) & ~(long)(sizeof(long) - 1))
diff --git a/include/utmp.h b/include/utmp.h
index 24e2da7..48a400d 100644
--- a/include/utmp.h
+++ b/include/utmp.h
@@ -22,7 +22,6 @@
 #define ut_name ut_user
 #define ut_addr ut_addr_v6[0]
 #define utmp utmpx
-#define utmpname(x) (-1)
 #define e_exit __e_exit
 #define e_termination __e_termination
 
@@ -34,6 +33,7 @@
 void         setutent(void);
 
 void updwtmp(const char *, const struct utmp *);
+int utmpname(const char *);
 
 int login_tty(int);
 
diff --git a/include/utmpx.h b/include/utmpx.h
index f0c3b01..44b501d 100644
--- a/include/utmpx.h
+++ b/include/utmpx.h
@@ -43,6 +43,7 @@
 #define e_exit __e_exit
 #define e_termination __e_termination
 void updwtmpx(const char *, const struct utmpx *);
+int utmpxname(const char *);
 #endif
 
 #define EMPTY           0
diff --git a/src/ldso/dlstart.c b/ldso/dlstart.c
similarity index 99%
rename from src/ldso/dlstart.c
rename to ldso/dlstart.c
index 46f5011..4482d52 100644
--- a/src/ldso/dlstart.c
+++ b/ldso/dlstart.c
@@ -1,8 +1,6 @@
 #include <stddef.h>
 #include "dynlink.h"
 
-#ifdef SHARED
-
 #ifndef START
 #define START "_dlstart"
 #endif
@@ -146,5 +144,3 @@
 	GETFUNCSYM(&dls2, __dls2, base+dyn[DT_PLTGOT]);
 	dls2((void *)base, sp);
 }
-
-#endif
diff --git a/src/ldso/dynlink.c b/ldso/dynlink.c
similarity index 90%
rename from src/ldso/dynlink.c
rename to ldso/dynlink.c
index 642ecc3..87f3b7f 100644
--- a/src/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -23,8 +23,6 @@
 
 static void error(const char *, ...);
 
-#ifdef SHARED
-
 #define MAXP2(a,b) (-(-(a)&-(b)))
 #define ALIGN(x,y) ((x)+(y)-1 & -(y))
 
@@ -70,8 +68,8 @@
 	char kernel_mapped;
 	struct dso **deps, *needed_by;
 	char *rpath_orig, *rpath;
-	void *tls_image;
-	size_t tls_len, tls_size, tls_align, tls_id, tls_offset;
+	struct tls_module tls;
+	size_t tls_id;
 	size_t relro_start, relro_end;
 	void **new_dtv;
 	unsigned char *new_tls;
@@ -99,7 +97,9 @@
 
 int __init_tp(void *);
 void __init_libc(char **, char *);
+void *__copy_tls(unsigned char *);
 
+__attribute__((__visibility__("hidden")))
 const char *__libc_get_version(void);
 
 static struct builtin_tls {
@@ -123,6 +123,7 @@
 static jmp_buf *rtld_fail;
 static pthread_rwlock_t lock;
 static struct debug debug;
+static struct tls_module *tls_tail;
 static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;
 static size_t static_tls_cnt;
 static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
@@ -131,6 +132,15 @@
 
 struct debug *_dl_debug_addr = &debug;
 
+__attribute__((__visibility__("hidden")))
+void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;
+
+__attribute__((__visibility__("hidden")))
+extern void (*const __init_array_end)(void), (*const __fini_array_end)(void);
+
+weak_alias(__init_array_start, __init_array_end);
+weak_alias(__fini_array_start, __fini_array_end);
+
 static int dl_strcmp(const char *l, const char *r)
 {
 	for (; *l==*r && *l; l++, r++);
@@ -397,14 +407,14 @@
 			break;
 #ifdef TLS_ABOVE_TP
 		case REL_TPOFF:
-			*reloc_addr = tls_val + def.dso->tls_offset + TPOFF_K + addend;
+			*reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend;
 			break;
 #else
 		case REL_TPOFF:
-			*reloc_addr = tls_val - def.dso->tls_offset + addend;
+			*reloc_addr = tls_val - def.dso->tls.offset + addend;
 			break;
 		case REL_TPOFF_NEG:
-			*reloc_addr = def.dso->tls_offset - tls_val + addend;
+			*reloc_addr = def.dso->tls.offset - tls_val + addend;
 			break;
 #endif
 		case REL_TLSDESC:
@@ -426,10 +436,10 @@
 			} else {
 				reloc_addr[0] = (size_t)__tlsdesc_static;
 #ifdef TLS_ABOVE_TP
-				reloc_addr[1] = tls_val + def.dso->tls_offset
+				reloc_addr[1] = tls_val + def.dso->tls.offset
 					+ TPOFF_K + addend;
 #else
-				reloc_addr[1] = tls_val - def.dso->tls_offset
+				reloc_addr[1] = tls_val - def.dso->tls.offset
 					+ addend;
 #endif
 			}
@@ -482,8 +492,14 @@
 
 static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
 {
-	char *q = mmap(p, n, prot, flags, fd, off);
-	if (q != MAP_FAILED || errno != EINVAL) return q;
+	static int no_map_fixed;
+	char *q;
+	if (!no_map_fixed) {
+		q = mmap(p, n, prot, flags|MAP_FIXED, fd, off);
+		if (!DL_NOMMU_SUPPORT || q != MAP_FAILED || errno != EINVAL)
+			return q;
+		no_map_fixed = 1;
+	}
 	/* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
 	if (flags & MAP_ANONYMOUS) {
 		memset(p, 0, n);
@@ -561,9 +577,9 @@
 			dyn = ph->p_vaddr;
 		} else if (ph->p_type == PT_TLS) {
 			tls_image = ph->p_vaddr;
-			dso->tls_align = ph->p_align;
-			dso->tls_len = ph->p_filesz;
-			dso->tls_size = ph->p_memsz;
+			dso->tls.align = ph->p_align;
+			dso->tls.len = ph->p_filesz;
+			dso->tls.size = ph->p_memsz;
 		} else if (ph->p_type == PT_GNU_RELRO) {
 			dso->relro_start = ph->p_vaddr & -PAGE_SIZE;
 			dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
@@ -593,7 +609,7 @@
 				((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
 				((ph->p_flags&PF_X) ? PROT_EXEC : 0));
 			map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),
-				prot, (prot&PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED,
+				prot, MAP_PRIVATE,
 				fd, ph->p_offset & -PAGE_SIZE);
 			if (map == MAP_FAILED) {
 				unmap_library(dso);
@@ -604,6 +620,19 @@
 			dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
 			dso->loadmap->segs[i].p_memsz = ph->p_memsz;
 			i++;
+			if (prot & PROT_WRITE) {
+				size_t brk = (ph->p_vaddr & PAGE_SIZE-1)
+					+ ph->p_filesz;
+				size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE;
+				size_t pgend = brk + ph->p_memsz - ph->p_filesz
+					+ PAGE_SIZE-1 & -PAGE_SIZE;
+				if (pgend > pgbrk && mmap_fixed(map+pgbrk,
+					pgend-pgbrk, prot,
+					MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
+					-1, off_start) == MAP_FAILED)
+					goto error;
+				memset(map + brk, 0, pgbrk-brk);
+			}
 		}
 		map = (void *)dso->loadmap->segs[0].addr;
 		map_len = 0;
@@ -618,7 +647,11 @@
 	 * the length of the file. This is okay because we will not
 	 * use the invalid part; we just need to reserve the right
 	 * amount of virtual address space to map over later. */
-	map = mmap((void *)addr_min, map_len, prot, MAP_PRIVATE, fd, off_start);
+	map = DL_NOMMU_SUPPORT
+		? mmap((void *)addr_min, map_len, PROT_READ|PROT_WRITE|PROT_EXEC,
+			MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
+		: mmap((void *)addr_min, map_len, prot,
+			MAP_PRIVATE, fd, off_start);
 	if (map==MAP_FAILED) goto error;
 	dso->map = map;
 	dso->map_len = map_len;
@@ -643,7 +676,8 @@
 			dso->phentsize = eh->e_phentsize;
 		}
 		/* Reuse the existing mapping for the lowest-address LOAD */
-		if ((ph->p_vaddr & -PAGE_SIZE) == addr_min) continue;
+		if ((ph->p_vaddr & -PAGE_SIZE) == addr_min && !DL_NOMMU_SUPPORT)
+			continue;
 		this_min = ph->p_vaddr & -PAGE_SIZE;
 		this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
 		off_start = ph->p_offset & -PAGE_SIZE;
@@ -670,7 +704,7 @@
 done_mapping:
 	dso->base = base;
 	dso->dynv = laddr(dso, dyn);
-	if (dso->tls_size) dso->tls_image = laddr(dso, tls_image);
+	if (dso->tls.size) dso->tls.image = laddr(dso, tls_image);
 	if (!runtime) reclaim_gaps(dso);
 	free(allocated_buf);
 	return map;
@@ -987,8 +1021,8 @@
 	 * extended DTV capable of storing an additional slot for
 	 * the newly-loaded DSO. */
 	alloc_size = sizeof *p + strlen(pathname) + 1;
-	if (runtime && temp_dso.tls_image) {
-		size_t per_th = temp_dso.tls_size + temp_dso.tls_align
+	if (runtime && temp_dso.tls.image) {
+		size_t per_th = temp_dso.tls.size + temp_dso.tls.align
 			+ sizeof(void *) * (tls_cnt+3);
 		n_th = libc.threads_minus_1 + 1;
 		if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
@@ -1009,22 +1043,25 @@
 	strcpy(p->name, pathname);
 	/* Add a shortname only if name arg was not an explicit pathname. */
 	if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
-	if (p->tls_image) {
+	if (p->tls.image) {
 		p->tls_id = ++tls_cnt;
-		tls_align = MAXP2(tls_align, p->tls_align);
+		tls_align = MAXP2(tls_align, p->tls.align);
 #ifdef TLS_ABOVE_TP
-		p->tls_offset = tls_offset + ( (tls_align-1) &
-			-(tls_offset + (uintptr_t)p->tls_image) );
-		tls_offset += p->tls_size;
+		p->tls.offset = tls_offset + ( (tls_align-1) &
+			-(tls_offset + (uintptr_t)p->tls.image) );
+		tls_offset += p->tls.size;
 #else
-		tls_offset += p->tls_size + p->tls_align - 1;
-		tls_offset -= (tls_offset + (uintptr_t)p->tls_image)
-			& (p->tls_align-1);
-		p->tls_offset = tls_offset;
+		tls_offset += p->tls.size + p->tls.align - 1;
+		tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
+			& (p->tls.align-1);
+		p->tls.offset = tls_offset;
 #endif
 		p->new_dtv = (void *)(-sizeof(size_t) &
 			(uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
 		p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
+		if (tls_tail) tls_tail->next = &p->tls;
+		else libc.tls_head = &p->tls;
+		tls_tail = &p->tls;
 	}
 
 	tail->next = p;
@@ -1151,7 +1188,7 @@
 	p->kernel_mapped = 1;
 }
 
-static void do_fini()
+void __libc_exit_fini()
 {
 	struct dso *p;
 	size_t dyn[DYN_CNT];
@@ -1214,53 +1251,8 @@
 
 weak_alias(dl_debug_state, _dl_debug_state);
 
-void __reset_tls()
+void __init_tls(size_t *auxv)
 {
-	pthread_t self = __pthread_self();
-	struct dso *p;
-	for (p=head; p; p=p->next) {
-		if (!p->tls_id || !self->dtv[p->tls_id]) continue;
-		memcpy(self->dtv[p->tls_id], p->tls_image, p->tls_len);
-		memset((char *)self->dtv[p->tls_id]+p->tls_len, 0,
-			p->tls_size - p->tls_len);
-		if (p->tls_id == (size_t)self->dtv[0]) break;
-	}
-}
-
-void *__copy_tls(unsigned char *mem)
-{
-	pthread_t td;
-	struct dso *p;
-	void **dtv;
-
-#ifdef TLS_ABOVE_TP
-	dtv = (void **)(mem + libc.tls_size) - (tls_cnt + 1);
-
-	mem += -((uintptr_t)mem + sizeof(struct pthread)) & (tls_align-1);
-	td = (pthread_t)mem;
-	mem += sizeof(struct pthread);
-
-	for (p=head; p; p=p->next) {
-		if (!p->tls_id) continue;
-		dtv[p->tls_id] = mem + p->tls_offset;
-		memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
-	}
-#else
-	dtv = (void **)mem;
-
-	mem += libc.tls_size - sizeof(struct pthread);
-	mem -= (uintptr_t)mem & (tls_align-1);
-	td = (pthread_t)mem;
-
-	for (p=head; p; p=p->next) {
-		if (!p->tls_id) continue;
-		dtv[p->tls_id] = mem - p->tls_offset;
-		memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
-	}
-#endif
-	dtv[0] = (void *)tls_cnt;
-	td->dtv = td->dtv_copy = dtv;
-	return td;
 }
 
 __attribute__((__visibility__("hidden")))
@@ -1286,7 +1278,7 @@
 	/* Get new DTV space from new DSO if needed */
 	if (v[0] > (size_t)self->dtv[0]) {
 		void **newdtv = p->new_dtv +
-			(v[0]+1)*sizeof(void *)*a_fetch_add(&p->new_dtv_idx,1);
+			(v[0]+1)*a_fetch_add(&p->new_dtv_idx,1);
 		memcpy(newdtv, self->dtv,
 			((size_t)self->dtv[0]+1) * sizeof(void *));
 		newdtv[0] = (void *)v[0];
@@ -1297,12 +1289,12 @@
 	unsigned char *mem;
 	for (p=head; ; p=p->next) {
 		if (!p->tls_id || self->dtv[p->tls_id]) continue;
-		mem = p->new_tls + (p->tls_size + p->tls_align)
+		mem = p->new_tls + (p->tls.size + p->tls.align)
 			* a_fetch_add(&p->new_tls_idx,1);
-		mem += ((uintptr_t)p->tls_image - (uintptr_t)mem)
-			& (p->tls_align-1);
+		mem += ((uintptr_t)p->tls.image - (uintptr_t)mem)
+			& (p->tls.align-1);
 		self->dtv[p->tls_id] = mem;
-		memcpy(mem, p->tls_image, p->tls_len);
+		memcpy(mem, p->tls.image, p->tls.len);
 		if (p->tls_id == v[0]) break;
 	}
 	__restore_sigs(&set);
@@ -1311,6 +1303,8 @@
 
 static void update_tls_size()
 {
+	libc.tls_cnt = tls_cnt;
+	libc.tls_align = tls_align;
 	libc.tls_size = ALIGN(
 		(1+tls_cnt) * sizeof(void *) +
 		tls_offset +
@@ -1421,6 +1415,7 @@
 	 * use during dynamic linking. If possible it will also serve as the
 	 * thread pointer at runtime. */
 	libc.tls_size = sizeof builtin_tls;
+	libc.tls_align = tls_align;
 	if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
 		a_crash();
 	}
@@ -1448,13 +1443,13 @@
 				interp_off = (size_t)phdr->p_vaddr;
 			else if (phdr->p_type == PT_TLS) {
 				tls_image = phdr->p_vaddr;
-				app.tls_len = phdr->p_filesz;
-				app.tls_size = phdr->p_memsz;
-				app.tls_align = phdr->p_align;
+				app.tls.len = phdr->p_filesz;
+				app.tls.size = phdr->p_memsz;
+				app.tls.align = phdr->p_align;
 			}
 		}
 		if (DL_FDPIC) app.loadmap = app_loadmap;
-		if (app.tls_size) app.tls_image = laddr(&app, tls_image);
+		if (app.tls.size) app.tls.image = laddr(&app, tls_image);
 		if (interp_off) ldso.name = laddr(&app, interp_off);
 		if ((aux[0] & (1UL<<AT_EXECFN))
 		    && strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
@@ -1489,7 +1484,7 @@
 		}
 		argv[-1] = (void *)(argc - (argv-argv_orig));
 		if (!argv[0]) {
-			dprintf(2, "musl libc\n"
+			dprintf(2, "musl libc (" LDSO_ARCH ")\n"
 				"Version %s\n"
 				"Dynamic Program Loader\n"
 				"Usage: %s [options] [--] pathname%s\n",
@@ -1523,19 +1518,20 @@
 			dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
 		}
 	}
-	if (app.tls_size) {
+	if (app.tls.size) {
+		libc.tls_head = tls_tail = &app.tls;
 		app.tls_id = tls_cnt = 1;
 #ifdef TLS_ABOVE_TP
-		app.tls_offset = 0;
-		tls_offset = app.tls_size
-			+ ( -((uintptr_t)app.tls_image + app.tls_size)
-			& (app.tls_align-1) );
+		app.tls.offset = 0;
+		tls_offset = app.tls.size
+			+ ( -((uintptr_t)app.tls.image + app.tls.size)
+			& (app.tls.align-1) );
 #else
-		tls_offset = app.tls_offset = app.tls_size
-			+ ( -((uintptr_t)app.tls_image + app.tls_size)
-			& (app.tls_align-1) );
+		tls_offset = app.tls.offset = app.tls.size
+			+ ( -((uintptr_t)app.tls.image + app.tls.size)
+			& (app.tls.align-1) );
 #endif
-		tls_align = MAXP2(tls_align, app.tls_align);
+		tls_align = MAXP2(tls_align, app.tls.align);
 	}
 	app.global = 1;
 	decode_dyn(&app);
@@ -1586,11 +1582,14 @@
 	load_deps(&app);
 	make_global(&app);
 
-#ifndef DYNAMIC_IS_RO
-	for (i=0; app.dynv[i]; i+=2)
-		if (app.dynv[i]==DT_DEBUG)
+	for (i=0; app.dynv[i]; i+=2) {
+		if (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG)
 			app.dynv[i+1] = (size_t)&debug;
-#endif
+		if (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) {
+			size_t *ptr = (size_t *) app.dynv[i+1];
+			*ptr = (size_t)&debug;
+		}
+	}
 
 	/* The main program must be relocated LAST since it may contin
 	 * copy relocations which depend on libraries' relocations. */
@@ -1635,8 +1634,6 @@
 	debug.state = 0;
 	_dl_debug_state();
 
-	__init_libc(envp, argv[0]);
-	atexit(do_fini);
 	errno = 0;
 
 	CRTJMP((void *)aux[AT_ENTRY], argv-1);
@@ -1646,6 +1643,7 @@
 void *dlopen(const char *file, int mode)
 {
 	struct dso *volatile p, *orig_tail, *next;
+	struct tls_module *orig_tls_tail;
 	size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
 	size_t i;
 	int cs;
@@ -1658,6 +1656,7 @@
 	__inhibit_ptc();
 
 	p = 0;
+	orig_tls_tail = tls_tail;
 	orig_tls_cnt = tls_cnt;
 	orig_tls_offset = tls_offset;
 	orig_tls_align = tls_align;
@@ -1684,6 +1683,8 @@
 			unmap_library(p);
 			free(p);
 		}
+		if (!orig_tls_tail) libc.tls_head = 0;
+		tls_tail = orig_tls_tail;
 		tls_cnt = orig_tls_cnt;
 		tls_offset = orig_tls_offset;
 		tls_align = orig_tls_align;
@@ -1733,7 +1734,8 @@
 	return p;
 }
 
-static int invalid_dso_handle(void *h)
+__attribute__((__visibility__("hidden")))
+int __dl_invalid_handle(void *h)
 {
 	struct dso *p;
 	for (p=head; p; p=p->next) if (h==p) return 0;
@@ -1788,7 +1790,7 @@
 			return def.dso->funcdescs + (def.sym - def.dso->syms);
 		return laddr(def.dso, def.sym->st_value);
 	}
-	if (invalid_dso_handle(p))
+	if (__dl_invalid_handle(p))
 		return 0;
 	if ((ght = p->ghashtab)) {
 		gh = gnu_hash(s);
@@ -1823,7 +1825,7 @@
 	return 0;
 }
 
-int __dladdr(const void *addr, Dl_info *info)
+int dladdr(const void *addr, Dl_info *info)
 {
 	struct dso *p;
 	Sym *sym, *bestsym;
@@ -1900,7 +1902,7 @@
 		info.dlpi_adds      = gencnt;
 		info.dlpi_subs      = 0;
 		info.dlpi_tls_modid = current->tls_id;
-		info.dlpi_tls_data  = current->tls_image;
+		info.dlpi_tls_data  = current->tls.image;
 
 		ret = (callback)(&info, sizeof (info), data);
 
@@ -1912,68 +1914,14 @@
 	}
 	return ret;
 }
-#else
-static int invalid_dso_handle(void *h)
-{
-	error("Invalid library handle %p", (void *)h);
-	return 1;
-}
-void *dlopen(const char *file, int mode)
-{
-	error("Dynamic loading not supported");
-	return 0;
-}
-void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
-{
-	error("Symbol not found: %s", s);
-	return 0;
-}
-int __dladdr (const void *addr, Dl_info *info)
-{
-	return 0;
-}
-#endif
 
-int __dlinfo(void *dso, int req, void *res)
-{
-	if (invalid_dso_handle(dso)) return -1;
-	if (req != RTLD_DI_LINKMAP) {
-		error("Unsupported request %d", req);
-		return -1;
-	}
-	*(struct link_map **)res = dso;
-	return 0;
-}
-
-char *dlerror()
-{
-	pthread_t self = __pthread_self();
-	if (!self->dlerror_flag) return 0;
-	self->dlerror_flag = 0;
-	char *s = self->dlerror_buf;
-	if (s == (void *)-1)
-		return "Dynamic linker failed to allocate memory for error message";
-	else
-		return s;
-}
-
-int dlclose(void *p)
-{
-	return invalid_dso_handle(p);
-}
-
-void __dl_thread_cleanup(void)
-{
-	pthread_t self = __pthread_self();
-	if (self->dlerror_buf != (void *)-1)
-		free(self->dlerror_buf);
-}
+__attribute__((__visibility__("hidden")))
+void __dl_vseterr(const char *, va_list);
 
 static void error(const char *fmt, ...)
 {
 	va_list ap;
 	va_start(ap, fmt);
-#ifdef SHARED
 	if (!runtime) {
 		vdprintf(2, fmt, ap);
 		dprintf(2, "\n");
@@ -1981,20 +1929,6 @@
 		va_end(ap);
 		return;
 	}
-#endif
-	pthread_t self = __pthread_self();
-	if (self->dlerror_buf != (void *)-1)
-		free(self->dlerror_buf);
-	size_t len = vsnprintf(0, 0, fmt, ap);
+	__dl_vseterr(fmt, ap);
 	va_end(ap);
-	char *buf = malloc(len+1);
-	if (buf) {
-		va_start(ap, fmt);
-		vsnprintf(buf, len+1, fmt, ap);
-		va_end(ap);
-	} else {
-		buf = (void *)-1;	
-	}
-	self->dlerror_buf = buf;
-	self->dlerror_flag = 1;
 }
diff --git a/lib/empty b/lib/empty
deleted file mode 100644
index e69de29..0000000
--- a/lib/empty
+++ /dev/null
diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
index 73551e6..0107a54 100644
--- a/src/env/__init_tls.c
+++ b/src/env/__init_tls.c
@@ -8,9 +8,6 @@
 #include "atomic.h"
 #include "syscall.h"
 
-#ifndef SHARED
-static
-#endif
 int __init_tp(void *p)
 {
 	pthread_t td = p;
@@ -24,8 +21,6 @@
 	return 0;
 }
 
-#ifndef SHARED
-
 static struct builtin_tls {
 	char c;
 	struct pthread pt;
@@ -33,33 +28,40 @@
 } builtin_tls[1];
 #define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
 
-struct tls_image {
-	void *image;
-	size_t len, size, align;
-} __static_tls;
-
-#define T __static_tls
+static struct tls_module main_tls;
 
 void *__copy_tls(unsigned char *mem)
 {
 	pthread_t td;
-	if (!T.image) return mem;
-	void **dtv = (void *)mem;
-	dtv[0] = (void *)1;
+	struct tls_module *p;
+	size_t i;
+	void **dtv;
+
 #ifdef TLS_ABOVE_TP
-	mem += sizeof(void *) * 2;
-	mem += -((uintptr_t)mem + sizeof(struct pthread)) & (T.align-1);
+	dtv = (void **)(mem + libc.tls_size) - (libc.tls_cnt + 1);
+
+	mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1);
 	td = (pthread_t)mem;
 	mem += sizeof(struct pthread);
+
+	for (i=1, p=libc.tls_head; p; i++, p=p->next) {
+		dtv[i] = mem + p->offset;
+		memcpy(dtv[i], p->image, p->len);
+	}
 #else
+	dtv = (void **)mem;
+
 	mem += libc.tls_size - sizeof(struct pthread);
-	mem -= (uintptr_t)mem & (T.align-1);
+	mem -= (uintptr_t)mem & (libc.tls_align-1);
 	td = (pthread_t)mem;
-	mem -= T.size;
+
+	for (i=1, p=libc.tls_head; p; i++, p=p->next) {
+		dtv[i] = mem - p->offset;
+		memcpy(dtv[i], p->image, p->len);
+	}
 #endif
+	dtv[0] = (void *)libc.tls_cnt;
 	td->dtv = td->dtv_copy = dtv;
-	dtv[1] = mem;
-	memcpy(mem, T.image, T.len);
 	return td;
 }
 
@@ -69,7 +71,7 @@
 typedef Elf64_Phdr Phdr;
 #endif
 
-void __init_tls(size_t *aux)
+static void static_init_tls(size_t *aux)
 {
 	unsigned char *p;
 	size_t n;
@@ -86,16 +88,24 @@
 	}
 
 	if (tls_phdr) {
-		T.image = (void *)(base + tls_phdr->p_vaddr);
-		T.len = tls_phdr->p_filesz;
-		T.size = tls_phdr->p_memsz;
-		T.align = tls_phdr->p_align;
+		main_tls.image = (void *)(base + tls_phdr->p_vaddr);
+		main_tls.len = tls_phdr->p_filesz;
+		main_tls.size = tls_phdr->p_memsz;
+		main_tls.align = tls_phdr->p_align;
+		libc.tls_cnt = 1;
+		libc.tls_head = &main_tls;
 	}
 
-	T.size += (-T.size - (uintptr_t)T.image) & (T.align-1);
-	if (T.align < MIN_TLS_ALIGN) T.align = MIN_TLS_ALIGN;
+	main_tls.size += (-main_tls.size - (uintptr_t)main_tls.image)
+		& (main_tls.align-1);
+	if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN;
+#ifndef TLS_ABOVE_TP
+	main_tls.offset = main_tls.size;
+#endif
 
-	libc.tls_size = 2*sizeof(void *)+T.size+T.align+sizeof(struct pthread)
+	libc.tls_align = main_tls.align;
+	libc.tls_size = 2*sizeof(void *) + sizeof(struct pthread)
+		+ main_tls.size + main_tls.align
 		+ MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN;
 
 	if (libc.tls_size > sizeof builtin_tls) {
@@ -117,6 +127,5 @@
 	if (__init_tp(__copy_tls(mem)) < 0)
 		a_crash();
 }
-#else
-void __init_tls(size_t *auxv) { }
-#endif
+
+weak_alias(static_init_tls, __init_tls);
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index d1f6a5e..5c79be2 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -8,21 +8,17 @@
 
 void __init_tls(size_t *);
 
-#ifndef SHARED
-static void dummy() {}
+static void dummy(void) {}
 weak_alias(dummy, _init);
-extern void (*const __init_array_start)() __attribute__((weak));
-extern void (*const __init_array_end)() __attribute__((weak));
-#endif
+
+__attribute__((__weak__, __visibility__("hidden")))
+extern void (*const __init_array_start)(void), (*const __init_array_end)(void);
 
 static void dummy1(void *p) {}
 weak_alias(dummy1, __init_ssp);
 
 #define AUX_CNT 38
 
-#ifndef SHARED
-static
-#endif
 void __init_libc(char **envp, char *pn)
 {
 	size_t i, *auxv, aux[AUX_CNT] = { 0 };
@@ -57,20 +53,22 @@
 	libc.secure = 1;
 }
 
-int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
+static void libc_start_init(void)
 {
-	char **envp = argv+argc+1;
-
-#ifndef SHARED
-	__init_libc(envp, argv[0]);
 	_init();
 	uintptr_t a = (uintptr_t)&__init_array_start;
 	for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
 		(*(void (**)())a)();
-#else
-	void __libc_start_init(void);
+}
+
+weak_alias(libc_start_init, __libc_start_init);
+
+int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
+{
+	char **envp = argv+argc+1;
+
+	__init_libc(envp, argv[0]);
 	__libc_start_init();
-#endif
 
 	/* Pass control to the application */
 	exit(main(argc, argv, envp));
diff --git a/src/env/__reset_tls.c b/src/env/__reset_tls.c
index bd61f31..677e57f 100644
--- a/src/env/__reset_tls.c
+++ b/src/env/__reset_tls.c
@@ -1,21 +1,16 @@
-#ifndef SHARED
-
 #include <string.h>
 #include "pthread_impl.h"
-
-extern struct tls_image {
-	void *image;
-	size_t len, size, align;
-} __static_tls;
-
-#define T __static_tls
+#include "libc.h"
 
 void __reset_tls()
 {
-	if (!T.size) return;
 	pthread_t self = __pthread_self();
-	memcpy(self->dtv[1], T.image, T.len);
-	memset((char *)self->dtv[1]+T.len, 0, T.size-T.len);
+	struct tls_module *p;
+	size_t i, n = (size_t)self->dtv[0];
+	if (n) for (p=libc.tls_head, i=1; i<=n; i++, p=p->next) {
+		if (!self->dtv[i]) continue;
+		memcpy(self->dtv[i], p->image, p->len);
+		memset((char *)self->dtv[i]+p->len, 0,
+			p->size - p->len);
+	}
 }
-
-#endif
diff --git a/src/env/__stack_chk_fail.c b/src/env/__stack_chk_fail.c
index be0c184..4de82fd 100644
--- a/src/env/__stack_chk_fail.c
+++ b/src/env/__stack_chk_fail.c
@@ -17,16 +17,7 @@
 	a_crash();
 }
 
-#ifdef SHARED
-
 __attribute__((__visibility__("hidden")))
-void __stack_chk_fail_local(void)
-{
-	a_crash();
-}
-
-#else
+void __stack_chk_fail_local(void);
 
 weak_alias(__stack_chk_fail, __stack_chk_fail_local);
-
-#endif
diff --git a/arch/arm/src/__aeabi_atexit.c b/src/exit/arm/__aeabi_atexit.c
similarity index 100%
rename from arch/arm/src/__aeabi_atexit.c
rename to src/exit/arm/__aeabi_atexit.c
diff --git a/src/exit/exit.c b/src/exit/exit.c
index 163d8f1..bf7835a 100644
--- a/src/exit/exit.c
+++ b/src/exit/exit.c
@@ -10,25 +10,25 @@
  * as a consequence of linking either __toread.c or __towrite.c. */
 weak_alias(dummy, __funcs_on_exit);
 weak_alias(dummy, __stdio_exit);
-
-#ifndef SHARED
 weak_alias(dummy, _fini);
-extern void (*const __fini_array_start)() __attribute__((weak));
-extern void (*const __fini_array_end)() __attribute__((weak));
-#endif
 
-_Noreturn void exit(int code)
+__attribute__((__weak__, __visibility__("hidden")))
+extern void (*const __fini_array_start)(void), (*const __fini_array_end)(void);
+
+static void libc_exit_fini(void)
 {
-	__funcs_on_exit();
-
-#ifndef SHARED
 	uintptr_t a = (uintptr_t)&__fini_array_end;
 	for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)()))
 		(*(void (**)())(a-sizeof(void(*)())))();
 	_fini();
-#endif
+}
 
+weak_alias(libc_exit_fini, __libc_exit_fini);
+
+_Noreturn void exit(int code)
+{
+	__funcs_on_exit();
+	__libc_exit_fini();
 	__stdio_exit();
-
 	_Exit(code);
 }
diff --git a/src/fenv/armhf/fenv.s b/src/fenv/arm/fenv-hf.S
similarity index 72%
rename from src/fenv/armhf/fenv.s
rename to src/fenv/arm/fenv-hf.S
index c1ffd2e..f55d798 100644
--- a/src/fenv/armhf/fenv.s
+++ b/src/fenv/arm/fenv-hf.S
@@ -1,19 +1,22 @@
+#if __ARM_PCS_VFP
+
+.syntax unified
 .fpu vfp
 
 .global fegetround
 .type fegetround,%function
 fegetround:
-	mrc p10, 7, r0, cr1, cr0, 0
+	fmrx r0, fpscr
 	and r0, r0, #0xc00000
 	bx lr
 
 .global __fesetround
 .type __fesetround,%function
 __fesetround:
-	mrc p10, 7, r3, cr1, cr0, 0
+	fmrx r3, fpscr
 	bic r3, r3, #0xc00000
 	orr r3, r3, r0
-	mcr p10, 7, r3, cr1, cr0, 0
+	fmxr fpscr, r3
 	mov r0, #0
 	bx lr
 
@@ -21,7 +24,7 @@
 .type fetestexcept,%function
 fetestexcept:
 	and r0, r0, #0x1f
-	mrc p10, 7, r3, cr1, cr0, 0
+	fmrx r3, fpscr
 	and r0, r0, r3
 	bx lr
 
@@ -29,9 +32,9 @@
 .type feclearexcept,%function
 feclearexcept:
 	and r0, r0, #0x1f
-	mrc p10, 7, r3, cr1, cr0, 0
+	fmrx r3, fpscr
 	bic r3, r3, r0
-	mcr p10, 7, r3, cr1, cr0, 0
+	fmxr fpscr, r3
 	mov r0, #0
 	bx lr
 
@@ -39,16 +42,16 @@
 .type feraiseexcept,%function
 feraiseexcept:
 	and r0, r0, #0x1f
-	mrc p10, 7, r3, cr1, cr0, 0
+	fmrx r3, fpscr
 	orr r3, r3, r0
-	mcr p10, 7, r3, cr1, cr0, 0
+	fmxr fpscr, r3
 	mov r0, #0
 	bx lr
 
 .global fegetenv
 .type fegetenv,%function
 fegetenv:
-	mrc p10, 7, r3, cr1, cr0, 0
+	fmrx r3, fpscr
 	str r3, [r0]
 	mov r0, #0
 	bx lr
@@ -59,6 +62,8 @@
 	cmn r0, #1
 	moveq r3, #0
 	ldrne r3, [r0]
-	mcr p10, 7, r3, cr1, cr0, 0
+	fmxr fpscr, r3
 	mov r0, #0
 	bx lr
+
+#endif
diff --git a/src/fenv/arm/fenv.c b/src/fenv/arm/fenv.c
new file mode 100644
index 0000000..ad295f5
--- /dev/null
+++ b/src/fenv/arm/fenv.c
@@ -0,0 +1,3 @@
+#if !__ARM_PCS_VFP
+#include "../fenv.c"
+#endif
diff --git a/src/fenv/armebhf/fenv.sub b/src/fenv/armebhf/fenv.sub
deleted file mode 100644
index 5281e40..0000000
--- a/src/fenv/armebhf/fenv.sub
+++ /dev/null
@@ -1 +0,0 @@
-../armhf/fenv.s
diff --git a/src/fenv/armhf/fenv.sub b/src/fenv/armhf/fenv.sub
deleted file mode 100644
index ec559cd..0000000
--- a/src/fenv/armhf/fenv.sub
+++ /dev/null
@@ -1 +0,0 @@
-fenv.s
diff --git a/src/fenv/mips-sf/fenv.sub b/src/fenv/mips-sf/fenv.sub
deleted file mode 100644
index 9cafca5..0000000
--- a/src/fenv/mips-sf/fenv.sub
+++ /dev/null
@@ -1 +0,0 @@
-../fenv.c
diff --git a/src/fenv/mips/fenv-sf.c b/src/fenv/mips/fenv-sf.c
new file mode 100644
index 0000000..4aa3dbf
--- /dev/null
+++ b/src/fenv/mips/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifdef __mips_soft_float
+#include "../fenv.c"
+#endif
diff --git a/src/fenv/mips/fenv.s b/src/fenv/mips/fenv.S
similarity index 96%
rename from src/fenv/mips/fenv.s
rename to src/fenv/mips/fenv.S
index 6282821..a5cb1f5 100644
--- a/src/fenv/mips/fenv.s
+++ b/src/fenv/mips/fenv.S
@@ -1,3 +1,5 @@
+#ifndef __mips_soft_float
+
 .set noreorder
 
 .global feclearexcept
@@ -65,3 +67,5 @@
 1:	ctc1    $5, $31
 	jr      $ra
 	li      $2, 0
+
+#endif
diff --git a/src/fenv/mipsel-sf/fenv.sub b/src/fenv/mipsel-sf/fenv.sub
deleted file mode 100644
index 9cafca5..0000000
--- a/src/fenv/mipsel-sf/fenv.sub
+++ /dev/null
@@ -1 +0,0 @@
-../fenv.c
diff --git a/src/fenv/sh-nofpu/fenv.sub b/src/fenv/sh-nofpu/fenv.sub
deleted file mode 100644
index 9cafca5..0000000
--- a/src/fenv/sh-nofpu/fenv.sub
+++ /dev/null
@@ -1 +0,0 @@
-../fenv.c
diff --git a/src/fenv/sh/fenv-nofpu.c b/src/fenv/sh/fenv-nofpu.c
new file mode 100644
index 0000000..b2495a6
--- /dev/null
+++ b/src/fenv/sh/fenv-nofpu.c
@@ -0,0 +1,3 @@
+#if !__SH_FPU_ANY__ && !__SH4__
+#include "../fenv.c"
+#endif
diff --git a/src/fenv/sh/fenv.s b/src/fenv/sh/fenv.S
similarity index 96%
rename from src/fenv/sh/fenv.s
rename to src/fenv/sh/fenv.S
index 7f5c627..cd47b5b 100644
--- a/src/fenv/sh/fenv.s
+++ b/src/fenv/sh/fenv.S
@@ -1,3 +1,5 @@
+#if __SH_FPU_ANY__ || __SH4__
+
 .global fegetround
 .type   fegetround, @function
 fegetround:
@@ -72,3 +74,5 @@
 2:	lds r0, fpscr
 	rts
 	 mov #0, r0
+
+#endif
diff --git a/src/fenv/sheb-nofpu/fenv.sub b/src/fenv/sheb-nofpu/fenv.sub
deleted file mode 100644
index 9cafca5..0000000
--- a/src/fenv/sheb-nofpu/fenv.sub
+++ /dev/null
@@ -1 +0,0 @@
-../fenv.c
diff --git a/src/internal/arm/syscall.s b/src/internal/arm/syscall.s
index 2028456..64dba2f 100644
--- a/src/internal/arm/syscall.s
+++ b/src/internal/arm/syscall.s
@@ -1,3 +1,4 @@
+.syntax unified
 .global __syscall
 .hidden __syscall
 .type __syscall,%function
@@ -11,6 +12,4 @@
 	ldmfd ip,{r3,r4,r5,r6}
 	svc 0
 	ldmfd sp!,{r4,r5,r6,r7}
-	tst lr,#1
-	moveq pc,lr
 	bx lr
diff --git a/src/internal/atomic.h b/src/internal/atomic.h
new file mode 100644
index 0000000..2097247
--- /dev/null
+++ b/src/internal/atomic.h
@@ -0,0 +1,275 @@
+#ifndef _ATOMIC_H
+#define _ATOMIC_H
+
+#include <stdint.h>
+
+#include "atomic_arch.h"
+
+#ifdef a_ll
+
+#ifndef a_pre_llsc
+#define a_pre_llsc()
+#endif
+
+#ifndef a_post_llsc
+#define a_post_llsc()
+#endif
+
+#ifndef a_cas
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (old==t && !a_sc(p, s));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_swap
+#define a_swap a_swap
+static inline int a_swap(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_fetch_add
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, (unsigned)old + v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_fetch_and
+#define a_fetch_and a_fetch_and
+static inline int a_fetch_and(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, old & v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_fetch_or
+#define a_fetch_or a_fetch_or
+static inline int a_fetch_or(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, old | v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#endif
+
+#ifndef a_cas
+#error missing definition of a_cas
+#endif
+
+#ifndef a_swap
+#define a_swap a_swap
+static inline int a_swap(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, v) != old);
+	return old;
+}
+#endif
+
+#ifndef a_fetch_add
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, (unsigned)old+v) != old);
+	return old;
+}
+#endif
+
+#ifndef a_fetch_and
+#define a_fetch_and a_fetch_and
+static inline int a_fetch_and(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, old&v) != old);
+	return old;
+}
+#endif
+#ifndef a_fetch_or
+#define a_fetch_or a_fetch_or
+static inline int a_fetch_or(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, old|v) != old);
+	return old;
+}
+#endif
+
+#ifndef a_and
+#define a_and a_and
+static inline void a_and(volatile int *p, int v)
+{
+	a_fetch_and(p, v);
+}
+#endif
+
+#ifndef a_or
+#define a_or a_or
+static inline void a_or(volatile int *p, int v)
+{
+	a_fetch_or(p, v);
+}
+#endif
+
+#ifndef a_inc
+#define a_inc a_inc
+static inline void a_inc(volatile int *p)
+{
+	a_fetch_add(p, 1);
+}
+#endif
+
+#ifndef a_dec
+#define a_dec a_dec
+static inline void a_dec(volatile int *p)
+{
+	a_fetch_add(p, -1);
+}
+#endif
+
+#ifndef a_store
+#define a_store a_store
+static inline void a_store(volatile int *p, int v)
+{
+#ifdef a_barrier
+	a_barrier();
+	*p = v;
+	a_barrier();
+#else
+	a_swap(p, v);
+#endif
+}
+#endif
+
+#ifndef a_barrier
+#define a_barrier a_barrier
+static void a_barrier()
+{
+	volatile int tmp = 0;
+	a_cas(&tmp, 0, 0);
+}
+#endif
+
+#ifndef a_spin
+#define a_spin a_barrier
+#endif
+
+#ifndef a_and_64
+#define a_and_64 a_and_64
+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
+{
+	union { uint64_t v; uint32_t r[2]; } u = { v };
+	if (u.r[0]+1) a_and((int *)p, u.r[0]);
+	if (u.r[1]+1) a_and((int *)p+1, u.r[1]);
+}
+#endif
+
+#ifndef a_or_64
+#define a_or_64 a_or_64
+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
+{
+	union { uint64_t v; uint32_t r[2]; } u = { v };
+	if (u.r[0]) a_or((int *)p, u.r[0]);
+	if (u.r[1]) a_or((int *)p+1, u.r[1]);
+}
+#endif
+
+#ifndef a_cas_p
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	return (void *)a_cas((volatile int *)p, (int)t, (int)s);
+}
+#endif
+
+#ifndef a_or_l
+#define a_or_l a_or_l
+static inline void a_or_l(volatile void *p, long v)
+{
+	if (sizeof(long) == sizeof(int)) a_or(p, v);
+	else a_or_64(p, v);
+}
+#endif
+
+#ifndef a_crash
+#define a_crash a_crash
+static inline void a_crash()
+{
+	*(volatile char *)0=0;
+}
+#endif
+
+#ifndef a_ctz_64
+#define a_ctz_64 a_ctz_64
+static inline int a_ctz_64(uint64_t x)
+{
+	static const char debruijn64[64] = {
+		0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
+		62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
+		63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
+		51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
+	};
+	static const char debruijn32[32] = {
+		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
+		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
+	};
+	if (sizeof(long) < 8) {
+		uint32_t y = x;
+		if (!y) {
+			y = x>>32;
+			return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
+		}
+		return debruijn32[(y&-y)*0x076be629 >> 27];
+	}
+	return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
+}
+#endif
+
+#ifndef a_ctz_l
+#define a_ctz_l a_ctz_l
+static inline int a_ctz_l(unsigned long x)
+{
+	static const char debruijn32[32] = {
+		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
+		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
+	};
+	if (sizeof(long) == 8) return a_ctz_64(x);
+	return debruijn32[(x&-x)*0x076be629 >> 27];
+}
+#endif
+
+#endif
diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h
index 86f379e..48890b2 100644
--- a/src/internal/dynlink.h
+++ b/src/internal/dynlink.h
@@ -64,6 +64,10 @@
 #define DL_FDPIC 0
 #endif
 
+#ifndef DL_NOMMU_SUPPORT
+#define DL_NOMMU_SUPPORT 0
+#endif
+
 #if !DL_FDPIC
 #define IS_RELATIVE(x,s) ( \
 	(R_TYPE(x) == REL_RELATIVE) || \
@@ -79,6 +83,10 @@
 #define NEED_MIPS_GOT_RELOCS 0
 #endif
 
+#ifndef DT_DEBUG_INDIRECT
+#define DT_DEBUG_INDIRECT 0
+#endif
+
 #define AUX_CNT 32
 #define DYN_CNT 32
 
diff --git a/src/internal/libc.h b/src/internal/libc.h
index 98c7535..5e14518 100644
--- a/src/internal/libc.h
+++ b/src/internal/libc.h
@@ -11,13 +11,20 @@
 	const struct __locale_map *volatile cat[6];
 };
 
+struct tls_module {
+	struct tls_module *next;
+	void *image;
+	size_t len, size, align, offset;
+};
+
 struct __libc {
 	int can_do_threads;
 	int threaded;
 	int secure;
 	volatile int threads_minus_1;
 	size_t *auxv;
-	size_t tls_size;
+	struct tls_module *tls_head;
+	size_t tls_size, tls_align, tls_cnt;
 	size_t page_size;
 	struct __locale_struct global_locale;
 };
diff --git a/arch/sh/src/__shcall.c b/src/internal/sh/__shcall.c
similarity index 100%
rename from arch/sh/src/__shcall.c
rename to src/internal/sh/__shcall.c
diff --git a/src/internal/stdio_impl.h b/src/internal/stdio_impl.h
index 0dd7fb5..7cdf729 100644
--- a/src/internal/stdio_impl.h
+++ b/src/internal/stdio_impl.h
@@ -86,7 +86,8 @@
 #define getc_unlocked(f) \
 	( ((f)->rpos < (f)->rend) ? *(f)->rpos++ : __uflow((f)) )
 
-#define putc_unlocked(c, f) ( ((c)!=(f)->lbf && (f)->wpos<(f)->wend) \
+#define putc_unlocked(c, f) \
+	( ((unsigned char)(c)!=(f)->lbf && (f)->wpos<(f)->wend) \
 	? *(f)->wpos++ = (c) : __overflow((f),(c)) )
 
 /* Caller-allocated FILE * operations */
diff --git a/src/internal/syscall.h b/src/internal/syscall.h
index a93f6d1..ff3cf53 100644
--- a/src/internal/syscall.h
+++ b/src/internal/syscall.h
@@ -17,9 +17,7 @@
 typedef long syscall_arg_t;
 #endif
 
-#ifdef SHARED
 __attribute__((visibility("hidden")))
-#endif
 long __syscall_ret(unsigned long), __syscall(syscall_arg_t, ...),
 	__syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t,
 	             syscall_arg_t, syscall_arg_t, syscall_arg_t);
@@ -65,7 +63,7 @@
 #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
 #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
 
-#ifdef SYS_socket
+#ifndef SYSCALL_USE_SOCKETCALL
 #define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_##nm, a, b, c, d, e, f)
 #define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_##nm, a, b, c, d, e, f)
 #else
diff --git a/src/internal/version.c b/src/internal/version.c
index 16554ba..dc044ec 100644
--- a/src/internal/version.c
+++ b/src/internal/version.c
@@ -1,12 +1,9 @@
-#ifdef SHARED
-
 #include "version.h"
 
 static const char version[] = VERSION;
 
+__attribute__((__visibility__("hidden")))
 const char *__libc_get_version()
 {
 	return version;
 }
-
-#endif
diff --git a/src/internal/vis.h b/src/internal/vis.h
index bf7a5b2..35855fc 100644
--- a/src/internal/vis.h
+++ b/src/internal/vis.h
@@ -4,10 +4,9 @@
  * override default visibilities to reduce the size and performance costs
  * of position-independent code. */
 
-#ifndef CRT
-#ifdef SHARED
+#if !defined(CRT) && !defined(__ASSEMBLER__)
 
-/* For shared libc.so, all symbols should be protected, but some toolchains
+/* Conceptually, all symbols should be protected, but some toolchains
  * fail to support copy relocations for protected data, so exclude all
  * exported data symbols. */
 
@@ -25,16 +24,4 @@
 
 #pragma GCC visibility push(protected)
 
-#elif defined(__PIC__)
-
-/* If building static libc.a as position-independent code, try to make
- * everything hidden except possibly-undefined weak references. */
-
-__attribute__((__visibility__("default")))
-extern void (*const __init_array_start)(), (*const __init_array_end)(),
-	(*const __fini_array_start)(), (*const __fini_array_end)();
-
-#pragma GCC visibility push(hidden)
-
-#endif
 #endif
diff --git a/src/ldso/__dlsym.c b/src/ldso/__dlsym.c
new file mode 100644
index 0000000..99aafdf
--- /dev/null
+++ b/src/ldso/__dlsym.c
@@ -0,0 +1,13 @@
+#include <dlfcn.h>
+#include "libc.h"
+
+__attribute__((__visibility__("hidden")))
+void __dl_seterr(const char *, ...);
+
+static void *stub_dlsym(void *restrict p, const char *restrict s, void *restrict ra)
+{
+	__dl_seterr("Symbol not found: %s", s);
+	return 0;
+}
+
+weak_alias(stub_dlsym, __dlsym);
diff --git a/src/ldso/arm/dlsym.s b/src/ldso/arm/dlsym.s
index 3b88d91..2652c34 100644
--- a/src/ldso/arm/dlsym.s
+++ b/src/ldso/arm/dlsym.s
@@ -1,3 +1,4 @@
+.syntax unified
 .text
 .global dlsym
 .hidden __dlsym
diff --git a/arch/arm/src/find_exidx.c b/src/ldso/arm/find_exidx.c
similarity index 100%
rename from arch/arm/src/find_exidx.c
rename to src/ldso/arm/find_exidx.c
diff --git a/src/ldso/dl_iterate_phdr.c b/src/ldso/dl_iterate_phdr.c
index 49b321a..c141fd9 100644
--- a/src/ldso/dl_iterate_phdr.c
+++ b/src/ldso/dl_iterate_phdr.c
@@ -1,12 +1,10 @@
-#ifndef SHARED
-
 #include <elf.h>
 #include <link.h>
 #include "libc.h"
 
 #define AUX_CNT 38
 
-int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
+static int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
 {
 	unsigned char *p;
 	ElfW(Phdr) *phdr, *tls_phdr=0;
@@ -40,4 +38,5 @@
 	}
 	return (callback)(&info, sizeof (info), data);
 }
-#endif
+
+weak_alias(static_dl_iterate_phdr, dl_iterate_phdr);
diff --git a/src/ldso/dladdr.c b/src/ldso/dladdr.c
index 7ca718f..659ab91 100644
--- a/src/ldso/dladdr.c
+++ b/src/ldso/dladdr.c
@@ -1,9 +1,10 @@
 #define _GNU_SOURCE
 #include <dlfcn.h>
+#include "libc.h"
 
-int __dladdr(const void *, Dl_info *);
-
-int dladdr(const void *addr, Dl_info *info)
+static int stub_dladdr(const void *addr, Dl_info *info)
 {
-	return __dladdr(addr, info);
+	return 0;
 }
+
+weak_alias(stub_dladdr, dladdr);
diff --git a/src/ldso/dlclose.c b/src/ldso/dlclose.c
new file mode 100644
index 0000000..0ef2231
--- /dev/null
+++ b/src/ldso/dlclose.c
@@ -0,0 +1,9 @@
+#include <dlfcn.h>
+
+__attribute__((__visibility__("hidden")))
+int __dl_invalid_handle(void *);
+
+int dlclose(void *p)
+{
+	return __dl_invalid_handle(p);
+}
diff --git a/src/ldso/dlerror.c b/src/ldso/dlerror.c
new file mode 100644
index 0000000..378f035
--- /dev/null
+++ b/src/ldso/dlerror.c
@@ -0,0 +1,64 @@
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+char *dlerror()
+{
+	pthread_t self = __pthread_self();
+	if (!self->dlerror_flag) return 0;
+	self->dlerror_flag = 0;
+	char *s = self->dlerror_buf;
+	if (s == (void *)-1)
+		return "Dynamic linker failed to allocate memory for error message";
+	else
+		return s;
+}
+
+void __dl_thread_cleanup(void)
+{
+	pthread_t self = __pthread_self();
+	if (self->dlerror_buf != (void *)-1)
+		free(self->dlerror_buf);
+}
+
+__attribute__((__visibility__("hidden")))
+void __dl_vseterr(const char *fmt, va_list ap)
+{
+	va_list ap2;
+	va_copy(ap2, ap);
+	pthread_t self = __pthread_self();
+	if (self->dlerror_buf != (void *)-1)
+		free(self->dlerror_buf);
+	size_t len = vsnprintf(0, 0, fmt, ap2);
+	va_end(ap2);
+	char *buf = malloc(len+1);
+	if (buf) {
+		vsnprintf(buf, len+1, fmt, ap);
+	} else {
+		buf = (void *)-1;	
+	}
+	self->dlerror_buf = buf;
+	self->dlerror_flag = 1;
+}
+
+__attribute__((__visibility__("hidden")))
+void __dl_seterr(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	__dl_vseterr(fmt, ap);
+	va_end(ap);
+}
+
+__attribute__((__visibility__("hidden")))
+int __dl_invalid_handle(void *);
+
+static int stub_invalid_handle(void *h)
+{
+	__dl_seterr("Invalid library handle %p", (void *)h);
+	return 1;
+}
+
+weak_alias(stub_invalid_handle, __dl_invalid_handle);
diff --git a/src/ldso/dlinfo.c b/src/ldso/dlinfo.c
index 63d276d..a173d1a 100644
--- a/src/ldso/dlinfo.c
+++ b/src/ldso/dlinfo.c
@@ -1,9 +1,19 @@
 #define _GNU_SOURCE
 #include <dlfcn.h>
 
-int __dlinfo(void *, int, void *);
+__attribute__((__visibility__("hidden")))
+int __dl_invalid_handle(void *);
+
+__attribute__((__visibility__("hidden")))
+void __dl_seterr(const char *, ...);
 
 int dlinfo(void *dso, int req, void *res)
 {
-	return __dlinfo(dso, req, res);
+	if (__dl_invalid_handle(dso)) return -1;
+	if (req != RTLD_DI_LINKMAP) {
+		__dl_seterr("Unsupported request %d", req);
+		return -1;
+	}
+	*(struct link_map **)res = dso;
+	return 0;
 }
diff --git a/src/ldso/dlopen.c b/src/ldso/dlopen.c
new file mode 100644
index 0000000..dcdb439
--- /dev/null
+++ b/src/ldso/dlopen.c
@@ -0,0 +1,13 @@
+#include <dlfcn.h>
+#include "libc.h"
+
+__attribute__((__visibility__("hidden")))
+void __dl_seterr(const char *, ...);
+
+static void *stub_dlopen(const char *file, int mode)
+{
+	__dl_seterr("Dynamic loading not supported");
+	return 0;
+}
+
+weak_alias(stub_dlopen, dlopen);
diff --git a/src/ldso/tlsdesc.c b/src/ldso/tlsdesc.c
index 4bc654f..a2985cb 100644
--- a/src/ldso/tlsdesc.c
+++ b/src/ldso/tlsdesc.c
@@ -1,5 +1,3 @@
-#ifdef SHARED
-
 #include <stddef.h>
 #include "libc.h"
 
@@ -12,5 +10,3 @@
 }
 
 weak_alias(__tlsdesc_static, __tlsdesc_dynamic);
-
-#endif
diff --git a/src/legacy/utmpx.c b/src/legacy/utmpx.c
index c483e4e..e2843c9 100644
--- a/src/legacy/utmpx.c
+++ b/src/legacy/utmpx.c
@@ -1,5 +1,6 @@
 #include <utmpx.h>
 #include <stddef.h>
+#include <errno.h>
 #include "libc.h"
 
 void endutxent(void)
@@ -34,6 +35,12 @@
 {
 }
 
+int __utmpxname(const char *f)
+{
+	errno = ENOTSUP;
+	return -1;
+}
+
 weak_alias(endutxent, endutent);
 weak_alias(setutxent, setutent);
 weak_alias(getutxent, getutent);
@@ -41,3 +48,5 @@
 weak_alias(getutxline, getutline);
 weak_alias(pututxline, pututline);
 weak_alias(updwtmpx, updwtmp);
+weak_alias(__utmpxname, utmpname);
+weak_alias(__utmpxname, utmpxname);
diff --git a/arch/x32/src/sysinfo.c b/src/linux/x32/sysinfo.c
similarity index 100%
rename from arch/x32/src/sysinfo.c
rename to src/linux/x32/sysinfo.c
diff --git a/src/linux/x32/sysinfo.s b/src/linux/x32/sysinfo.s
deleted file mode 100644
index 53d79db..0000000
--- a/src/linux/x32/sysinfo.s
+++ /dev/null
@@ -1 +0,0 @@
-# see arch/x32/src/sysinfo.c
diff --git a/src/locale/langinfo.c b/src/locale/langinfo.c
index d3c90d9..b2c8569 100644
--- a/src/locale/langinfo.c
+++ b/src/locale/langinfo.c
@@ -37,23 +37,23 @@
 	
 	switch (cat) {
 	case LC_NUMERIC:
-		if (idx > 1) return NULL;
+		if (idx > 1) return "";
 		str = c_numeric;
 		break;
 	case LC_TIME:
-		if (idx > 0x31) return NULL;
+		if (idx > 0x31) return "";
 		str = c_time;
 		break;
 	case LC_MONETARY:
-		if (idx > 0) return NULL;
+		if (idx > 0) return "";
 		str = "";
 		break;
 	case LC_MESSAGES:
-		if (idx > 3) return NULL;
+		if (idx > 3) return "";
 		str = c_messages;
 		break;
 	default:
-		return NULL;
+		return "";
 	}
 
 	for (; idx; idx--, str++) for (; *str; str++);
diff --git a/src/malloc/lite_malloc.c b/src/malloc/lite_malloc.c
index 09ac575..a7e4a9f 100644
--- a/src/malloc/lite_malloc.c
+++ b/src/malloc/lite_malloc.c
@@ -8,7 +8,7 @@
 
 void *__expand_heap(size_t *);
 
-void *__simple_malloc(size_t n)
+static void *__simple_malloc(size_t n)
 {
 	static char *cur, *end;
 	static volatile int lock[2];
diff --git a/src/malloc/malloc_usable_size.c b/src/malloc/malloc_usable_size.c
index 8cccd9d..6743ea7 100644
--- a/src/malloc/malloc_usable_size.c
+++ b/src/malloc/malloc_usable_size.c
@@ -13,5 +13,5 @@
 
 size_t malloc_usable_size(void *p)
 {
-	return CHUNK_SIZE(MEM_TO_CHUNK(p)) - OVERHEAD;
+	return p ? CHUNK_SIZE(MEM_TO_CHUNK(p)) - OVERHEAD : 0;
 }
diff --git a/src/math/__rem_pio2.c b/src/math/__rem_pio2.c
index a40db9f..d403f81 100644
--- a/src/math/__rem_pio2.c
+++ b/src/math/__rem_pio2.c
@@ -118,7 +118,7 @@
 	if (ix < 0x413921fb) {  /* |x| ~< 2^20*(pi/2), medium size */
 medium:
 		/* rint(x/(pi/2)), Assume round-to-nearest. */
-		fn = x*invpio2 + toint - toint;
+		fn = (double_t)x*invpio2 + toint - toint;
 		n = (int32_t)fn;
 		r = x - fn*pio2_1;
 		w = fn*pio2_1t;  /* 1st round, good to 85 bits */
diff --git a/src/math/__rem_pio2f.c b/src/math/__rem_pio2f.c
index f516385..4473c1c 100644
--- a/src/math/__rem_pio2f.c
+++ b/src/math/__rem_pio2f.c
@@ -51,7 +51,7 @@
 	/* 25+53 bit pi is good enough for medium size */
 	if (ix < 0x4dc90fdb) {  /* |x| ~< 2^28*(pi/2), medium size */
 		/* Use a specialized rint() to get fn.  Assume round-to-nearest. */
-		fn = x*invpio2 + toint - toint;
+		fn = (double_t)x*invpio2 + toint - toint;
 		n  = (int32_t)fn;
 		*y = x - fn*pio2_1 - fn*pio2_1t;
 		return n;
diff --git a/src/math/arm/fabs.c b/src/math/arm/fabs.c
new file mode 100644
index 0000000..f890520
--- /dev/null
+++ b/src/math/arm/fabs.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __ARM_PCS_VFP
+
+double fabs(double x)
+{
+	__asm__ ("vabs.f64 %P0, %P1" : "=w"(x) : "w"(x));
+	return x;
+}
+
+#else
+
+#include "../fabs.c"
+
+#endif
diff --git a/src/math/arm/fabsf.c b/src/math/arm/fabsf.c
new file mode 100644
index 0000000..28153a6
--- /dev/null
+++ b/src/math/arm/fabsf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __ARM_PCS_VFP
+
+float fabsf(float x)
+{
+	__asm__ ("vabs.f32 %0, %1" : "=t"(x) : "t"(x));
+	return x;
+}
+
+#else
+
+#include "../fabsf.c"
+
+#endif
diff --git a/src/math/arm/sqrt.c b/src/math/arm/sqrt.c
new file mode 100644
index 0000000..c9c0008
--- /dev/null
+++ b/src/math/arm/sqrt.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __VFP_FP__ && !__SOFTFP__
+
+double sqrt(double x)
+{
+	__asm__ ("vsqrt.f64 %P0, %P1" : "=w"(x) : "w"(x));
+	return x;
+}
+
+#else
+
+#include "../sqrt.c"
+
+#endif
diff --git a/src/math/arm/sqrtf.c b/src/math/arm/sqrtf.c
new file mode 100644
index 0000000..e657665
--- /dev/null
+++ b/src/math/arm/sqrtf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __VFP_FP__ && !__SOFTFP__
+
+float sqrtf(float x)
+{
+	__asm__ ("vsqrt.f32 %0, %1" : "=t"(x) : "t"(x));
+	return x;
+}
+
+#else
+
+#include "../sqrtf.c"
+
+#endif
diff --git a/src/math/armebhf/fabs.sub b/src/math/armebhf/fabs.sub
deleted file mode 100644
index 10d9fb7..0000000
--- a/src/math/armebhf/fabs.sub
+++ /dev/null
@@ -1 +0,0 @@
-../armhf/fabs.s
diff --git a/src/math/armebhf/fabsf.sub b/src/math/armebhf/fabsf.sub
deleted file mode 100644
index 940b20b..0000000
--- a/src/math/armebhf/fabsf.sub
+++ /dev/null
@@ -1 +0,0 @@
-../armhf/fabsf.s
diff --git a/src/math/armebhf/sqrt.sub b/src/math/armebhf/sqrt.sub
deleted file mode 100644
index de2be11..0000000
--- a/src/math/armebhf/sqrt.sub
+++ /dev/null
@@ -1 +0,0 @@
-../armhf/sqrt.s
diff --git a/src/math/armebhf/sqrtf.sub b/src/math/armebhf/sqrtf.sub
deleted file mode 100644
index 150ab9c..0000000
--- a/src/math/armebhf/sqrtf.sub
+++ /dev/null
@@ -1 +0,0 @@
-../armhf/sqrtf.s
diff --git a/src/math/armhf/fabs.s b/src/math/armhf/fabs.s
deleted file mode 100644
index 8a705e1..0000000
--- a/src/math/armhf/fabs.s
+++ /dev/null
@@ -1,7 +0,0 @@
-.fpu vfp
-.text
-.global fabs
-.type   fabs,%function
-fabs:
-	vabs.f64 d0, d0
-	bx lr
diff --git a/src/math/armhf/fabs.sub b/src/math/armhf/fabs.sub
deleted file mode 100644
index 99e8740..0000000
--- a/src/math/armhf/fabs.sub
+++ /dev/null
@@ -1 +0,0 @@
-fabs.s
diff --git a/src/math/armhf/fabsf.s b/src/math/armhf/fabsf.s
deleted file mode 100644
index 2c7beb6..0000000
--- a/src/math/armhf/fabsf.s
+++ /dev/null
@@ -1,7 +0,0 @@
-.fpu vfp
-.text
-.global fabsf
-.type   fabsf,%function
-fabsf:
-	vabs.f32 s0, s0
-	bx lr
diff --git a/src/math/armhf/fabsf.sub b/src/math/armhf/fabsf.sub
deleted file mode 100644
index c04638a..0000000
--- a/src/math/armhf/fabsf.sub
+++ /dev/null
@@ -1 +0,0 @@
-fabsf.s
diff --git a/src/math/armhf/sqrt.s b/src/math/armhf/sqrt.s
deleted file mode 100644
index 90f74a9..0000000
--- a/src/math/armhf/sqrt.s
+++ /dev/null
@@ -1,7 +0,0 @@
-.fpu vfp
-.text
-.global sqrt
-.type   sqrt,%function
-sqrt:
-	vsqrt.f64 d0, d0
-	bx lr
diff --git a/src/math/armhf/sqrt.sub b/src/math/armhf/sqrt.sub
deleted file mode 100644
index 25de7cf..0000000
--- a/src/math/armhf/sqrt.sub
+++ /dev/null
@@ -1 +0,0 @@
-sqrt.s
diff --git a/src/math/armhf/sqrtf.s b/src/math/armhf/sqrtf.s
deleted file mode 100644
index 91d8ad6..0000000
--- a/src/math/armhf/sqrtf.s
+++ /dev/null
@@ -1,7 +0,0 @@
-.fpu vfp
-.text
-.global sqrtf
-.type   sqrtf,%function
-sqrtf:
-	vsqrt.f32 s0, s0
-	bx lr
diff --git a/src/math/armhf/sqrtf.sub b/src/math/armhf/sqrtf.sub
deleted file mode 100644
index 3bcbac8..0000000
--- a/src/math/armhf/sqrtf.sub
+++ /dev/null
@@ -1 +0,0 @@
-sqrtf.s
diff --git a/src/math/hypot.c b/src/math/hypot.c
index 29ec6a4..6071bf1 100644
--- a/src/math/hypot.c
+++ b/src/math/hypot.c
@@ -12,10 +12,10 @@
 {
 	double_t xh, xl, xc;
 
-	xc = x*SPLIT;
+	xc = (double_t)x*SPLIT;
 	xh = x - xc + xc;
 	xl = x - xh;
-	*hi = x*x;
+	*hi = (double_t)x*x;
 	*lo = xh*xh - *hi + 2*xh*xl + xl*xl;
 }
 
diff --git a/src/mman/mremap.c b/src/mman/mremap.c
index 596c45f..ce4e8ea 100644
--- a/src/mman/mremap.c
+++ b/src/mman/mremap.c
@@ -1,17 +1,31 @@
+#define _GNU_SOURCE
 #include <unistd.h>
 #include <sys/mman.h>
+#include <errno.h>
+#include <stdint.h>
 #include <stdarg.h>
 #include "syscall.h"
 #include "libc.h"
 
+static void dummy(void) { }
+weak_alias(dummy, __vm_wait);
+
 void *__mremap(void *old_addr, size_t old_len, size_t new_len, int flags, ...)
 {
 	va_list ap;
-	void *new_addr;
-	
-	va_start(ap, flags);
-	new_addr = va_arg(ap, void *);
-	va_end(ap);
+	void *new_addr = 0;
+
+	if (new_len >= PTRDIFF_MAX) {
+		errno = ENOMEM;
+		return MAP_FAILED;
+	}
+
+	if (flags & MREMAP_FIXED) {
+		__vm_wait();
+		va_start(ap, flags);
+		new_addr = va_arg(ap, void *);
+		va_end(ap);
+	}
 
 	return (void *)syscall(SYS_mremap, old_addr, old_len, new_len, flags, new_addr);
 }
diff --git a/src/network/getifaddrs.c b/src/network/getifaddrs.c
index 89a8f72..fed75bd 100644
--- a/src/network/getifaddrs.c
+++ b/src/network/getifaddrs.c
@@ -162,13 +162,26 @@
 		for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
 			switch (rta->rta_type) {
 			case IFA_ADDRESS:
-				copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				/* If ifa_addr is already set we, received an IFA_LOCAL before
+				 * so treat this as destination address */
+				if (ifs->ifa.ifa_addr)
+					copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				else
+					copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
 				break;
 			case IFA_BROADCAST:
-				/* For point-to-point links this is peer, but ifa_broadaddr
-				 * and ifa_dstaddr are union, so this works for both.  */
 				copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
 				break;
+			case IFA_LOCAL:
+				/* If ifa_addr is set and we get IFA_LOCAL, assume we have
+				 * a point-to-point network. Move address to correct field. */
+				if (ifs->ifa.ifa_addr) {
+					ifs->ifu = ifs->addr;
+					ifs->ifa.ifa_dstaddr = &ifs->ifu.sa;
+					memset(&ifs->addr, 0, sizeof(ifs->addr));
+				}
+				copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				break;
 			case IFA_LABEL:
 				if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
 					memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
diff --git a/src/network/getnameinfo.c b/src/network/getnameinfo.c
index 3484fc6..5e6fae3 100644
--- a/src/network/getnameinfo.c
+++ b/src/network/getnameinfo.c
@@ -135,13 +135,13 @@
 	switch (af) {
 	case AF_INET:
 		a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
-		if (sl != sizeof(struct sockaddr_in)) return EAI_FAMILY;
+		if (sl < sizeof(struct sockaddr_in)) return EAI_FAMILY;
 		mkptr4(ptr, a);
 		scopeid = 0;
 		break;
 	case AF_INET6:
 		a = (void *)&((struct sockaddr_in6 *)sa)->sin6_addr;
-		if (sl != sizeof(struct sockaddr_in6)) return EAI_FAMILY;
+		if (sl < sizeof(struct sockaddr_in6)) return EAI_FAMILY;
 		if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12))
 			mkptr6(ptr, a);
 		else
diff --git a/src/network/if_nametoindex.c b/src/network/if_nametoindex.c
index cb6ec05..331413c 100644
--- a/src/network/if_nametoindex.c
+++ b/src/network/if_nametoindex.c
@@ -10,7 +10,7 @@
 	struct ifreq ifr;
 	int fd, r;
 
-	if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return -1;
+	if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
 	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
 	r = ioctl(fd, SIOCGIFINDEX, &ifr);
 	__syscall(SYS_close, fd);
diff --git a/src/network/lookup.h b/src/network/lookup.h
index 6941911..0468edb 100644
--- a/src/network/lookup.h
+++ b/src/network/lookup.h
@@ -2,6 +2,7 @@
 #define LOOKUP_H
 
 #include <stdint.h>
+#include <stddef.h>
 
 struct address {
 	int family;
@@ -15,6 +16,14 @@
 	unsigned char proto, socktype;
 };
 
+#define MAXNS 3
+
+struct resolvconf {
+	struct address ns[MAXNS];
+	unsigned nns, attempts, ndots;
+	unsigned timeout;
+};
+
 /* The limit of 48 results is a non-sharp bound on the number of addresses
  * that can fit in one 512-byte DNS packet full of v4 results and a second
  * packet full of v6 results. Due to headers, the actual limit is lower. */
@@ -25,4 +34,6 @@
 int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags);
 int __lookup_ipliteral(struct address buf[static 1], const char *name, int family);
 
+int __get_resolv_conf(struct resolvconf *, char *, size_t);
+
 #endif
diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
index 0225a93..a26ad53 100644
--- a/src/network/lookup_name.c
+++ b/src/network/lookup_name.c
@@ -9,6 +9,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <pthread.h>
+#include <errno.h>
 #include "lookup.h"
 #include "stdio_impl.h"
 #include "syscall.h"
@@ -51,7 +52,14 @@
 	int cnt = 0;
 	unsigned char _buf[1032];
 	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
-	if (!f) return 0;
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		return 0;
+	default:
+		return EAI_SYSTEM;
+	}
 	while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
 		char *p, *z;
 
@@ -85,7 +93,7 @@
 int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *);
 int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
 int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
-int __res_msend(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int);
+int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *);
 
 #define RR_A 1
 #define RR_CNAME 5
@@ -117,7 +125,7 @@
 	return 0;
 }
 
-static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf)
 {
 	unsigned char qbuf[2][280], abuf[2][512];
 	const unsigned char *qp[2] = { qbuf[0], qbuf[1] };
@@ -137,17 +145,59 @@
 		nq++;
 	}
 
-	if (__res_msend(nq, qp, qlens, ap, alens, sizeof *abuf) < 0) return EAI_SYSTEM;
+	if (__res_msend_rc(nq, qp, qlens, ap, alens, sizeof *abuf, conf) < 0)
+		return EAI_SYSTEM;
 
 	for (i=0; i<nq; i++)
 		__dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
 
 	if (ctx.cnt) return ctx.cnt;
 	if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
-	if ((abuf[0][3] & 15) == 3) return EAI_NONAME;
+	if ((abuf[0][3] & 15) == 0) return EAI_NONAME;
+	if ((abuf[0][3] & 15) == 3) return 0;
 	return EAI_FAIL;
 }
 
+static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+{
+	char search[256];
+	struct resolvconf conf;
+	size_t l, dots;
+	char *p, *z;
+
+	if (__get_resolv_conf(&conf, search, sizeof search) < 0) return -1;
+
+	/* Count dots, suppress search when >=ndots or name ends in
+	 * a dot, which is an explicit request for global scope. */
+	for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++;
+	if (dots >= conf.ndots || name[l-1]=='.') *search = 0;
+
+	/* This can never happen; the caller already checked length. */
+	if (l >= 256) return EAI_NONAME;
+
+	/* Name with search domain appended is setup in canon[]. This both
+	 * provides the desired default canonical name (if the requested
+	 * name is not a CNAME record) and serves as a buffer for passing
+	 * the full requested name to name_from_dns. */
+	memcpy(canon, name, l);
+	canon[l] = '.';
+
+	for (p=search; *p; p=z) {
+		for (; isspace(*p); p++);
+		for (z=p; *z && !isspace(*z); z++);
+		if (z==p) break;
+		if (z-p < 256 - l - 1) {
+			memcpy(canon+l+1, p, z-p);
+			canon[z-p+1+l] = 0;
+			int cnt = name_from_dns(buf, canon, canon, family, &conf);
+			if (cnt) return cnt;
+		}
+	}
+
+	canon[l] = 0;
+	return name_from_dns(buf, canon, name, family, &conf);
+}
+
 static const struct policy {
 	unsigned char addr[16];
 	unsigned char len, mask;
@@ -248,7 +298,7 @@
 	if (!cnt) cnt = name_from_numeric(buf, name, family);
 	if (!cnt && !(flags & AI_NUMERICHOST)) {
 		cnt = name_from_hosts(buf, canon, name, family);
-		if (!cnt) cnt = name_from_dns(buf, canon, name, family);
+		if (!cnt) cnt = name_from_dns_search(buf, canon, name, family);
 	}
 	if (cnt<=0) return cnt ? cnt : EAI_NONAME;
 
diff --git a/src/network/lookup_serv.c b/src/network/lookup_serv.c
index 4faa5bc..66ebaea 100644
--- a/src/network/lookup_serv.c
+++ b/src/network/lookup_serv.c
@@ -4,6 +4,7 @@
 #include <ctype.h>
 #include <string.h>
 #include <fcntl.h>
+#include <errno.h>
 #include "lookup.h"
 #include "stdio_impl.h"
 
@@ -69,7 +70,14 @@
 
 	unsigned char _buf[1032];
 	FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
-	if (!f) return EAI_SERVICE;
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		return EAI_SERVICE;
+	default:
+		return EAI_SYSTEM;
+	}
 
 	while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
 		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
diff --git a/src/network/proto.c b/src/network/proto.c
index 43aa17a..a42d145 100644
--- a/src/network/proto.c
+++ b/src/network/proto.c
@@ -9,21 +9,36 @@
 	"\001icmp\0"
 	"\002igmp\0"
 	"\003ggp\0"
+	"\004ipencap\0"
+	"\005st\0"
 	"\006tcp\0"
+	"\008egp\0"
 	"\014pup\0"
 	"\021udp\0"
-	"\026idp\0"
+	"\024hmp\0"
+	"\026xns-idp\0"
+	"\033rdp\0"
+	"\035iso-tp4\0"
+	"\044xtp\0"
+	"\045ddp\0"
+	"\046idpr-cmtp\0"
 	"\051ipv6\0"
 	"\053ipv6-route\0"
 	"\054ipv6-frag\0"
+	"\055idrp\0"
+	"\056rsvp\0"
 	"\057gre\0"
 	"\062esp\0"
 	"\063ah\0"
+	"\071skip\0"
 	"\072ipv6-icmp\0"
 	"\073ipv6-nonxt\0"
 	"\074ipv6-opts\0"
+	"\111rspf\0"
+	"\121vmtp\0"
 	"\131ospf\0"
 	"\136ipip\0"
+	"\142encap\0"
 	"\147pim\0"
 	"\377raw"
 };
diff --git a/src/network/res_msend.c b/src/network/res_msend.c
index 35f106d..a47d18d 100644
--- a/src/network/res_msend.c
+++ b/src/network/res_msend.c
@@ -27,18 +27,16 @@
 		+ ts.tv_nsec / 1000000;
 }
 
-int __res_msend(int nqueries, const unsigned char *const *queries,
-	const int *qlens, unsigned char *const *answers, int *alens, int asize)
+int __res_msend_rc(int nqueries, const unsigned char *const *queries,
+	const int *qlens, unsigned char *const *answers, int *alens, int asize,
+	const struct resolvconf *conf)
 {
 	int fd;
-	FILE *f, _f;
-	unsigned char _buf[256];
-	char line[64], *s, *z;
-	int timeout = 5000, attempts = 2, retry_interval, servfail_retry;
+	int timeout, attempts, retry_interval, servfail_retry;
 	union {
 		struct sockaddr_in sin;
 		struct sockaddr_in6 sin6;
-	} sa = {0}, ns[3] = {{0}};
+	} sa = {0}, ns[MAXNS] = {{0}};
 	socklen_t sl = sizeof sa.sin;
 	int nns = 0;
 	int family = AF_INET;
@@ -48,57 +46,27 @@
 	int cs;
 	struct pollfd pfd;
 	unsigned long t0, t1, t2;
-	struct address iplit;
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 
-	/* Get nameservers from resolv.conf, fallback to localhost */
-	f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
-	if (f) for (nns=0; nns<3 && fgets(line, sizeof line, f); ) {
-		if (!strncmp(line, "options", 7) && isspace(line[7])) {
-			unsigned long x;
-			char *p, *z;
-			p = strstr(line, "timeout:");
-			if (p && isdigit(p[8])) {
-				p += 8;
-				x = strtoul(p, &z, 10);
-				if (z != p) timeout = x < 30 ? x*1000 : 30000;
-			}
-			p = strstr(line, "attempts:");
-			if (p && isdigit(p[9])) {
-				p += 9;
-				x = strtoul(p, &z, 10);
-				if (z != p) attempts = x < 10 ? x : 10;
-				if (!attempts) attempts = 1;
-			}
-		}
-		if (strncmp(line, "nameserver", 10) || !isspace(line[10]))
-			continue;
-		for (s=line+11; isspace(*s); s++);
-		for (z=s; *z && !isspace(*z); z++);
-		*z=0;
+	timeout = 1000*conf->timeout;
+	attempts = conf->attempts;
 
-		if (__lookup_ipliteral(&iplit, s, AF_UNSPEC)>0) {
-			if (iplit.family == AF_INET) {
-				memcpy(&ns[nns].sin.sin_addr, iplit.addr, 4);
-				ns[nns].sin.sin_port = htons(53);
-				ns[nns++].sin.sin_family = AF_INET;
-			} else {
-				sl = sizeof sa.sin6;
-				memcpy(&ns[nns].sin6.sin6_addr, iplit.addr, 16);
-				ns[nns].sin6.sin6_port = htons(53);
-				ns[nns].sin6.sin6_scope_id = iplit.scopeid;
-				ns[nns++].sin6.sin6_family = family = AF_INET6;
-			}
+	nns = conf->nns;
+	for (nns=0; nns<conf->nns; nns++) {
+		const struct address *iplit = &conf->ns[nns];
+		if (iplit->family == AF_INET) {
+			memcpy(&ns[nns].sin.sin_addr, iplit->addr, 4);
+			ns[nns].sin.sin_port = htons(53);
+			ns[nns].sin.sin_family = AF_INET;
+		} else {
+			sl = sizeof sa.sin6;
+			memcpy(&ns[nns].sin6.sin6_addr, iplit->addr, 16);
+			ns[nns].sin6.sin6_port = htons(53);
+			ns[nns].sin6.sin6_scope_id = iplit->scopeid;
+			ns[nns].sin6.sin6_family = family = AF_INET6;
 		}
 	}
-	if (f) __fclose_ca(f);
-	if (!nns) {
-		ns[0].sin.sin_family = AF_INET;
-		ns[0].sin.sin_port = htons(53);
-		ns[0].sin.sin_addr.s_addr = htonl(0x7f000001);
-		nns=1;
-	}
 
 	/* Get local address and open/bind a socket */
 	sa.sin.sin_family = family;
@@ -207,3 +175,11 @@
 
 	return 0;
 }
+
+int __res_msend(int nqueries, const unsigned char *const *queries,
+	const int *qlens, unsigned char *const *answers, int *alens, int asize)
+{
+	struct resolvconf conf;
+	if (__get_resolv_conf(&conf, 0, 0) < 0) return -1;
+	return __res_msend_rc(nqueries, queries, qlens, answers, alens, asize, &conf);
+}
diff --git a/src/network/resolvconf.c b/src/network/resolvconf.c
new file mode 100644
index 0000000..2cf1f47
--- /dev/null
+++ b/src/network/resolvconf.c
@@ -0,0 +1,93 @@
+#include "lookup.h"
+#include "stdio_impl.h"
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <netinet/in.h>
+
+int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
+{
+	char line[256];
+	unsigned char _buf[256];
+	FILE *f, _f;
+	int nns = 0;
+
+	conf->ndots = 1;
+	conf->timeout = 5;
+	conf->attempts = 2;
+	if (search) *search = 0;
+
+	f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		goto no_resolv_conf;
+	default:
+		return -1;
+	}
+
+	while (fgets(line, sizeof line, f)) {
+		char *p, *z;
+		if (!strchr(line, '\n') && !feof(f)) {
+			/* Ignore lines that get truncated rather than
+			 * potentially misinterpreting them. */
+			int c;
+			do c = getc(f);
+			while (c != '\n' && c != EOF);
+			continue;
+		}
+		if (!strncmp(line, "options", 7) && isspace(line[7])) {
+			p = strstr(line, "ndots:");
+			if (p && isdigit(p[6])) {
+				p += 6;
+				unsigned long x = strtoul(p, &z, 10);
+				if (z != p) conf->ndots = x > 15 ? 15 : x;
+			}
+			p = strstr(line, "attempts:");
+			if (p && isdigit(p[6])) {
+				p += 6;
+				unsigned long x = strtoul(p, &z, 10);
+				if (z != p) conf->attempts = x > 10 ? 10 : x;
+			}
+			p = strstr(line, "timeout:");
+			if (p && (isdigit(p[8]) || p[8]=='.')) {
+				p += 8;
+				unsigned long x = strtoul(p, &z, 10);
+				if (z != p) conf->timeout = x > 60 ? 60 : x;
+			}
+			continue;
+		}
+		if (!strncmp(line, "nameserver", 10) && isspace(line[10])) {
+			if (nns >= MAXNS) continue;
+			for (p=line+11; isspace(*p); p++);
+			for (z=p; *z && !isspace(*z); z++);
+			*z=0;
+			if (__lookup_ipliteral(conf->ns+nns, p, AF_UNSPEC) > 0)
+				nns++;
+			continue;
+		}
+
+		if (!search) continue;
+		if ((strncmp(line, "domain", 6) && strncmp(line, "search", 6))
+		    || !isspace(line[6]))
+			continue;
+		for (p=line+7; isspace(*p); p++);
+		size_t l = strlen(p);
+		/* This can never happen anyway with chosen buffer sizes. */
+		if (l >= search_sz) continue;
+		memcpy(search, p, l+1);
+	}
+
+	__fclose_ca(f);
+
+no_resolv_conf:
+	if (!nns) {
+		__lookup_ipliteral(conf->ns, "127.0.0.1", AF_UNSPEC);
+		nns = 1;
+	}
+
+	conf->nns = nns;
+
+	return 0;
+}
diff --git a/src/regex/regcomp.c b/src/regex/regcomp.c
index 330de46..da6abd1 100644
--- a/src/regex/regcomp.c
+++ b/src/regex/regcomp.c
@@ -708,7 +708,7 @@
 	return s;
 }
 
-static reg_errcode_t parse_dup(tre_parse_ctx_t *ctx, const char *s)
+static const char *parse_dup(const char *s, int ere, int *pmin, int *pmax)
 {
 	int min, max;
 
@@ -723,19 +723,13 @@
 		max > RE_DUP_MAX ||
 		min > RE_DUP_MAX ||
 		min < 0 ||
-		(!(ctx->cflags & REG_EXTENDED) && *s++ != '\\') ||
+		(!ere && *s++ != '\\') ||
 		*s++ != '}'
 	)
-		return REG_BADBR;
-
-	if (min == 0 && max == 0)
-		ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
-	else
-		ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);
-	if (!ctx->n)
-		return REG_ESPACE;
-	ctx->s = s;
-	return REG_OK;
+		return 0;
+	*pmin = min;
+	*pmax = max;
+	return s;
 }
 
 static int hexval(unsigned c)
@@ -834,22 +828,35 @@
 					return REG_EBRACE;
 				s++;
 			}
-			node = tre_ast_new_literal(ctx->mem, v, v, ctx->position);
-			ctx->position++;
+			node = tre_ast_new_literal(ctx->mem, v, v, ctx->position++);
 			s--;
 			break;
+		case '{':
+		case '+':
+		case '?':
+			/* extension: treat \+, \? as repetitions in BRE */
+			/* reject repetitions after empty expression in BRE */
+			if (!ere)
+				return REG_BADRPT;
+		case '|':
+			/* extension: treat \| as alternation in BRE */
+			if (!ere) {
+				node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+				s--;
+				goto end;
+			}
+			/* fallthrough */
 		default:
 			if (!ere && (unsigned)*s-'1' < 9) {
 				/* back reference */
 				int val = *s - '0';
-				node = tre_ast_new_literal(ctx->mem, BACKREF, val, ctx->position);
+				node = tre_ast_new_literal(ctx->mem, BACKREF, val, ctx->position++);
 				ctx->max_backref = MAX(val, ctx->max_backref);
 			} else {
 				/* extension: accept unknown escaped char
 				   as a literal */
 				goto parse_literal;
 			}
-			ctx->position++;
 		}
 		s++;
 		break;
@@ -882,10 +889,14 @@
 		s++;
 		break;
 	case '*':
-	case '|':
+		return REG_BADPAT;
 	case '{':
 	case '+':
 	case '?':
+		/* reject repetitions after empty expression in ERE */
+		if (ere)
+			return REG_BADRPT;
+	case '|':
 		if (!ere)
 			goto parse_literal;
 	case 0:
@@ -912,6 +923,7 @@
 		s += len;
 		break;
 	}
+end:
 	if (!node)
 		return REG_ESPACE;
 	ctx->n = node;
@@ -966,56 +978,69 @@
 		}
 
 	parse_iter:
-		/* extension: repetitions are accepted after an empty node
-		   eg. (+), ^*, a$?, a|{2} */
-		switch (*s) {
-		case '+':
-		case '?':
-			if (!ere)
+		/* extension: repetitions are rejected after an empty node
+		   eg. (+), |*, {2}, but assertions are not treated as empty
+		   so ^* or $? are accepted currently. */
+		for (;;) {
+			int min, max;
+
+			if (*s!='\\' && *s!='*') {
+				if (!ere)
+					break;
+				if (*s!='+' && *s!='?' && *s!='{')
+					break;
+			}
+			if (*s=='\\' && ere)
 				break;
-			/* fallthrough */
-		case '*':;
-			int min=0, max=-1;
-			if (*s == '+')
-				min = 1;
-			if (*s == '?')
-				max = 1;
-			s++;
-			ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);
-			if (!ctx->n)
-				return REG_ESPACE;
+			/* extension: treat \+, \? as repetitions in BRE */
+			if (*s=='\\' && s[1]!='+' && s[1]!='?' && s[1]!='{')
+				break;
+			if (*s=='\\')
+				s++;
+
 			/* extension: multiple consecutive *+?{,} is unspecified,
 			   but (a+)+ has to be supported so accepting a++ makes
 			   sense, note however that the RE_DUP_MAX limit can be
 			   circumvented: (a{255}){255} uses a lot of memory.. */
-			goto parse_iter;
-		case '\\':
-			if (ere || s[1] != '{')
-				break;
-			s++;
-			goto parse_brace;
-		case '{':
-			if (!ere)
-				break;
-		parse_brace:
-			err = parse_dup(ctx, s+1);
-			if (err != REG_OK)
-				return err;
-			s = ctx->s;
-			goto parse_iter;
+			if (*s=='{') {
+				s = parse_dup(s+1, ere, &min, &max);
+				if (!s)
+					return REG_BADBR;
+			} else {
+				min=0;
+				max=-1;
+				if (*s == '+')
+					min = 1;
+				if (*s == '?')
+					max = 1;
+				s++;
+			}
+			if (max == 0)
+				ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+			else
+				ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);
+			if (!ctx->n)
+				return REG_ESPACE;
 		}
 
 		nbranch = tre_ast_new_catenation(ctx->mem, nbranch, ctx->n);
 		if ((ere && *s == '|') ||
 		    (ere && *s == ')' && depth) ||
 		    (!ere && *s == '\\' && s[1] == ')') ||
+		    /* extension: treat \| as alternation in BRE */
+		    (!ere && *s == '\\' && s[1] == '|') ||
 		    !*s) {
 			/* extension: empty branch is unspecified (), (|a), (a|)
 			   here they are not rejected but match on empty string */
 			int c = *s;
 			nunion = tre_ast_new_union(ctx->mem, nunion, nbranch);
 			nbranch = 0;
-			if (c != '|') {
+
+			if (c == '\\' && s[1] == '|') {
+				s+=2;
+			} else if (c == '|') {
+				s++;
+			} else {
 				if (c == '\\') {
 					if (!depth) return REG_EPAREN;
 					s+=2;
@@ -1035,7 +1060,6 @@
 				nunion = tre_stack_pop_voidptr(stack);
 				goto parse_iter;
 			}
-			s++;
 		}
 	}
 }
@@ -2664,7 +2688,7 @@
 
   /* Allocate a stack used throughout the compilation process for various
      purposes. */
-  stack = tre_stack_new(512, 10240, 128);
+  stack = tre_stack_new(512, 1024000, 128);
   if (!stack)
     return REG_ESPACE;
   /* Allocate a fast memory allocator. */
diff --git a/src/search/tsearch_avl.c b/src/search/tsearch_avl.c
index 8620092..57194c8 100644
--- a/src/search/tsearch_avl.c
+++ b/src/search/tsearch_avl.c
@@ -77,38 +77,45 @@
 		return find(n->right, k, cmp);
 }
 
-static struct node *insert(struct node **n, const void *k,
-	int (*cmp)(const void *, const void *), int *new)
+static struct node *insert(struct node *n, const void *k,
+	int (*cmp)(const void *, const void *), struct node **found)
 {
-	struct node *r = *n;
+	struct node *r;
 	int c;
 
-	if (!r) {
-		*n = r = malloc(sizeof **n);
-		if (r) {
-			r->key = k;
-			r->left = r->right = 0;
-			r->height = 1;
+	if (!n) {
+		n = malloc(sizeof *n);
+		if (n) {
+			n->key = k;
+			n->left = n->right = 0;
+			n->height = 1;
 		}
-		*new = 1;
-		return r;
+		*found = n;
+		return n;
 	}
-	c = cmp(k, r->key);
-	if (c == 0)
-		return r;
-	if (c < 0)
-		r = insert(&r->left, k, cmp, new);
-	else
-		r = insert(&r->right, k, cmp, new);
-	if (*new)
-		*n = balance(*n);
+	c = cmp(k, n->key);
+	if (c == 0) {
+		*found = n;
+		return 0;
+	}
+	r = insert(c < 0 ? n->left : n->right, k, cmp, found);
+	if (r) {
+		if (c < 0)
+			n->left = r;
+		else
+			n->right = r;
+		r = balance(n);
+	}
 	return r;
 }
 
-static struct node *movr(struct node *n, struct node *r) {
-	if (!n)
-		return r;
-	n->right = movr(n->right, r);
+static struct node *remove_rightmost(struct node *n, struct node **rightmost)
+{
+	if (!n->right) {
+		*rightmost = n;
+		return n->left;
+	}
+	n->right = remove_rightmost(n->right, rightmost);
 	return balance(n);
 }
 
@@ -122,7 +129,13 @@
 	c = cmp(k, (*n)->key);
 	if (c == 0) {
 		struct node *r = *n;
-		*n = movr(r->left, r->right);
+		if (r->left) {
+			r->left = remove_rightmost(r->left, n);
+			(*n)->left = r->left;
+			(*n)->right = r->right;
+			*n = balance(*n);
+		} else
+			*n = r->right;
 		free(r);
 		return parent;
 	}
@@ -138,6 +151,8 @@
 void *tdelete(const void *restrict key, void **restrict rootp,
 	int(*compar)(const void *, const void *))
 {
+	if (!rootp)
+		return 0;
 	struct node *n = *rootp;
 	struct node *ret;
 	/* last argument is arbitrary non-null pointer
@@ -150,17 +165,21 @@
 void *tfind(const void *key, void *const *rootp,
 	int(*compar)(const void *, const void *))
 {
+	if (!rootp)
+		return 0;
 	return find(*rootp, key, compar);
 }
 
 void *tsearch(const void *key, void **rootp,
 	int (*compar)(const void *, const void *))
 {
-	int new = 0;
-	struct node *n = *rootp;
+	struct node *update;
 	struct node *ret;
-	ret = insert(&n, key, compar, &new);
-	*rootp = n;
+	if (!rootp)
+		return 0;
+	update = insert(*rootp, key, compar, &ret);
+	if (update)
+		*rootp = update;
 	return ret;
 }
 
diff --git a/src/setjmp/arm/longjmp.s b/src/setjmp/arm/longjmp.s
index c3d15ae..e28d8f3 100644
--- a/src/setjmp/arm/longjmp.s
+++ b/src/setjmp/arm/longjmp.s
@@ -1,3 +1,4 @@
+.syntax unified
 .global _longjmp
 .global longjmp
 .type _longjmp,%function
@@ -20,7 +21,11 @@
 	ldc p2, cr4, [ip], #48
 2:	tst r1,#0x40
 	beq 2f
-	.word 0xecbc8b10 /* vldmia ip!, {d8-d15} */
+	.fpu vfp
+	vldmia ip!, {d8-d15}
+	.fpu softvfp
+	.eabi_attribute 10, 0
+	.eabi_attribute 27, 0
 2:	tst r1,#0x200
 	beq 3f
 	ldcl p1, cr10, [ip], #8
@@ -29,9 +34,7 @@
 	ldcl p1, cr13, [ip], #8
 	ldcl p1, cr14, [ip], #8
 	ldcl p1, cr15, [ip], #8
-3:	tst lr,#1
-	moveq pc,lr
-	bx lr
+3:	bx lr
 
 .hidden __hwcap
 1:	.word __hwcap-1b
diff --git a/src/setjmp/arm/setjmp.s b/src/setjmp/arm/setjmp.s
index 19f8abc..8779163 100644
--- a/src/setjmp/arm/setjmp.s
+++ b/src/setjmp/arm/setjmp.s
@@ -1,3 +1,4 @@
+.syntax unified
 .global __setjmp
 .global _setjmp
 .global setjmp
@@ -22,7 +23,11 @@
 	stc p2, cr4, [ip], #48
 2:	tst r1,#0x40
 	beq 2f
-	.word 0xecac8b10 /* vstmia ip!, {d8-d15} */
+	.fpu vfp
+	vstmia ip!, {d8-d15}
+	.fpu softvfp
+	.eabi_attribute 10, 0
+	.eabi_attribute 27, 0
 2:	tst r1,#0x200
 	beq 3f
 	stcl p1, cr10, [ip], #8
@@ -31,9 +36,7 @@
 	stcl p1, cr13, [ip], #8
 	stcl p1, cr14, [ip], #8
 	stcl p1, cr15, [ip], #8
-3:	tst lr,#1
-	moveq pc,lr
-	bx lr
+3:	bx lr
 
 .hidden __hwcap
 1:	.word __hwcap-1b
diff --git a/src/setjmp/mips-sf/longjmp.s b/src/setjmp/mips-sf/longjmp.s
deleted file mode 100644
index 8e76967..0000000
--- a/src/setjmp/mips-sf/longjmp.s
+++ /dev/null
@@ -1,25 +0,0 @@
-.set noreorder
-
-.global _longjmp
-.global longjmp
-.type   _longjmp,@function
-.type   longjmp,@function
-_longjmp:
-longjmp:
-	move    $2, $5
-	bne     $2, $0, 1f
-	nop
-	addu    $2, $2, 1
-1:	lw      $ra,  0($4)
-	lw      $sp,  4($4)
-	lw      $16,  8($4)
-	lw      $17, 12($4)
-	lw      $18, 16($4)
-	lw      $19, 20($4)
-	lw      $20, 24($4)
-	lw      $21, 28($4)
-	lw      $22, 32($4)
-	lw      $23, 36($4)
-	lw      $30, 40($4)
-	jr      $ra
-	lw      $28, 44($4)
diff --git a/src/setjmp/mips-sf/longjmp.sub b/src/setjmp/mips-sf/longjmp.sub
deleted file mode 100644
index e80331b..0000000
--- a/src/setjmp/mips-sf/longjmp.sub
+++ /dev/null
@@ -1 +0,0 @@
-longjmp.s
diff --git a/src/setjmp/mips-sf/setjmp.s b/src/setjmp/mips-sf/setjmp.s
deleted file mode 100644
index 38ed5e0..0000000
--- a/src/setjmp/mips-sf/setjmp.s
+++ /dev/null
@@ -1,25 +0,0 @@
-.set noreorder
-
-.global __setjmp
-.global _setjmp
-.global setjmp
-.type   __setjmp,@function
-.type   _setjmp,@function
-.type   setjmp,@function
-__setjmp:
-_setjmp:
-setjmp:
-	sw      $ra,  0($4)
-	sw      $sp,  4($4)
-	sw      $16,  8($4)
-	sw      $17, 12($4)
-	sw      $18, 16($4)
-	sw      $19, 20($4)
-	sw      $20, 24($4)
-	sw      $21, 28($4)
-	sw      $22, 32($4)
-	sw      $23, 36($4)
-	sw      $30, 40($4)
-	sw      $28, 44($4)
-	jr      $ra
-	li      $2, 0
diff --git a/src/setjmp/mips-sf/setjmp.sub b/src/setjmp/mips-sf/setjmp.sub
deleted file mode 100644
index b7ad221..0000000
--- a/src/setjmp/mips-sf/setjmp.sub
+++ /dev/null
@@ -1 +0,0 @@
-setjmp.s
diff --git a/src/setjmp/mips/longjmp.s b/src/setjmp/mips/longjmp.S
similarity index 91%
rename from src/setjmp/mips/longjmp.s
rename to src/setjmp/mips/longjmp.S
index a972d67..fdb6c95 100644
--- a/src/setjmp/mips/longjmp.s
+++ b/src/setjmp/mips/longjmp.S
@@ -10,7 +10,9 @@
 	bne     $2, $0, 1f
 	nop
 	addu    $2, $2, 1
-1:	lwc1    $20, 56($4)
+1:
+#ifndef __mips_soft_float
+	lwc1    $20, 56($4)
 	lwc1    $21, 60($4)
 	lwc1    $22, 64($4)
 	lwc1    $23, 68($4)
@@ -22,6 +24,7 @@
 	lwc1    $29, 92($4)
 	lwc1    $30, 96($4)
 	lwc1    $31, 100($4)
+#endif
 	lw      $ra,  0($4)
 	lw      $sp,  4($4)
 	lw      $16,  8($4)
diff --git a/src/setjmp/mips/setjmp.s b/src/setjmp/mips/setjmp.S
similarity index 95%
rename from src/setjmp/mips/setjmp.s
rename to src/setjmp/mips/setjmp.S
index 53d702a..501d526 100644
--- a/src/setjmp/mips/setjmp.s
+++ b/src/setjmp/mips/setjmp.S
@@ -21,6 +21,7 @@
 	sw      $23, 36($4)
 	sw      $30, 40($4)
 	sw      $28, 44($4)
+#ifndef __mips_soft_float
 	swc1    $20, 56($4)
 	swc1    $21, 60($4)
 	swc1    $22, 64($4)
@@ -33,5 +34,6 @@
 	swc1    $29, 92($4)
 	swc1    $30, 96($4)
 	swc1    $31, 100($4)
+#endif
 	jr      $ra
 	li      $2, 0
diff --git a/src/setjmp/mipsel-sf/longjmp.sub b/src/setjmp/mipsel-sf/longjmp.sub
deleted file mode 100644
index 6907202..0000000
--- a/src/setjmp/mipsel-sf/longjmp.sub
+++ /dev/null
@@ -1 +0,0 @@
-../mips-sf/longjmp.s
diff --git a/src/setjmp/mipsel-sf/setjmp.sub b/src/setjmp/mipsel-sf/setjmp.sub
deleted file mode 100644
index 9917475..0000000
--- a/src/setjmp/mipsel-sf/setjmp.sub
+++ /dev/null
@@ -1 +0,0 @@
-../mips-sf/setjmp.s
diff --git a/src/setjmp/sh-nofpu/longjmp.s b/src/setjmp/sh-nofpu/longjmp.s
deleted file mode 100644
index cda482c..0000000
--- a/src/setjmp/sh-nofpu/longjmp.s
+++ /dev/null
@@ -1,22 +0,0 @@
-.global _longjmp
-.global longjmp
-.type   _longjmp, @function
-.type   longjmp,  @function
-_longjmp:
-longjmp:
-	mov.l  @r4+, r8
-	mov.l  @r4+, r9
-	mov.l  @r4+, r10
-	mov.l  @r4+, r11
-	mov.l  @r4+, r12
-	mov.l  @r4+, r13
-	mov.l  @r4+, r14
-	mov.l  @r4+, r15
-	lds.l  @r4+, pr
-
-	tst  r5, r5
-	movt r0
-	add  r5, r0
-
-	rts
-	 nop
diff --git a/src/setjmp/sh-nofpu/longjmp.sub b/src/setjmp/sh-nofpu/longjmp.sub
deleted file mode 100644
index e80331b..0000000
--- a/src/setjmp/sh-nofpu/longjmp.sub
+++ /dev/null
@@ -1 +0,0 @@
-longjmp.s
diff --git a/src/setjmp/sh-nofpu/setjmp.s b/src/setjmp/sh-nofpu/setjmp.s
deleted file mode 100644
index 41210f9..0000000
--- a/src/setjmp/sh-nofpu/setjmp.s
+++ /dev/null
@@ -1,24 +0,0 @@
-.global ___setjmp
-.hidden ___setjmp
-.global __setjmp
-.global _setjmp
-.global setjmp
-.type   __setjmp, @function
-.type   _setjmp,  @function
-.type   setjmp,   @function
-___setjmp:
-__setjmp:
-_setjmp:
-setjmp:
-	add   #36, r4
-	sts.l  pr,   @-r4
-	mov.l  r15   @-r4
-	mov.l  r14,  @-r4
-	mov.l  r13,  @-r4
-	mov.l  r12,  @-r4
-	mov.l  r11,  @-r4
-	mov.l  r10,  @-r4
-	mov.l  r9,   @-r4
-	mov.l  r8,   @-r4
-	rts
-	 mov  #0, r0
diff --git a/src/setjmp/sh-nofpu/setjmp.sub b/src/setjmp/sh-nofpu/setjmp.sub
deleted file mode 100644
index b7ad221..0000000
--- a/src/setjmp/sh-nofpu/setjmp.sub
+++ /dev/null
@@ -1 +0,0 @@
-setjmp.s
diff --git a/src/setjmp/sh/longjmp.s b/src/setjmp/sh/longjmp.S
similarity index 90%
rename from src/setjmp/sh/longjmp.s
rename to src/setjmp/sh/longjmp.S
index e9aa4e5..08f668b 100644
--- a/src/setjmp/sh/longjmp.s
+++ b/src/setjmp/sh/longjmp.S
@@ -13,10 +13,12 @@
 	mov.l  @r4+, r14
 	mov.l  @r4+, r15
 	lds.l  @r4+, pr
+#if __SH_FPU_ANY__ || __SH4__
 	fmov.s @r4+, fr12
 	fmov.s @r4+, fr13
 	fmov.s @r4+, fr14
 	fmov.s @r4+, fr15
+#endif
 
 	tst  r5, r5
 	movt r0
diff --git a/src/setjmp/sh/setjmp.s b/src/setjmp/sh/setjmp.S
similarity index 88%
rename from src/setjmp/sh/setjmp.s
rename to src/setjmp/sh/setjmp.S
index ffde868..d476e63 100644
--- a/src/setjmp/sh/setjmp.s
+++ b/src/setjmp/sh/setjmp.S
@@ -10,11 +10,15 @@
 __setjmp:
 _setjmp:
 setjmp:
+#if __SH_FPU_ANY__ || __SH4__
 	add   #52, r4
 	fmov.s fr15, @-r4
 	fmov.s fr14, @-r4
 	fmov.s fr13, @-r4
 	fmov.s fr12, @-r4
+#else
+	add   #36, r4
+#endif
 	sts.l  pr,   @-r4
 	mov.l  r15,  @-r4
 	mov.l  r14,  @-r4
diff --git a/src/setjmp/sheb-nofpu/longjmp.sub b/src/setjmp/sheb-nofpu/longjmp.sub
deleted file mode 100644
index 62fcd2b..0000000
--- a/src/setjmp/sheb-nofpu/longjmp.sub
+++ /dev/null
@@ -1 +0,0 @@
-../sh-nofpu/longjmp.s
diff --git a/src/setjmp/sheb-nofpu/setjmp.sub b/src/setjmp/sheb-nofpu/setjmp.sub
deleted file mode 100644
index a5bb294..0000000
--- a/src/setjmp/sheb-nofpu/setjmp.sub
+++ /dev/null
@@ -1 +0,0 @@
-../sh-nofpu/setjmp.s
diff --git a/src/signal/arm/restore.s b/src/signal/arm/restore.s
index 18f7216..22fb1a5 100644
--- a/src/signal/arm/restore.s
+++ b/src/signal/arm/restore.s
@@ -1,3 +1,5 @@
+.syntax unified
+
 .global __restore
 .type __restore,%function
 __restore:
diff --git a/src/signal/arm/sigsetjmp.s b/src/signal/arm/sigsetjmp.s
index 89c020b..318addb 100644
--- a/src/signal/arm/sigsetjmp.s
+++ b/src/signal/arm/sigsetjmp.s
@@ -1,3 +1,4 @@
+.syntax unified
 .global sigsetjmp
 .global __sigsetjmp
 .type sigsetjmp,%function
diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c
index ab23a6f..6eca06f 100644
--- a/src/signal/sigaction.c
+++ b/src/signal/sigaction.c
@@ -17,10 +17,6 @@
 int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
 {
 	struct k_sigaction ksa, ksa_old;
-	if (sig >= (unsigned)_NSIG) {
-		errno = EINVAL;
-		return -1;
-	}
 	if (sa) {
 		if ((uintptr_t)sa->sa_handler > 1UL) {
 			a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
@@ -57,7 +53,7 @@
 
 int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
 {
-	if (sig-32U < 3) {
+	if (sig-32U < 3 || sig-1U >= _NSIG-1) {
 		errno = EINVAL;
 		return -1;
 	}
diff --git a/src/signal/sigsetjmp_tail.c b/src/signal/sigsetjmp_tail.c
index 487ad8c..78762aa 100644
--- a/src/signal/sigsetjmp_tail.c
+++ b/src/signal/sigsetjmp_tail.c
@@ -2,9 +2,7 @@
 #include <signal.h>
 #include "syscall.h"
 
-#ifdef SHARED
 __attribute__((__visibility__("hidden")))
-#endif
 int __sigsetjmp_tail(sigjmp_buf jb, int ret)
 {
 	void *p = jb->__ss;
diff --git a/src/stdio/fread.c b/src/stdio/fread.c
index 33a65f5..aef75f7 100644
--- a/src/stdio/fread.c
+++ b/src/stdio/fread.c
@@ -7,6 +7,7 @@
 {
 	unsigned char *dest = destv;
 	size_t len = size*nmemb, l = len, k;
+	if (!size) nmemb = 0;
 
 	FLOCK(f);
 
diff --git a/src/stdio/fwrite.c b/src/stdio/fwrite.c
index 81ec271..7a567b2 100644
--- a/src/stdio/fwrite.c
+++ b/src/stdio/fwrite.c
@@ -13,8 +13,8 @@
 		/* Match /^(.*\n|)/ */
 		for (i=l; i && s[i-1] != '\n'; i--);
 		if (i) {
-			if (f->write(f, s, i) < i)
-				return i;
+			size_t n = f->write(f, s, i);
+			if (n < i) return n;
 			s += i;
 			l -= i;
 		}
@@ -28,6 +28,7 @@
 size_t fwrite(const void *restrict src, size_t size, size_t nmemb, FILE *restrict f)
 {
 	size_t k, l = size*nmemb;
+	if (!size) nmemb = 0;
 	FLOCK(f);
 	k = __fwritex(src, l, f);
 	FUNLOCK(f);
diff --git a/src/stdio/getdelim.c b/src/stdio/getdelim.c
index a88c393..1ccd802 100644
--- a/src/stdio/getdelim.c
+++ b/src/stdio/getdelim.c
@@ -27,17 +27,18 @@
 	for (;;) {
 		z = memchr(f->rpos, delim, f->rend - f->rpos);
 		k = z ? z - f->rpos + 1 : f->rend - f->rpos;
-		if (i+k >= *n) {
+		if (i+k+1 >= *n) {
 			if (k >= SIZE_MAX/2-i) goto oom;
-			*n = i+k+2;
-			if (*n < SIZE_MAX/4) *n *= 2;
-			tmp = realloc(*s, *n);
+			size_t m = i+k+2;
+			if (!z && m < SIZE_MAX/4) m += m/2;
+			tmp = realloc(*s, m);
 			if (!tmp) {
-				*n = i+k+2;
-				tmp = realloc(*s, *n);
+				m = i+k+2;
+				tmp = realloc(*s, m);
 				if (!tmp) goto oom;
 			}
 			*s = tmp;
+			*n = m;
 		}
 		memcpy(*s+i, f->rpos, k);
 		f->rpos += k;
diff --git a/arch/arm/src/__aeabi_memclr.c b/src/string/arm/__aeabi_memclr.c
similarity index 100%
rename from arch/arm/src/__aeabi_memclr.c
rename to src/string/arm/__aeabi_memclr.c
diff --git a/arch/arm/src/__aeabi_memcpy.c b/src/string/arm/__aeabi_memcpy.c
similarity index 100%
rename from arch/arm/src/__aeabi_memcpy.c
rename to src/string/arm/__aeabi_memcpy.c
diff --git a/arch/arm/src/__aeabi_memmove.c b/src/string/arm/__aeabi_memmove.c
similarity index 100%
rename from arch/arm/src/__aeabi_memmove.c
rename to src/string/arm/__aeabi_memmove.c
diff --git a/arch/arm/src/__aeabi_memset.c b/src/string/arm/__aeabi_memset.c
similarity index 100%
rename from arch/arm/src/__aeabi_memset.c
rename to src/string/arm/__aeabi_memset.c
diff --git a/src/string/arm/memcpy.c b/src/string/arm/memcpy.c
new file mode 100644
index 0000000..041614f
--- /dev/null
+++ b/src/string/arm/memcpy.c
@@ -0,0 +1,3 @@
+#if __ARMEB__
+#include "../memcpy.c"
+#endif
diff --git a/src/string/armel/memcpy.s b/src/string/arm/memcpy_le.S
similarity index 90%
rename from src/string/armel/memcpy.s
rename to src/string/arm/memcpy_le.S
index 9c5e38d..4db4844 100644
--- a/src/string/armel/memcpy.s
+++ b/src/string/arm/memcpy_le.S
@@ -1,3 +1,5 @@
+#ifndef __ARMEB__
+
 /*
  * Copyright (C) 2008 The Android Open Source Project
  * All rights reserved.
@@ -42,6 +44,8 @@
  * of prefetch code that is not compatible with older cpus.
  */
 
+.syntax unified
+
 .global memcpy
 .type memcpy,%function
 memcpy:
@@ -73,12 +77,12 @@
 	 */
 	movs    r12, r3, lsl #31
 	sub     r2, r2, r3              /* we know that r3 <= r2 because r2 >= 4 */
-	.word 0x44d13001 /* ldrbmi r3, [r1], #1 */
-	.word 0x24d14001 /* ldrbcs r4, [r1], #1 */
-	.word 0x24d1c001 /* ldrbcs r12,[r1], #1 */
-	.word 0x44c03001 /* strbmi r3, [r0], #1 */
-	.word 0x24c04001 /* strbcs r4, [r0], #1 */
-	.word 0x24c0c001 /* strbcs r12,[r0], #1 */
+	ldrbmi r3, [r1], #1
+	ldrbcs r4, [r1], #1
+	ldrbcs r12,[r1], #1
+	strbmi r3, [r0], #1
+	strbcs r4, [r0], #1
+	strbcs r12,[r0], #1
 
 src_aligned:
 
@@ -177,18 +181,16 @@
 	stmmi   r0!, {r8, r9}
 	movs    r12, r2, lsl #30
 	ldrcs   r3, [r1], #4                    /*  4 bytes */
-	.word 0x40d140b2 /* ldrhmi r4, [r1], #2 */ /*  2 bytes */
+	ldrhmi r4, [r1], #2                     /*  2 bytes */
 	strcs   r3, [r0], #4
-	.word 0x40c040b2 /* strhmi r4, [r0], #2 */
+	strhmi r4, [r0], #2
 	tst     r2, #0x1
-	.word 0x15d13000 /* ldrbne r3, [r1] */  /*  last byte  */
-	.word 0x15c03000 /* strbne r3, [r0] */
+	ldrbne r3, [r1]                         /*  last byte  */
+	strbne r3, [r0]
 
 	/* we're done! restore everything and return */
 1:      ldmfd   sp!, {r5-r11}
 	ldmfd   sp!, {r0, r4, lr}
-	tst     lr, #1
-	moveq   pc, lr
 	bx      lr
 
 	/********************************************************************/
@@ -224,11 +226,11 @@
 	 * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
 	 */
 	movs    r5, r5, lsl #31
-	.word 0x44c03001 /* strbmi r3, [r0], #1 */
+	strbmi r3, [r0], #1
 	movmi   r3, r3, lsr #8
-	.word 0x24c03001 /* strbcs r3, [r0], #1 */
+	strbcs r3, [r0], #1
 	movcs   r3, r3, lsr #8
-	.word 0x24c03001 /* strbcs r3, [r0], #1 */
+	strbcs r3, [r0], #1
 	movcs   r3, r3, lsr #8
 
 	cmp     r2, #4
@@ -355,27 +357,27 @@
 partial_word_tail:
 	/* we have a partial word in the input buffer */
 	movs    r5, lr, lsl #(31-3)
-	.word 0x44c03001 /* strbmi r3, [r0], #1 */
+	strbmi r3, [r0], #1
 	movmi   r3, r3, lsr #8
-	.word 0x24c03001 /* strbcs r3, [r0], #1 */
+	strbcs r3, [r0], #1
 	movcs   r3, r3, lsr #8
-	.word 0x24c03001 /* strbcs r3, [r0], #1 */
+	strbcs r3, [r0], #1
 
 	/* Refill spilled registers from the stack. Don't update sp. */
 	ldmfd   sp, {r5-r11}
 
 copy_last_3_and_return:
 	movs    r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
-	.word 0x44d12001 /* ldrbmi r2, [r1], #1 */
-	.word 0x24d13001 /* ldrbcs r3, [r1], #1 */
-	.word 0x25d1c000 /* ldrbcs r12,[r1] */
-	.word 0x44c02001 /* strbmi r2, [r0], #1 */
-	.word 0x24c03001 /* strbcs r3, [r0], #1 */
-	.word 0x25c0c000 /* strbcs r12,[r0] */
+	ldrbmi r2, [r1], #1
+	ldrbcs r3, [r1], #1
+	ldrbcs r12,[r1]
+	strbmi r2, [r0], #1
+	strbcs r3, [r0], #1
+	strbcs r12,[r0]
 
 	/* we're done! restore sp and spilled registers and return */
 	add     sp,  sp, #28
 	ldmfd   sp!, {r0, r4, lr}
-	tst     lr, #1
-	moveq   pc, lr
 	bx      lr
+
+#endif
diff --git a/src/string/armel/memcpy.sub b/src/string/armel/memcpy.sub
deleted file mode 100644
index 543f583..0000000
--- a/src/string/armel/memcpy.sub
+++ /dev/null
@@ -1 +0,0 @@
-memcpy.s
diff --git a/src/string/armhf/memcpy.sub b/src/string/armhf/memcpy.sub
deleted file mode 100644
index add0590..0000000
--- a/src/string/armhf/memcpy.sub
+++ /dev/null
@@ -1 +0,0 @@
-../armel/memcpy.s
diff --git a/src/thread/__syscall_cp.c b/src/thread/__syscall_cp.c
index faf57b1..09a2be8 100644
--- a/src/thread/__syscall_cp.c
+++ b/src/thread/__syscall_cp.c
@@ -1,9 +1,7 @@
 #include "pthread_impl.h"
 #include "syscall.h"
 
-#ifdef SHARED
 __attribute__((__visibility__("hidden")))
-#endif
 long __syscall_cp_c();
 
 static long sccp(syscall_arg_t nr,
diff --git a/src/thread/__tls_get_addr.c b/src/thread/__tls_get_addr.c
index 84a413d..6945faa 100644
--- a/src/thread/__tls_get_addr.c
+++ b/src/thread/__tls_get_addr.c
@@ -1,16 +1,16 @@
 #include <stddef.h>
 #include "pthread_impl.h"
+#include "libc.h"
+
+__attribute__((__visibility__("hidden")))
+void *__tls_get_new(size_t *);
 
 void *__tls_get_addr(size_t *v)
 {
 	pthread_t self = __pthread_self();
-#ifdef SHARED
-	__attribute__((__visibility__("hidden")))
-	void *__tls_get_new(size_t *);
 	if (v[0]<=(size_t)self->dtv[0])
 		return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
 	return __tls_get_new(v);
-#else
-	return (char *)self->dtv[1]+v[1]+DTP_OFFSET;
-#endif
 }
+
+weak_alias(__tls_get_addr, __tls_get_new);
diff --git a/src/thread/aarch64/syscall_cp.s b/src/thread/aarch64/syscall_cp.s
index 30e677c..41db68a 100644
--- a/src/thread/aarch64/syscall_cp.s
+++ b/src/thread/aarch64/syscall_cp.s
@@ -17,7 +17,7 @@
 __syscall_cp_asm:
 __cp_begin:
 	ldr w0,[x0]
-	cbnz w0,1f
+	cbnz w0,__cp_cancel
 	mov x8,x1
 	mov x0,x2
 	mov x1,x3
@@ -28,6 +28,5 @@
 	svc 0
 __cp_end:
 	ret
-
-	// cbnz might not be able to jump far enough
-1:	b __cancel
+__cp_cancel:
+	b __cancel
diff --git a/arch/arm/src/__set_thread_area.c b/src/thread/arm/__set_thread_area.c
similarity index 100%
rename from arch/arm/src/__set_thread_area.c
rename to src/thread/arm/__set_thread_area.c
diff --git a/src/thread/arm/__set_thread_area.s b/src/thread/arm/__set_thread_area.s
deleted file mode 100644
index 4a4cd0d..0000000
--- a/src/thread/arm/__set_thread_area.s
+++ /dev/null
@@ -1 +0,0 @@
-/* Replaced by C code in arch/arm/src */
diff --git a/src/thread/arm/__unmapself.s b/src/thread/arm/__unmapself.s
index 62ebb7c..29c2d07 100644
--- a/src/thread/arm/__unmapself.s
+++ b/src/thread/arm/__unmapself.s
@@ -1,3 +1,4 @@
+.syntax unified
 .text
 .global __unmapself
 .type   __unmapself,%function
diff --git a/arch/arm/src/arm/atomics.s b/src/thread/arm/atomics.s
similarity index 96%
rename from arch/arm/src/arm/atomics.s
rename to src/thread/arm/atomics.s
index f241cc0..673fc03 100644
--- a/arch/arm/src/arm/atomics.s
+++ b/src/thread/arm/atomics.s
@@ -1,3 +1,4 @@
+.syntax unified
 .text
 
 .global __a_barrier
@@ -11,8 +12,6 @@
 .global __a_barrier_dummy
 .hidden __a_barrier_dummy
 __a_barrier_dummy:
-	tst lr,#1
-	moveq pc,lr
 	bx lr
 .global __a_barrier_oldkuser
 .hidden __a_barrier_oldkuser
@@ -24,8 +23,6 @@
 	mov lr,pc
 	mov pc,ip
 	pop {r0,r1,r2,r3,ip,lr}
-	tst lr,#1
-	moveq pc,lr
 	bx lr
 .global __a_barrier_v6
 .hidden __a_barrier_v6
@@ -53,8 +50,6 @@
 	ldr r0,[r2]
 	subs r0,r3,r0
 	streq r1,[r2]
-	tst lr,#1
-	moveq pc,lr
 	bx lr
 .global __a_cas_v6
 .hidden __a_cas_v6
@@ -100,6 +95,8 @@
 	bx lr
 
 .data
+.align 2
+
 .global __a_barrier_ptr
 .hidden __a_barrier_ptr
 __a_barrier_ptr:
diff --git a/src/thread/arm/clone.s b/src/thread/arm/clone.s
index d146999..fe2e0e6 100644
--- a/src/thread/arm/clone.s
+++ b/src/thread/arm/clone.s
@@ -1,3 +1,4 @@
+.syntax unified
 .text
 .global __clone
 .type   __clone,%function
@@ -15,8 +16,6 @@
 	tst r0,r0
 	beq 1f
 	ldmfd sp!,{r4,r5,r6,r7}
-	tst lr,#1
-	moveq pc,lr
 	bx lr
 
 1:	mov r0,r6
diff --git a/src/thread/arm/syscall_cp.s b/src/thread/arm/syscall_cp.s
index 96ce613..a5730c0 100644
--- a/src/thread/arm/syscall_cp.s
+++ b/src/thread/arm/syscall_cp.s
@@ -1,3 +1,4 @@
+.syntax unified
 .global __cp_begin
 .hidden __cp_begin
 .global __cp_end
@@ -22,8 +23,6 @@
 	svc 0
 __cp_end:
 	ldmfd sp!,{r4,r5,r6,r7,lr}
-	tst lr,#1
-	moveq pc,lr
 	bx lr
 __cp_cancel:
 	ldmfd sp!,{r4,r5,r6,r7,lr}
diff --git a/src/thread/microblaze/syscall_cp.s b/src/thread/microblaze/syscall_cp.s
index 51599c9..b0df61c 100644
--- a/src/thread/microblaze/syscall_cp.s
+++ b/src/thread/microblaze/syscall_cp.s
@@ -11,7 +11,7 @@
 __syscall_cp_asm:
 __cp_begin:
 	lwi     r5, r5, 0
-	bnei    r5, __cancel
+	bnei    r5, __cp_cancel
 	addi    r12, r6, 0
 	add     r5, r7, r0
 	add     r6, r8, r0
@@ -23,3 +23,5 @@
 __cp_end:
 	rtsd    r15, 8
 	nop
+__cp_cancel:
+	bri     __cancel
diff --git a/src/thread/mips/syscall_cp.s b/src/thread/mips/syscall_cp.s
index 8f76d40..d284626 100644
--- a/src/thread/mips/syscall_cp.s
+++ b/src/thread/mips/syscall_cp.s
@@ -40,7 +40,14 @@
 	nop
 
 __cp_cancel:
+	move    $2, $ra
+	bal     1f
 	addu    $sp, $sp, 32
-	lw      $25, %call16(__cancel)($gp)
+	.gpword .
+	.gpword __cancel
+1:	lw      $3, ($ra)
+	subu    $3, $ra, $3
+	lw      $25, 4($ra)
+	addu    $25, $25, $3
 	jr      $25
-	nop
+	move    $ra, $2
diff --git a/src/thread/or1k/syscall_cp.s b/src/thread/or1k/syscall_cp.s
index 2c0bf0e..7951166 100644
--- a/src/thread/or1k/syscall_cp.s
+++ b/src/thread/or1k/syscall_cp.s
@@ -12,7 +12,7 @@
 __cp_begin:
 	l.lwz	r3, 0(r3)
 	l.sfeqi	r3, 0
-	l.bnf	__cancel
+	l.bnf	__cp_cancel
 	 l.ori	r11, r4, 0
 	l.ori	r3, r5, 0
 	l.ori	r4, r6, 0
@@ -24,3 +24,6 @@
 __cp_end:
 	l.jr	r9
 	 l.nop
+__cp_cancel:
+	l.j	__cancel
+	 l.nop
diff --git a/src/thread/powerpc/syscall_cp.s b/src/thread/powerpc/syscall_cp.s
index 20b5e0a..77f8938 100644
--- a/src/thread/powerpc/syscall_cp.s
+++ b/src/thread/powerpc/syscall_cp.s
@@ -38,7 +38,7 @@
 	cmpwi cr7, 0, 0 #compare r0 with 0, store result in cr7. 
 	beq+ cr7, 1f #jump to label 1 if r0 was 0
 	
-	b __cancel #else call cancel 
+	b __cp_cancel #else call cancel
 1:
 	#ok, the cancel flag was not set
 	# syscall: number goes to r0, the rest 3-8
@@ -55,3 +55,5 @@
 	#else negate result.
 	neg 3, 3
 	blr
+__cp_cancel:
+	b __cancel
diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c
index 0151a1a..3d22922 100644
--- a/src/thread/pthread_cancel.c
+++ b/src/thread/pthread_cancel.c
@@ -1,12 +1,11 @@
+#define _GNU_SOURCE
 #include <string.h>
 #include "pthread_impl.h"
 #include "syscall.h"
 #include "libc.h"
 
-#ifdef SHARED
 __attribute__((__visibility__("hidden")))
-#endif
-long __cancel(), __cp_cancel(), __syscall_cp_asm(), __syscall_cp_c();
+long __cancel(), __syscall_cp_asm(), __syscall_cp_c();
 
 long __cancel()
 {
@@ -17,12 +16,6 @@
 	return -ECANCELED;
 }
 
-/* If __syscall_cp_asm has adjusted the stack pointer, it must provide a
- * definition of __cp_cancel to undo those adjustments and call __cancel.
- * Otherwise, __cancel provides a definition for __cp_cancel. */
-
-weak_alias(__cancel, __cp_cancel);
-
 long __syscall_cp_asm(volatile void *, syscall_arg_t,
                       syscall_arg_t, syscall_arg_t, syscall_arg_t,
                       syscall_arg_t, syscall_arg_t, syscall_arg_t);
@@ -52,24 +45,22 @@
 	set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
 }
 
-#ifdef SHARED
 __attribute__((__visibility__("hidden")))
-#endif
-extern const char __cp_begin[1], __cp_end[1];
+extern const char __cp_begin[1], __cp_end[1], __cp_cancel[1];
 
 static void cancel_handler(int sig, siginfo_t *si, void *ctx)
 {
 	pthread_t self = __pthread_self();
 	ucontext_t *uc = ctx;
-	const char *ip = ((char **)&uc->uc_mcontext)[CANCEL_REG_IP];
+	uintptr_t pc = uc->uc_mcontext.MC_PC;
 
 	a_barrier();
 	if (!self->cancel || self->canceldisable == PTHREAD_CANCEL_DISABLE) return;
 
 	_sigaddset(&uc->uc_sigmask, SIGCANCEL);
 
-	if (self->cancelasync || ip >= __cp_begin && ip < __cp_end) {
-		((char **)&uc->uc_mcontext)[CANCEL_REG_IP] = (char *)__cp_cancel;
+	if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {
+		uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel;
 		return;
 	}
 
@@ -101,5 +92,6 @@
 		init = 1;
 	}
 	a_store(&t->cancel, 1);
+	if (t == pthread_self() && !t->cancelasync) return 0;
 	return pthread_kill(t, SIGCANCEL);
 }
diff --git a/src/thread/sh/__set_thread_area.c b/src/thread/sh/__set_thread_area.c
new file mode 100644
index 0000000..9c47f78
--- /dev/null
+++ b/src/thread/sh/__set_thread_area.c
@@ -0,0 +1,40 @@
+#include "pthread_impl.h"
+#include "libc.h"
+#include <elf.h>
+
+/* Also perform sh-specific init */
+
+#define CPU_HAS_LLSC 0x0040
+#define CPU_HAS_CAS_L 0x0400
+
+__attribute__((__visibility__("hidden")))
+extern const char __sh_cas_gusa[], __sh_cas_llsc[], __sh_cas_imask[], __sh_cas_cas_l[];
+
+__attribute__((__visibility__("hidden")))
+const void *__sh_cas_ptr;
+
+__attribute__((__visibility__("hidden")))
+unsigned __sh_nommu;
+
+int __set_thread_area(void *p)
+{
+	size_t *aux;
+	__asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
+#ifndef __SH4A__
+	__sh_cas_ptr = __sh_cas_gusa;
+#if !defined(__SH3__) && !defined(__SH4__)
+	for (aux=libc.auxv; *aux; aux+=2) {
+		if (*aux != AT_PLATFORM) continue;
+		const char *s = (void *)aux[1];
+		if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
+		__sh_cas_ptr = __sh_cas_imask;
+		__sh_nommu = 1;
+	}
+#endif
+	if (__hwcap & CPU_HAS_CAS_L)
+		__sh_cas_ptr = __sh_cas_cas_l;
+	else if (__hwcap & CPU_HAS_LLSC)
+		__sh_cas_ptr = __sh_cas_llsc;
+#endif
+	return 0;
+}
diff --git a/src/thread/sh/__set_thread_area.s b/src/thread/sh/__set_thread_area.s
deleted file mode 100644
index e69de29..0000000
--- a/src/thread/sh/__set_thread_area.s
+++ /dev/null
diff --git a/arch/sh/src/__unmapself.c b/src/thread/sh/__unmapself.c
similarity index 92%
rename from arch/sh/src/__unmapself.c
rename to src/thread/sh/__unmapself.c
index b804aef..d4fb8be 100644
--- a/arch/sh/src/__unmapself.c
+++ b/src/thread/sh/__unmapself.c
@@ -10,7 +10,7 @@
 #define CRTJMP(pc,sp) __asm__ __volatile__( \
 	"mov.l @%0+,r0 ; mov.l @%0,r12 ; jmp @r0 ; mov %1,r15" \
 	: : "r"(pc), "r"(sp) : "r0", "memory" )
-#include "../../../src/thread/__unmapself.c"
+#include "../__unmapself.c"
 #undef __unmapself
 extern __attribute__((__visibility__("hidden"))) unsigned __sh_nommu;
 #else
diff --git a/src/thread/sh/__unmapself.s b/src/thread/sh/__unmapself_mmu.s
similarity index 100%
rename from src/thread/sh/__unmapself.s
rename to src/thread/sh/__unmapself_mmu.s
diff --git a/src/thread/sh/atomics.s b/src/thread/sh/atomics.s
new file mode 100644
index 0000000..3b58ccc
--- /dev/null
+++ b/src/thread/sh/atomics.s
@@ -0,0 +1,65 @@
+/* Contract for all versions is same as cas.l r2,r3,@r0
+ * pr and r1 are also clobbered (by jsr & r1 as temp).
+ * r0,r2,r4-r15 must be preserved.
+ * r3 contains result (==r2 iff cas succeeded). */
+
+	.align 2
+.global __sh_cas_gusa
+.hidden __sh_cas_gusa
+__sh_cas_gusa:
+	mov.l r5,@-r15
+	mov.l r4,@-r15
+	mov r0,r4
+	mova 1f,r0
+	mov r15,r1
+	mov #(0f-1f),r15
+0:	mov.l @r4,r5
+	cmp/eq r5,r2
+	bf 1f
+	mov.l r3,@r4
+1:	mov r1,r15
+	mov r5,r3
+	mov r4,r0
+	mov.l @r15+,r4
+	rts
+	 mov.l @r15+,r5
+
+.global __sh_cas_llsc
+.hidden __sh_cas_llsc
+__sh_cas_llsc:
+	mov r0,r1
+	synco
+0:	movli.l @r1,r0
+	cmp/eq r0,r2
+	bf 1f
+	mov r3,r0
+	movco.l r0,@r1
+	bf 0b
+	mov r2,r0
+1:	synco
+	mov r0,r3
+	rts
+	 mov r1,r0
+
+.global __sh_cas_imask
+.hidden __sh_cas_imask
+__sh_cas_imask:
+	mov r0,r1
+	stc sr,r0
+	mov.l r0,@-r15
+	or #0xf0,r0
+	ldc r0,sr
+	mov.l @r1,r0
+	cmp/eq r0,r2
+	bf 1f
+	mov.l r3,@r1
+1:	ldc.l @r15+,sr
+	mov r0,r3
+	rts
+	 mov r1,r0
+
+.global __sh_cas_cas_l
+.hidden __sh_cas_cas_l
+__sh_cas_cas_l:
+	rts
+	 .word 0x2323 /* cas.l r2,r3,@r0 */
diff --git a/src/thread/sh/syscall_cp.s b/src/thread/sh/syscall_cp.s
index c3cafac..bb848ef 100644
--- a/src/thread/sh/syscall_cp.s
+++ b/src/thread/sh/syscall_cp.s
@@ -14,17 +14,8 @@
 __cp_begin:
 	mov.l @r4, r4
 	tst   r4, r4
-	bt    2f
-
-	mov.l L1, r0
-	braf  r0
-	 nop
-1:
-
-.align 2
-L1:	.long __cancel@PLT-(1b-.)
-
-2:	mov   r5, r3
+	bf    __cp_cancel
+	mov   r5, r3
 	mov   r6, r4
 	mov   r7, r5
 	mov.l @r15, r6
@@ -43,3 +34,12 @@
 
 	rts
 	 nop
+
+__cp_cancel:
+	mov.l 2f, r0
+	braf  r0
+	 nop
+1:
+
+.align 2
+2:	.long __cancel@PCREL-(1b-.)
diff --git a/src/thread/x32/syscall_cp.s b/src/thread/x32/syscall_cp.s
index 79709a5..9805af0 100644
--- a/src/thread/x32/syscall_cp.s
+++ b/src/thread/x32/syscall_cp.s
@@ -14,7 +14,7 @@
 __cp_begin:
 	mov (%rdi),%eax
 	test %eax,%eax
-	jnz __cancel
+	jnz __cp_cancel
 	mov %rdi,%r11
 	mov %rsi,%rax
 	mov %rdx,%rdi
@@ -27,3 +27,5 @@
 	syscall
 __cp_end:
 	ret
+__cp_cancel:
+	jmp __cancel
diff --git a/arch/x32/src/syscall_cp_fixup.c b/src/thread/x32/syscall_cp_fixup.c
similarity index 96%
rename from arch/x32/src/syscall_cp_fixup.c
rename to src/thread/x32/syscall_cp_fixup.c
index deb01ee..b1f3a38 100644
--- a/arch/x32/src/syscall_cp_fixup.c
+++ b/src/thread/x32/syscall_cp_fixup.c
@@ -1,8 +1,6 @@
 #include <sys/syscall.h>
 
-#ifdef SHARED
 __attribute__((__visibility__("hidden")))
-#endif
 long __syscall_cp_internal(volatile void*, long long, long long, long long, long long,
                              long long, long long, long long);
 
@@ -14,9 +12,7 @@
 	ts->tv_nsec = __tsc(X)->tv_nsec; \
 	(X) = (unsigned long)ts; } } while(0)
 
-#ifdef SHARED
 __attribute__((__visibility__("hidden")))
-#endif
 long __syscall_cp_asm (volatile void * foo, long long n, long long a1, long long a2, long long a3,
 	                     long long a4, long long a5, long long a6)
 {
diff --git a/src/thread/x86_64/syscall_cp.s b/src/thread/x86_64/syscall_cp.s
index 1a0fd5d..4f10171 100644
--- a/src/thread/x86_64/syscall_cp.s
+++ b/src/thread/x86_64/syscall_cp.s
@@ -14,7 +14,7 @@
 __cp_begin:
 	mov (%rdi),%eax
 	test %eax,%eax
-	jnz __cancel
+	jnz __cp_cancel
 	mov %rdi,%r11
 	mov %rsi,%rax
 	mov %rdx,%rdi
@@ -27,3 +27,5 @@
 	syscall
 __cp_end:
 	ret
+__cp_cancel:
+	jmp __cancel
diff --git a/src/time/clock_gettime.c b/src/time/clock_gettime.c
index 1572de0..2412880 100644
--- a/src/time/clock_gettime.c
+++ b/src/time/clock_gettime.c
@@ -5,10 +5,45 @@
 #include "libc.h"
 #include "atomic.h"
 
-static int sc_clock_gettime(clockid_t clk, struct timespec *ts)
+#ifdef VDSO_CGT_SYM
+
+void *__vdsosym(const char *, const char *);
+
+static void *volatile vdso_func;
+
+static int cgt_init(clockid_t clk, struct timespec *ts)
 {
-	int r = __syscall(SYS_clock_gettime, clk, ts);
-	if (!r) return r;
+	void *p = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM);
+	int (*f)(clockid_t, struct timespec *) =
+		(int (*)(clockid_t, struct timespec *))p;
+	a_cas_p(&vdso_func, (void *)cgt_init, p);
+	return f ? f(clk, ts) : -ENOSYS;
+}
+
+static void *volatile vdso_func = (void *)cgt_init;
+
+#endif
+
+int __clock_gettime(clockid_t clk, struct timespec *ts)
+{
+	int r;
+
+#ifdef VDSO_CGT_SYM
+	int (*f)(clockid_t, struct timespec *) =
+		(int (*)(clockid_t, struct timespec *))vdso_func;
+	if (f) {
+		r = f(clk, ts);
+		if (!r) return r;
+		if (r == -EINVAL) return __syscall_ret(r);
+		/* Fall through on errors other than EINVAL. Some buggy
+		 * vdso implementations return ENOSYS for clocks they
+		 * can't handle, rather than making the syscall. This
+		 * also handles the case where cgt_init fails to find
+		 * a vdso function to use. */
+	}
+#endif
+
+	r = __syscall(SYS_clock_gettime, clk, ts);
 	if (r == -ENOSYS) {
 		if (clk == CLOCK_REALTIME) {
 			__syscall(SYS_gettimeofday, ts, 0);
@@ -17,25 +52,7 @@
 		}
 		r = -EINVAL;
 	}
-	errno = -r;
-	return -1;
-}
-
-void *__vdsosym(const char *, const char *);
-
-int __clock_gettime(clockid_t clk, struct timespec *ts)
-{
-#ifdef VDSO_CGT_SYM
-	static int (*volatile cgt)(clockid_t, struct timespec *);
-	if (!cgt) {
-		void *f = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM);
-		if (!f) f = (void *)sc_clock_gettime;
-		a_cas_p(&cgt, 0, f);
-	}
-	return cgt(clk, ts);
-#else
-	return sc_clock_gettime(clk, ts);
-#endif
+	return __syscall_ret(r);
 }
 
 weak_alias(__clock_gettime, clock_gettime);