diff --git a/main/musl/0002-2b74315d-to-b9b2db2f.patch b/main/musl/0002-2b74315d-to-b9b2db2f.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0d3a49c49e04bd8bfc19a9d724a4fd22c585ed9a
--- /dev/null
+++ b/main/musl/0002-2b74315d-to-b9b2db2f.patch
@@ -0,0 +1,457 @@
+git diff 2b74315d8a31ad8fbcd369116c82e055e0ec3fb7...b9b2db2f374bce907fa5015c9cf63205054f2356
+
+diff --git a/arch/microblaze/syscall_arch.h b/arch/microblaze/syscall_arch.h
+index 70217ff..cab4607 100644
+--- a/arch/microblaze/syscall_arch.h
++++ b/arch/microblaze/syscall_arch.h
+@@ -13,7 +13,7 @@ static __inline long __syscall0(long n)
+ 	register unsigned long r3 __asm__("r3");
+ 	__asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3)
+ 		: "r"(r12)
+-		: "memory");
++		: "memory", "r4");
+ 	return r3;
+ }
+ 
+@@ -24,7 +24,7 @@ static inline long __syscall1(long n, long a)
+ 	register unsigned long r5 __asm__("r5") = a;
+ 	__asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3)
+ 		: "r"(r12), "r"(r5)
+-		: "memory");
++		: "memory", "r4");
+ 	return r3;
+ }
+ 
+@@ -36,7 +36,7 @@ static inline long __syscall2(long n, long a, long b)
+ 	register unsigned long r6 __asm__("r6") = b;
+ 	__asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3)
+ 		: "r"(r12), "r"(r5), "r"(r6)
+-		: "memory");
++		: "memory", "r4");
+ 	return r3;
+ }
+ 
+@@ -49,7 +49,7 @@ static inline long __syscall3(long n, long a, long b, long c)
+ 	register unsigned long r7 __asm__("r7") = c;
+ 	__asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3)
+ 		: "r"(r12), "r"(r5), "r"(r6), "r"(r7)
+-		: "memory");
++		: "memory", "r4");
+ 	return r3;
+ }
+ 
+@@ -63,7 +63,7 @@ static inline long __syscall4(long n, long a, long b, long c, long d)
+ 	register unsigned long r8 __asm__("r8") = d;
+ 	__asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3)
+ 		: "r"(r12), "r"(r5), "r"(r6), "r"(r7), "r"(r8)
+-		: "memory");
++		: "memory", "r4");
+ 	return r3;
+ }
+ 
+@@ -78,7 +78,7 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+ 	register unsigned long r9 __asm__("r9") = e;
+ 	__asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3)
+ 		: "r"(r12), "r"(r5), "r"(r6), "r"(r7), "r"(r8), "r"(r9)
+-		: "memory");
++		: "memory", "r4");
+ 	return r3;
+ }
+ 
+@@ -94,7 +94,7 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
+ 	register unsigned long r10 __asm__("r10") = f;
+ 	__asm__ __volatile__ ("brki r14, 0x8" : "=r"(r3)
+ 		: "r"(r12), "r"(r5), "r"(r6), "r"(r7), "r"(r8), "r"(r9), "r"(r10)
+-		: "memory");
++		: "memory", "r4");
+ 	return r3;
+ }
+ 
+diff --git a/include/search.h b/include/search.h
+index 27f6107..02e407e 100644
+--- a/include/search.h
++++ b/include/search.h
+@@ -22,6 +22,18 @@ int hcreate(size_t);
+ void hdestroy(void);
+ ENTRY *hsearch(ENTRY, ACTION);
+ 
++#ifdef _GNU_SOURCE
++struct hsearch_data {
++	struct __tab *__tab;
++	unsigned int __unused1;
++	unsigned int __unused2;
++};
++
++int hcreate_r(size_t, struct hsearch_data *);
++void hdestroy_r(struct hsearch_data *);
++int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
++#endif
++
+ void insque(void *, void *);
+ void remque(void *);
+ 
+diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c
+index d6ad904..7932a97 100644
+--- a/src/malloc/malloc.c
++++ b/src/malloc/malloc.c
+@@ -37,6 +37,7 @@ static struct {
+ 	struct bin bins[64];
+ 	int brk_lock[2];
+ 	int free_lock[2];
++	unsigned mmap_step;
+ } mal;
+ 
+ 
+@@ -162,7 +163,28 @@ static struct chunk *expand_heap(size_t n)
+ 	new = mal.brk + n + SIZE_ALIGN + PAGE_SIZE - 1 & -PAGE_SIZE;
+ 	n = new - mal.brk;
+ 
+-	if (__brk(new) != new) goto fail;
++	if (__brk(new) != new) {
++		size_t min = (size_t)PAGE_SIZE << mal.mmap_step/2;
++		n += -n & PAGE_SIZE-1;
++		if (n < min) n = min;
++		void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
++			MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
++		if (area == MAP_FAILED) goto fail;
++
++		mal.mmap_step++;
++		area = (char *)area + SIZE_ALIGN - OVERHEAD;
++		w = area;
++		n -= SIZE_ALIGN;
++		w->psize = 0 | C_INUSE;
++		w->csize = n | C_INUSE;
++		w = NEXT_CHUNK(w);
++		w->psize = n | C_INUSE;
++		w->csize = 0 | C_INUSE;
++
++		unlock(mal.brk_lock);
++
++		return area;
++	}
+ 
+ 	w = MEM_TO_CHUNK(new);
+ 	w->psize = n | C_INUSE;
+diff --git a/src/search/hsearch.c b/src/search/hsearch.c
+index 6fe5ced..5c89651 100644
+--- a/src/search/hsearch.c
++++ b/src/search/hsearch.c
+@@ -1,6 +1,8 @@
++#define _GNU_SOURCE
+ #include <stdlib.h>
+ #include <string.h>
+ #include <search.h>
++#include "libc.h"
+ 
+ /*
+ open addressing hash table with 2^n table size
+@@ -14,14 +16,17 @@ with the posix api items cannot be iterated and length cannot be queried
+ #define MINSIZE 8
+ #define MAXSIZE ((size_t)-1/2 + 1)
+ 
+-struct elem {
+-	ENTRY item;
+-	size_t hash;
++struct __tab {
++	ENTRY *entries;
++	size_t mask;
++	size_t used;
+ };
+ 
+-static size_t mask;
+-static size_t used;
+-static struct elem *tab;
++static struct hsearch_data htab;
++
++int __hcreate_r(size_t, struct hsearch_data *);
++void __hdestroy_r(struct hsearch_data *);
++int __hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
+ 
+ static size_t keyhash(char *k)
+ {
+@@ -33,30 +38,30 @@ static size_t keyhash(char *k)
+ 	return h;
+ }
+ 
+-static int resize(size_t nel)
++static int resize(size_t nel, struct hsearch_data *htab)
+ {
+ 	size_t newsize;
+ 	size_t i, j;
+-	struct elem *e, *newe;
+-	struct elem *oldtab = tab;
+-	struct elem *oldend = tab + mask + 1;
++	ENTRY *e, *newe;
++	ENTRY *oldtab = htab->__tab->entries;
++	ENTRY *oldend = htab->__tab->entries + htab->__tab->mask + 1;
+ 
+ 	if (nel > MAXSIZE)
+ 		nel = MAXSIZE;
+ 	for (newsize = MINSIZE; newsize < nel; newsize *= 2);
+-	tab = calloc(newsize, sizeof *tab);
+-	if (!tab) {
+-		tab = oldtab;
++	htab->__tab->entries = calloc(newsize, sizeof *htab->__tab->entries);
++	if (!htab->__tab->entries) {
++		htab->__tab->entries = oldtab;
+ 		return 0;
+ 	}
+-	mask = newsize - 1;
++	htab->__tab->mask = newsize - 1;
+ 	if (!oldtab)
+ 		return 1;
+ 	for (e = oldtab; e < oldend; e++)
+-		if (e->item.key) {
+-			for (i=e->hash,j=1; ; i+=j++) {
+-				newe = tab + (i & mask);
+-				if (!newe->item.key)
++		if (e->key) {
++			for (i=keyhash(e->key),j=1; ; i+=j++) {
++				newe = htab->__tab->entries + (i & htab->__tab->mask);
++				if (!newe->key)
+ 					break;
+ 			}
+ 			*newe = *e;
+@@ -67,29 +72,22 @@ static int resize(size_t nel)
+ 
+ int hcreate(size_t nel)
+ {
+-	mask = 0;
+-	used = 0;
+-	tab = 0;
+-	return resize(nel);
++	return __hcreate_r(nel, &htab);
+ }
+ 
+ void hdestroy(void)
+ {
+-	free(tab);
+-	tab = 0;
+-	mask = 0;
+-	used = 0;
++	__hdestroy_r(&htab);
+ }
+ 
+-static struct elem *lookup(char *key, size_t hash)
++static ENTRY *lookup(char *key, size_t hash, struct hsearch_data *htab)
+ {
+ 	size_t i, j;
+-	struct elem *e;
++	ENTRY *e;
+ 
+ 	for (i=hash,j=1; ; i+=j++) {
+-		e = tab + (i & mask);
+-		if (!e->item.key ||
+-		    (e->hash==hash && strcmp(e->item.key, key)==0))
++		e = htab->__tab->entries + (i & htab->__tab->mask);
++		if (!e->key || strcmp(e->key, key) == 0)
+ 			break;
+ 	}
+ 	return e;
+@@ -97,22 +95,60 @@ static struct elem *lookup(char *key, size_t hash)
+ 
+ ENTRY *hsearch(ENTRY item, ACTION action)
+ {
++	ENTRY *e;
++
++	__hsearch_r(item, action, &e, &htab);
++	return e;
++}
++
++int __hcreate_r(size_t nel, struct hsearch_data *htab)
++{
++	int r;
++
++	htab->__tab = calloc(1, sizeof *htab->__tab);
++	if (!htab->__tab)
++		return 0;
++	r = resize(nel, htab);
++	if (r == 0) {
++		free(htab->__tab);
++		htab->__tab = 0;
++	}
++	return r;
++}
++weak_alias(__hcreate_r, hcreate_r);
++
++void __hdestroy_r(struct hsearch_data *htab)
++{
++	if (htab->__tab) free(htab->__tab->entries);
++	free(htab->__tab);
++	htab->__tab = 0;
++}
++weak_alias(__hdestroy_r, hdestroy_r);
++
++int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
++{
+ 	size_t hash = keyhash(item.key);
+-	struct elem *e = lookup(item.key, hash);
++	ENTRY *e = lookup(item.key, hash, htab);
+ 
+-	if (e->item.key)
+-		return &e->item;
+-	if (action == FIND)
++	if (e->key) {
++		*retval = e;
++		return 1;
++	}
++	if (action == FIND) {
++		*retval = 0;
+ 		return 0;
+-	e->item = item;
+-	e->hash = hash;
+-	if (++used > mask - mask/4) {
+-		if (!resize(2*used)) {
+-			used--;
+-			e->item.key = 0;
++	}
++	*e = item;
++	if (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) {
++		if (!resize(2*htab->__tab->used, htab)) {
++			htab->__tab->used--;
++			e->key = 0;
++			*retval = 0;
+ 			return 0;
+ 		}
+-		e = lookup(item.key, hash);
++		e = lookup(item.key, hash, htab);
+ 	}
+-	return &e->item;
++	*retval = e;
++	return 1;
+ }
++weak_alias(__hsearch_r, hsearch_r);
+diff --git a/src/signal/arm/sigsetjmp.s b/src/signal/arm/sigsetjmp.s
+index acb0301..0e7bcd4 100644
+--- a/src/signal/arm/sigsetjmp.s
++++ b/src/signal/arm/sigsetjmp.s
+@@ -1,6 +1,9 @@
+ .global sigsetjmp
++.global __sigsetjmp
+ .type sigsetjmp,%function
++.type __sigsetjmp,%function
+ sigsetjmp:
++__sigsetjmp:
+ 	str a2,[a1,#256]
+ 	tst a2,a2
+ 	beq setjmp
+diff --git a/src/signal/i386/sigsetjmp.s b/src/signal/i386/sigsetjmp.s
+index 06e0a61..91c8c04 100644
+--- a/src/signal/i386/sigsetjmp.s
++++ b/src/signal/i386/sigsetjmp.s
+@@ -1,6 +1,9 @@
+ .global sigsetjmp
++.global __sigsetjmp
+ .type sigsetjmp,@function
++.type __sigsetjmp,@function
+ sigsetjmp:
++__sigsetjmp:
+ 	mov 4(%esp),%eax
+ 	mov 8(%esp),%ecx
+ 	mov %ecx,24(%eax)
+diff --git a/src/signal/microblaze/sigsetjmp.s b/src/signal/microblaze/sigsetjmp.s
+index be869d6..2a23d14 100644
+--- a/src/signal/microblaze/sigsetjmp.s
++++ b/src/signal/microblaze/sigsetjmp.s
+@@ -1,6 +1,9 @@
+ .global sigsetjmp
++.global __sigsetjmp
+ .type sigsetjmp,@function
++.type __sigsetjmp,@function
+ sigsetjmp:
++__sigsetjmp:
+ 	swi     r6, r5, 72
+ 	beqi    r6, setjmp@PLT
+ 
+diff --git a/src/signal/mips/sigsetjmp.s b/src/signal/mips/sigsetjmp.s
+index 502e079..133ca77 100644
+--- a/src/signal/mips/sigsetjmp.s
++++ b/src/signal/mips/sigsetjmp.s
+@@ -1,8 +1,11 @@
+ .set noreorder
+ 
+ .global sigsetjmp
++.global __sigsetjmp
+ .type sigsetjmp,@function
++.type __sigsetjmp,@function
+ sigsetjmp:
++__sigsetjmp:
+ 	lui $gp, %hi(_gp_disp)
+ 	addiu $gp, %lo(_gp_disp)
+ 	beq $5, $0, 1f
+diff --git a/src/signal/powerpc/sigsetjmp.s b/src/signal/powerpc/sigsetjmp.s
+index d7d1af3..461b737 100644
+--- a/src/signal/powerpc/sigsetjmp.s
++++ b/src/signal/powerpc/sigsetjmp.s
+@@ -1,6 +1,9 @@
+ 	.global sigsetjmp
++	.global __sigsetjmp
+ 	.type sigsetjmp,%function
++	.type __sigsetjmp,%function
+ sigsetjmp:
++__sigsetjmp:
+ 	#int sigsetjmp(sigjmp_buf buf, int save)
+ 	#		r3		r4
+ 	#0) store save into buf->__fl
+diff --git a/src/signal/sh/sigsetjmp.s b/src/signal/sh/sigsetjmp.s
+index f6cae80..7951f07 100644
+--- a/src/signal/sh/sigsetjmp.s
++++ b/src/signal/sh/sigsetjmp.s
+@@ -1,6 +1,9 @@
+ .global sigsetjmp
+-.type   sigsetjmp, @function
++.global __sigsetjmp
++.type sigsetjmp,@function
++.type __sigsetjmp,@function
+ sigsetjmp:
++__sigsetjmp:
+ 	mov.l r5, @(36,r4)
+ 	tst r5, r5
+ 	bf  2f
+diff --git a/src/signal/sigsetjmp.c b/src/signal/sigsetjmp.c
+index cb2257f..1bbe1a0 100644
+--- a/src/signal/sigsetjmp.c
++++ b/src/signal/sigsetjmp.c
+@@ -1,5 +1,6 @@
+ #include <setjmp.h>
+ #include <signal.h>
++#include "libc.h"
+ 
+ /* !!! This function will not work unless the compiler performs
+  * tail call optimization. Machine-specific asm versions should
+@@ -12,3 +13,5 @@ int sigsetjmp(sigjmp_buf buf, int save)
+ 		pthread_sigmask(SIG_SETMASK, 0, (sigset_t *)buf->__ss);
+ 	return setjmp(buf);
+ }
++
++weak_alias(sigsetjmp, __sigsetjmp);
+diff --git a/src/signal/x32/sigsetjmp.s b/src/signal/x32/sigsetjmp.s
+index dc38f03..17436f0 100644
+--- a/src/signal/x32/sigsetjmp.s
++++ b/src/signal/x32/sigsetjmp.s
+@@ -1,7 +1,10 @@
+ /* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+ .global sigsetjmp
++.global __sigsetjmp
+ .type sigsetjmp,@function
++.type __sigsetjmp,@function
+ sigsetjmp:
++__sigsetjmp:
+ 	andl %esi,%esi
+ 	movq %rsi,64(%rdi)
+ 	jz 1f
+diff --git a/src/signal/x86_64/sigsetjmp.s b/src/signal/x86_64/sigsetjmp.s
+index dc38f03..17436f0 100644
+--- a/src/signal/x86_64/sigsetjmp.s
++++ b/src/signal/x86_64/sigsetjmp.s
+@@ -1,7 +1,10 @@
+ /* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+ .global sigsetjmp
++.global __sigsetjmp
+ .type sigsetjmp,@function
++.type __sigsetjmp,@function
+ sigsetjmp:
++__sigsetjmp:
+ 	andl %esi,%esi
+ 	movq %rsi,64(%rdi)
+ 	jz 1f
diff --git a/main/musl/1002-no-kuser_helpers-on-armv6.patch b/main/musl/1002-no-kuser_helpers-on-armv6.patch
new file mode 100644
index 0000000000000000000000000000000000000000..94379905bc3fbbe6fcc18885e4de20caf8b6d70a
--- /dev/null
+++ b/main/musl/1002-no-kuser_helpers-on-armv6.patch
@@ -0,0 +1,64 @@
+From: Rich Felker <dalias@aerifal.cx>
+
+diff --git a/arch/arm/atomic.h b/arch/arm/atomic.h
+index 734d287..ed1f467 100644
+--- a/arch/arm/atomic.h
++++ b/arch/arm/atomic.h
+@@ -22,7 +22,28 @@ static inline int a_ctz_64(uint64_t x)
+ 	return a_ctz_l(y);
+ }
+ 
++#if __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__ \
++ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ \
++ || __ARM_ARCH >= 6
++static inline int __k_cas(int t, int s, volatile int *p)
++{
++	int ret;
++	__asm__(
++		"	mcr p15,0,r0,c7,c10,5\n"
++		"1:	ldrex %0,[%3]\n"
++		"	subs %0,%0,%1\n"
++		"	strexeq %0,%2,[%3]\n"
++		"	teqeq %0,#1\n"
++		"	beq 1b\n"
++		"	mcr p15,0,r0,c7,c10,5\n"
++		: "=&r"(ret)
++		: "r"(t), "r"(s), "r"(p)
++		: "memory", "cc" );
++	return ret;
++}
++#else
+ #define __k_cas ((int (*)(int, int, volatile int *))0xffff0fc0)
++#endif
+ 
+ static inline int a_cas(volatile int *p, int t, int s)
+ {
+diff --git a/arch/arm/pthread_arch.h b/arch/arm/pthread_arch.h
+index 43a1c01..ae3e80b 100644
+--- a/arch/arm/pthread_arch.h
++++ b/arch/arm/pthread_arch.h
+@@ -1,8 +1,22 @@
+-typedef char *(*__ptr_func_t)(void) __attribute__((const));
++#if __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__ \
++ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ \
++ || __ARM_ARCH >= 7
++
++static inline pthread_t __pthread_self()
++{
++	char *p;
++	__asm__( "mrc p15,0,%0,c13,c0,3" : "=r"(p) );
++	return (void *)(p+8-sizeof(struct pthread));
++}
++
++#else
+ 
++typedef char *(*__ptr_func_t)(void) __attribute__((const));
+ #define __pthread_self() \
+ 	((pthread_t)(((__ptr_func_t)0xffff0fe0)()+8-sizeof(struct pthread)))
+ 
++#endif
++
+ #define TLS_ABOVE_TP
+ #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
+ 
+
diff --git a/main/musl/1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch b/main/musl/1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
deleted file mode 100644
index e05a6cd7de4ec5bb7a0288cb16b2615fa0d12ee7..0000000000000000000000000000000000000000
--- a/main/musl/1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 59077a9fd34986482ee980cc6b1b989fced0d65a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
-Date: Tue, 1 Apr 2014 10:53:23 +0300
-Subject: [PATCH 1/1] use armv6+ opcodes for atomics if targetting such
- architecture
-
----
- Makefile                | 6 ++++++
- arch/arm/atomic.h       | 4 ++++
- arch/arm/pthread_arch.h | 7 ++++++-
- src/thread/arm/tls.S    | 9 +++++++++
- src/thread/arm/tls.s    | 4 ----
- 5 files changed, 25 insertions(+), 5 deletions(-)
- create mode 100644 src/thread/arm/tls.S
- delete mode 100644 src/thread/arm/tls.s
-
-diff --git a/Makefile b/Makefile
-index 0ab0bfd..b96c76b 100644
---- a/Makefile
-+++ b/Makefile
-@@ -111,6 +111,9 @@ $(foreach s,$(wildcard src/*/$(ARCH)*/*.s),$(eval $(call mkasmdep,$(s))))
- %.o: $(ARCH)/%.s
- 	$(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $<
- 
-+%.o: $(ARCH)/%.s
-+	$(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $<
-+
- %.o: %.c $(GENH) $(IMPH)
- 	$(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $<
- 
-@@ -120,6 +123,9 @@ $(foreach s,$(wildcard src/*/$(ARCH)*/*.s),$(eval $(call mkasmdep,$(s))))
- %.lo: $(ARCH)/%.s
- 	$(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $<
- 
-+%.lo: $(ARCH)/%.S
-+	$(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $<
-+
- %.lo: %.c $(GENH) $(IMPH)
- 	$(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $<
- 
-diff --git a/arch/arm/atomic.h b/arch/arm/atomic.h
-index 734d287..cb8fb31 100644
---- a/arch/arm/atomic.h
-+++ b/arch/arm/atomic.h
-@@ -22,7 +22,11 @@ static inline int a_ctz_64(uint64_t x)
- 	return a_ctz_l(y);
- }
- 
-+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
-+#define __k_cas(t, s, p) (!__sync_bool_compare_and_swap(p, t, s))
-+#else
- #define __k_cas ((int (*)(int, int, volatile int *))0xffff0fc0)
-+#endif
- 
- static inline int a_cas(volatile int *p, int t, int s)
- {
-diff --git a/arch/arm/pthread_arch.h b/arch/arm/pthread_arch.h
-index 43a1c01..3ac2779 100644
---- a/arch/arm/pthread_arch.h
-+++ b/arch/arm/pthread_arch.h
-@@ -1,7 +1,12 @@
-+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
-+char *__aeabi_read_tp(void) __attribute__((const));
-+#define __pthread_self() \
-+	((pthread_t)((char *)__aeabi_read_tp()+8-sizeof(struct pthread)))
-+#else
- typedef char *(*__ptr_func_t)(void) __attribute__((const));
--
- #define __pthread_self() \
- 	((pthread_t)(((__ptr_func_t)0xffff0fe0)()+8-sizeof(struct pthread)))
-+#endif
- 
- #define TLS_ABOVE_TP
- #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
-diff --git a/src/thread/arm/tls.S b/src/thread/arm/tls.S
-new file mode 100644
-index 0000000..f255e83
---- /dev/null
-+++ b/src/thread/arm/tls.S
-@@ -0,0 +1,9 @@
-+.global __aeabi_read_tp
-+.type __aeabi_read_tp,%function
-+__aeabi_read_tp:
-+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
-+	.inst 0xee1d0f70 /* mrc 15,0,r0,cr13,cr0,{3} */
-+	bx lr
-+#else
-+	ldr pc,=0xffff0fe0
-+#endif
-diff --git a/src/thread/arm/tls.s b/src/thread/arm/tls.s
-deleted file mode 100644
-index 59736ac..0000000
---- a/src/thread/arm/tls.s
-+++ /dev/null
-@@ -1,4 +0,0 @@
--.global __aeabi_read_tp
--.type __aeabi_read_tp,%function
--__aeabi_read_tp:
--	ldr pc,=0xffff0fe0
--- 
-1.9.1
-
diff --git a/main/musl/APKBUILD b/main/musl/APKBUILD
index c3bf4bb42eb29ecd8e48f2a5ed017504f669267b..2bb42abdc2c37a85e3b66cdbbcf288383edbd029 100644
--- a/main/musl/APKBUILD
+++ b/main/musl/APKBUILD
@@ -2,7 +2,7 @@
 # Maintainer: Timo Teräs <timo.teras@iki.fi>
 pkgname=musl
 pkgver=1.0.0
-pkgrel=4
+pkgrel=5
 pkgdesc="the musl c library (libc) implementation"
 url="http://www.musl-libc.org/"
 arch="all"
@@ -15,10 +15,9 @@ subpackages="$pkgname-dev $pkgname-utils"
 [ "${CTARGET#*musl}" = "$CTARGET" ] && subpackages="$subpackages musl-gcc:crosstool"
 source="http://www.musl-libc.org/releases/musl-$pkgver.tar.gz
 	0001-v1.0.0-to-2b74315d.patch
+	0002-2b74315d-to-b9b2db2f.patch
 	1001-add-basic-dns-record-parsing-functions.patch
-	1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
-	hsearch-1.patch
-	hsearch-2.patch
+	1002-no-kuser_helpers-on-armv6.patch
 
 	getopt_long.c
 	__stack_chk_fail_local.c
@@ -116,10 +115,9 @@ crosstool() {
 
 md5sums="e54664fdf211d27737e328c4462b545e  musl-1.0.0.tar.gz
 d081fc3424229c639e636be2dd00d221  0001-v1.0.0-to-2b74315d.patch
+48fa02a48a33bbcb8149edf6540d02f9  0002-2b74315d-to-b9b2db2f.patch
 a3810683ef61ac27e2f6ec9801280c81  1001-add-basic-dns-record-parsing-functions.patch
-e2bdd9d7d057c28c1f45c8930e40276a  1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
-f82a3988422584cda506ca1ca59114ef  hsearch-1.patch
-6045d289d7b1b12c02ce583f407fdb17  hsearch-2.patch
+3e275d833412e490f8f75acc76116de3  1002-no-kuser_helpers-on-armv6.patch
 61c6c1e84ed1df82abbe6d75e90cf21c  getopt_long.c
 0df687757221bbb0fc1aa67f1bd646f9  __stack_chk_fail_local.c
 7b391300396e58fe9073866b5a80cfe8  getconf.c
@@ -127,10 +125,9 @@ ef81489a6258501cf45db58dfc6d5211  getent
 33e4fd94e2560e008e2c3b431d0e3419  ldconfig"
 sha256sums="1ad7f45d2972daff19c9e6a92714e6d70f4aad003cd8c3d1e6113432114c1a32  musl-1.0.0.tar.gz
 aa632b635d472d5a6a49800899ce34cddc89a63a489690faa683d08622b9cd60  0001-v1.0.0-to-2b74315d.patch
+edc0cebaabd16f894d91c1860bfb70d3f2d9a70cf558c5455689610374447f7d  0002-2b74315d-to-b9b2db2f.patch
 758390768b1bc4159d56908ca332b9640cd0552ed3b4b2b8d4a6d499c54c11a1  1001-add-basic-dns-record-parsing-functions.patch
-2069f2de91fc584282fefef8618808f3182837ec3f09848028b9480cfc90d46f  1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
-35c93d9e14fc136b6f31940425b43bb42de6ea64045b6cacb5fae41625049bb6  hsearch-1.patch
-c501b141a6d401dbb5a78ba3758a4b7c78907da11052878a2a73ca81554ef740  hsearch-2.patch
+092cd39fe1f7e6f65b4df1c3de7b0bfb5509b6fb468a467d2580b19db85349f6  1002-no-kuser_helpers-on-armv6.patch
 d9b644ec20bc33e81a7c52b9fcf7973d835923a69faf50f03db45534b811bd96  getopt_long.c
 299a7d75a09de3e2e11e7fb4acc3182e4a14e868093d2f30938fce9bfcff13da  __stack_chk_fail_local.c
 530ea449f93d53fafcb377fa0a23a7564f2961e49c07a8fdef6c960110317301  getconf.c
@@ -138,10 +135,9 @@ d6996273f5aaaed429058257e4646b243d9e3a4d8609522f802762453f5be4cb  getent
 306c6ca7407560340797866e077e053627ad409277d1b9da58106fce4cf717cb  ldconfig"
 sha512sums="c76cbfe60cbe9b1ceb1faedddf2dcce0f11c942c8f74e4f217efe63e8e1d7be70fcb6cf1182eeaee90441152c4493d678682cb247a0dbc7537d24f943a7bbdf8  musl-1.0.0.tar.gz
 e04f0f9de2859d18cb13aa8bfd839cc757aa9d835f133e46b48a760c7e689a92c641abe1e84dcaab6134c22500603e66d9a880f9b80b77e36a063348f5879878  0001-v1.0.0-to-2b74315d.patch
+19c09e09d61ba31caeece27ea4241be4f14f73ab958da7f37fc4f0c8391fcaa912a750a2b79c29b3fec24ad22995244c91d1f0372d9b8481c99411e2442c2d4e  0002-2b74315d-to-b9b2db2f.patch
 dad965258daf69371b844f76bfe5a914b0eca0ca76f3fc340b8fd7acf598b5f87bbe6d68b1f43ed0293ee0ed3bfd85d5173ccc169aa6265646248d5b8a906708  1001-add-basic-dns-record-parsing-functions.patch
-afbec2ae86e3406cc4116b217ecee7fbd0b995c6635a455e6166cb04798968abbd5be33161e3bc19e2665cdec07a4249ca3b7c535da97922c03d8d6ac6535a76  1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
-c226aec49a7935de3d31c708da7c3493a67153cc443c4b3fe534cbe4442bb66cc07aa73cd6a9651f3088b8951ad8849bc9adcba89ce9be26398ed7c51c5c1701  hsearch-1.patch
-43583e071487813b6f0f8759c92b2c1ef7523fd33076040e545cdd645e9a6aa4274611cb3b4a7b401f4a99b455cf7637c3dc26c97255bbde79c4eef900d2c224  hsearch-2.patch
+6a0ba5817b22906fb5503972969f0ba41609121b91427e25ced0cc7f9033f7b80c760d33ce54a815378d4bc77119bf6f2ea25d3da49157fd3d6ac944ea593882  1002-no-kuser_helpers-on-armv6.patch
 140f3f20d30bd95ebce8c41b8cc7f616c6cbedf4ea06c729c21014e74f6043796825cc40ebc5180620ea38173afdba23f09ebf6d8b11fa05440b14d23764fca9  getopt_long.c
 062bb49fa54839010acd4af113e20f7263dde1c8a2ca359b5fb2661ef9ed9d84a0f7c3bc10c25dcfa10bb3c5a4874588dff636ac43d5dbb3d748d75400756d0b  __stack_chk_fail_local.c
 d638cdd02371351190fd0545fb83f44b822fa8c930e9fb47ef93d32a1aaee27641f875e10fa2e9833f1a56dfc2055fb89932a89c88da3e2eb17529bca58f5182  getconf.c
diff --git a/main/musl/hsearch-1.patch b/main/musl/hsearch-1.patch
deleted file mode 100644
index ced1cc4af5525c5dc33eaf09e3db1739c8064943..0000000000000000000000000000000000000000
--- a/main/musl/hsearch-1.patch
+++ /dev/null
@@ -1,213 +0,0 @@
-From fe1ba7dbf187e34985896b40d469d84a7a4a98d0 Mon Sep 17 00:00:00 2001
-From: sin <sin@2f30.org>
-Date: Tue, 25 Mar 2014 16:37:51 +0000
-Subject: implement hcreate_r, hdestroy_r and hsearch_r
-
-the size and alignment of struct hsearch_data are matched to the glibc
-definition for binary compatibility. the members of the structure do
-not match, which should not be a problem as long as applications
-correctly treat the structure as opaque.
-
-unlike the glibc implementation, this version of hcreate_r does not
-require the caller to zero-fill the structure before use.
----
-diff --git a/include/search.h b/include/search.h
-index 27f6107..02e407e 100644
---- a/include/search.h
-+++ b/include/search.h
-@@ -22,6 +22,18 @@ int hcreate(size_t);
- void hdestroy(void);
- ENTRY *hsearch(ENTRY, ACTION);
- 
-+#ifdef _GNU_SOURCE
-+struct hsearch_data {
-+	struct __tab *__tab;
-+	unsigned int __unused1;
-+	unsigned int __unused2;
-+};
-+
-+int hcreate_r(size_t, struct hsearch_data *);
-+void hdestroy_r(struct hsearch_data *);
-+int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
-+#endif
-+
- void insque(void *, void *);
- void remque(void *);
- 
-diff --git a/src/search/hsearch.c b/src/search/hsearch.c
-index 6fe5ced..88edb26 100644
---- a/src/search/hsearch.c
-+++ b/src/search/hsearch.c
-@@ -1,6 +1,8 @@
-+#define _GNU_SOURCE
- #include <stdlib.h>
- #include <string.h>
- #include <search.h>
-+#include "libc.h"
- 
- /*
- open addressing hash table with 2^n table size
-@@ -19,9 +21,17 @@ struct elem {
- 	size_t hash;
- };
- 
--static size_t mask;
--static size_t used;
--static struct elem *tab;
-+struct __tab {
-+	struct elem *elems;
-+	size_t mask;
-+	size_t used;
-+};
-+
-+static struct hsearch_data htab;
-+
-+int __hcreate_r(size_t, struct hsearch_data *);
-+void __hdestroy_r(struct hsearch_data *);
-+int __hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
- 
- static size_t keyhash(char *k)
- {
-@@ -33,29 +43,29 @@ static size_t keyhash(char *k)
- 	return h;
- }
- 
--static int resize(size_t nel)
-+static int resize(size_t nel, struct hsearch_data *htab)
- {
- 	size_t newsize;
- 	size_t i, j;
- 	struct elem *e, *newe;
--	struct elem *oldtab = tab;
--	struct elem *oldend = tab + mask + 1;
-+	struct elem *oldtab = htab->__tab->elems;
-+	struct elem *oldend = htab->__tab->elems + htab->__tab->mask + 1;
- 
- 	if (nel > MAXSIZE)
- 		nel = MAXSIZE;
- 	for (newsize = MINSIZE; newsize < nel; newsize *= 2);
--	tab = calloc(newsize, sizeof *tab);
--	if (!tab) {
--		tab = oldtab;
-+	htab->__tab->elems = calloc(newsize, sizeof *htab->__tab->elems);
-+	if (!htab->__tab->elems) {
-+		htab->__tab->elems = oldtab;
- 		return 0;
- 	}
--	mask = newsize - 1;
-+	htab->__tab->mask = newsize - 1;
- 	if (!oldtab)
- 		return 1;
- 	for (e = oldtab; e < oldend; e++)
- 		if (e->item.key) {
- 			for (i=e->hash,j=1; ; i+=j++) {
--				newe = tab + (i & mask);
-+				newe = htab->__tab->elems + (i & htab->__tab->mask);
- 				if (!newe->item.key)
- 					break;
- 			}
-@@ -67,27 +77,21 @@ static int resize(size_t nel)
- 
- int hcreate(size_t nel)
- {
--	mask = 0;
--	used = 0;
--	tab = 0;
--	return resize(nel);
-+	return __hcreate_r(nel, &htab);
- }
- 
- void hdestroy(void)
- {
--	free(tab);
--	tab = 0;
--	mask = 0;
--	used = 0;
-+	__hdestroy_r(&htab);
- }
- 
--static struct elem *lookup(char *key, size_t hash)
-+static struct elem *lookup(char *key, size_t hash, struct hsearch_data *htab)
- {
- 	size_t i, j;
- 	struct elem *e;
- 
- 	for (i=hash,j=1; ; i+=j++) {
--		e = tab + (i & mask);
-+		e = htab->__tab->elems + (i & htab->__tab->mask);
- 		if (!e->item.key ||
- 		    (e->hash==hash && strcmp(e->item.key, key)==0))
- 			break;
-@@ -97,22 +101,61 @@ static struct elem *lookup(char *key, size_t hash)
- 
- ENTRY *hsearch(ENTRY item, ACTION action)
- {
-+	ENTRY *e;
-+
-+	__hsearch_r(item, action, &e, &htab);
-+	return e;
-+}
-+
-+int __hcreate_r(size_t nel, struct hsearch_data *htab)
-+{
-+	int r;
-+
-+	htab->__tab = calloc(1, sizeof *htab->__tab);
-+	if (!htab->__tab)
-+		return 0;
-+	r = resize(nel, htab);
-+	if (r == 0) {
-+		free(htab->__tab);
-+		htab->__tab = 0;
-+	}
-+	return r;
-+}
-+weak_alias(__hcreate_r, hcreate_r);
-+
-+void __hdestroy_r(struct hsearch_data *htab)
-+{
-+	if (htab->__tab) free(htab->__tab->elems);
-+	free(htab->__tab);
-+	htab->__tab = 0;
-+}
-+weak_alias(__hdestroy_r, hdestroy_r);
-+
-+int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
-+{
- 	size_t hash = keyhash(item.key);
--	struct elem *e = lookup(item.key, hash);
-+	struct elem *e = lookup(item.key, hash, htab);
- 
--	if (e->item.key)
--		return &e->item;
--	if (action == FIND)
-+	if (e->item.key) {
-+		*retval = &e->item;
-+		return 1;
-+	}
-+	if (action == FIND) {
-+		*retval = 0;
- 		return 0;
-+	}
- 	e->item = item;
- 	e->hash = hash;
--	if (++used > mask - mask/4) {
--		if (!resize(2*used)) {
--			used--;
-+	if (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) {
-+		if (!resize(2*htab->__tab->used, htab)) {
-+			htab->__tab->used--;
- 			e->item.key = 0;
-+			*retval = 0;
- 			return 0;
- 		}
--		e = lookup(item.key, hash);
-+		e = lookup(item.key, hash, htab);
- 	}
--	return &e->item;
-+	*retval = &e->item;
-+	return 1;
- }
-+weak_alias(__hsearch_r, hsearch_r);
---
-cgit v0.9.0.3-65-g4555
diff --git a/main/musl/hsearch-2.patch b/main/musl/hsearch-2.patch
deleted file mode 100644
index 3f795dce8751cffc21f5fc395fb89a77eb4b9981..0000000000000000000000000000000000000000
--- a/main/musl/hsearch-2.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From 141d3b5c2a93dd48096a13ce051d09eaf3ec0b4a Mon Sep 17 00:00:00 2001
-From: sin <sin@2f30.org>
-Date: Thu, 27 Mar 2014 11:20:17 +0000
-Subject: remove struct elem entirely from hsearch.c
-
-There are two changes here, both of which make sense to be done in a
-single patch:
-
-- Remove hash from struct elem and compute it at runtime wherever
-  necessary.
-- Eliminate struct elem and use ENTRY directly.
-
-As a result we cut down on the memory usage as each element in the
-hash table now contains only an ENTRY not an ENTRY + size_t for the
-hash. The downside is that the hash needs to be computed at runtime.
----
-diff --git a/src/search/hsearch.c b/src/search/hsearch.c
-index 88edb26..5c89651 100644
---- a/src/search/hsearch.c
-+++ b/src/search/hsearch.c
-@@ -16,13 +16,8 @@ with the posix api items cannot be iterated and length cannot be queried
- #define MINSIZE 8
- #define MAXSIZE ((size_t)-1/2 + 1)
- 
--struct elem {
--	ENTRY item;
--	size_t hash;
--};
--
- struct __tab {
--	struct elem *elems;
-+	ENTRY *entries;
- 	size_t mask;
- 	size_t used;
- };
-@@ -47,26 +42,26 @@ static int resize(size_t nel, struct hsearch_data *htab)
- {
- 	size_t newsize;
- 	size_t i, j;
--	struct elem *e, *newe;
--	struct elem *oldtab = htab->__tab->elems;
--	struct elem *oldend = htab->__tab->elems + htab->__tab->mask + 1;
-+	ENTRY *e, *newe;
-+	ENTRY *oldtab = htab->__tab->entries;
-+	ENTRY *oldend = htab->__tab->entries + htab->__tab->mask + 1;
- 
- 	if (nel > MAXSIZE)
- 		nel = MAXSIZE;
- 	for (newsize = MINSIZE; newsize < nel; newsize *= 2);
--	htab->__tab->elems = calloc(newsize, sizeof *htab->__tab->elems);
--	if (!htab->__tab->elems) {
--		htab->__tab->elems = oldtab;
-+	htab->__tab->entries = calloc(newsize, sizeof *htab->__tab->entries);
-+	if (!htab->__tab->entries) {
-+		htab->__tab->entries = oldtab;
- 		return 0;
- 	}
- 	htab->__tab->mask = newsize - 1;
- 	if (!oldtab)
- 		return 1;
- 	for (e = oldtab; e < oldend; e++)
--		if (e->item.key) {
--			for (i=e->hash,j=1; ; i+=j++) {
--				newe = htab->__tab->elems + (i & htab->__tab->mask);
--				if (!newe->item.key)
-+		if (e->key) {
-+			for (i=keyhash(e->key),j=1; ; i+=j++) {
-+				newe = htab->__tab->entries + (i & htab->__tab->mask);
-+				if (!newe->key)
- 					break;
- 			}
- 			*newe = *e;
-@@ -85,15 +80,14 @@ void hdestroy(void)
- 	__hdestroy_r(&htab);
- }
- 
--static struct elem *lookup(char *key, size_t hash, struct hsearch_data *htab)
-+static ENTRY *lookup(char *key, size_t hash, struct hsearch_data *htab)
- {
- 	size_t i, j;
--	struct elem *e;
-+	ENTRY *e;
- 
- 	for (i=hash,j=1; ; i+=j++) {
--		e = htab->__tab->elems + (i & htab->__tab->mask);
--		if (!e->item.key ||
--		    (e->hash==hash && strcmp(e->item.key, key)==0))
-+		e = htab->__tab->entries + (i & htab->__tab->mask);
-+		if (!e->key || strcmp(e->key, key) == 0)
- 			break;
- 	}
- 	return e;
-@@ -125,7 +119,7 @@ weak_alias(__hcreate_r, hcreate_r);
- 
- void __hdestroy_r(struct hsearch_data *htab)
- {
--	if (htab->__tab) free(htab->__tab->elems);
-+	if (htab->__tab) free(htab->__tab->entries);
- 	free(htab->__tab);
- 	htab->__tab = 0;
- }
-@@ -134,28 +128,27 @@ weak_alias(__hdestroy_r, hdestroy_r);
- int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
- {
- 	size_t hash = keyhash(item.key);
--	struct elem *e = lookup(item.key, hash, htab);
-+	ENTRY *e = lookup(item.key, hash, htab);
- 
--	if (e->item.key) {
--		*retval = &e->item;
-+	if (e->key) {
-+		*retval = e;
- 		return 1;
- 	}
- 	if (action == FIND) {
- 		*retval = 0;
- 		return 0;
- 	}
--	e->item = item;
--	e->hash = hash;
-+	*e = item;
- 	if (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) {
- 		if (!resize(2*htab->__tab->used, htab)) {
- 			htab->__tab->used--;
--			e->item.key = 0;
-+			e->key = 0;
- 			*retval = 0;
- 			return 0;
- 		}
- 		e = lookup(item.key, hash, htab);
- 	}
--	*retval = &e->item;
-+	*retval = e;
- 	return 1;
- }
- weak_alias(__hsearch_r, hsearch_r);
---
-cgit v0.9.0.3-65-g4555