diff mbox

[uclibc-ng-devel] uClibc-ng - small C library for embedded systems branch master updated. v1.0.19-5-g1917395

Message ID 20161103222749.CEE0410151@helium.openadk.org
State Not Applicable
Headers show

Commit Message

wbx Nov. 3, 2016, 10:27 p.m. UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "uClibc-ng - small C library for embedded systems".

The branch, master has been updated
       via  191739597c6d380692885cfdd8dd8aa4f31f029d (commit)
       via  7825930078208462655e107677656c45014e91b4 (commit)
       via  a7f8986f6e81b912b35b46dcad4b8258f75c8b29 (commit)
      from  99ef2719fb3d703fe38c4113cd7f5adec516dd3a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 191739597c6d380692885cfdd8dd8aa4f31f029d
Author: Waldemar Brodkorb <wbx@uclibc-ng.org>
Date:   Mon Oct 31 18:05:44 2016 +0100

    microblaze: add NPTL/TLS support from GNU libc
    
    Not perfect, but a starting point.
    Some tests of the test suite are failing.

commit 7825930078208462655e107677656c45014e91b4
Author: Waldemar Brodkorb <wbx@uclibc-ng.org>
Date:   Wed Jul 20 23:41:10 2016 +0200

    microblaze: use assembly version of clone, fix vfork
    
    Signed-off-by: Waldemar Brodkorb <wbx@uclibc-ng.org>

commit a7f8986f6e81b912b35b46dcad4b8258f75c8b29
Author: Waldemar Brodkorb <wbx@uclibc-ng.org>
Date:   Sun Jul 24 19:15:09 2016 +0200

    ldso: remove useless debug output, too much noise

-----------------------------------------------------------------------

Summary of changes:
 extra/Configs/Config.in                            |   1 -
 include/elf.h                                      |  55 +++----
 ldso/ldso/dl-startup.c                             |   2 -
 ldso/ldso/microblaze/dl-debug.h                    |   8 ++
 ldso/ldso/microblaze/dl-startup.h                  |   3 -
 ldso/ldso/microblaze/dl-sysdep.h                   |  28 ++--
 ldso/ldso/microblaze/elfinterp.c                   |  22 +--
 libc/sysdeps/linux/microblaze/Makefile.arch        |   4 +-
 .../linux/{xtensa => microblaze}/__syscall_error.c |   0
 .../linux/microblaze/bits/uClibc_arch_features.h   |   3 +-
 libc/sysdeps/linux/microblaze/clone.S              |  77 ++++++++++
 libc/sysdeps/linux/microblaze/clone.c              |  47 ------
 libc/sysdeps/linux/microblaze/jmpbuf-offsets.h     |   6 -
 libc/sysdeps/linux/microblaze/jmpbuf-unwind.h      |  25 ++++
 libc/sysdeps/linux/microblaze/sysdep.h             |  83 ++++++++++-
 libc/sysdeps/linux/microblaze/vfork.S              |  73 +++++-----
 .../nptl/sysdeps/{arc => microblaze}/Makefile.arch |   4 -
 .../nptl/sysdeps/{sh => microblaze}/dl-tls.h       |  12 +-
 .../nptl/sysdeps/{arm => microblaze}/libc-tls.c    |  16 +--
 .../{arm => microblaze}/pthread_spin_lock.c        |   4 -
 .../{arm => microblaze}/pthread_spin_trylock.c     |   0
 .../nptl/sysdeps/{mips => microblaze}/pthreaddef.h |  26 ++--
 .../sysdeps/{mips => microblaze}/tcb-offsets.sym   |   4 +-
 libpthread/nptl/sysdeps/microblaze/tls.h           | 159 +++++++++++++++++++++
 .../unix/sysv/linux/{metag => microblaze}/Makefile |   0
 .../sysv/linux/{arc => microblaze}/Makefile.arch   |   6 -
 .../{xtensa => microblaze}/bits/pthreadtypes.h     |  75 +++++-----
 .../linux/{arm => microblaze}/bits/semaphore.h     |   8 +-
 .../sysdeps/unix/sysv/linux/microblaze/clone.S     |   4 +
 .../sysv/linux/{arm => microblaze}/createthread.c  |   0
 .../unix/sysv/linux/{xtensa => microblaze}/fork.c  |   0
 .../sysv/linux/{arc => microblaze}/lowlevellock.h  |  24 ++--
 .../linux/{xtensa => microblaze}/pthread_once.c    |   0
 .../unix/sysv/linux/microblaze/sysdep-cancel.h     | 139 ++++++++++++++++++
 .../sysdeps/unix/sysv/linux/microblaze/vfork.S     |   5 +
 35 files changed, 673 insertions(+), 250 deletions(-)
 copy libc/sysdeps/linux/{xtensa => microblaze}/__syscall_error.c (100%)
 create mode 100644 libc/sysdeps/linux/microblaze/clone.S
 delete mode 100644 libc/sysdeps/linux/microblaze/clone.c
 delete mode 100644 libc/sysdeps/linux/microblaze/jmpbuf-offsets.h
 copy libpthread/nptl/sysdeps/{arc => microblaze}/Makefile.arch (69%)
 copy libpthread/nptl/sysdeps/{sh => microblaze}/dl-tls.h (69%)
 copy libpthread/nptl/sysdeps/{arm => microblaze}/libc-tls.c (70%)
 copy libpthread/nptl/sysdeps/{arm => microblaze}/pthread_spin_lock.c (88%)
 copy libpthread/nptl/sysdeps/{arm => microblaze}/pthread_spin_trylock.c (100%)
 copy libpthread/nptl/sysdeps/{mips => microblaze}/pthreaddef.h (62%)
 copy libpthread/nptl/sysdeps/{mips => microblaze}/tcb-offsets.sym (52%)
 create mode 100644 libpthread/nptl/sysdeps/microblaze/tls.h
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{metag => microblaze}/Makefile (100%)
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{arc => microblaze}/Makefile.arch (71%)
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{xtensa => microblaze}/bits/pthreadtypes.h (77%)
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{arm => microblaze}/bits/semaphore.h (90%)
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/clone.S
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{arm => microblaze}/createthread.c (100%)
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{xtensa => microblaze}/fork.c (100%)
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{arc => microblaze}/lowlevellock.h (93%)
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{xtensa => microblaze}/pthread_once.c (100%)
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/vfork.S



hooks/post-receive
diff mbox

Patch

diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index b259464..cb2d4d1 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -521,7 +521,6 @@  config UCLIBC_HAS_THREADS_NATIVE
 		   !TARGET_hppa && \
 		   !TARGET_ia64 && \
 		   !TARGET_m68k && \
-		   !TARGET_microblaze && \
 		   !TARGET_nds32 && \
 		   !TARGET_nios2 && \
 		   !TARGET_or1k && \
diff --git a/include/elf.h b/include/elf.h
index 17a6143..cca3d38 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -3234,30 +3234,37 @@  typedef Elf32_Addr Elf32_Conflict;
 
 #define DT_C6000_NUM    4
 
-/* microblaze specific relocs */
-#define R_MICROBLAZE_NONE 0
-#define R_MICROBLAZE_32 1
-#define R_MICROBLAZE_32_PCREL 2
-#define R_MICROBLAZE_64_PCREL 3
-#define R_MICROBLAZE_32_PCREL_LO 4
-#define R_MICROBLAZE_64 5
-#define R_MICROBLAZE_32_LO 6
-#define R_MICROBLAZE_SRO32 7
-#define R_MICROBLAZE_SRW32 8
-#define R_MICROBLAZE_64_NONE 9
-#define R_MICROBLAZE_32_SYM_OP_SYM 10
-#define R_MICROBLAZE_GNU_VTINHERIT 11
-#define R_MICROBLAZE_GNU_VTENTRY 12
-#define R_MICROBLAZE_GOTPC_64 13  /* PC-relative GOT offset */
-#define R_MICROBLAZE_GOT_64 14  /* GOT entry offset */
-#define R_MICROBLAZE_PLT_64 15  /* PLT offset (PC-relative  */
-#define R_MICROBLAZE_REL 16  /* adjust by program base */
-#define R_MICROBLAZE_JUMP_SLOT 17  /* create PLT entry */
-#define R_MICROBLAZE_GLOB_DAT 18  /* create GOT entry */
-#define R_MICROBLAZE_GOTOFF_64 19  /* offset relative to GOT */
-#define R_MICROBLAZE_GOTOFF_32 20  /* offset relative to GOT */
-#define R_MICROBLAZE_COPY 21  /* runtime copy */
-#define R_MICROBLAZE_NUM 22
+/* MicroBlaze relocations */
+#define R_MICROBLAZE_NONE		0	/* No reloc. */
+#define R_MICROBLAZE_32 		1	/* Direct 32 bit. */
+#define R_MICROBLAZE_32_PCREL		2	/* PC relative 32 bit. */
+#define R_MICROBLAZE_64_PCREL		3	/* PC relative 64 bit. */
+#define R_MICROBLAZE_32_PCREL_LO	4	/* Low 16 bits of PCREL32. */
+#define R_MICROBLAZE_64 		5	/* Direct 64 bit. */
+#define R_MICROBLAZE_32_LO		6	/* Low 16 bit. */
+#define R_MICROBLAZE_SRO32		7	/* Read-only small data area. */
+#define R_MICROBLAZE_SRW32		8	/* Read-write small data area. */
+#define R_MICROBLAZE_64_NONE		9	/* No reloc. */
+#define R_MICROBLAZE_32_SYM_OP_SYM	10	/* Symbol Op Symbol relocation. */
+#define R_MICROBLAZE_GNU_VTINHERIT	11	/* GNU C++ vtable hierarchy. */
+#define R_MICROBLAZE_GNU_VTENTRY	12	/* GNU C++ vtable member usage. */
+#define R_MICROBLAZE_GOTPC_64		13	/* PC-relative GOT offset.  */
+#define R_MICROBLAZE_GOT_64		14	/* GOT entry offset.  */
+#define R_MICROBLAZE_PLT_64		15	/* PLT offset (PC-relative).  */
+#define R_MICROBLAZE_REL		16	/* Adjust by program base.  */
+#define R_MICROBLAZE_JUMP_SLOT		17	/* Create PLT entry.  */
+#define R_MICROBLAZE_GLOB_DAT		18	/* Create GOT entry.  */
+#define R_MICROBLAZE_GOTOFF_64		19	/* 64 bit offset to GOT. */
+#define R_MICROBLAZE_GOTOFF_32		20	/* 32 bit offset to GOT. */
+#define R_MICROBLAZE_COPY		21	/* Runtime copy.  */
+#define R_MICROBLAZE_TLS		22	/* TLS Reloc. */
+#define R_MICROBLAZE_TLSGD		23	/* TLS General Dynamic. */
+#define R_MICROBLAZE_TLSLD		24	/* TLS Local Dynamic. */
+#define R_MICROBLAZE_TLSDTPMOD32	25	/* TLS Module ID. */
+#define R_MICROBLAZE_TLSDTPREL32	26	/* TLS Offset Within TLS Block. */
+#define R_MICROBLAZE_TLSDTPREL64	27	/* TLS Offset Within TLS Block. */
+#define R_MICROBLAZE_TLSGOTTPREL32	28	/* TLS Offset From Thread Pointer. */
+#define R_MICROBLAZE_TLSTPREL32 	29	/* TLS Offset From Thread Pointer. */
 
 /* Meta relocations */
 #define R_METAG_HIADDR16                 0
diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c
index 18a39ce..87f564f 100644
--- a/ldso/ldso/dl-startup.c
+++ b/ldso/ldso/dl-startup.c
@@ -319,8 +319,6 @@  DL_START(unsigned long args)
 						SEND_STDERR_DEBUG(strtab + sym->st_name);
 						SEND_STDERR_DEBUG("\n");
 #endif
-					} else {
-						SEND_STDERR_DEBUG("relocating unknown symbol\n");
 					}
 					/* Use this machine-specific macro to perform the actual relocation.  */
 					PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym);
diff --git a/ldso/ldso/microblaze/dl-debug.h b/ldso/ldso/microblaze/dl-debug.h
index 6fd7bd5..30b27bb 100644
--- a/ldso/ldso/microblaze/dl-debug.h
+++ b/ldso/ldso/microblaze/dl-debug.h
@@ -51,4 +51,12 @@  static const char * const _dl_reltypes_tab[] =
 		"R_MICROBLAZE_GOTOFF_64",
 		"R_MICROBLAZE_GOTOFF_32",
 		"R_MICROBLAZE_COPY",
+		"R_MICROBLAZE_TLS",
+		"R_MICROBLAZE_TLSGD",
+		"R_MICROBLAZE_TLSLD",
+		"R_MICROBLAZE_TLSDTPMOD32",
+		"R_MICROBLAZE_TLSDTPREL32",
+		"R_MICROBLAZE_TLSDTPREL64",
+		"R_MICROBLAZE_TLSGOTTPREL32",
+		"R_MICROBLAZE_TLSTPREL32",
 	};
diff --git a/ldso/ldso/microblaze/dl-startup.h b/ldso/ldso/microblaze/dl-startup.h
index ba15a87..720c53a 100644
--- a/ldso/ldso/microblaze/dl-startup.h
+++ b/ldso/ldso/microblaze/dl-startup.h
@@ -78,9 +78,6 @@  _dl_start_user:\n\
  */
 #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1)
 
-/* The ld.so library requires relocations */
-#define ARCH_NEEDS_BOOTSTRAP_RELOCS
-
 static __always_inline
 void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
 	unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab)
diff --git a/ldso/ldso/microblaze/dl-sysdep.h b/ldso/ldso/microblaze/dl-sysdep.h
index b293d27..4320027 100644
--- a/ldso/ldso/microblaze/dl-sysdep.h
+++ b/ldso/ldso/microblaze/dl-sysdep.h
@@ -1,5 +1,3 @@ 
-/* elf reloc code for the microblaze platform, based on glibc 2.3.6, dl-machine.h */
-
 /*
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -15,37 +13,41 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-/* Use reloca */
 #define ELF_USES_RELOCA
 
 #include <elf.h>
 
-
 /* Initialise the GOT */
-#define INIT_GOT(GOT_BASE,MODULE)							\
-do {														\
-	GOT_BASE[2] = (unsigned long) _dl_linux_resolve;		\
-	GOT_BASE[1] = (unsigned long) MODULE;					\
+#define INIT_GOT(GOT_BASE,MODULE)				\
+do {								\
+	GOT_BASE[1] = (unsigned long) MODULE;			\
+	GOT_BASE[2] = (unsigned long) _dl_linux_resolve;	\
 } while(0)
 
 /* Here we define the magic numbers that this dynamic loader should accept */
-
 #define MAGIC1 EM_MICROBLAZE
 #undef  MAGIC2
 /* Used for error messages */
 #define ELF_TARGET "microblaze"
 
+/* Need bootstrap relocations */
+#define ARCH_NEEDS_BOOTSTRAP_RELOCS
+
 struct elf_resolve;
 unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
 
 #define elf_machine_type_class(type) \
-  (((type) == R_MICROBLAZE_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT \
+  (((type) == R_MICROBLAZE_JUMP_SLOT || \
+    (type) == R_MICROBLAZE_TLSDTPREL32 || \
+    (type) == R_MICROBLAZE_TLSDTPMOD32 || \
+    (type) == R_MICROBLAZE_TLSTPREL32) \
+    * ELF_RTYPE_CLASS_PLT \
    | ((type) == R_MICROBLAZE_COPY) * ELF_RTYPE_CLASS_COPY)
 
 /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
    first element of the GOT.  This must be inlined in a function which
    uses global data.  */
-static inline Elf32_Addr
+static __always_inline Elf32_Addr __attribute__ ((unused))
 elf_machine_dynamic (void)
 {
   Elf32_Addr got_entry_0;
@@ -56,7 +58,6 @@  elf_machine_dynamic (void)
   return got_entry_0;
 }
 
-
 /* Return the run-time load address of the shared object.  */
 static inline Elf32_Addr
 elf_machine_load_address (void)
@@ -64,6 +65,7 @@  elf_machine_load_address (void)
   /* Compute the difference between the runtime address of _DYNAMIC as seen
      by a GOTOFF reference, and the link-time address found in the special
      unrelocated first GOT entry.  */
+
   Elf32_Addr dyn;
   __asm__ __volatile__ (
     "addik %0,r20,_DYNAMIC@GOTOFF"
@@ -72,8 +74,6 @@  elf_machine_load_address (void)
   return dyn - elf_machine_dynamic ();
 }
 
-
-
 static __always_inline void
 elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
 		      Elf32_Word relative_count)
diff --git a/ldso/ldso/microblaze/elfinterp.c b/ldso/ldso/microblaze/elfinterp.c
index 1f6aeff..33aef2f 100644
--- a/ldso/ldso/microblaze/elfinterp.c
+++ b/ldso/ldso/microblaze/elfinterp.c
@@ -214,16 +214,13 @@  _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
 		case R_MICROBLAZE_NONE:
 		case R_MICROBLAZE_64_NONE:
 			break;
-
 		case R_MICROBLAZE_64:
 			*reloc_addr = symbol_addr + rpnt->r_addend;
 			break;
-
 		case R_MICROBLAZE_32:
 		case R_MICROBLAZE_32_LO:
 			*reloc_addr = symbol_addr + rpnt->r_addend;
 			break;
-
 		case R_MICROBLAZE_32_PCREL:
 		case R_MICROBLAZE_32_PCREL_LO:
 		case R_MICROBLAZE_64_PCREL:
@@ -231,16 +228,25 @@  _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
 		case R_MICROBLAZE_SRW32:
 			*reloc_addr = symbol_addr + rpnt->r_addend;
 			break;
-
 		case R_MICROBLAZE_GLOB_DAT:
 		case R_MICROBLAZE_JUMP_SLOT:
 			*reloc_addr = symbol_addr + rpnt->r_addend;
 			break;
-/* Handled by elf_machine_relative */
 		case R_MICROBLAZE_REL:
 			*reloc_addr = (unsigned long)tpnt->loadaddr + rpnt->r_addend;
 			break;
-
+#if defined USE_TLS && USE_TLS
+		case R_MICROBLAZE_TLSDTPMOD32:
+			*reloc_addr = tls_tpnt->l_tls_modid;
+			break;
+		case R_MICROBLAZE_TLSDTPREL32:
+			*reloc_addr = symbol_addr;
+			break;
+		case R_MICROBLAZE_TLSTPREL32:
+			CHECK_STATIC_TLS ((struct link_map *) tls_tpnt);
+			*reloc_addr = tls_tpnt->l_tls_offset + symbol_addr + rpnt->r_addend;
+			break;
+#endif
 		case R_MICROBLAZE_COPY:
 			if (symbol_addr) {
 #if defined (__SUPPORT_LD_DEBUG__)
@@ -250,7 +256,6 @@  _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
 						    symname, sym_ref.sym->st_size,
 						    symbol_addr, reloc_addr);
 #endif
-
 				_dl_memcpy((char *)reloc_addr,
 					   (char *)symbol_addr,
 					   sym_ref.sym->st_size);
@@ -260,7 +265,6 @@  _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
 				_dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
 #endif
 			break;
-
 		default:
 			return -1;	/* Calls _dl_exit(1). */
 	}
@@ -279,14 +283,12 @@  _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
 		  ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
 {
 	int reloc_type;
-	int symtab_index;
 	ElfW(Addr) *reloc_addr;
 #if defined (__SUPPORT_LD_DEBUG__)
 	ElfW(Addr) old_val;
 #endif
 
 	(void)scope;
-	symtab_index = ELF_R_SYM(rpnt->r_info);
 	(void)strtab;
 
 	reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);
diff --git a/libc/sysdeps/linux/microblaze/Makefile.arch b/libc/sysdeps/linux/microblaze/Makefile.arch
index 6f1e9fb..b89f7f9 100644
--- a/libc/sysdeps/linux/microblaze/Makefile.arch
+++ b/libc/sysdeps/linux/microblaze/Makefile.arch
@@ -5,5 +5,5 @@ 
 #
 # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
 
-CSRC-y := clone.c
-SSRC-y := setjmp.S __longjmp.S vfork.S
+CSRC-y := __syscall_error.c
+SSRC-y := setjmp.S __longjmp.S vfork.S clone.S
diff --git a/libc/sysdeps/linux/xtensa/__syscall_error.c b/libc/sysdeps/linux/microblaze/__syscall_error.c
similarity index 100%
copy from libc/sysdeps/linux/xtensa/__syscall_error.c
copy to libc/sysdeps/linux/microblaze/__syscall_error.c
diff --git a/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h b/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h
index ea767ab..321d699 100644
--- a/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h
@@ -6,8 +6,7 @@ 
 #define _BITS_UCLIBC_ARCH_FEATURES_H
 
 /* instruction used when calling abort() to kill yourself */
-/*#define __UCLIBC_ABORT_INSTRUCTION__ "asm instruction"*/
-#undef __UCLIBC_ABORT_INSTRUCTION__
+#define __UCLIBC_ABORT_INSTRUCTION__ "brki r0, -1"
 
 /* can your target use syscall6() for mmap ? */
 #define __UCLIBC_MMAP_HAS_6_ARGS__
diff --git a/libc/sysdeps/linux/microblaze/clone.S b/libc/sysdeps/linux/microblaze/clone.S
new file mode 100644
index 0000000..69c2045
--- /dev/null
+++ b/libc/sysdeps/linux/microblaze/clone.S
@@ -0,0 +1,77 @@ 
+/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* clone() is even more special than fork() as it mucks with stacks
+   and invokes a function in the right context after its all over.  */
+
+#include <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+
+#if defined __UCLIBC_HAS_THREADS__ && !defined __UCLIBC_HAS_LINUXTHREADS__
+#include <sysdep-cancel.h>
+#endif
+
+/* int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+              pid_t *ptid, struct user_desc *tls, pid_t *ctid);
+
+   INCOMING: r5 (fn), r6 (child_stack), r7 (flags), r8 (arg), r9 (ptid)
+             r10 (tls), 28 (r1) ctid
+
+   OUTGOING:
+
+   linux: arch/microblaze/entry.S: sys_clone expects
+          r5 (flags)  r6 (child stack) r7 (stack_size) r8 (ptid)r9 (ctid)
+          r10 (tls)
+*/
+
+        .text
+ENTRY (__clone)
+	addik	r3,r0,-EINVAL
+	beqi	r5,SYSCALL_ERROR_LABEL	; // Invalid func
+	beqi	r6,SYSCALL_ERROR_LABEL	; // Invalid stack
+	addik	r6,r6,-8
+	swi	r5,r6,0			; // Push fn onto child's stack
+	swi	r8,r6,4			; // Push arg for child
+	addk	r5,r0,r7		; // flags for clone() syscall
+	addk	r7,r0,r0
+	addk	r8,r0,r9		; // parent tid ptr
+	lwi	r9,r1,28		; // child tid ptr
+	addik	r12,r0,SYS_ify(clone)
+	brki	r14,8
+	addk	r0,r0,r0
+	addik	r4,r0,-4095
+	cmpu	r4,r4,r3
+	bgei	r4,SYSCALL_ERROR_LABEL
+	beqi	r3,L(thread_start)
+	rtsd	r15,8
+	nop
+
+L(thread_start):
+	lwi	r12,r1,0		; // fn
+	lwi	r5,r1,4			; // arg
+	brald	r15,r12
+	nop
+	addk	r5,r0,r3
+	addik	r12,r0,SYS_ify(exit)
+	brki	r14,8
+	nop
+PSEUDO_END(__clone)
+
+libc_hidden_def (__clone)
+weak_alias (__clone,clone)
diff --git a/libc/sysdeps/linux/microblaze/clone.c b/libc/sysdeps/linux/microblaze/clone.c
deleted file mode 100644
index d921008..0000000
--- a/libc/sysdeps/linux/microblaze/clone.c
+++ /dev/null
@@ -1,47 +0,0 @@ 
-/*
- * Copyright (C) 2004 Atmel Corporation
- *
- * This file is subject to the terms and conditions of the GNU Lesser General
- * Public License.  See the file "COPYING.LIB" in the main directory of this
- * archive for more details.
- */
-#include <sched.h>
-#include <errno.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-
-int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...)
-{
-	int rval = -EINVAL;
-	if (fn && child_stack)
-		rval = INTERNAL_SYSCALL(clone, 0, 2, flags, child_stack);
-
-	if (rval == 0)
-	{
-		int exitCode = fn(arg);
-		rval = INTERNAL_SYSCALL(exit, 0, 1, exitCode);
-	}
-
-	return rval;
-}
-
-#ifdef __NR_clone2
-int
-__clone2(int (*fn)(void *arg), void *child_stack, size_t stack_size,
-	 int flags, void *arg, ...)
-{
-	int rval = -EINVAL;
-	if (fn && child_stack)
-	{
-		rval = INTERNAL_SYSCALL(clone2, 0, 3, flags, child_stack, stack_size);
-	}
-
-	if (rval == 0)
-	{
-		int exitCode = fn(arg);
-		rval = INTERNAL_SYSCALL(exit, 0, 1, exitCode);
-	}
-
-	return rval;
-}
-#endif
diff --git a/libc/sysdeps/linux/microblaze/jmpbuf-offsets.h b/libc/sysdeps/linux/microblaze/jmpbuf-offsets.h
deleted file mode 100644
index c6cccc7..0000000
--- a/libc/sysdeps/linux/microblaze/jmpbuf-offsets.h
+++ /dev/null
@@ -1,6 +0,0 @@ 
-/*
- * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-#define JB_SIZE		(4 * 18)
diff --git a/libc/sysdeps/linux/microblaze/jmpbuf-unwind.h b/libc/sysdeps/linux/microblaze/jmpbuf-unwind.h
index 2c1c079..155792b 100644
--- a/libc/sysdeps/linux/microblaze/jmpbuf-unwind.h
+++ b/libc/sysdeps/linux/microblaze/jmpbuf-unwind.h
@@ -10,3 +10,28 @@ 
    containing a local variable at ADDRESS.  */
 #define _JMPBUF_UNWINDS(jmpbuf, address) \
   ((void *) (address) < (void *) (jmpbuf)[0].__sp)
+
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <stdint.h>
+#include <unwind.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+   containing a local variable at ADDRESS.  */
+#undef _JMPBUF_UNWINDS
+#define _JMPBUF_UNWINDS(jmpbuf, address)		\
+  ((void *) (address) < (void *) (jmpbuf)[0].__sp)
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+  void *sp = (void *) regs[0].__sp;
+  return (uintptr_t) sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+#endif
diff --git a/libc/sysdeps/linux/microblaze/sysdep.h b/libc/sysdeps/linux/microblaze/sysdep.h
index 1f01a2a..a463d33 100644
--- a/libc/sysdeps/linux/microblaze/sysdep.h
+++ b/libc/sysdeps/linux/microblaze/sysdep.h
@@ -1,9 +1,25 @@ 
+/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
 #include <common/sysdep.h>
 
 #ifdef  __ASSEMBLER__
 
-/* Syntactic details of assembler.  */
-
 # define ALIGNARG(log2) log2
 # define ASM_SIZE_DIRECTIVE(name) .size name,.-name
 
@@ -22,4 +38,67 @@ 
 #  define L(name) $L##name
 # endif
 
+/* We don't want the label for the error handler to be visible in the symbol
+   table when we define it here.  */
+# ifdef __PIC__
+#  define SYSCALL_ERROR_LABEL 0f
+# else
+#  define SYSCALL_ERROR_LABEL __syscall_error
+# endif
+
+# define DO_CALL(syscall_name, args)                \
+    addik r12,r0,SYS_ify (syscall_name);            \
+    brki  r14,8;                                    \
+    addk  r0,r0,r0;
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)           \
+  .text;                                            \
+  ENTRY (name)                                      \
+    DO_CALL (syscall_name, args);                   \
+    addik r12,r0,-4095;                             \
+    cmpu  r12,r12,r3;                               \
+    bgei  r12,SYSCALL_ERROR_LABEL;
+
+# undef PSEUDO_END
+# define PSEUDO_END(name)                           \
+  SYSCALL_ERROR_HANDLER;                            \
+  END (name)
+
+#ifdef __PIC__
+# define SYSCALL_ERROR_LABEL_DCL 0
+# if defined _LIBC_REENTRANT
+#  define SYSCALL_ERROR_HANDLER                     \
+SYSCALL_ERROR_LABEL_DCL:                            \
+    addik r1,r1,-16;                                \
+    swi   r15,r1,0;                                 \
+    swi   r20,r1,8;                                 \
+    rsubk r3,r3,r0;                                 \
+    swi   r3,r1,12;                                 \
+    mfs   r20,rpc;                                  \
+    addik r20,r20,_GLOBAL_OFFSET_TABLE_+8;          \
+    brlid r15,__errno_location@PLT;                 \
+    nop;                                            \
+    lwi   r4,r1,12;                                 \
+    swi   r4,r3,0;                                  \
+    lwi   r20,r1,8;                                 \
+    lwi   r15,r1,0;                                 \
+    addik r1,r1,16;                                 \
+    rtsd  r15,8;                                    \
+    addik r3,r0,-1;
+# else /* !_LIBC_REENTRANT.  */
+#  define SYSCALL_ERROR_HANDLER                     \
+SYSCALL_ERROR_LABEL_DCL:                            \
+    mfs   r12,rpc;                                  \
+    addik r12,r12,_GLOBAL_OFFSET_TABLE_+8;          \
+    lwi   r12,r12,errno@GOT;                        \
+    rsubk r3,r3,r0;                                 \
+    swi   r3,r12,0;                                 \
+    rtsd  r15,8;                                    \
+    addik r3,r0,-1;
+# endif /* _LIBC_REENTRANT.  */
+#else
+#  define SYSCALL_ERROR_HANDLER  /* Nothing here; code in sysdep.S is used.  */
+#endif /* PIC.  */
+
 #endif
diff --git a/libc/sysdeps/linux/microblaze/vfork.S b/libc/sysdeps/linux/microblaze/vfork.S
index cd60128..11b9e27 100644
--- a/libc/sysdeps/linux/microblaze/vfork.S
+++ b/libc/sysdeps/linux/microblaze/vfork.S
@@ -1,47 +1,44 @@ 
-/*
- * libc/sysdeps/linux/microblaze/vfork.S -- `vfork' syscall for linux/microblaze
- *
- * Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
- * Copyright (C) 2001  NEC Corporation
- * Copyright (C) 2001  Miles Bader <miles@gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License.  See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles@gnu.org>
- * Microblaze port by John Williams
- */
-
-#include <sys/syscall.h>
+/* Copyright (C) 2005-2016 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
 
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
    replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
    and the process ID of the new process to the old process.  */
 
-	.globl __vfork
-	.hidden __vfork
-	.align 4
-__vfork:
-	addi	r12, r0, SYS_vfork
-	brki	r14, 0x08;
-	addi	r4, r3, 125		/* minimum err value */
-	blti	r4, 1f			/* is r3 < -125? */
-	bri	2f			/* normal return */
-1:	sub 	r3, r3, r0		/* r3 = -r3 */
-#ifdef __PIC__
-	mfs	r3,rpc
-	addik	r3,r3,_GLOBAL_OFFSET_TABLE_+8
-	lwi	r3,r3,C_SYMBOL_NAME(errno)@GOT
-	sw	r3, r0, r3
-#else
-	swi	r3, r0, C_SYMBOL_NAME(errno);
-#endif
-					/* state restore etc */
-2:	rtsd	r15, 8			/* error return */
+ENTRY(__vfork)
+
+	DO_CALL (vfork, 0)
+	addik	r12,r0,-4095
+	cmpu	r12,r12,r3
+	bgei	r12,1f
+	rtsd	r15,8
 	nop
-       .size   __vfork, .-__vfork
 
-weak_alias(__vfork,vfork)
+1:      rsubk   r3,r3,r0
+        rtsd    r15,8
+        addik   r3,r0,-1        /* delay slot.  */
+
+END(__vfork)
+
+weak_alias(__vfork, vfork)
 libc_hidden_def(vfork)
diff --git a/libpthread/nptl/sysdeps/arc/Makefile.arch b/libpthread/nptl/sysdeps/microblaze/Makefile.arch
similarity index 69%
copy from libpthread/nptl/sysdeps/arc/Makefile.arch
copy to libpthread/nptl/sysdeps/microblaze/Makefile.arch
index 08ec7e7..b69fb48 100644
--- a/libpthread/nptl/sysdeps/arc/Makefile.arch
+++ b/libpthread/nptl/sysdeps/microblaze/Makefile.arch
@@ -1,8 +1,4 @@ 
 # Makefile for uClibc NPTL
-#
-# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
-#
 # Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
-#
 
 libc_arch_a_CSRC = libc-tls.c
diff --git a/libpthread/nptl/sysdeps/sh/dl-tls.h b/libpthread/nptl/sysdeps/microblaze/dl-tls.h
similarity index 69%
copy from libpthread/nptl/sysdeps/sh/dl-tls.h
copy to libpthread/nptl/sysdeps/microblaze/dl-tls.h
index f5f90be..5613e21 100644
--- a/libpthread/nptl/sysdeps/sh/dl-tls.h
+++ b/libpthread/nptl/sysdeps/microblaze/dl-tls.h
@@ -1,11 +1,11 @@ 
-/* Thread-local storage handling in the ELF dynamic linker.  SH version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2016 Free Software Foundation, Inc.
+
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
 
    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,7 +16,6 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-
 /* Type used for the representation of TLS information in the GOT.  */
 typedef struct
 {
@@ -24,5 +23,4 @@  typedef struct
   unsigned long int ti_offset;
 } tls_index;
 
-
 extern void *__tls_get_addr (tls_index *ti);
diff --git a/libpthread/nptl/sysdeps/arm/libc-tls.c b/libpthread/nptl/sysdeps/microblaze/libc-tls.c
similarity index 70%
copy from libpthread/nptl/sysdeps/arm/libc-tls.c
copy to libpthread/nptl/sysdeps/microblaze/libc-tls.c
index 6576072..7f440fb 100644
--- a/libpthread/nptl/sysdeps/arm/libc-tls.c
+++ b/libpthread/nptl/sysdeps/microblaze/libc-tls.c
@@ -1,11 +1,11 @@ 
-/* Thread-local storage handling in the ELF dynamic linker.  ARM version.
-   Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2016 Free Software Foundation, Inc.
+
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
 
    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,13 +19,13 @@ 
 #include <sysdeps/generic/libc-tls.c>
 #include <dl-tls.h>
 
-#if defined(USE_TLS) && USE_TLS
-
-/* On ARM, linker optimizations are not required, so __tls_get_addr
+/* On Microblaze, linker optimizations are not required, so __tls_get_addr
    can be called even in statically linked binaries.  In this case module
    must be always 1 and PT_TLS segment exist in the binary, otherwise it
    would not link.  */
 
+#if defined(USE_TLS) && USE_TLS
+
 void *
 __tls_get_addr (tls_index *ti)
 {
diff --git a/libpthread/nptl/sysdeps/arm/pthread_spin_lock.c b/libpthread/nptl/sysdeps/microblaze/pthread_spin_lock.c
similarity index 88%
copy from libpthread/nptl/sysdeps/arm/pthread_spin_lock.c
copy to libpthread/nptl/sysdeps/microblaze/pthread_spin_lock.c
index 77f5f50..e393a73 100644
--- a/libpthread/nptl/sysdeps/arm/pthread_spin_lock.c
+++ b/libpthread/nptl/sysdeps/microblaze/pthread_spin_lock.c
@@ -19,10 +19,6 @@ 
 #include <atomic.h>
 #include "pthreadP.h"
 
-/* A machine-specific version can define SPIN_LOCK_READS_BETWEEN_CMPXCHG
-  to the number of plain reads that it's optimal to spin on between uses
-  of atomic_compare_and_exchange_val_acq.  If spinning forever is optimal
-  then use -1.  If no plain reads here would ever be optimal, use 0.  */
 #define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
 
 int
diff --git a/libpthread/nptl/sysdeps/arm/pthread_spin_trylock.c b/libpthread/nptl/sysdeps/microblaze/pthread_spin_trylock.c
similarity index 100%
copy from libpthread/nptl/sysdeps/arm/pthread_spin_trylock.c
copy to libpthread/nptl/sysdeps/microblaze/pthread_spin_trylock.c
diff --git a/libpthread/nptl/sysdeps/mips/pthreaddef.h b/libpthread/nptl/sysdeps/microblaze/pthreaddef.h
similarity index 62%
copy from libpthread/nptl/sysdeps/mips/pthreaddef.h
copy to libpthread/nptl/sysdeps/microblaze/pthreaddef.h
index 6929882..47e87dd 100644
--- a/libpthread/nptl/sysdeps/mips/pthreaddef.h
+++ b/libpthread/nptl/sysdeps/microblaze/pthreaddef.h
@@ -1,10 +1,11 @@ 
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
 
    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,24 +16,25 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <stdlib.h>
+#include <string.h>
+
 /* Default stack size.  */
-#define ARCH_STACK_DEFAULT_SIZE	(2 * 1024 * 1024)
+#define ARCH_STACK_DEFAULT_SIZE  (2 * 1024 * 1024)
 
 /* Required stack pointer alignment at beginning.  */
-#define STACK_ALIGN		16
+#define STACK_ALIGN         16
 
 /* Minimal stack size after allocating thread descriptor and guard size.  */
-#define MINIMAL_REST_STACK	2048
+#define MINIMAL_REST_STACK  2048
 
 /* Alignment requirement for TCB.  */
-#define TCB_ALIGNMENT		16
-
+#define TCB_ALIGNMENT       16
 
 /* Location of current stack frame.  */
-#define CURRENT_STACK_FRAME	__builtin_frame_address (0)
-
+#define CURRENT_STACK_FRAME __builtin_frame_address (0)
 
 /* XXX Until we have a better place keep the definitions here.  */
 
 #define __exit_thread_inline(val) \
-  INLINE_SYSCALL (exit, 1, (val))
+INLINE_SYSCALL (exit, 1, (val))
diff --git a/libpthread/nptl/sysdeps/mips/tcb-offsets.sym b/libpthread/nptl/sysdeps/microblaze/tcb-offsets.sym
similarity index 52%
copy from libpthread/nptl/sysdeps/mips/tcb-offsets.sym
copy to libpthread/nptl/sysdeps/microblaze/tcb-offsets.sym
index e0e71dc..18afbee 100644
--- a/libpthread/nptl/sysdeps/mips/tcb-offsets.sym
+++ b/libpthread/nptl/sysdeps/microblaze/tcb-offsets.sym
@@ -4,8 +4,8 @@ 
 --
 
 -- Abuse tls.h macros to derive offsets relative to the thread register.
-#define thread_offsetof(mem)	(long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
+#define thread_offsetof(mem)	(long)(offsetof (struct pthread, mem) - sizeof (struct pthread))
 
-MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
+MULTIPLE_THREADS_OFFSET	thread_offsetof (header.multiple_threads)
 PID_OFFSET			thread_offsetof (pid)
 TID_OFFSET			thread_offsetof (tid)
diff --git a/libpthread/nptl/sysdeps/microblaze/tls.h b/libpthread/nptl/sysdeps/microblaze/tls.h
new file mode 100644
index 0000000..b5bcde9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/microblaze/tls.h
@@ -0,0 +1,159 @@ 
+/* Copyright (C) 2005-2016 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TLS_H
+# define _TLS_H 1
+
+#ifndef __ASSEMBLER__
+
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+/* We require TLS support in the tools.  */
+#define HAVE_TLS_SUPPORT		1
+#define HAVE___THREAD   		1
+#define HAVE_TLS_MODEL_ATTRIBUTE       	1
+
+/* Signal that TLS support is available.  */
+#define USE_TLS 1
+
+#ifndef __ASSEMBLER__
+
+/* Get system call information.  */
+# include <sysdep.h>
+
+/* The TP points to the start of the thread blocks.  */
+# define TLS_DTV_AT_TP  1
+
+/* Get the thread descriptor definition.  */
+# include <../../descr.h>
+
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+#define READ_THREAD_POINTER() \
+  ({ register void *__microblaze_thread_area __asm__ ("r21"); \
+     __microblaze_thread_area; })
+
+/* This is the size of the initial TCB.  */
+# define TLS_INIT_TCB_SIZE	sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN	16
+
+/* This is the size of the TCB.  */
+# define TLS_TCB_SIZE       	sizeof (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+# define TLS_PRE_TCB_SIZE   	sizeof (struct pthread)
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN      	16
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+# define INSTALL_DTV(tcbp, dtvp) \
+  (((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1)
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtv) \
+  (THREAD_DTV() = (dtv))
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(tcbp) \
+  (((tcbhead_t *) (tcbp))->dtv)
+
+/* Code to initially initialize the thread pointer.
+   r21 is reserved for thread pointer.  */
+# define TLS_INIT_TP(tcbp, secondcall) \
+  ({ __asm__ __volatile__ ("or r21,r0,%0" : : "r" ((void *)tcbp)); NULL; })
+
+# define TLS_DEFINE_INIT_TP(tp, pd) void *tp = (pd) + 1
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  (((tcbhead_t *) READ_THREAD_POINTER())->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+  (((struct pthread *) READ_THREAD_POINTER()) - 1)
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF \
+  CONST_THREAD_AREA (32, sizeof (struct pthread))
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) (descr->member)
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+# define THREAD_GETMEM_NC(descr, member, idx) \
+  (descr->member[idx])
+
+/* Set member of the thread descriptor directly.  */
+# define THREAD_SETMEM(descr, member, value) \
+  (descr->member = (value))
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+  (descr->member[idx] = (value))
+
+/* Get and set the global scope generation counter in struct pthread.  */
+# define THREAD_GSCOPE_FLAG_UNUSED 0
+# define THREAD_GSCOPE_FLAG_USED   1
+# define THREAD_GSCOPE_FLAG_WAIT   2
+# define THREAD_GSCOPE_RESET_FLAG()                                         \
+  do                                                                        \
+    { int __res                                                             \
+      = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,              \
+                             THREAD_GSCOPE_FLAG_UNUSED);                    \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)                                 \
+        lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);  \
+    }                                                                       \
+  while (0)
+# define THREAD_GSCOPE_SET_FLAG()                                           \
+  do                                                                        \
+    {                                                                       \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;            \
+      atomic_write_barrier ();                                              \
+    }                                                                       \
+  while (0)
+# define THREAD_GSCOPE_WAIT() \
+  GL (dl_wait_lookup_done) ()
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h.  */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/metag/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile
similarity index 100%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/metag/Makefile
copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arc/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile.arch
similarity index 71%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/arc/Makefile.arch
copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile.arch
index fa5d530..77707a0 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/arc/Makefile.arch
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile.arch
@@ -1,14 +1,8 @@ 
 # Makefile for uClibc NPTL
-#
-# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
-#
 # Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
-#
 
 libpthread_linux_arch_SSRC =
 libpthread_linux_arch_CSRC = pthread_once.c
 
 libc_linux_arch_CSRC = fork.c
 libc_linux_arch_SSRC = clone.S vfork.S
-libc_linux_arch_SSRC-OMIT = waitpid.S
-
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/pthreadtypes.h
similarity index 77%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h
copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/pthreadtypes.h
index 5e44020..9e9e307 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/pthreadtypes.h
@@ -1,4 +1,5 @@ 
-/* Copyright (C) 2002-2012 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -12,48 +13,46 @@ 
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
+   License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
 #ifndef _BITS_PTHREADTYPES_H
-#define _BITS_PTHREADTYPES_H	1
+# define _BITS_PTHREADTYPES_H	1
 
-#include <endian.h>
+# include <endian.h>
 
-#define __SIZEOF_PTHREAD_ATTR_T 36
-#define __SIZEOF_PTHREAD_MUTEX_T 24
-#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
-#define __SIZEOF_PTHREAD_COND_T 48
-#define __SIZEOF_PTHREAD_COND_COMPAT_T 12
-#define __SIZEOF_PTHREAD_CONDATTR_T 4
-#define __SIZEOF_PTHREAD_RWLOCK_T 32
-#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
-#define __SIZEOF_PTHREAD_BARRIER_T 20
-#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+# define __SIZEOF_PTHREAD_ATTR_T         36
+# define __SIZEOF_PTHREAD_MUTEX_T        24
+# define __SIZEOF_PTHREAD_MUTEXATTR_T     4
+# define __SIZEOF_PTHREAD_COND_T         48
+# define __SIZEOF_PTHREAD_COND_COMPAT_T  12
+# define __SIZEOF_PTHREAD_CONDATTR_T      4
+# define __SIZEOF_PTHREAD_RWLOCK_T       32
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T    8
+# define __SIZEOF_PTHREAD_BARRIER_T      20
+# define __SIZEOF_PTHREAD_BARRIERATTR_T   4
 
 
 /* Thread identifiers.  The structure of the attribute type is not
    exposed on purpose.  */
 typedef unsigned long int pthread_t;
 
-
 union pthread_attr_t
 {
   char __size[__SIZEOF_PTHREAD_ATTR_T];
   long int __align;
 };
-#ifndef __have_pthread_attr_t
-typedef union pthread_attr_t pthread_attr_t;
-# define __have_pthread_attr_t	1
-#endif
 
+# ifndef __have_pthread_attr_t
+typedef union pthread_attr_t pthread_attr_t;
+#  define __have_pthread_attr_t	1
+# endif
 
 typedef struct __pthread_internal_slist
 {
   struct __pthread_internal_slist *__next;
 } __pthread_slist_t;
 
-
 /* Data structures for mutex handling.  The structure of the attribute
    type is not exposed on purpose.  */
 typedef union
@@ -77,13 +76,15 @@  typedef union
   long int __align;
 } pthread_mutex_t;
 
+/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER.  */
+#define __PTHREAD_SPINS 0
+
 typedef union
 {
   char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
-  long int __align;
+  int __align;
 } pthread_mutexattr_t;
 
-
 /* Data structure for conditional variable handling.  The structure of
    the attribute type is not exposed on purpose.  */
 typedef union
@@ -106,19 +107,16 @@  typedef union
 typedef union
 {
   char __size[__SIZEOF_PTHREAD_CONDATTR_T];
-  long int __align;
+  int __align;
 } pthread_condattr_t;
 
-
-/* Keys for thread-specific data */
+/* Keys for thread-specific data.  */
 typedef unsigned int pthread_key_t;
 
-
-/* Once-only execution */
+/* Once-only execution.  */
 typedef int pthread_once_t;
 
-
-#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+# if defined __USE_UNIX98 || defined __USE_XOPEN2K
 /* Data structure for read-write lock variable handling.  The
    structure of the attribute type is not exposed on purpose.  */
 typedef union
@@ -131,40 +129,40 @@  typedef union
     unsigned int __writer_wakeup;
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
-#if __BYTE_ORDER == __BIG_ENDIAN
+#  if __BYTE_ORDER == __BIG_ENDIAN
     unsigned char __pad1;
     unsigned char __pad2;
     unsigned char __shared;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
     unsigned char __flags;
-#else
+#  else
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
     unsigned char __flags;
     unsigned char __shared;
     unsigned char __pad1;
     unsigned char __pad2;
-#endif
+#  endif
     int __writer;
   } __data;
   char __size[__SIZEOF_PTHREAD_RWLOCK_T];
   long int __align;
 } pthread_rwlock_t;
 
+#define __PTHREAD_RWLOCK_ELISION_EXTRA 0
+
 typedef union
 {
   char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
   long int __align;
 } pthread_rwlockattr_t;
-#endif
-
+# endif
 
-#ifdef __USE_XOPEN2K
+# ifdef __USE_XOPEN2K
 /* POSIX spinlock data type.  */
 typedef volatile int pthread_spinlock_t;
 
-
 /* POSIX barriers data type.  The structure of the type is
    deliberately not exposed.  */
 typedef union
@@ -178,7 +176,6 @@  typedef union
   char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
   int __align;
 } pthread_barrierattr_t;
-#endif
-
+# endif
 
-#endif	/* bits/pthreadtypes.h */
+#endif	/* bits/pthreadtypes.h.  */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/semaphore.h
similarity index 90%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h
copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/semaphore.h
index e68fbcc..ea05026 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/semaphore.h
@@ -1,4 +1,5 @@ 
-/* Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -19,13 +20,10 @@ 
 # error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
 #endif
 
-
 #define __SIZEOF_SEM_T	16
 
-
 /* Value returned if `sem_open' failed.  */
-#define SEM_FAILED      ((sem_t *) 0)
-
+#define SEM_FAILED	((sem_t *) 0)
 
 typedef union
 {
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/clone.S
new file mode 100644
index 0000000..faa78d9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/clone.S
@@ -0,0 +1,4 @@ 
+#define RESET_PID
+#include <tls.h>
+#include <tcb-offsets.h>
+#include "../../../../../../../libc/sysdeps/linux/microblaze/clone.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/createthread.c
similarity index 100%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/arm/createthread.c
copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/createthread.c
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/fork.c
similarity index 100%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/fork.c
copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/fork.c
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arc/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/lowlevellock.h
similarity index 93%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/arc/lowlevellock.h
copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/lowlevellock.h
index 44a1ac0..e8dce9d 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/arc/lowlevellock.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/lowlevellock.h
@@ -79,21 +79,21 @@ 
 #define lll_futex_timed_wait(futexp, val, timespec, private) \
   ({									      \
     INTERNAL_SYSCALL_DECL (__err);					      \
-    long int __ret;							      \
-    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
+    long int __sysret;							      \
+    __sysret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
 			      __lll_private_flag (FUTEX_WAIT, private),	      \
 			      (val), (timespec));			      \
-    __ret;								      \
+    __sysret;								      \
   })
 
 #define lll_futex_wake(futexp, nr, private) \
   ({									      \
     INTERNAL_SYSCALL_DECL (__err);					      \
-    long int __ret;							      \
-    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
+    long int __sysret;							      \
+    __sysret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
 			      __lll_private_flag (FUTEX_WAKE, private),	      \
 			      (nr), 0);					      \
-    __ret;								      \
+    __sysret;								      \
   })
 
 #define lll_robust_dead(futexv, private) \
@@ -109,11 +109,11 @@ 
 #define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
   ({									      \
     INTERNAL_SYSCALL_DECL (__err);					      \
-    long int __ret;							      \
-    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
+    long int __sysret;							      \
+    __sysret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
 			      __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
 			      (nr_wake), (nr_move), (mutex), (val));	      \
-    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+    INTERNAL_SYSCALL_ERROR_P (__sysret, __err);				      \
   })
 
 
@@ -121,12 +121,12 @@ 
 #define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
   ({									      \
     INTERNAL_SYSCALL_DECL (__err);					      \
-    long int __ret;							      \
-    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
+    long int __sysret;							      \
+    __sysret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
 			      __lll_private_flag (FUTEX_WAKE_OP, private),    \
 			      (nr_wake), (nr_wake2), (futexp2),		      \
 			      FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);		      \
-    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+    INTERNAL_SYSCALL_ERROR_P (__sysret, __err);				      \
   })
 
 
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/pthread_once.c
similarity index 100%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/pthread_once.c
copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/pthread_once.c
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h
new file mode 100644
index 0000000..2af79ca
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h
@@ -0,0 +1,139 @@ 
+/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+#ifdef __ASSEMBLER__
+
+#undef ret
+#define ret
+
+# if !IS_IN_librt || !defined(PIC)
+#  define AC_STACK_SIZE  16  /* space for r15, async_cancel arg and 2 temp words */
+#  define AC_SET_GOT /* empty */
+#  define AC_RESTORE_GOT /* empty */
+# else
+#  define AC_STACK_SIZE  20  /* extra 4 bytes for r20 */
+#  define AC_SET_GOT                                                 \
+    swi   r20, r1, AC_STACK_SIZE-4;                                  \
+    mfs   r20, rpc;                                                  \
+    addik r20, r20, _GLOBAL_OFFSET_TABLE_+8;
+#  define AC_RESTORE_GOT                                             \
+    lwi   r20, r1, AC_STACK_SIZE-4;
+# endif
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)                            \
+  .text;                                                             \
+  ENTRY (name)                                                       \
+    SINGLE_THREAD_P(r12);                                            \
+    bnei r12, L(pseudo_cancel);                                      \
+  .globl __##syscall_name##_nocancel;                                \
+  .type __##syscall_name##_nocancel,@function;                       \
+__##syscall_name##_nocancel:                                         \
+    DO_CALL (syscall_name, args);                                    \
+    addik r4, r0, -4095;                                             \
+    cmpu  r4, r4, r3;                                                \
+    rsubk   r3,r3,r0;						     \
+    rtsd    r15,8;						     \
+    addik   r3,r0,-1;						     \
+    rtsd  r15, 8;                                                    \
+    nop;                                                             \
+  .size __##syscall_name##_nocancel, .-__##syscall_name##_nocancel;  \
+L(pseudo_cancel):                                                    \
+    addik r1, r1, -AC_STACK_SIZE;                                    \
+    swi   r15, r1, 0;                                                \
+    AC_SET_GOT                                                       \
+    DOCARGS_##args                                                   \
+    CENABLE;                                                         \
+    swi   r3, r1, 8;                                                 \
+    UNDOCARGS_##args                                                 \
+    DO_CALL (syscall_name, args);                                    \
+    swi   r3, r1, 12;                                                \
+    lwi   r5, r1, 8;                                                 \
+    CDISABLE;                                                        \
+    lwi   r3, r1, 12;                                                \
+    lwi   r15, r1, 0;                                                \
+    AC_RESTORE_GOT                                                   \
+    addik r1, r1, AC_STACK_SIZE;                                     \
+    addik r4, r0, -4095;                                             \
+    cmpu  r4, r4, r3;                                                \
+    rsubk   r3,r3,r0;						     \
+    rtsd    r15,8;						     \
+    addik   r3,r0,-1;						     \
+    rtsd  r15, 8;                                                    \
+    nop;
+
+/*
+ * Macros to save/restore syscall arguments across CENABLE
+ * The arguments are saved into the caller's stack (original r1 + 4)
+ */
+
+# define DOCARGS_0
+# define DOCARGS_1  swi   r5, r1, AC_STACK_SIZE + 4;
+# define DOCARGS_2  swi   r6, r1, AC_STACK_SIZE + 8; DOCARGS_1
+# define DOCARGS_3  swi   r7, r1, AC_STACK_SIZE + 12; DOCARGS_2
+# define DOCARGS_4  swi   r8, r1, AC_STACK_SIZE + 16; DOCARGS_3
+# define DOCARGS_5  swi   r9, r1, AC_STACK_SIZE + 20; DOCARGS_4
+# define DOCARGS_6  swi   r10, r1, AC_STACK_SIZE + 24; DOCARGS_5
+
+# define UNDOCARGS_0
+# define UNDOCARGS_1  lwi   r5, r1, AC_STACK_SIZE + 4;
+# define UNDOCARGS_2  UNDOCARGS_1 lwi   r6, r1, AC_STACK_SIZE + 8;
+# define UNDOCARGS_3  UNDOCARGS_2 lwi   r7, r1, AC_STACK_SIZE + 12;
+# define UNDOCARGS_4  UNDOCARGS_3 lwi   r8, r1, AC_STACK_SIZE + 16;
+# define UNDOCARGS_5  UNDOCARGS_4 lwi   r9, r1, AC_STACK_SIZE + 20;
+# define UNDOCARGS_6  UNDOCARGS_5 lwi   r10, r1, AC_STACK_SIZE + 24;
+
+# ifdef PIC
+#  define PSEUDO_JMP(sym)  brlid r15, sym##@PLTPC; addk r0, r0, r0
+# else
+#  define PSEUDO_JMP(sym)  brlid r15, sym; addk r0, r0, r0
+# endif
+
+# if defined IS_IN_libpthread
+#  define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel)
+#  define CDISABLE  PSEUDO_JMP (__pthread_disable_asynccancel)
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define CENABLE PSEUDO_JMP (__libc_enable_asynccancel)
+#  define CDISABLE  PSEUDO_JMP (__libc_disable_asynccancel)
+#  define __local_multiple_threads __libc_multiple_threads
+# elif defined IS_IN_librt
+#  define CENABLE PSEUDO_JMP (__librt_enable_asynccancel)
+#  define CDISABLE  PSEUDO_JMP (__librt_disable_asynccancel)
+# else
+#  error Unsupported library
+# endif
+
+#define SINGLE_THREAD_P(reg)                                         \
+     lwi reg, r0, MULTIPLE_THREADS_OFFSET(reg)
+
+#else /* !__ASSEMBLER__ */
+# define SINGLE_THREAD_P                                             \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,                      \
+                                   header.multiple_threads) == 0, 1)
+
+#endif /* __ASSEMBLER__ */
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/vfork.S
new file mode 100644
index 0000000..4336717
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/vfork.S
@@ -0,0 +1,5 @@ 
+#define SAVE_PID
+#define RESTORE_PID
+#include <tls.h>
+#include <tcb-offsets.h>
+#include <libc/sysdeps/linux/microblaze/vfork.S>