diff --git a/include/sys/mman.h b/include/sys/mman.h
index 71d553a..fc8fce5 100644
--- a/include/sys/mman.h
+++ b/include/sys/mman.h
@@ -99,6 +99,7 @@ static __inline__ int msync (void *__addr, size_t __len, int __flags) { return 0
 
 #endif
 
+#ifdef __ARCH_USE_MMU__
 #if defined __USE_BSD && (defined __UCLIBC_LINUX_SPECIFIC__ || defined __UCLIBC_HAS_THREADS_NATIVE__)
 /* Advise the system about particular usage patterns the program follows
    for the region starting at ADDR and extending LEN bytes.  */
@@ -108,6 +109,8 @@ extern int madvise (void *__addr, size_t __len, int __advice) __THROW;
 /* This is the POSIX name for this function.  */
 extern int posix_madvise (void *__addr, size_t __len, int __advice) __THROW;
 #endif
+#endif /* __ARCH_USE_MMU__ */
+
 
 #if defined __UCLIBC_HAS_REALTIME__
 # ifdef __ARCH_USE_MMU__
diff --git a/ldso/ldso/bfin/dl-sysdep.h b/ldso/ldso/bfin/dl-sysdep.h
index 5758117..4262a26 100644
--- a/ldso/ldso/bfin/dl-sysdep.h
+++ b/ldso/ldso/bfin/dl-sysdep.h
@@ -93,6 +93,6 @@ static __always_inline void
 elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
 		      Elf32_Word relative_count)
 {
-	return 0;
+	return;
 }
 #endif
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 0cf3b70..04d7c43 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -30,6 +30,14 @@
  */
 
 
+/* When libdl is linked in statically into libc.a, we need to replace
+ * these symbols that otherwise would have been loaded in from ldso.
+ * This must be before including ldso.h */
+#ifndef SHARED
+#define _dl_malloc malloc
+#define _dl_free free
+#endif
+
 #include <ldso.h>
 #include <stdio.h>
 #include <string.h>
@@ -86,9 +94,6 @@ extern char *_dl_debug;
 
 #else /* !SHARED */
 
-#define _dl_malloc malloc
-#define _dl_free free
-
 /* When libdl is linked as a static library, we need to replace all
  * the symbols that otherwise would have been loaded in from ldso... */
 
diff --git a/libc/misc/internals/Makefile.in b/libc/misc/internals/Makefile.in
index ae094ee..ce7f75a 100644
--- a/libc/misc/internals/Makefile.in
+++ b/libc/misc/internals/Makefile.in
@@ -25,7 +25,9 @@ libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.oS
 else
 libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.os
 endif
-libc-static-y += $(MISC_INTERNALS_OUT)/__uClibc_main.o
+# link order is important to not pull in pthread functions, when
+# a single threaded application is statically linked
+libc-static-y := $(MISC_INTERNALS_OUT)/__uClibc_main.o $(libc-static-y)
 libc-static-$(UCLIBC_FORMAT_FLAT_SEP_DATA) += \
   $(MISC_INTERNALS_OUT)/shared_flat_initfini.o \
   $(MISC_INTERNALS_OUT)/shared_flat_add_library.o
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index 46e24d8..d80565e 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -68,6 +68,43 @@ uintptr_t __stack_chk_guard attribute_relro;
 
 void internal_function _dl_aux_init (ElfW(auxv_t) *av);
 
+#ifdef __UCLIBC_HAS_THREADS__
+/*
+ * uClibc internal locking requires that we have weak aliases
+ * for dummy functions in case a single threaded application is linked.
+ * This needs to be in compilation unit that is pulled always
+ * in or linker will disregard these weaks.
+ */
+
+static int __pthread_return_0 (pthread_mutex_t *unused) { return 0; }
+weak_alias (__pthread_return_0, __pthread_mutex_lock)
+weak_alias (__pthread_return_0, __pthread_mutex_trylock)
+weak_alias (__pthread_return_0, __pthread_mutex_unlock)
+
+int weak_function
+__pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
+{
+        return 0;
+}
+
+void weak_function
+_pthread_cleanup_push_defer(struct _pthread_cleanup_buffer *__buffer,
+                            void (*__routine) (void *), void *__arg)
+{
+        __buffer->__routine = __routine;
+        __buffer->__arg = __arg;
+}
+
+void weak_function
+_pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *__buffer,
+                             int __execute)
+{
+        if (__execute)
+                __buffer->__routine(__buffer->__arg);
+}
+
+#endif /* __UCLIBC_HAS_THREADS__ */
+
 #endif /* !SHARED */
 
 /* Defeat compiler optimization which assumes function addresses are never NULL */
diff --git a/libc/sysdeps/linux/common/madvise.c b/libc/sysdeps/linux/common/madvise.c
index e953d7b..bb486d2 100644
--- a/libc/sysdeps/linux/common/madvise.c
+++ b/libc/sysdeps/linux/common/madvise.c
@@ -9,6 +9,8 @@
 
 #include <sys/syscall.h>
 #include <sys/mman.h>
+#ifdef __ARCH_USE_MMU__
 #if defined __NR_madvise && defined __USE_BSD
 _syscall3(int, madvise, void *, __addr, size_t, __len, int, __advice)
+#endif /* __ARCH_USE_MMU__ */
 #endif
diff --git a/libpthread/nptl/sysdeps/Makefile.commonarch b/libpthread/nptl/sysdeps/Makefile.commonarch
index c206ac9..134eade 100644
--- a/libpthread/nptl/sysdeps/Makefile.commonarch
+++ b/libpthread/nptl/sysdeps/Makefile.commonarch
@@ -32,10 +32,11 @@ libpthread_arch_SOBJ = $(patsubst %.S,$(libpthread_arch_OUT)/%.o,$(libpthread_ar
 libpthread_arch_OBJS = $(libpthread_subarch_OBJS) $(libpthread_arch_COBJ) $(libpthread_arch_SOBJ)
 
 libc_arch_COBJ = $(patsubst %.c,$(libpthread_arch_OUT)/%.o,$(libc_arch_CSRC))
-libc_arch_SOBJ = $(patsubst %.c,$(libpthread_arch_OUT)/%.o,$(libc_arch_SSRC))
+libc_arch_SOBJ = $(patsubst %.S,$(libpthread_arch_OUT)/%.o,$(libc_arch_SSRC))
 libc_arch_OBJS = $(libc_arch_COBJ) $(libc_arch_SOBJ)
 libc_arch_a_COBJ = $(patsubst %.c,$(libpthread_arch_OUT)/%.o,$(libc_arch_a_CSRC))
-libc_arch_a_OBJS = $(libc_arch_a_COBJ)
+libc_arch_a_SOBJ = $(patsubst %.S,$(libpthread_arch_OUT)/%.o,$(libc_arch_a_SSRC))
+libc_arch_a_OBJS = $(libc_arch_a_COBJ) $(libc_arch_a_SOBJ)
 
 librt_arch_COBJ = $(patsubst %.c,$(libpthread_arch_OUT)/%.o,$(librt_arch_CSRC))
 librt_arch_SOBJ = $(patsubst %.S,$(libpthread_arch_OUT)/%.o,$(librt_arch_SSRC))
diff --git a/libpthread/nptl/sysdeps/xtensa/Makefile.arch b/libpthread/nptl/sysdeps/xtensa/Makefile.arch
index 9e63b19..642e4ba 100644
--- a/libpthread/nptl/sysdeps/xtensa/Makefile.arch
+++ b/libpthread/nptl/sysdeps/xtensa/Makefile.arch
@@ -20,7 +20,7 @@ ASFLAGS-pthread_spin_lock.S = -DNOT_IN_libc -DIS_IN_libpthread
 ASFLAGS-pthread_spin_trylock.S = -DNOT_IN_libc -DIS_IN_libpthread
 
 libc_arch_a_CSRC = libc-tls.c
-librt_arch_a_SSRC = dl-tlsdesc.S
+libc_arch_a_SSRC = libc-dl-tlsdesc.S
 
 CFLAGS-gen_tlsdesc.c = -S
 $(libpthread_arch_OUT)/gen_tlsdesc.c: $(libpthread_arch_DIR)/tlsdesc.sym | $(libpthread_arch_OUT)
diff --git a/libpthread/nptl/sysdeps/xtensa/libc-dl-tlsdesc.S b/libpthread/nptl/sysdeps/xtensa/libc-dl-tlsdesc.S
new file mode 100644
index 0000000..39da7c2
--- /dev/null
+++ b/libpthread/nptl/sysdeps/xtensa/libc-dl-tlsdesc.S
@@ -0,0 +1 @@
+#include <ldso/ldso/xtensa/dl-tlsdesc.S>
