diff mbox

[uclibc-ng-devel] uClibc-ng - small C library for embedded systems branch master updated. v1.0.21-38-gc0a0905

Message ID 20170201202425.5E1F010083@helium.openadk.org
State Not Applicable
Headers show

Commit Message

wbx Feb. 1, 2017, 8:24 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  c0a09054b238982e7d40d7dd6fe571bbd9664fe3 (commit)
       via  dc79afc0facb5de24d63fbaba6a345222a86d0d5 (commit)
       via  dba942c80dc2cfa5768a856fff98e22a755fdd27 (commit)
       via  9b457baf8d46329f7d7ee2aa084022bb0df88551 (commit)
       via  2d3403be6c680fddcc66238baa0a25c0554e2227 (commit)
       via  c98ef313e6b7c8e8d224157e3473e0a4ce019139 (commit)
       via  65e3f409df6a9d5f4e6fb3655150eca90b101fc0 (commit)
      from  bddde5860ffb8a78587854cc8e3e914bd69269ca (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 c0a09054b238982e7d40d7dd6fe571bbd9664fe3
Author: Waldemar Brodkorb <wbx@uclibc-ng.org>
Date:   Mon Jan 30 05:07:36 2017 +0100

    aarch64: fix syscall_error_handler, fixes tst-mqueue errors
    
    Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>

commit dc79afc0facb5de24d63fbaba6a345222a86d0d5
Author: mirabilos <m@mirbsd.org>
Date:   Sun Jan 29 14:22:02 2017 +0100

    g/c __libc_errno
    
    Signed-off-by: mirabilos <m@mirbsd.org>
    Signed-off-by: Waldemar Brodkorb <wbx@uclibc-ng.org>

commit dba942c80dc2cfa5768a856fff98e22a755fdd27
Author: Waldemar Brodkorb <wbx@uclibc-ng.org>
Date:   Tue Oct 4 06:51:35 2016 +0200

    add experimental aarch64 support
    
    Ported over from GNU C Library and runtime tested in Qemu.

commit 9b457baf8d46329f7d7ee2aa084022bb0df88551
Author: mirabilos <m@mirbsd.org>
Date:   Sun Jan 29 15:30:50 2017 +0100

    use safe, even if possibly a few cycles slower, six-argument syscall implementation
    
    Signed-off-by: mirabilos <m@mirbsd.org>
    Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>

commit 2d3403be6c680fddcc66238baa0a25c0554e2227
Author: mirabilos <m@mirbsd.org>
Date:   Sun Jan 29 15:05:13 2017 +0100

    extract six-argument syscalls from the rest
    
    (still same implementation though)
    
    Signed-off-by: mirabilos <m@mirbsd.org>
    Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>

commit c98ef313e6b7c8e8d224157e3473e0a4ce019139
Author: Waldemar Brodkorb <wbx@openadk.org>
Date:   Sun Jan 29 15:00:07 2017 +0100

    remove dead code
    
    Signed-off-by: mirabilos <m@mirbsd.org>
    Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>

commit 65e3f409df6a9d5f4e6fb3655150eca90b101fc0
Author: Sergey Organov <sorganov@gmail.com>
Date:   Thu Jan 26 14:33:18 2017 +0300

    Fix make rule for generation of "ucontext_i.h" when building in separate directory (with O=)
    
    For me it was enabling of UCLIBC_SUSV3_LEGACY=y that broke compilation
    in separate directory.

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

Summary of changes:
 Rules.mak                                          |   6 +
 extra/Configs/Config.aarch64                       |  32 ++
 extra/Configs/Config.in                            |  11 +-
 extra/Configs/Config.in.arch                       |   2 +-
 include/atomic.h                                   |  10 +-
 include/elf.h                                      | 166 +++++++++++
 include/errno.h                                    |   4 -
 ldso/include/dl-syscall.h                          |  10 +
 ldso/ldso/aarch64/dl-startup.h                     |  98 ++++++
 ldso/ldso/{xtensa => aarch64}/dl-syscalls.h        |   0
 ldso/ldso/aarch64/dl-sysdep.h                      | 107 +++++++
 ldso/ldso/aarch64/dl-tlsdesc.S                     | 207 +++++++++++++
 ldso/ldso/aarch64/elfinterp.c                      | 306 +++++++++++++++++++
 ldso/ldso/aarch64/resolve.S                        |  97 ++++++
 ldso/ldso/i386/syscall6.S                          |   1 +
 libc/misc/internals/errno.c                        |   3 +-
 libc/string/{xtensa => aarch64}/Makefile           |   0
 libc/string/aarch64/memcpy.S                       | 230 ++++++++++++++
 libc/string/aarch64/memset.S                       | 189 ++++++++++++
 libc/sysdeps/linux/Makefile.commonarch             |   2 +-
 libc/sysdeps/linux/{nds32 => aarch64}/Makefile     |   0
 libc/sysdeps/linux/aarch64/Makefile.arch           |   5 +
 libc/sysdeps/linux/aarch64/__longjmp.S             | 107 +++++++
 .../linux/{xtensa => aarch64}/__syscall_error.c    |   0
 libc/sysdeps/linux/aarch64/bits/atomic.h           | 172 +++++++++++
 libc/sysdeps/linux/aarch64/bits/endian.h           |  30 ++
 libc/sysdeps/linux/aarch64/bits/fcntl.h            | 329 +++++++++++++++++++++
 libc/sysdeps/linux/aarch64/bits/kernel_types.h     |  42 +++
 libc/sysdeps/linux/aarch64/bits/setjmp.h           |  33 +++
 libc/sysdeps/linux/aarch64/bits/stackinfo.h        |  33 +++
 libc/sysdeps/linux/aarch64/bits/syscalls.h         | 106 +++++++
 .../linux/aarch64/bits/uClibc_arch_features.h      |  38 +++
 libc/sysdeps/linux/aarch64/bits/uClibc_page.h      |  25 ++
 libc/sysdeps/linux/aarch64/bits/wordsize.h         |  18 ++
 .../linux/{xtensa => aarch64}/bsd-_setjmp.S        |   0
 .../sysdeps/linux/{xtensa => aarch64}/bsd-setjmp.S |   0
 libc/sysdeps/linux/aarch64/clone.S                 |  85 ++++++
 libc/sysdeps/linux/aarch64/crt1.S                  |  89 ++++++
 libc/sysdeps/linux/aarch64/crti.S                  |  59 ++++
 libc/sysdeps/linux/aarch64/crtn.S                  |  46 +++
 libc/sysdeps/linux/aarch64/jmpbuf-offsets.h        |  57 ++++
 libc/sysdeps/linux/aarch64/jmpbuf-unwind.h         |  34 +++
 libc/sysdeps/linux/aarch64/setjmp.S                |  59 ++++
 libc/sysdeps/linux/aarch64/sys/procfs.h            | 123 ++++++++
 libc/sysdeps/linux/aarch64/sys/ucontext.h          |  53 ++++
 libc/sysdeps/linux/aarch64/sys/user.h              |  37 +++
 libc/sysdeps/linux/aarch64/syscall.S               |  42 +++
 libc/sysdeps/linux/aarch64/sysdep.h                | 140 +++++++++
 libc/sysdeps/linux/aarch64/vfork.S                 |  37 +++
 libc/sysdeps/linux/common-generic/bits/stat.h      |  49 ---
 libc/sysdeps/linux/common/fstat.c                  |  28 +-
 libc/sysdeps/linux/common/fstatat.c                |   9 -
 libc/sysdeps/linux/common/lstat.c                  |   9 +
 libc/sysdeps/linux/common/lstat64.c                |  14 +-
 libc/sysdeps/linux/common/stat.c                   |   8 +
 libc/sysdeps/linux/i386/Makefile.arch              |   4 +-
 libc/sysdeps/linux/i386/bits/syscalls.h            |  72 +----
 libc/sysdeps/linux/i386/syscall6.S                 |  67 +++++
 libc/sysdeps/linux/i386/sysdep.h                   |   4 -
 libc/sysdeps/linux/sh/sysdep.h                     |   4 -
 libc/sysdeps/linux/x86_64/sysdep.h                 |   4 -
 libc/sysdeps/linux/xtensa/sysdep.h                 |   4 -
 libpthread/nptl/sysdeps/aarch64/Makefile.arch      |  32 ++
 libpthread/nptl/sysdeps/aarch64/dl-tls.h           |  55 ++++
 libpthread/nptl/sysdeps/aarch64/libc-dl-tlsdesc.S  |   1 +
 libpthread/nptl/sysdeps/aarch64/libc-tls.c         |  35 +++
 .../sysdeps/{nds32 => aarch64}/pthread_spin_lock.c |   0
 .../{nds32 => aarch64}/pthread_spin_trylock.c      |   0
 libpthread/nptl/sysdeps/aarch64/pthreaddef.h       |  34 +++
 libpthread/nptl/sysdeps/aarch64/tcb-offsets.sym    |   6 +
 libpthread/nptl/sysdeps/aarch64/tls.h              | 149 ++++++++++
 libpthread/nptl/sysdeps/aarch64/tlsdesc.sym        |  17 ++
 .../sysv/linux/{microblaze => aarch64}/Makefile    |   0
 .../sysdeps/unix/sysv/linux/aarch64/Makefile.arch  |  14 +
 .../unix/sysv/linux/aarch64/bits/pthreadtypes.h    | 174 +++++++++++
 .../unix/sysv/linux/aarch64/bits/semaphore.h       |  30 ++
 .../sysdeps/unix/sysv/linux/aarch64/createthread.c |  21 ++
 .../nptl/sysdeps/unix/sysv/linux/aarch64/fork.c    |  11 +
 .../sysdeps/unix/sysv/linux/aarch64/lowlevellock.h | 323 ++++++++++++++++++++
 .../unix/sysv/linux/{nds32 => aarch64}/pt-raise.c  |   0
 .../sysdeps/unix/sysv/linux/aarch64/pthread_once.c |  90 ++++++
 .../unix/sysv/linux/aarch64/sysdep-cancel.h        | 132 +++++++++
 utils/ldd.c                                        |   5 +
 83 files changed, 4518 insertions(+), 167 deletions(-)
 create mode 100644 extra/Configs/Config.aarch64
 create mode 100644 ldso/ldso/aarch64/dl-startup.h
 copy ldso/ldso/{xtensa => aarch64}/dl-syscalls.h (100%)
 create mode 100644 ldso/ldso/aarch64/dl-sysdep.h
 create mode 100644 ldso/ldso/aarch64/dl-tlsdesc.S
 create mode 100644 ldso/ldso/aarch64/elfinterp.c
 create mode 100644 ldso/ldso/aarch64/resolve.S
 create mode 100644 ldso/ldso/i386/syscall6.S
 copy libc/string/{xtensa => aarch64}/Makefile (100%)
 create mode 100644 libc/string/aarch64/memcpy.S
 create mode 100644 libc/string/aarch64/memset.S
 copy libc/sysdeps/linux/{nds32 => aarch64}/Makefile (100%)
 create mode 100644 libc/sysdeps/linux/aarch64/Makefile.arch
 create mode 100644 libc/sysdeps/linux/aarch64/__longjmp.S
 copy libc/sysdeps/linux/{xtensa => aarch64}/__syscall_error.c (100%)
 create mode 100644 libc/sysdeps/linux/aarch64/bits/atomic.h
 create mode 100644 libc/sysdeps/linux/aarch64/bits/endian.h
 create mode 100644 libc/sysdeps/linux/aarch64/bits/fcntl.h
 create mode 100644 libc/sysdeps/linux/aarch64/bits/kernel_types.h
 create mode 100644 libc/sysdeps/linux/aarch64/bits/setjmp.h
 create mode 100644 libc/sysdeps/linux/aarch64/bits/stackinfo.h
 create mode 100644 libc/sysdeps/linux/aarch64/bits/syscalls.h
 create mode 100644 libc/sysdeps/linux/aarch64/bits/uClibc_arch_features.h
 create mode 100755 libc/sysdeps/linux/aarch64/bits/uClibc_page.h
 create mode 100644 libc/sysdeps/linux/aarch64/bits/wordsize.h
 copy libc/sysdeps/linux/{xtensa => aarch64}/bsd-_setjmp.S (100%)
 copy libc/sysdeps/linux/{xtensa => aarch64}/bsd-setjmp.S (100%)
 create mode 100644 libc/sysdeps/linux/aarch64/clone.S
 create mode 100644 libc/sysdeps/linux/aarch64/crt1.S
 create mode 100644 libc/sysdeps/linux/aarch64/crti.S
 create mode 100644 libc/sysdeps/linux/aarch64/crtn.S
 create mode 100644 libc/sysdeps/linux/aarch64/jmpbuf-offsets.h
 create mode 100644 libc/sysdeps/linux/aarch64/jmpbuf-unwind.h
 create mode 100644 libc/sysdeps/linux/aarch64/setjmp.S
 create mode 100644 libc/sysdeps/linux/aarch64/sys/procfs.h
 create mode 100644 libc/sysdeps/linux/aarch64/sys/ucontext.h
 create mode 100644 libc/sysdeps/linux/aarch64/sys/user.h
 create mode 100644 libc/sysdeps/linux/aarch64/syscall.S
 create mode 100644 libc/sysdeps/linux/aarch64/sysdep.h
 create mode 100644 libc/sysdeps/linux/aarch64/vfork.S
 create mode 100644 libc/sysdeps/linux/i386/syscall6.S
 create mode 100644 libpthread/nptl/sysdeps/aarch64/Makefile.arch
 create mode 100644 libpthread/nptl/sysdeps/aarch64/dl-tls.h
 create mode 100644 libpthread/nptl/sysdeps/aarch64/libc-dl-tlsdesc.S
 create mode 100644 libpthread/nptl/sysdeps/aarch64/libc-tls.c
 copy libpthread/nptl/sysdeps/{nds32 => aarch64}/pthread_spin_lock.c (100%)
 copy libpthread/nptl/sysdeps/{nds32 => aarch64}/pthread_spin_trylock.c (100%)
 create mode 100644 libpthread/nptl/sysdeps/aarch64/pthreaddef.h
 create mode 100644 libpthread/nptl/sysdeps/aarch64/tcb-offsets.sym
 create mode 100644 libpthread/nptl/sysdeps/aarch64/tls.h
 create mode 100644 libpthread/nptl/sysdeps/aarch64/tlsdesc.sym
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{microblaze => aarch64}/Makefile (100%)
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/Makefile.arch
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/bits/pthreadtypes.h
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/bits/semaphore.h
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/createthread.c
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/fork.c
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/lowlevellock.h
 copy libpthread/nptl/sysdeps/unix/sysv/linux/{nds32 => aarch64}/pt-raise.c (100%)
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/pthread_once.c
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h



hooks/post-receive
diff mbox

Patch

diff --git a/Rules.mak b/Rules.mak
index 8bd2863..f53c581 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -300,6 +300,7 @@  ifneq ($(TARGET_ARCH),sh)
 ifneq ($(TARGET_ARCH),c6x)
 ifneq ($(TARGET_ARCH),h8300)
 ifneq ($(TARGET_ARCH),arc)
+ifneq ($(TARGET_ARCH),aarch64)
 CPU_CFLAGS-y += -msoft-float
 endif
 endif
@@ -310,6 +311,11 @@  endif
 endif
 endif
 endif
+endif
+
+ifeq ($(TARGET_ARCH),aarch64)
+CPU_CFLAGS-y += -ftls-model=initial-exec
+endif
 
 $(eval $(call check-gcc-var,-std=gnu99))
 CPU_CFLAGS-y += $(CFLAG_-std=gnu99)
diff --git a/extra/Configs/Config.aarch64 b/extra/Configs/Config.aarch64
new file mode 100644
index 0000000..cf1ce3b
--- /dev/null
+++ b/extra/Configs/Config.aarch64
@@ -0,0 +1,32 @@ 
+#
+# For a description of the syntax of this configuration file,
+# see extra/config/Kconfig-language.txt
+#
+
+config TARGET_ARCH
+	string
+	default "aarch64"
+
+config FORCE_OPTIONS_FOR_ARCH
+	bool
+	default y
+	select ARCH_ANY_ENDIAN
+	select ARCH_HAS_MMU
+	select UCLIBC_HAS_FPU
+
+choice
+	prompt "MMU Page Size"
+	default CONFIG_AARCH64_PAGE_SIZE_4K
+
+config CONFIG_AARCH64_PAGE_SIZE_4K
+	bool "4KB"
+	help
+	  Choose between 4k(default), 16k or 64k
+
+config CONFIG_AARCH64_PAGE_SIZE_16K
+	bool "16KB"
+
+config CONFIG_AARCH64_PAGE_SIZE_64K
+	bool "64KB"
+
+endchoice
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index b2cf977..850bd7d 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -15,6 +15,7 @@  config VERSION
 
 choice
 	prompt "Target Architecture"
+	default TARGET_aarch64 if DESIRED_TARGET_ARCH = "aarch64"
 	default TARGET_alpha if DESIRED_TARGET_ARCH = "alpha"
 	default TARGET_arc if DESIRED_TARGET_ARCH = "arc"
 	default TARGET_arm if DESIRED_TARGET_ARCH = "arm"
@@ -42,6 +43,9 @@  choice
 	help
 	  The architecture of your target.
 
+config TARGET_aarch64
+	bool "aarch64"
+
 config TARGET_alpha
 	bool "alpha"
 
@@ -124,6 +128,10 @@  endchoice
 
 menu "Target Architecture Features and Options"
 
+if TARGET_aarch64
+source "extra/Configs/Config.aarch64"
+endif
+
 if TARGET_alpha
 source "extra/Configs/Config.alpha"
 endif
@@ -500,7 +508,8 @@  config UCLIBC_HAS_LINUXTHREADS
 	bool "Linuxthreads"
 	# linuxthreads need nanosleep()
 	select UCLIBC_HAS_REALTIME
-	depends on !TARGET_metag
+	depends on !TARGET_aarch64 && \
+		   !TARGET_metag
 	help
 	  If you want to compile uClibc with Linuxthreads support, then answer Y.
 
diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch
index 37dd8bd..a1a2a5f 100644
--- a/extra/Configs/Config.in.arch
+++ b/extra/Configs/Config.in.arch
@@ -191,7 +191,7 @@  config UCLIBC_HAS_FENV
 config UCLIBC_HAS_LONG_DOUBLE_MATH
 	bool "Enable long double support"
 	depends on DO_C99_MATH
-	depends on TARGET_aarch64 || TARGET_alpha || TARGET_i386 || TARGET_ia64 || TARGET_m68k || TARGET_powerpc || TARGET_s390 || TARGET_sparc || TARGET_tile || TARGET_x86_64
+	depends on TARGET_alpha || TARGET_i386 || TARGET_ia64 || TARGET_m68k || TARGET_powerpc || TARGET_s390 || TARGET_sparc || TARGET_tile || TARGET_x86_64
 	default y
 	help
 	  If you want the uClibc math library to contain the full set of C99
diff --git a/include/atomic.h b/include/atomic.h
index 3680d87..267aff5 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -542,24 +542,18 @@ 
   ({ __typeof (x) __x; __asm__ ("" : "=r" (__x) : "0" (x)); __x; })
 #endif
 
-/* This is equal to 1 iff the architecture supports 64b atomic operations.  */
-#define __HAVE_64B_ATOMICS 0 /* TODO: not yet used - Add these to arch bits! */
-#ifndef __HAVE_64B_ATOMICS
-#error Unable to determine if 64-bit atomics are present.
-#endif
-
 /* The following functions are a subset of the atomic operations provided by
    C11.  Usually, a function named atomic_OP_MO(args) is equivalent to C11's
    atomic_OP_explicit(args, memory_order_MO); exceptions noted below.  */
 
 /* Each arch can request to use compiler built-ins for C11 atomics.  If it
    does, all atomics will be based on these.  */
-#if 0 /* not yet used USE_ATOMIC_COMPILER_BUILTINS */
+#if defined USE_ATOMIC_COMPILER_BUILTINS
 
 /* We require 32b atomic operations; some archs also support 64b atomic
    operations.  */
 void __atomic_link_error (void);
-# if __HAVE_64B_ATOMICS == 1
+# if defined(__HAVE_64B_ATOMICS) && __HAVE_64B_ATOMICS
 #  define __atomic_check_size(mem) \
    if ((sizeof (*mem) != 4) && (sizeof (*mem) != 8))			      \
      __atomic_link_error ();
diff --git a/include/elf.h b/include/elf.h
index 0f188e7..5312be9 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -269,6 +269,7 @@  typedef struct
 #define EM_TI_C6000	140
 #define EM_NDS32	167		/* Andes Tech NDS32 */
 #define EM_METAG	174		/* Imagination Technologies Meta */
+#define EM_AARCH64	183		/* ARM AARCH64 */
 #define EM_MICROBLAZE	189		/* Xilinx Microblaze */
 #define EM_ARCV2	195		/* ARCv2 Cores */
 
@@ -725,6 +726,31 @@  typedef struct
 #define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
 #define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
 #define NT_PRFPXREG	20		/* Contains copy of fprxregset struct*/
+#define NT_SIGINFO	0x53494749	/* Contains copy of siginfo_t,
+					   size might increase */
+#define NT_FILE		0x46494c45	/* Contains information about mapped
+					   files */
+#define NT_PRXFPREG	0x46e62b7f	/* Contains copy of user_fxsr_struct */
+#define NT_PPC_VMX	0x100		/* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE	0x101		/* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX	0x102		/* PowerPC VSX registers */
+#define NT_386_TLS	0x200		/* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM	0x201		/* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
+#define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */
+#define NT_S390_TIMER	0x301		/* s390 timer register */
+#define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */
+#define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */
+#define NT_S390_CTRS	0x304		/* s390 control registers */
+#define NT_S390_PREFIX	0x305		/* s390 prefix register */
+#define NT_S390_LAST_BREAK	0x306	/* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL	0x307	/* s390 system call restart data */
+#define NT_S390_TDB	0x308		/* s390 transaction diagnostic block */
+#define NT_ARM_VFP	0x400		/* ARM VFP/NEON registers */
+#define NT_ARM_TLS	0x401		/* ARM TLS register */
+#define NT_ARM_HW_BREAK	0x402		/* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH	0x403		/* ARM hardware watchpoint registers */
+#define NT_ARM_SYSTEM_CALL	0x404	/* ARM system call number */
 
 /* Legal values for the note segment descriptor types for object files.  */
 
@@ -2358,6 +2384,146 @@  typedef Elf32_Addr Elf32_Conflict;
 /* Processor specific values for the Phdr p_type field.  */
 #define PT_ARM_EXIDX	0x70000001	/* .ARM.exidx segment */
 
+/* AArch64 relocs.  */
+
+#define R_AARCH64_NONE            0	/* No relocation.  */
+
+/* ILP32 AArch64 relocs.  */
+#define R_AARCH64_P32_ABS32		  1	/* Direct 32 bit.  */
+#define R_AARCH64_P32_COPY		180	/* Copy symbol at runtime.  */
+#define R_AARCH64_P32_GLOB_DAT		181	/* Create GOT entry.  */
+#define R_AARCH64_P32_JUMP_SLOT		182	/* Create PLT entry.  */
+#define R_AARCH64_P32_RELATIVE		183	/* Adjust by program base.  */
+#define R_AARCH64_P32_TLS_DTPMOD	184	/* Module number, 32 bit.  */
+#define R_AARCH64_P32_TLS_DTPREL	185	/* Module-relative offset, 32 bit.  */
+#define R_AARCH64_P32_TLS_TPREL		186	/* TP-relative offset, 32 bit.  */
+#define R_AARCH64_P32_TLSDESC		187	/* TLS Descriptor.  */
+#define R_AARCH64_P32_IRELATIVE		188	/* STT_GNU_IFUNC relocation. */
+
+/* LP64 AArch64 relocs.  */
+#define R_AARCH64_ABS64         257	/* Direct 64 bit. */
+#define R_AARCH64_ABS32         258	/* Direct 32 bit.  */
+#define R_AARCH64_ABS16		259	/* Direct 16-bit.  */
+#define R_AARCH64_PREL64	260	/* PC-relative 64-bit.	*/
+#define R_AARCH64_PREL32	261	/* PC-relative 32-bit.	*/
+#define R_AARCH64_PREL16	262	/* PC-relative 16-bit.	*/
+#define R_AARCH64_MOVW_UABS_G0	263	/* Dir. MOVZ imm. from bits 15:0.  */
+#define R_AARCH64_MOVW_UABS_G0_NC 264	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G1	265	/* Dir. MOVZ imm. from bits 31:16.  */
+#define R_AARCH64_MOVW_UABS_G1_NC 266	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G2	267	/* Dir. MOVZ imm. from bits 47:32.  */
+#define R_AARCH64_MOVW_UABS_G2_NC 268	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G3	269	/* Dir. MOV{K,Z} imm. from 63:48.  */
+#define R_AARCH64_MOVW_SABS_G0	270	/* Dir. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_SABS_G1	271	/* Dir. MOV{N,Z} imm. from 31:16.  */
+#define R_AARCH64_MOVW_SABS_G2	272	/* Dir. MOV{N,Z} imm. from 47:32.  */
+#define R_AARCH64_LD_PREL_LO19	273	/* PC-rel. LD imm. from bits 20:2.  */
+#define R_AARCH64_ADR_PREL_LO21	274	/* PC-rel. ADR imm. from bits 20:0.  */
+#define R_AARCH64_ADR_PREL_PG_HI21 275	/* Page-rel. ADRP imm. from 32:12.  */
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check.  */
+#define R_AARCH64_ADD_ABS_LO12_NC 277	/* Dir. ADD imm. from bits 11:0.  */
+#define R_AARCH64_LDST8_ABS_LO12_NC 278	/* Likewise for LD/ST; no check. */
+#define R_AARCH64_TSTBR14	279	/* PC-rel. TBZ/TBNZ imm. from 15:2.  */
+#define R_AARCH64_CONDBR19	280	/* PC-rel. cond. br. imm. from 20:2. */
+#define R_AARCH64_JUMP26	282	/* PC-rel. B imm. from bits 27:2.  */
+#define R_AARCH64_CALL26	283	/* Likewise for CALL.  */
+#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1.  */
+#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2.  */
+#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3.  */
+#define R_AARCH64_MOVW_PREL_G0	287	/* PC-rel. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_PREL_G0_NC 288	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G1	289	/* PC-rel. MOV{N,Z} imm. from 31:16. */
+#define R_AARCH64_MOVW_PREL_G1_NC 290	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G2	291	/* PC-rel. MOV{N,Z} imm. from 47:32. */
+#define R_AARCH64_MOVW_PREL_G2_NC 292	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G3	293	/* PC-rel. MOV{N,Z} imm. from 63:48. */
+#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4.  */
+#define R_AARCH64_MOVW_GOTOFF_G0 300	/* GOT-rel. off. MOV{N,Z} imm. 15:0. */
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G1 302	/* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G2 304	/* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G3 306	/* GOT-rel. o. MOV{N,Z} imm. 63:48.  */
+#define R_AARCH64_GOTREL64	307	/* GOT-relative 64-bit.  */
+#define R_AARCH64_GOTREL32	308	/* GOT-relative 32-bit.  */
+#define R_AARCH64_GOT_LD_PREL19	309	/* PC-rel. GOT off. load imm. 20:2.  */
+#define R_AARCH64_LD64_GOTOFF_LO15 310	/* GOT-rel. off. LD/ST imm. 14:3.  */
+#define R_AARCH64_ADR_GOT_PAGE	311	/* P-page-rel. GOT off. ADRP 32:12.  */
+#define R_AARCH64_LD64_GOT_LO12_NC 312	/* Dir. GOT off. LD/ST imm. 11:3.  */
+#define R_AARCH64_LD64_GOTPAGE_LO15 313	/* GOT-page-rel. GOT off. LD/ST 14:3 */
+#define R_AARCH64_TLSGD_ADR_PREL21 512	/* PC-relative ADR imm. 20:0.  */
+#define R_AARCH64_TLSGD_ADR_PAGE21 513	/* page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514	/* direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSGD_MOVW_G1	515	/* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516	/* GOT-rel. MOVK imm. 15:0.  */
+#define R_AARCH64_TLSLD_ADR_PREL21 517	/* Like 512; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADR_PAGE21 518	/* Like 513; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519	/* Like 514; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G1	520	/* Like 515; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521	/* Like 516; local dynamic model.  */
+#define R_AARCH64_TLSLD_LD_PREL19 522	/* TLS PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0.  */
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12.  */
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3.  */
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1.  */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check.  */
+#define R_AARCH64_TLSDESC_LD_PREL19 560	/* PC-rel. load immediate 20:2.  */
+#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0.  */
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSDESC_LD64_LO12 563	/* Direct LD off. from 11:3.  */
+#define R_AARCH64_TLSDESC_ADD_LO12 564	/* Direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSDESC_OFF_G1 565	/* GOT-rel. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566	/* GOT-rel. MOVK imm. 15:0; no ck.  */
+#define R_AARCH64_TLSDESC_LDR	567	/* Relax LDR.  */
+#define R_AARCH64_TLSDESC_ADD	568	/* Relax ADD.  */
+#define R_AARCH64_TLSDESC_CALL	569	/* Relax BLR.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check.  */
+#define R_AARCH64_COPY         1024	/* Copy symbol at runtime.  */
+#define R_AARCH64_GLOB_DAT     1025	/* Create GOT entry.  */
+#define R_AARCH64_JUMP_SLOT    1026	/* Create PLT entry.  */
+#define R_AARCH64_RELATIVE     1027	/* Adjust by program base.  */
+#define R_AARCH64_TLS_DTPMOD   1028	/* Module number, 64 bit.  */
+#define R_AARCH64_TLS_DTPREL   1029	/* Module-relative offset, 64 bit.  */
+#define R_AARCH64_TLS_TPREL    1030	/* TP-relative offset, 64 bit.  */
+#define R_AARCH64_TLSDESC      1031	/* TLS Descriptor.  */
+#define R_AARCH64_IRELATIVE	1032	/* STT_GNU_IFUNC relocation.  */
+
 /* ARM relocs.  */
 
 #define R_ARM_NONE		0	/* No reloc */
diff --git a/include/errno.h b/include/errno.h
index 4e3a816..380a0b7 100644
--- a/include/errno.h
+++ b/include/errno.h
@@ -70,11 +70,7 @@  extern int _dl_errno; /* attribute_hidden */
 #elif defined __UCLIBC_HAS_TLS__
 # if !defined NOT_IN_libc || defined IS_IN_libpthread
 #  undef errno
-#  ifndef NOT_IN_libc
-#   define errno __libc_errno
-#  else
 #   define errno errno             /* For #ifndef errno tests.  */
-#  endif
 extern __thread int errno attribute_tls_model_ie;
 # endif
 #endif
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 5528ba6..3baddd3 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -96,6 +96,16 @@  static __always_inline int _dl_stat(const char *file_name,
 {
 	return _dl_fstatat64(AT_FDCWD, file_name, buf, 0);
 }
+#elif defined __NR_newfstatat && !defined __NR_stat
+# define __NR__dl_newfstatat __NR_newfstatat
+static __always_inline _syscall4(int, _dl_newfstatat, int, fd, const char *,
+				 fn, struct stat *, stat, int, flags)
+
+static __always_inline int _dl_stat(const char *file_name,
+                        struct stat *buf)
+{
+	return _dl_newfstatat(AT_FDCWD, file_name, buf, 0);
+}
 #elif defined __NR_stat
 # define __NR__dl_stat __NR_stat
 static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
diff --git a/ldso/ldso/aarch64/dl-startup.h b/ldso/ldso/aarch64/dl-startup.h
new file mode 100644
index 0000000..1fac5ec
--- /dev/null
+++ b/ldso/ldso/aarch64/dl-startup.h
@@ -0,0 +1,98 @@ 
+/*
+ * Architecture specific code used by dl-startup.c
+ * Copyright (C) 2016 Waldemar Brodkorb <wbx@uclibc-ng.org>
+ * Ported from GNU libc
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
+
+   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 <features.h>
+
+__asm__("\
+.text									\n\
+.globl _start								\n\
+.type _start, %function							\n\
+.globl _dl_start_user							\n\
+.type _dl_start_user, %function						\n\
+_start:									\n\
+	mov	x0, sp							\n\
+	bl	_dl_start						\n\
+	// returns user entry point in x0				\n\
+	mov	x21, x0							\n\
+_dl_start_user:								\n\
+	// get the original arg count					\n\
+	ldr	x1, [sp]						\n\
+	// get the argv address						\n\
+	add	x2, sp, #(1<<3)						\n\
+	// get _dl_skip_args to see if we were				\n\
+	// invoked as an executable					\n\
+	adrp	x4, _dl_skip_args					\n\
+        ldr	w4, [x4, #:lo12:_dl_skip_args]				\n\
+	// do we need to adjust argc/argv				\n\
+        cmp	w4, 0							\n\
+	beq	.L_done_stack_adjust					\n\
+	// subtract _dl_skip_args from original arg count		\n\
+	sub	x1, x1, x4						\n\
+	// store adjusted argc back to stack				\n\
+	str	x1, [sp]						\n\
+	// find the first unskipped argument				\n\
+	mov	x3, x2							\n\
+	add	x4, x2, x4, lsl #3					\n\
+	// shuffle envp down						\n\
+1:	ldr	x5, [x4], #(1<<3)					\n\
+	str	x5, [x3], #(1<<3)					\n\
+	cmp	x5, #0							\n\
+	bne	1b							\n\
+	// shuffle auxv down						\n\
+1:	ldp	x0, x5, [x4, #(2<<3)]!					\n\
+	stp	x0, x5, [x3], #(2<<3)					\n\
+	cmp	x0, #0							\n\
+	bne	1b							\n\
+.L_done_stack_adjust:							\n\
+	// compute envp							\n\
+	add	x3, x2, x1, lsl #3					\n\
+	add	x3, x3, #(1<<3)						\n\
+	// load the finalizer function					\n\
+	adrp	x0, _dl_fini						\n\
+	add	x0, x0, #:lo12:_dl_fini					\n\
+	// jump to the user_s entry point				\n\
+	br      x21							\n\
+");
+
+/* Get a pointer to the argv array.  On many platforms this can be just
+ * the address of the first argument, on other platforms we need to
+ * do something a little more subtle here.  */
+#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*)ARGS)+1)
+
+/* Handle relocation of the symbols in the dynamic loader. */
+static __always_inline
+void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, ElfW(Addr) *reloc_addr,
+	ElfW(Addr) symbol_addr, ElfW(Addr) load_addr, ElfW(Addr) *sym)
+{
+	switch (ELF_R_TYPE(rpnt->r_info)) {
+		case R_AARCH64_NONE:
+			break;
+		case R_AARCH64_ABS64:
+		case R_AARCH64_GLOB_DAT:
+		case R_AARCH64_JUMP_SLOT:
+			*reloc_addr = symbol_addr + rpnt->r_addend;
+			break;
+		default:
+			_dl_exit(1);
+	}
+}
diff --git a/ldso/ldso/xtensa/dl-syscalls.h b/ldso/ldso/aarch64/dl-syscalls.h
similarity index 100%
copy from ldso/ldso/xtensa/dl-syscalls.h
copy to ldso/ldso/aarch64/dl-syscalls.h
diff --git a/ldso/ldso/aarch64/dl-sysdep.h b/ldso/ldso/aarch64/dl-sysdep.h
new file mode 100644
index 0000000..4e8cdd9
--- /dev/null
+++ b/ldso/ldso/aarch64/dl-sysdep.h
@@ -0,0 +1,107 @@ 
+/*
+ * Various assembly language/system dependent hacks that are required
+ * so that we can minimize the amount of platform specific code.
+ * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 2017 by Waldemar Brodkorb <wbx@uclibc-ng.org>
+ * Ported from GNU C Library
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
+
+   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/>.  */
+
+/* Define this if the system uses RELOCA.  */
+#define ELF_USES_RELOCA
+
+#include <elf.h>
+#include <link.h>
+
+/* Initialization sequence for the GOT.  */
+#define INIT_GOT(GOT_BASE,MODULE) \
+{				\
+  GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
+  GOT_BASE[1] = (unsigned long) MODULE; \
+}
+
+/* Here we define the magic numbers that this dynamic loader should accept */
+#define MAGIC1 EM_AARCH64
+#undef  MAGIC2
+
+/* Used for error messages */
+#define ELF_TARGET "aarch64"
+
+struct elf_resolve;
+unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+
+#define elf_machine_type_class(type)					\
+  ((((type) == R_AARCH64_JUMP_SLOT 					\
+     || (type) == R_AARCH64_TLS_DTPMOD					\
+     || (type) == R_AARCH64_TLS_DTPREL 					\
+     || (type) == R_AARCH64_TLS_TPREL					\
+     || (type) == R_AARCH64_TLSDESC) * ELF_RTYPE_CLASS_PLT)		\
+   | (((type) == R_AARCH64_COPY) * ELF_RTYPE_CLASS_COPY))
+
+/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
+   first element of the GOT. */
+extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden;
+static __always_inline ElfW(Addr) __attribute__ ((unused))
+elf_machine_dynamic (void)
+{
+  return _GLOBAL_OFFSET_TABLE_[0];
+}
+
+/* Return the run-time load address of the shared object.  */
+
+static __always_inline ElfW(Addr) __attribute__ ((unused))
+elf_machine_load_address (void)
+{
+  /* To figure out the load address we use the definition that for any symbol:
+     dynamic_addr(symbol) = static_addr(symbol) + load_addr
+
+     The choice of symbol is arbitrary. The static address we obtain
+     by constructing a non GOT reference to the symbol, the dynamic
+     address of the symbol we compute using adrp/add to compute the
+     symbol's address relative to the PC.
+     This depends on 32/16bit relocations being resolved at link time
+     and that the static address fits in the 32/16 bits.  */
+
+  ElfW(Addr) static_addr;
+  ElfW(Addr) dynamic_addr;
+
+  __asm__("					\n"
+"	adrp	%1, _dl_start;			\n"
+"	add	%1, %1, #:lo12:_dl_start	\n"
+"	ldr	%w0, 1f				\n"
+"	b	2f				\n"
+"1:						\n"
+"	.word	_dl_start			\n"
+"2:						\n"
+    : "=r" (static_addr),  "=r" (dynamic_addr));
+  return dynamic_addr - static_addr;
+}
+
+static __always_inline void
+elf_machine_relative(Elf64_Addr load_off, const Elf64_Addr rel_addr,
+                     Elf64_Word relative_count)
+{
+	Elf64_Rela *rpnt = (Elf64_Rela*)rel_addr;
+	--rpnt;
+	do {
+		Elf64_Addr *const reloc_addr = (Elf64_Addr*)(load_off + (++rpnt)->r_offset);
+
+		*reloc_addr = load_off + rpnt->r_addend;
+	} while (--relative_count);
+}
diff --git a/ldso/ldso/aarch64/dl-tlsdesc.S b/ldso/ldso/aarch64/dl-tlsdesc.S
new file mode 100644
index 0000000..4520da6
--- /dev/null
+++ b/ldso/ldso/aarch64/dl-tlsdesc.S
@@ -0,0 +1,207 @@ 
+/*
+ * Copyright (C) 2017 Waldemar Brodkorb <wbx@uclibc-ng.org>
+ * Ported from GNU C Library
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Thread-local storage handling in the ELF dynamic linker.
+   AArch64 version.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+
+   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>
+
+#if defined __UCLIBC_HAS_TLS__
+
+#include <tls.h>
+#include "tlsdesc.h"
+
+#define PTR_REG(n)              x##n
+#define PTR_LOG_SIZE            3
+#define PTR_SIZE        (1<<PTR_LOG_SIZE)
+
+#define NSAVEDQREGPAIRS	16
+#define SAVE_Q_REGISTERS				\
+	stp	q0, q1,	[sp, #-32*NSAVEDQREGPAIRS]!;	\
+	cfi_adjust_cfa_offset (32*NSAVEDQREGPAIRS);	\
+	stp	 q2,  q3, [sp, #32*1];			\
+	stp	 q4,  q5, [sp, #32*2];			\
+	stp	 q6,  q7, [sp, #32*3];			\
+	stp	 q8,  q9, [sp, #32*4];			\
+	stp	q10, q11, [sp, #32*5];			\
+	stp	q12, q13, [sp, #32*6];			\
+	stp	q14, q15, [sp, #32*7];			\
+	stp	q16, q17, [sp, #32*8];			\
+	stp	q18, q19, [sp, #32*9];			\
+	stp	q20, q21, [sp, #32*10];			\
+	stp	q22, q23, [sp, #32*11];			\
+	stp	q24, q25, [sp, #32*12];			\
+	stp	q26, q27, [sp, #32*13];			\
+	stp	q28, q29, [sp, #32*14];			\
+	stp	q30, q31, [sp, #32*15];
+
+#define RESTORE_Q_REGISTERS				\
+	ldp	 q2,  q3, [sp, #32*1];			\
+	ldp	 q4,  q5, [sp, #32*2];			\
+	ldp	 q6,  q7, [sp, #32*3];			\
+	ldp	 q8,  q9, [sp, #32*4];			\
+	ldp	q10, q11, [sp, #32*5];			\
+	ldp	q12, q13, [sp, #32*6];			\
+	ldp	q14, q15, [sp, #32*7];			\
+	ldp	q16, q17, [sp, #32*8];			\
+	ldp	q18, q19, [sp, #32*9];			\
+	ldp	q20, q21, [sp, #32*10];			\
+	ldp	q22, q23, [sp, #32*11];			\
+	ldp	q24, q25, [sp, #32*12];			\
+	ldp	q26, q27, [sp, #32*13];			\
+	ldp	q28, q29, [sp, #32*14];			\
+	ldp	q30, q31, [sp, #32*15];			\
+	ldp	 q0,  q1, [sp], #32*NSAVEDQREGPAIRS;	\
+	cfi_adjust_cfa_offset (-32*NSAVEDQREGPAIRS);
+
+	.text
+
+	/* Compute the thread pointer offset for symbols in the static
+	   TLS block. The offset is the same for all threads.
+	   Prototype:
+	   _dl_tlsdesc_return (tlsdesc *) ;
+	 */
+	.hidden _dl_tlsdesc_return
+	.global	_dl_tlsdesc_return
+	.type	_dl_tlsdesc_return,%function
+	.align 2
+_dl_tlsdesc_return:
+	ldr x0,[x0,#8]
+	ret
+	.size	_dl_tlsdesc_return, .-_dl_tlsdesc_return
+
+#ifdef SHARED
+	/* Handler for dynamic TLS symbols.
+	   Prototype:
+	   _dl_tlsdesc_dynamic (tlsdesc *) ;
+
+	   The second word of the descriptor points to a
+	   tlsdesc_dynamic_arg structure.
+
+	   Returns the offset between the thread pointer and the
+	   object referenced by the argument.
+
+	   ptrdiff_t
+	   __attribute__ ((__regparm__ (1)))
+	   _dl_tlsdesc_dynamic (struct tlsdesc *tdp)
+	   {
+	     struct tlsdesc_dynamic_arg *td = tdp->arg;
+	     dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + TCBHEAD_DTV);
+	     if (__builtin_expect (td->gen_count <= dtv[0].counter
+		&& (dtv[td->tlsinfo.ti_module].pointer.val
+		    != TLS_DTV_UNALLOCATED),
+		1))
+	       return dtv[td->tlsinfo.ti_module].pointer.val
+		+ td->tlsinfo.ti_offset
+		- __thread_pointer;
+
+	     return ___tls_get_addr (&td->tlsinfo) - __thread_pointer;
+	   }
+	 */
+
+	.hidden _dl_tlsdesc_dynamic
+	.global	_dl_tlsdesc_dynamic
+	.type	_dl_tlsdesc_dynamic,%function
+	cfi_startproc
+	.align 2
+_dl_tlsdesc_dynamic:
+# define NSAVEXREGPAIRS 2
+	stp	x29, x30, [sp,#-(32+16*NSAVEXREGPAIRS)]!
+	cfi_adjust_cfa_offset (32+16*NSAVEXREGPAIRS)
+	mov	x29, sp
+
+	/* Save just enough registers to support fast path, if we fall
+	   into slow path we will save additional registers.  */
+
+	stp	x1,  x2, [sp, #32+16*0]
+	stp	x3,  x4, [sp, #32+16*1]
+
+	mrs	x4, tpidr_el0
+	/* The ldar here happens after the load from [x0] at the call site
+	   (that is generated by the compiler as part of the TLS access ABI),
+	   so it reads the same value (this function is the final value of
+	   td->entry) and thus it synchronizes with the release store to
+	   td->entry in _dl_tlsdesc_resolve_rela_fixup ensuring that the load
+	   from [x0,#PTR_SIZE] here happens after the initialization of td->arg.  */
+	ldar	PTR_REG (zr), [x0]
+	ldr	PTR_REG (1), [x0,#TLSDESC_ARG]
+	ldr	PTR_REG (0), [x4,#TCBHEAD_DTV]
+	ldr	PTR_REG (3), [x1,#TLSDESC_GEN_COUNT]
+	ldr	PTR_REG (2), [x0,#DTV_COUNTER]
+	cmp	PTR_REG (3), PTR_REG (2)
+	b.hi	2f
+	ldr	PTR_REG (2), [x1,#TLSDESC_MODID]
+	add	PTR_REG (0), PTR_REG (0), PTR_REG (2), lsl #(PTR_LOG_SIZE + 1)
+	ldr	PTR_REG (0), [x0] /* Load val member of DTV entry.  */
+	cmp	x0, #TLS_DTV_UNALLOCATED
+	b.eq	2f
+	ldr	PTR_REG (1), [x1,#TLSDESC_MODOFF]
+	add	PTR_REG (0), PTR_REG (0), PTR_REG (1)
+	sub	PTR_REG (0), PTR_REG (0), PTR_REG (4)
+1:
+	ldp	 x1,  x2, [sp, #32+16*0]
+	ldp	 x3,  x4, [sp, #32+16*1]
+
+	ldp	x29, x30, [sp], #(32+16*NSAVEXREGPAIRS)
+	cfi_adjust_cfa_offset (-32-16*NSAVEXREGPAIRS)
+# undef NSAVEXREGPAIRS
+	ret
+2:
+	/* This is the slow path. We need to call __tls_get_addr() which
+	   means we need to save and restore all the register that the
+	   callee will trash.  */
+
+	/* Save the remaining registers that we must treat as caller save.  */
+# define NSAVEXREGPAIRS 7
+	stp	 x5,  x6, [sp, #-16*NSAVEXREGPAIRS]!
+	cfi_adjust_cfa_offset (16*NSAVEXREGPAIRS)
+	stp	 x7,  x8, [sp, #16*1]
+	stp	 x9, x10, [sp, #16*2]
+	stp	x11, x12, [sp, #16*3]
+	stp	x13, x14, [sp, #16*4]
+	stp	x15, x16, [sp, #16*5]
+	stp	x17, x18, [sp, #16*6]
+
+	SAVE_Q_REGISTERS
+
+	mov	x0, x1
+	bl	__tls_get_addr
+
+	mrs	x1, tpidr_el0
+	sub	PTR_REG (0), PTR_REG (0), PTR_REG (1)
+
+	RESTORE_Q_REGISTERS
+
+	ldp	 x7,  x8, [sp, #16*1]
+	ldp	 x9, x10, [sp, #16*2]
+	ldp	x11, x12, [sp, #16*3]
+	ldp	x13, x14, [sp, #16*4]
+	ldp	x15, x16, [sp, #16*5]
+	ldp	x17, x18, [sp, #16*6]
+	ldp	 x5,  x6, [sp], #16*NSAVEXREGPAIRS
+	cfi_adjust_cfa_offset (-16*NSAVEXREGPAIRS)
+	b	1b
+	cfi_endproc
+	.size	_dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
+# undef NSAVEXREGPAIRS
+
+#endif // SHARED
+#endif // __UCLIBC_HAS_TLS__
diff --git a/ldso/ldso/aarch64/elfinterp.c b/ldso/ldso/aarch64/elfinterp.c
new file mode 100644
index 0000000..879484e
--- /dev/null
+++ b/ldso/ldso/aarch64/elfinterp.c
@@ -0,0 +1,306 @@ 
+/* AARCH64 ELF shared library loader suppport
+ *
+ * Copyright (C) 2001-2004 Erik Andersen
+ * Copyright (C) 2016-2017 Waldemar Brodkorb <wbx@uclibc-ng.org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. The name of the above contributors may not be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Program to load an ELF binary on a linux system, and run it.
+   References to symbols in sharable libraries can be resolved by either
+   an ELF sharable library or a linux style of shared library. */
+
+#include "ldso.h"
+
+#if defined(USE_TLS) && USE_TLS
+#include "dl-tls.h"
+#include "tlsdeschtab.h"
+#endif
+
+extern int _dl_linux_resolve(void);
+
+unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+{
+	ELF_RELOC *this_reloc;
+	char *strtab;
+	ElfW(Sym) *symtab;
+	int symtab_index;
+	char *rel_addr;
+	char *new_addr;
+	char **got_addr;
+	ElfW(Addr) instr_addr;
+	char *symname;
+
+	rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
+	this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry);
+	symtab_index = ELF_R_SYM(this_reloc->r_info);
+
+	symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
+	strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
+	symname = strtab + symtab[symtab_index].st_name;
+
+	/* Address of jump instruction to fix up */
+	instr_addr = (this_reloc->r_offset + tpnt->loadaddr);
+	got_addr = (char **)instr_addr;
+
+	/* Get the address of the GOT entry */
+	new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
+	if (unlikely(!new_addr)) {
+		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
+		_dl_exit(1);
+	}
+#if defined (__SUPPORT_LD_DEBUG__)
+	if (_dl_debug_bindings) {
+		_dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
+		if (_dl_debug_detail) _dl_dprintf(_dl_debug_file,
+				"\tpatched %x ==> %x @ %x", *got_addr, new_addr, got_addr);
+	}
+	if (!_dl_debug_nofixups) {
+		*got_addr = new_addr;
+	}
+#else
+	*got_addr = new_addr;
+#endif
+	return (unsigned long)new_addr;
+}
+
+static int
+_dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope,
+	  unsigned long rel_addr, unsigned long rel_size,
+	  int (*reloc_fnc) (struct elf_resolve *tpnt, struct r_scope_elem *scope,
+			    ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab))
+{
+	unsigned int i;
+	char *strtab;
+	ElfW(Sym) *symtab;
+	ELF_RELOC *rpnt;
+	int symtab_index;
+
+	/* Parse the relocation information */
+	rpnt = (ELF_RELOC *)rel_addr;
+	rel_size = rel_size / sizeof(ELF_RELOC);
+
+	symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB];
+	strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
+
+	for (i = 0; i < rel_size; i++, rpnt++) {
+		int res;
+
+		symtab_index = ELF_R_SYM(rpnt->r_info);
+
+		debug_sym(symtab, strtab, symtab_index);
+		debug_reloc(symtab, strtab, rpnt);
+
+		res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
+
+		if (res==0) 
+			continue;
+
+		_dl_dprintf(2, "\n%s: ", _dl_progname);
+
+		if (symtab_index)
+			_dl_dprintf(2, "symbol '%s': ", 
+				strtab + symtab[symtab_index].st_name);
+
+		if (unlikely(res < 0)) {
+		        int reloc_type = ELF_R_TYPE(rpnt->r_info);
+			_dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
+			_dl_exit(-res);
+		} else if (unlikely(res > 0)) {
+			_dl_dprintf(2, "can't resolve symbol\n");
+			return res;
+		}
+	  }
+
+	  return 0;
+}
+
+static int
+_dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
+	      ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
+{
+	int reloc_type;
+	int symtab_index;
+	char *symname;
+#if defined USE_TLS && USE_TLS
+	struct elf_resolve *tls_tpnt = NULL;
+#endif
+	struct symbol_ref sym_ref;
+	ElfW(Addr) *reloc_addr;
+	ElfW(Addr) symbol_addr;
+#if defined (__SUPPORT_LD_DEBUG__)
+	ElfW(Addr) old_val;
+#endif
+
+	reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
+	reloc_type = ELF_R_TYPE(rpnt->r_info);
+	symtab_index = ELF_R_SYM(rpnt->r_info);
+	sym_ref.sym = &symtab[symtab_index];
+	sym_ref.tpnt = NULL;
+	symbol_addr = 0;
+	symname = strtab + sym_ref.sym->st_name;
+
+	if (symtab_index) {
+		symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
+				elf_machine_type_class(reloc_type), &sym_ref);
+
+		/*
+		 * We want to allow undefined references to weak symbols - this might
+		 * have been intentional.  We should not be linking local symbols
+		 * here, so all bases should be covered.
+		 */
+		if (unlikely (!symbol_addr && 
+			(ELF_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS) &&
+			(ELF_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))) {
+			return 1;
+		}
+		if (_dl_trace_prelink) {
+			_dl_debug_lookup (symname, tpnt, &symtab[symtab_index],
+						&sym_ref, elf_machine_type_class(reloc_type));
+		}
+#if defined USE_TLS && USE_TLS
+		tls_tpnt = sym_ref.tpnt;
+#endif
+	} else {
+		/*
+		 * Relocs against STN_UNDEF are usually treated as using a
+		 * symbol value of zero, and using the module containing the
+		 * reloc itself.
+		 */
+		symbol_addr = sym_ref.sym->st_value;
+#if defined USE_TLS && USE_TLS
+		tls_tpnt = tpnt;
+#endif
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = *reloc_addr;
+#endif
+
+	switch (reloc_type) {
+		case R_AARCH64_NONE:
+			break;
+		case R_AARCH64_ABS64: 		/* REL_SYMBOLIC */
+		case R_AARCH64_GLOB_DAT:	/* REL_GOT */
+		case R_AARCH64_JUMP_SLOT:	/* REL_PLT */
+			*reloc_addr = symbol_addr + rpnt->r_addend;
+			break;
+		case R_AARCH64_RELATIVE:
+			*reloc_addr += tpnt->loadaddr + rpnt->r_addend;
+			break;
+		case R_AARCH64_COPY:
+			_dl_memcpy((void *) reloc_addr,
+				   (void *) symbol_addr, sym_ref.sym->st_size);
+			break;
+#if defined USE_TLS && USE_TLS
+		case R_AARCH64_TLS_TPREL:
+			CHECK_STATIC_TLS ((struct link_map *) tls_tpnt);
+			*reloc_addr = (symbol_addr + tls_tpnt->l_tls_offset);
+			break;
+		case R_AARCH64_TLSDESC:
+				{
+					struct tlsdesc volatile *td =
+							(struct tlsdesc volatile *)reloc_addr;
+#ifndef SHARED
+					CHECK_STATIC_TLS((struct link_map *) tls_tpnt);
+#else
+					if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt))
+					{
+					        td->arg = _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt, symbol_addr);
+					        td->entry = _dl_tlsdesc_dynamic;
+					}
+					else
+#endif
+					{
+					        td->arg = symbol_addr + tls_tpnt->l_tls_offset;
+					        td->entry = _dl_tlsdesc_return;
+					}
+				}
+			break;
+#endif
+		default:
+			return -1; /*call _dl_exit(1) */
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if (_dl_debug_reloc && _dl_debug_detail) {
+		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", 
+				old_val, *reloc_addr, reloc_addr);
+	}
+#endif
+
+	return 0;
+}
+
+static int
+_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
+		   ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
+{
+	int reloc_type;
+	ElfW(Addr) *reloc_addr;
+#if defined (__SUPPORT_LD_DEBUG__)
+	ElfW(Addr) old_val;
+#endif
+
+	(void)scope;
+	(void)strtab;
+
+	reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);
+	reloc_type = ELF_R_TYPE(rpnt->r_info);
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	old_val = *reloc_addr;
+#endif
+
+	switch (reloc_type) {
+		case R_AARCH64_NONE:
+			break;
+		case R_AARCH64_JUMP_SLOT:
+			*reloc_addr += tpnt->loadaddr;
+			break;
+		default:
+			return -1; /*call _dl_exit(1) */
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if (_dl_debug_reloc && _dl_debug_detail) {
+		_dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n",
+			    old_val, *reloc_addr, reloc_addr);
+	}
+#endif
+
+	return 0;
+}
+
+void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
+	unsigned long rel_addr, unsigned long rel_size)
+{
+	(void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
+}
+
+int _dl_parse_relocation_information(struct dyn_elf *rpnt,
+	struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size)
+{
+	return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc);
+}
diff --git a/ldso/ldso/aarch64/resolve.S b/ldso/ldso/aarch64/resolve.S
new file mode 100644
index 0000000..3b907c4
--- /dev/null
+++ b/ldso/ldso/aarch64/resolve.S
@@ -0,0 +1,97 @@ 
+/*
+ * Copyright (C) 2016 by Waldemar Brodkorb <wbx@uclibc-ng.org>
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ * ported from GNU libc
+ */
+
+/* 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 <features.h>
+
+#define PTR_REG(n)		x##n
+#define PTR_LOG_SIZE		3
+#define PTR_SIZE	(1<<PTR_LOG_SIZE)
+
+#define ip0 x16
+#define ip0l PTR_REG (16)
+#define ip1 x17
+#define lr  x30
+
+/* RELA relocatons are 3 pointers */
+#define RELA_SIZE (PTR_SIZE * 3)
+
+ .text
+ .globl _dl_linux_resolve
+ .type _dl_linux_resolve, %function
+ .align 2
+
+_dl_linux_resolve:
+	/* AArch64 we get called with:
+	   ip0		&PLTGOT[2]
+	   ip1		temp(dl resolver entry point)
+	   [sp, #8]	lr
+	   [sp, #0]	&PLTGOT[n]
+	 */
+
+	/* Save arguments.  */
+	stp	x8, x9, [sp, #-(80+8*16)]!
+	stp	x6, x7, [sp,  #16]
+	stp	x4, x5, [sp,  #32]
+	stp	x2, x3, [sp,  #48]
+	stp	x0, x1, [sp,  #64]
+	stp	q0, q1, [sp, #(80+0*16)]
+	stp	q2, q3, [sp, #(80+2*16)]
+	stp	q4, q5, [sp, #(80+4*16)]
+	stp	q6, q7, [sp, #(80+6*16)]
+
+	/* Get pointer to linker struct.  */
+	ldr	PTR_REG (0), [ip0, #-PTR_SIZE]
+
+	/* Prepare to call _dl_linux_resolver().  */
+	ldr	x1, [sp, 80+8*16]	/* Recover &PLTGOT[n] */
+
+	sub     x1, x1, ip0
+	add     x1, x1, x1, lsl #1
+	lsl     x1, x1, #3
+	sub     x1, x1, #(RELA_SIZE<<3)
+	lsr     x1, x1, #3
+
+	/* Call resolver routine.  */
+	bl	_dl_linux_resolver
+
+	/* Save the return.  */
+	mov	ip0, x0
+
+	/* Get arguments and return address back.  */
+	ldp	q0, q1, [sp, #(80+0*16)]
+	ldp	q2, q3, [sp, #(80+2*16)]
+	ldp	q4, q5, [sp, #(80+4*16)]
+	ldp	q6, q7, [sp, #(80+6*16)]
+	ldp	x0, x1, [sp, #64]
+	ldp	x2, x3, [sp, #48]
+	ldp	x4, x5, [sp, #32]
+	ldp	x6, x7, [sp, #16]
+	ldp	x8, x9, [sp], #(80+8*16)
+
+	ldp	ip1, lr, [sp], #16
+
+	/* Jump to the newly found address.  */
+	br	ip0
+
+.size _dl_linux_resolve, .-_dl_linux_resolve
diff --git a/ldso/ldso/i386/syscall6.S b/ldso/ldso/i386/syscall6.S
new file mode 100644
index 0000000..59852e2
--- /dev/null
+++ b/ldso/ldso/i386/syscall6.S
@@ -0,0 +1 @@ 
+#include <libc/sysdeps/linux/i386/syscall6.S>
diff --git a/libc/misc/internals/errno.c b/libc/misc/internals/errno.c
index d990885..442f43f 100644
--- a/libc/misc/internals/errno.c
+++ b/libc/misc/internals/errno.c
@@ -3,8 +3,7 @@ 
 #undef errno
 
 #ifdef __UCLIBC_HAS_TLS__
-__thread int errno;
-extern __thread int __libc_errno __attribute__ ((alias ("errno"))) attribute_hidden;
+__thread int errno attribute_tls_model_ie;
 #else
 extern int errno;
 int errno = 0;
diff --git a/libc/string/xtensa/Makefile b/libc/string/aarch64/Makefile
similarity index 100%
copy from libc/string/xtensa/Makefile
copy to libc/string/aarch64/Makefile
diff --git a/libc/string/aarch64/memcpy.S b/libc/string/aarch64/memcpy.S
new file mode 100644
index 0000000..87b2552
--- /dev/null
+++ b/libc/string/aarch64/memcpy.S
@@ -0,0 +1,230 @@ 
+/* Copyright (C) 2012-2017 Free Software Foundation, Inc.
+
+   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>
+
+/* Assumptions:
+ *
+ * ARMv8-a, AArch64, unaligned accesses.
+ *
+ */
+
+#define dstin	x0
+#define src	x1
+#define count	x2
+#define dst	x3
+#define srcend	x4
+#define dstend	x5
+#define A_l	x6
+#define A_lw	w6
+#define A_h	x7
+#define A_hw	w7
+#define B_l	x8
+#define B_lw	w8
+#define B_h	x9
+#define C_l	x10
+#define C_h	x11
+#define D_l	x12
+#define D_h	x13
+#define E_l	src
+#define E_h	count
+#define F_l	srcend
+#define F_h	dst
+#define G_l	count
+#define G_h	dst
+#define tmp1	x14
+
+ENTRY (memcpy)
+
+	prfm	PLDL1KEEP, [src]
+	add	srcend, src, count
+	add	dstend, dstin, count
+	cmp	count, 16
+	b.ls	L(copy16)
+	cmp	count, 96
+	b.hi	L(copy_long)
+
+	/* Medium copies: 17..96 bytes.  */
+	sub	tmp1, count, 1
+	ldp	A_l, A_h, [src]
+	tbnz	tmp1, 6, L(copy96)
+	ldp	D_l, D_h, [srcend, -16]
+	tbz	tmp1, 5, 1f
+	ldp	B_l, B_h, [src, 16]
+	ldp	C_l, C_h, [srcend, -32]
+	stp	B_l, B_h, [dstin, 16]
+	stp	C_l, C_h, [dstend, -32]
+1:
+	stp	A_l, A_h, [dstin]
+	stp	D_l, D_h, [dstend, -16]
+	ret
+
+	.p2align 4
+	/* Small copies: 0..16 bytes.  */
+L(copy16):
+	cmp	count, 8
+	b.lo	1f
+	ldr	A_l, [src]
+	ldr	A_h, [srcend, -8]
+	str	A_l, [dstin]
+	str	A_h, [dstend, -8]
+	ret
+	.p2align 4
+1:
+	tbz	count, 2, 1f
+	ldr	A_lw, [src]
+	ldr	A_hw, [srcend, -4]
+	str	A_lw, [dstin]
+	str	A_hw, [dstend, -4]
+	ret
+
+	/* Copy 0..3 bytes.  Use a branchless sequence that copies the same
+	   byte 3 times if count==1, or the 2nd byte twice if count==2.  */
+1:
+	cbz	count, 2f
+	lsr	tmp1, count, 1
+	ldrb	A_lw, [src]
+	ldrb	A_hw, [srcend, -1]
+	ldrb	B_lw, [src, tmp1]
+	strb	A_lw, [dstin]
+	strb	B_lw, [dstin, tmp1]
+	strb	A_hw, [dstend, -1]
+2:	ret
+
+	.p2align 4
+	/* Copy 64..96 bytes.  Copy 64 bytes from the start and
+	   32 bytes from the end.  */
+L(copy96):
+	ldp	B_l, B_h, [src, 16]
+	ldp	C_l, C_h, [src, 32]
+	ldp	D_l, D_h, [src, 48]
+	ldp	E_l, E_h, [srcend, -32]
+	ldp	F_l, F_h, [srcend, -16]
+	stp	A_l, A_h, [dstin]
+	stp	B_l, B_h, [dstin, 16]
+	stp	C_l, C_h, [dstin, 32]
+	stp	D_l, D_h, [dstin, 48]
+	stp	E_l, E_h, [dstend, -32]
+	stp	F_l, F_h, [dstend, -16]
+	ret
+
+	/* Align DST to 16 byte alignment so that we don't cross cache line
+	   boundaries on both loads and stores.  There are at least 96 bytes
+	   to copy, so copy 16 bytes unaligned and then align.  The loop
+	   copies 64 bytes per iteration and prefetches one iteration ahead.  */
+
+	.p2align 4
+L(copy_long):
+	and	tmp1, dstin, 15
+	bic	dst, dstin, 15
+	ldp	D_l, D_h, [src]
+	sub	src, src, tmp1
+	add	count, count, tmp1	/* Count is now 16 too large.  */
+	ldp	A_l, A_h, [src, 16]
+	stp	D_l, D_h, [dstin]
+	ldp	B_l, B_h, [src, 32]
+	ldp	C_l, C_h, [src, 48]
+	ldp	D_l, D_h, [src, 64]!
+	subs	count, count, 128 + 16	/* Test and readjust count.  */
+	b.ls	2f
+1:
+	stp	A_l, A_h, [dst, 16]
+	ldp	A_l, A_h, [src, 16]
+	stp	B_l, B_h, [dst, 32]
+	ldp	B_l, B_h, [src, 32]
+	stp	C_l, C_h, [dst, 48]
+	ldp	C_l, C_h, [src, 48]
+	stp	D_l, D_h, [dst, 64]!
+	ldp	D_l, D_h, [src, 64]!
+	subs	count, count, 64
+	b.hi	1b
+
+	/* Write the last full set of 64 bytes.  The remainder is at most 64
+	   bytes, so it is safe to always copy 64 bytes from the end even if
+	   there is just 1 byte left.  */
+2:
+	ldp	E_l, E_h, [srcend, -64]
+	stp	A_l, A_h, [dst, 16]
+	ldp	A_l, A_h, [srcend, -48]
+	stp	B_l, B_h, [dst, 32]
+	ldp	B_l, B_h, [srcend, -32]
+	stp	C_l, C_h, [dst, 48]
+	ldp	C_l, C_h, [srcend, -16]
+	stp	D_l, D_h, [dst, 64]
+	stp	E_l, E_h, [dstend, -64]
+	stp	A_l, A_h, [dstend, -48]
+	stp	B_l, B_h, [dstend, -32]
+	stp	C_l, C_h, [dstend, -16]
+	ret
+
+	.p2align 4
+L(move_long):
+	cbz	tmp1, 3f
+
+	add	srcend, src, count
+	add	dstend, dstin, count
+
+	/* Align dstend to 16 byte alignment so that we don't cross cache line
+	   boundaries on both loads and stores.  There are at least 96 bytes
+	   to copy, so copy 16 bytes unaligned and then align.  The loop
+	   copies 64 bytes per iteration and prefetches one iteration ahead.  */
+
+	and	tmp1, dstend, 15
+	ldp	D_l, D_h, [srcend, -16]
+	sub	srcend, srcend, tmp1
+	sub	count, count, tmp1
+	ldp	A_l, A_h, [srcend, -16]
+	stp	D_l, D_h, [dstend, -16]
+	ldp	B_l, B_h, [srcend, -32]
+	ldp	C_l, C_h, [srcend, -48]
+	ldp	D_l, D_h, [srcend, -64]!
+	sub	dstend, dstend, tmp1
+	subs	count, count, 128
+	b.ls	2f
+
+	nop
+1:
+	stp	A_l, A_h, [dstend, -16]
+	ldp	A_l, A_h, [srcend, -16]
+	stp	B_l, B_h, [dstend, -32]
+	ldp	B_l, B_h, [srcend, -32]
+	stp	C_l, C_h, [dstend, -48]
+	ldp	C_l, C_h, [srcend, -48]
+	stp	D_l, D_h, [dstend, -64]!
+	ldp	D_l, D_h, [srcend, -64]!
+	subs	count, count, 64
+	b.hi	1b
+
+	/* Write the last full set of 64 bytes.  The remainder is at most 64
+	   bytes, so it is safe to always copy 64 bytes from the start even if
+	   there is just 1 byte left.  */
+2:
+	ldp	G_l, G_h, [src, 48]
+	stp	A_l, A_h, [dstend, -16]
+	ldp	A_l, A_h, [src, 32]
+	stp	B_l, B_h, [dstend, -32]
+	ldp	B_l, B_h, [src, 16]
+	stp	C_l, C_h, [dstend, -48]
+	ldp	C_l, C_h, [src]
+	stp	D_l, D_h, [dstend, -64]
+	stp	G_l, G_h, [dstin, 48]
+	stp	A_l, A_h, [dstin, 32]
+	stp	B_l, B_h, [dstin, 16]
+	stp	C_l, C_h, [dstin]
+3:	ret
+
+END (memcpy)
+libc_hidden_def (memcpy)
diff --git a/libc/string/aarch64/memset.S b/libc/string/aarch64/memset.S
new file mode 100644
index 0000000..d6686be
--- /dev/null
+++ b/libc/string/aarch64/memset.S
@@ -0,0 +1,189 @@ 
+/* Copyright (C) 2012-2017 Free Software Foundation, Inc.
+
+   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>
+
+/* Assumptions:
+ *
+ * ARMv8-a, AArch64, unaligned accesses
+ *
+ */
+
+#define dstin	x0
+#define val	x1
+#define valw	w1
+#define count	x2
+#define dst	x3
+#define dstend	x4
+#define tmp1	x5
+#define tmp1w	w5
+#define tmp2	x6
+#define tmp2w	w6
+#define zva_len x7
+#define zva_lenw w7
+
+ENTRY_ALIGN (memset, 6)
+
+	dup	v0.16B, valw
+	add	dstend, dstin, count
+
+	cmp	count, 96
+	b.hi	L(set_long)
+	cmp	count, 16
+	b.hs	L(set_medium)
+	mov	val, v0.D[0]
+
+	/* Set 0..15 bytes.  */
+	tbz	count, 3, 1f
+	str	val, [dstin]
+	str	val, [dstend, -8]
+	ret
+	nop
+1:	tbz	count, 2, 2f
+	str	valw, [dstin]
+	str	valw, [dstend, -4]
+	ret
+2:	cbz	count, 3f
+	strb	valw, [dstin]
+	tbz	count, 1, 3f
+	strh	valw, [dstend, -2]
+3:	ret
+
+	/* Set 17..96 bytes.  */
+L(set_medium):
+	str	q0, [dstin]
+	tbnz	count, 6, L(set96)
+	str	q0, [dstend, -16]
+	tbz	count, 5, 1f
+	str	q0, [dstin, 16]
+	str	q0, [dstend, -32]
+1:	ret
+
+	.p2align 4
+	/* Set 64..96 bytes.  Write 64 bytes from the start and
+	   32 bytes from the end.  */
+L(set96):
+	str	q0, [dstin, 16]
+	stp	q0, q0, [dstin, 32]
+	stp	q0, q0, [dstend, -32]
+	ret
+
+	.p2align 3
+	nop
+L(set_long):
+	and	valw, valw, 255
+	bic	dst, dstin, 15
+	str	q0, [dstin]
+	cmp	count, 256
+	ccmp	valw, 0, 0, cs
+	b.eq	L(try_zva)
+L(no_zva):
+	sub	count, dstend, dst	/* Count is 16 too large.  */
+	add	dst, dst, 16
+	sub	count, count, 64 + 16	/* Adjust count and bias for loop.  */
+1:	stp	q0, q0, [dst], 64
+	stp	q0, q0, [dst, -32]
+L(tail64):
+	subs	count, count, 64
+	b.hi	1b
+2:	stp	q0, q0, [dstend, -64]
+	stp	q0, q0, [dstend, -32]
+	ret
+
+	.p2align 3
+L(try_zva):
+	mrs	tmp1, dczid_el0
+	tbnz	tmp1w, 4, L(no_zva)
+	and	tmp1w, tmp1w, 15
+	cmp	tmp1w, 4	/* ZVA size is 64 bytes.  */
+	b.ne	 L(zva_128)
+
+	/* Write the first and last 64 byte aligned block using stp rather
+	   than using DC ZVA.  This is faster on some cores.
+	 */
+L(zva_64):
+	str	q0, [dst, 16]
+	stp	q0, q0, [dst, 32]
+	bic	dst, dst, 63
+	stp	q0, q0, [dst, 64]
+	stp	q0, q0, [dst, 96]
+	sub	count, dstend, dst	/* Count is now 128 too large.	*/
+	sub	count, count, 128+64+64	/* Adjust count and bias for loop.  */
+	add	dst, dst, 128
+	nop
+1:	dc	zva, dst
+	add	dst, dst, 64
+	subs	count, count, 64
+	b.hi	1b
+	stp	q0, q0, [dst, 0]
+	stp	q0, q0, [dst, 32]
+	stp	q0, q0, [dstend, -64]
+	stp	q0, q0, [dstend, -32]
+	ret
+
+	.p2align 3
+L(zva_128):
+	cmp	tmp1w, 5	/* ZVA size is 128 bytes.  */
+	b.ne	L(zva_other)
+
+	str	q0, [dst, 16]
+	stp	q0, q0, [dst, 32]
+	stp	q0, q0, [dst, 64]
+	stp	q0, q0, [dst, 96]
+	bic	dst, dst, 127
+	sub	count, dstend, dst	/* Count is now 128 too large.	*/
+	sub	count, count, 128+128	/* Adjust count and bias for loop.  */
+	add	dst, dst, 128
+1:	dc	zva, dst
+	add	dst, dst, 128
+	subs	count, count, 128
+	b.hi	1b
+	stp	q0, q0, [dstend, -128]
+	stp	q0, q0, [dstend, -96]
+	stp	q0, q0, [dstend, -64]
+	stp	q0, q0, [dstend, -32]
+	ret
+
+L(zva_other):
+	mov	tmp2w, 4
+	lsl	zva_lenw, tmp2w, tmp1w
+	add	tmp1, zva_len, 64	/* Max alignment bytes written.	 */
+	cmp	count, tmp1
+	blo	L(no_zva)
+
+	sub	tmp2, zva_len, 1
+	add	tmp1, dst, zva_len
+	add	dst, dst, 16
+	subs	count, tmp1, dst	/* Actual alignment bytes to write.  */
+	bic	tmp1, tmp1, tmp2	/* Aligned dc zva start address.  */
+	beq	2f
+1:	stp	q0, q0, [dst], 64
+	stp	q0, q0, [dst, -32]
+	subs	count, count, 64
+	b.hi	1b
+2:	mov	dst, tmp1
+	sub	count, dstend, tmp1	/* Remaining bytes to write.  */
+	subs	count, count, zva_len
+	b.lo	4f
+3:	dc	zva, dst
+	add	dst, dst, zva_len
+	subs	count, count, zva_len
+	b.hs	3b
+4:	add	count, count, zva_len
+	b	L(tail64)
+
+END (memset)
+libc_hidden_def (memset)
diff --git a/libc/sysdeps/linux/Makefile.commonarch b/libc/sysdeps/linux/Makefile.commonarch
index f8dc17d..88309e4 100644
--- a/libc/sysdeps/linux/Makefile.commonarch
+++ b/libc/sysdeps/linux/Makefile.commonarch
@@ -47,7 +47,7 @@  HEADERCLEAN_$(subst $(top_builddir),,$(ARCH_OUT)):
 endif
 
 $(ARCH_OUT)/ucontext_i.h: $(top_srcdir)extra/scripts/gen-as-const.awk
-$(ARCH_OUT)/ucontext_i.h: $(ARCH_OUT)/ucontext_i.sym
+$(ARCH_OUT)/ucontext_i.h: $(ARCH_DIR)/ucontext_i.sym
 	@$(disp_gen)
 	$(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< \
 	| $(CC) $(CFLAGS) -x c - -S -o - \
diff --git a/libc/sysdeps/linux/nds32/Makefile b/libc/sysdeps/linux/aarch64/Makefile
similarity index 100%
copy from libc/sysdeps/linux/nds32/Makefile
copy to libc/sysdeps/linux/aarch64/Makefile
diff --git a/libc/sysdeps/linux/aarch64/Makefile.arch b/libc/sysdeps/linux/aarch64/Makefile.arch
new file mode 100644
index 0000000..b38f760
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/Makefile.arch
@@ -0,0 +1,5 @@ 
+# Makefile for uClibc-ng
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+CSRC-y := __syscall_error.c
+SSRC-y := clone.S setjmp.S syscall.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S vfork.S
diff --git a/libc/sysdeps/linux/aarch64/__longjmp.S b/libc/sysdeps/linux/aarch64/__longjmp.S
new file mode 100644
index 0000000..e4d11b1
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/__longjmp.S
@@ -0,0 +1,107 @@ 
+/* Copyright (C) 1997-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 <jmpbuf-offsets.h>
+
+/* __longjmp(jmpbuf, val) */
+
+ENTRY (__longjmp)
+	cfi_def_cfa(x0, 0)
+	cfi_offset(x19, JB_X19<<3)
+	cfi_offset(x20, JB_X20<<3)
+	cfi_offset(x21, JB_X21<<3)
+	cfi_offset(x22, JB_X22<<3)
+	cfi_offset(x23, JB_X23<<3)
+	cfi_offset(x24, JB_X24<<3)
+	cfi_offset(x25, JB_X25<<3)
+	cfi_offset(x26, JB_X26<<3)
+	cfi_offset(x27, JB_X27<<3)
+	cfi_offset(x28, JB_X28<<3)
+	cfi_offset(x29, JB_X29<<3)
+	cfi_offset(x30, JB_LR<<3)
+
+	cfi_offset( d8, JB_D8<<3)
+	cfi_offset( d9, JB_D9<<3)
+	cfi_offset(d10, JB_D10<<3)
+	cfi_offset(d11, JB_D11<<3)
+	cfi_offset(d12, JB_D12<<3)
+	cfi_offset(d13, JB_D13<<3)
+	cfi_offset(d14, JB_D14<<3)
+	cfi_offset(d15, JB_D15<<3)
+
+	ldp	x19, x20, [x0, #JB_X19<<3]
+	ldp	x21, x22, [x0, #JB_X21<<3]
+	ldp	x23, x24, [x0, #JB_X23<<3]
+	ldp	x25, x26, [x0, #JB_X25<<3]
+	ldp	x27, x28, [x0, #JB_X27<<3]
+	ldp	x29, x30, [x0, #JB_X29<<3]
+
+	/* longjmp probe takes 3 arguments, address of jump buffer as
+	   first argument (8@x0), return value as second argument (-4@x1),
+	   and target address (8@x30), respectively.  */
+	//LIBC_PROBE (longjmp, 3, 8@x0, -4@x1, 8@x30)
+	ldp	 d8,  d9, [x0, #JB_D8<<3]
+	ldp	d10, d11, [x0, #JB_D10<<3]
+	ldp	d12, d13, [x0, #JB_D12<<3]
+	ldp	d14, d15, [x0, #JB_D14<<3]
+
+        /* Originally this was implemented with a series of
+	   .cfi_restore() directives.
+
+           The theory was that cfi_restore should revert to previous
+           frame value is the same as the current value.  In practice
+           this doesn't work, even after cfi_restore() gdb continues
+           to try to recover a previous frame value offset from x0,
+           which gets stuffed after a few more instructions.  The
+           cfi_same_value() mechanism appears to work fine.  */
+
+	cfi_same_value(x19)
+	cfi_same_value(x20)
+	cfi_same_value(x21)
+	cfi_same_value(x22)
+	cfi_same_value(x23)
+	cfi_same_value(x24)
+	cfi_same_value(x25)
+	cfi_same_value(x26)
+	cfi_same_value(x27)
+	cfi_same_value(x28)
+	cfi_same_value(x29)
+	cfi_same_value(x30)
+	cfi_same_value(d8)
+	cfi_same_value(d9)
+	cfi_same_value(d10)
+	cfi_same_value(d11)
+	cfi_same_value(d12)
+	cfi_same_value(d13)
+	cfi_same_value(d14)
+	cfi_same_value(d15)
+	ldr	x5, [x0, #JB_SP<<3]
+	mov	sp, x5
+
+	/* longjmp_target probe takes 3 arguments, address of jump buffer
+	   as first argument (8@x0), return value as second argument (-4@x1),
+	   and target address (8@x30), respectively.  */
+	//LIBC_PROBE (longjmp_target, 3, 8@x0, -4@x1, 8@x30)
+	cmp	x1, #0
+	mov	x0, #1
+	csel	x0, x1, x0, ne
+	/* Use br instead of ret because ret is guaranteed to mispredict */
+	br	x30
+END (__longjmp)
+libc_hidden_def(__longjmp)
diff --git a/libc/sysdeps/linux/xtensa/__syscall_error.c b/libc/sysdeps/linux/aarch64/__syscall_error.c
similarity index 100%
copy from libc/sysdeps/linux/xtensa/__syscall_error.c
copy to libc/sysdeps/linux/aarch64/__syscall_error.c
diff --git a/libc/sysdeps/linux/aarch64/bits/atomic.h b/libc/sysdeps/linux/aarch64/bits/atomic.h
new file mode 100644
index 0000000..66e2f57
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/atomic.h
@@ -0,0 +1,172 @@ 
+/* Copyright (C) 2003-2017 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 _AARCH64_ATOMIC_MACHINE_H
+#define _AARCH64_ATOMIC_MACHINE_H	1
+
+#define typeof __typeof__
+
+#include <stdint.h>
+#include <sysdep.h>
+
+typedef int8_t  atomic8_t;
+typedef int16_t atomic16_t;
+typedef int32_t atomic32_t;
+typedef int64_t atomic64_t;
+
+typedef uint8_t  uatomic8_t;
+typedef uint16_t uatomic16_t;
+typedef uint32_t uatomic32_t;
+typedef uint64_t uatomic64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+#define __HAVE_64B_ATOMICS 1
+#define USE_ATOMIC_COMPILER_BUILTINS 1
+
+/* Compare and exchange.
+   For all "bool" routines, we return FALSE if exchange succesful.  */
+
+# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				  model, __ATOMIC_RELAXED);		\
+  })
+
+# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				  model, __ATOMIC_RELAXED);		\
+  })
+
+# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				  model, __ATOMIC_RELAXED);		\
+  })
+
+#  define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				  model, __ATOMIC_RELAXED);		\
+  })
+
+# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				 model, __ATOMIC_RELAXED);		\
+    __oldval;								\
+  })
+
+# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				 model, __ATOMIC_RELAXED);		\
+    __oldval;								\
+  })
+
+# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				 model, __ATOMIC_RELAXED);		\
+    __oldval;								\
+  })
+
+#  define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				 model, __ATOMIC_RELAXED);		\
+    __oldval;								\
+  })
+
+
+/* Compare and exchange with "acquire" semantics, ie barrier after.  */
+
+# define atomic_compare_and_exchange_bool_acq(mem, new, old)	\
+  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,	\
+			mem, new, old, __ATOMIC_ACQUIRE)
+
+# define atomic_compare_and_exchange_val_acq(mem, new, old)	\
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,	\
+		       mem, new, old, __ATOMIC_ACQUIRE)
+
+/* Compare and exchange with "release" semantics, ie barrier before.  */
+
+# define atomic_compare_and_exchange_val_rel(mem, new, old)	 \
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,    \
+                       mem, new, old, __ATOMIC_RELEASE)
+
+
+/* Atomic exchange (without compare).  */
+
+# define __arch_exchange_8_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+
+# define __arch_exchange_16_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+
+# define __arch_exchange_32_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+
+#  define __arch_exchange_64_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+
+# define atomic_exchange_acq(mem, value)				\
+  __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
+
+# define atomic_exchange_rel(mem, value)				\
+  __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
+
+
+/* Atomically add value and return the previous (unincremented) value.  */
+
+# define __arch_exchange_and_add_8_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+
+# define __arch_exchange_and_add_16_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+
+# define __arch_exchange_and_add_32_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+
+#  define __arch_exchange_and_add_64_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+
+# define atomic_exchange_and_add_acq(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       __ATOMIC_ACQUIRE)
+
+# define atomic_exchange_and_add_rel(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       __ATOMIC_RELEASE)
+
+/* Barrier macro. */
+#define atomic_full_barrier() __sync_synchronize()
+
+#endif
diff --git a/libc/sysdeps/linux/aarch64/bits/endian.h b/libc/sysdeps/linux/aarch64/bits/endian.h
new file mode 100644
index 0000000..a32ebc0
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/endian.h
@@ -0,0 +1,30 @@ 
+/* Copyright (C) 1997-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 _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+/* AArch64 can be either big or little endian.  */
+#ifdef __AARCH64EB__
+# define __BYTE_ORDER __BIG_ENDIAN
+#else
+# define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
+
+#define __FLOAT_WORD_ORDER __BYTE_ORDER
diff --git a/libc/sysdeps/linux/aarch64/bits/fcntl.h b/libc/sysdeps/linux/aarch64/bits/fcntl.h
new file mode 100644
index 0000000..d05798f
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/fcntl.h
@@ -0,0 +1,329 @@ 
+/* O_*, F_*, FD_* bit values for the AArch64 Linux ABI.
+   Copyright (C) 2011-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	_FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <sys/types.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+/* open/fcntl.  */
+#define O_ACCMODE	   0003
+#define O_RDONLY	     00
+#define O_WRONLY	     01
+#define O_RDWR		     02
+#define O_CREAT		   0100	/* Not fcntl.  */
+#define O_EXCL		   0200	/* Not fcntl.  */
+#define O_NOCTTY	   0400	/* Not fcntl.  */
+#define O_TRUNC		  01000	/* Not fcntl.  */
+#define O_APPEND	  02000
+#define O_NONBLOCK	  04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC	       04010000
+#define O_FSYNC		 O_SYNC
+#define O_ASYNC		 020000
+
+#ifdef __USE_GNU
+# define O_DIRECTORY	 040000
+# define O_NOFOLLOW	0100000
+# define O_DIRECT	0200000
+# define O_NOATIME     01000000
+# define O_CLOEXEC     02000000
+# define O_PATH       010000000
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+   We define the symbols here but let them do the same as O_SYNC since
+   this is a superset.	*/
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC	O_SYNC	/* Synchronize data.  */
+# define O_RSYNC	O_SYNC	/* Synchronize read operations.	 */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define O_LARGEFILE	0
+#endif
+
+/* Values for the second argument to `fcntl'.  */
+#define F_DUPFD		0	/* Duplicate file descriptor.  */
+#define F_GETFD		1	/* Get file descriptor flags.  */
+#define F_SETFD		2	/* Set file descriptor flags.  */
+#define F_GETFL		3	/* Get file status flags.  */
+#define F_SETFL		4	/* Set file status flags.  */
+#ifndef __USE_FILE_OFFSET64
+# define F_GETLK	5	/* Get record locking info.  */
+# define F_SETLK	6	/* Set record locking info (non-blocking).  */
+# define F_SETLKW	7	/* Set record locking info (blocking).	*/
+#else
+# define F_GETLK	F_GETLK64  /* Get record locking info.	*/
+# define F_SETLK	F_SETLK64  /* Set record locking info (non-blocking).*/
+# define F_SETLKW	F_SETLKW64 /* Set record locking info (blocking).  */
+#endif
+#define F_GETLK64	5	/* Get record locking info.  */
+#define F_SETLK64	6	/* Set record locking info (non-blocking).  */
+#define F_SETLKW64	7	/* Set record locking info (blocking).	*/
+
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_SETOWN	8	/* Get owner of socket (receiver of SIGIO).  */
+# define F_GETOWN	9	/* Set owner of socket (receiver of SIGIO).  */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG	10	/* Set number of signal to be sent.  */
+# define F_GETSIG	11	/* Get number of signal to be sent.  */
+# define F_SETOWN_EX	15	/* Get owner (thread receiving SIGIO).  */
+# define F_GETOWN_EX	16	/* Set owner (thread receiving SIGIO).  */
+#endif
+
+
+#ifdef __USE_GNU
+# define F_SETLEASE	1024	/* Set a lease.	 */
+# define F_GETLEASE	1025	/* Enquire what lease is active.  */
+# define F_NOTIFY	1026	/* Request notifications on a directory.  */
+# define F_SETPIPE_SZ	1031	/* Set pipe page size array.  */
+# define F_GETPIPE_SZ	1032	/* Set pipe page size array.  */
+#endif
+#ifdef __USE_XOPEN2K8
+# define F_DUPFD_CLOEXEC 1030	/* Duplicate file descriptor with
+				   close-on-exit set.  */
+#endif
+
+/* For F_[GET|SET]FD.  */
+#define FD_CLOEXEC	1	/* Actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
+# define F_RDLCK		0	/* Read lock.  */
+# define F_WRLCK		1	/* Write lock.	*/
+# define F_UNLCK		2	/* Remove lock.	 */
+
+/* For old implementation of BSD flock.  */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for BSD flock, also used by the kernel implementation.  */
+# define LOCK_SH	1	/* Shared lock.  */
+# define LOCK_EX	2	/* Exclusive lock.  */
+# define LOCK_NB	4	/* Or'd with one of the above to prevent
+				   blocking.  */
+# define LOCK_UN	8	/* Remove lock.  */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND	32	/* This is a mandatory flock:	*/
+# define LOCK_READ	64	/* ... which allows concurrent read operations.	 */
+# define LOCK_WRITE	128	/* ... which allows concurrent write operations.  */
+# define LOCK_RW	192	/* ... Which allows concurrent read & write operations.	 */
+#endif
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY.  */
+# define DN_ACCESS	0x00000001	/* File accessed.  */
+# define DN_MODIFY	0x00000002	/* File modified.  */
+# define DN_CREATE	0x00000004	/* File created.  */
+# define DN_DELETE	0x00000008	/* File removed.  */
+# define DN_RENAME	0x00000010	/* File renamed.  */
+# define DN_ATTRIB	0x00000020	/* File changed attributes.  */
+# define DN_MULTISHOT	0x80000000	/* Don't remove notifier.  */
+#endif
+
+struct flock
+  {
+    short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.	*/
+    short int l_whence;	/* Where `l_start' is relative to (like `lseek').  */
+    __off_t l_start;	/* Offset where the lock begins.  */
+    __off_t l_len;	/* Size of the locked area; zero means until EOF.  */
+    __pid_t l_pid;	/* Process holding the lock.  */
+  };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+  {
+    short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.	*/
+    short int l_whence;	/* Where `l_start' is relative to (like `lseek').  */
+    __off64_t l_start;	/* Offset where the lock begins.  */
+    __off64_t l_len;	/* Size of the locked area; zero means until EOF.  */
+    __pid_t l_pid;	/* Process holding the lock.  */
+  };
+#endif
+
+
+#ifdef __USE_GNU
+/* Owner types.  */
+enum __pid_type
+  {
+    F_OWNER_TID = 0,		/* Kernel thread.  */
+    F_OWNER_PID,		/* Process.  */
+    F_OWNER_PGRP,		/* Process group.  */
+    F_OWNER_GID = F_OWNER_PGRP	/* Alternative, obsolete name.  */
+  };
+
+/* Structure to use with F_GETOWN_EX and F_SETOWN_EX.  */
+struct f_owner_ex
+  {
+    enum __pid_type type;	/* Owner type of ID.  */
+    __pid_t pid;		/* ID of owner.  */
+  };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+   BSD systems which did not managed to hide these kernel macros.  */
+#ifdef	__USE_BSD
+# define FAPPEND	O_APPEND
+# define FFSYNC		O_FSYNC
+# define FASYNC		O_ASYNC
+# define FNONBLOCK	O_NONBLOCK
+# define FNDELAY	O_NDELAY
+#endif /* Use BSD.  */
+
+/* Advise to `posix_fadvise'.  */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL	0 /* No further special treatment.  */
+# define POSIX_FADV_RANDOM	1 /* Expect random page references.  */
+# define POSIX_FADV_SEQUENTIAL	2 /* Expect sequential page references.	 */
+# define POSIX_FADV_WILLNEED	3 /* Will need these pages.  */
+# define POSIX_FADV_DONTNEED	4 /* Don't need these pages.  */
+# define POSIX_FADV_NOREUSE	5 /* Data will be accessed once.  */
+#endif
+
+
+#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__
+/* Flags for SYNC_FILE_RANGE.  */
+# define SYNC_FILE_RANGE_WAIT_BEFORE	1 /* Wait upon writeout of all pages
+					     in the range before performing the
+					     write.  */
+# define SYNC_FILE_RANGE_WRITE		2 /* Initiate writeout of all those
+					     dirty pages in the range which are
+					     not presently under writeback.  */
+# define SYNC_FILE_RANGE_WAIT_AFTER	4 /* Wait upon writeout of all pages in
+					     the range after performing the
+					     write.  */
+
+/* Flags for SPLICE and VMSPLICE.  */
+# define SPLICE_F_MOVE		1	/* Move pages instead of copying.  */
+# define SPLICE_F_NONBLOCK	2	/* Don't block on the pipe splicing
+					   (but we may still block on the fd
+					   we splice from/to).  */
+# define SPLICE_F_MORE		4	/* Expect more data.  */
+# define SPLICE_F_GIFT		8	/* Pages passed in are a gift.  */
+
+
+/* Flags for fallocate.  */
+# define FALLOC_FL_KEEP_SIZE		1 /* Don't extend size of file
+					     even if offset + len is
+					     greater than file size.  */
+# define FALLOC_FL_PUNCH_HOLE		2 /* Create a hole in the file.  */
+# define FALLOC_FL_COLLAPSE_RANGE	8 /* Remove a range of a file
+					     without leaving a
+					     hole.  */
+# define FALLOC_FL_ZERO_RANGE		16 /* Convert a range of a
+					      file to zeros.  */
+
+
+/* File handle structure.  */
+struct file_handle
+{
+  unsigned int handle_bytes;
+  int handle_type;
+  /* File identifier.  */
+  unsigned char f_handle[0];
+};
+
+/* Maximum handle size (for now).  */
+# define MAX_HANDLE_SZ	128
+#endif
+
+__BEGIN_DECLS
+
+#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__
+
+/* Provide kernel hint to read ahead.  */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+    __THROW;
+
+
+/* Selective file content synch'ing.
+
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern int sync_file_range (int __fd, __off64_t __offset, __off64_t __count,
+			    unsigned int __flags);
+
+
+/* Splice address range into a pipe.
+
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern ssize_t vmsplice (int __fdout, const struct iovec *__iov,
+			 size_t __count, unsigned int __flags);
+
+/* Splice two files together.
+
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout,
+		       __off64_t *__offout, size_t __len,
+		       unsigned int __flags);
+
+/* In-kernel implementation of tee for pipe buffers.
+
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern ssize_t tee (int __fdin, int __fdout, size_t __len,
+		    unsigned int __flags);
+
+/* Reserve storage for the data of the file associated with FD.
+
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+# ifndef __USE_FILE_OFFSET64
+extern int fallocate (int __fd, int __mode, __off_t __offset, __off_t __len);
+# else
+#  ifdef __REDIRECT
+extern int __REDIRECT (fallocate, (int __fd, int __mode, __off64_t __offset,
+				   __off64_t __len),
+		       fallocate64);
+#  else
+#   define fallocate fallocate64
+#  endif
+# endif
+# ifdef __USE_LARGEFILE64
+extern int fallocate64 (int __fd, int __mode, __off64_t __offset,
+			__off64_t __len);
+# endif
+
+
+/* Map file name to file handle.  */
+extern int name_to_handle_at (int __dfd, const char *__name,
+			      struct file_handle *__handle, int *__mnt_id,
+			      int __flags) __THROW;
+
+/* Open file using the file handle.
+
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern int open_by_handle_at (int __mountdirfd, struct file_handle *__handle,
+			      int __flags);
+
+#endif	/* use GNU */
+
+__END_DECLS
diff --git a/libc/sysdeps/linux/aarch64/bits/kernel_types.h b/libc/sysdeps/linux/aarch64/bits/kernel_types.h
new file mode 100644
index 0000000..832b176
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/kernel_types.h
@@ -0,0 +1,42 @@ 
+/* Note that we use the exact same include guard #define names
+ * as asm/posix_types.h.  This will avoid gratuitous conflicts
+ * with the posix_types.h kernel header, and will ensure that
+ * our private content, and not the kernel header, will win.
+ *  -Erik
+ */
+#ifndef __ASM_GENERIC_POSIX_TYPES_H
+#define __ASM_GENERIC_POSIX_TYPES_H
+
+typedef unsigned long		__kernel_dev_t;
+typedef unsigned long		__kernel_ino_t;
+typedef unsigned int		__kernel_mode_t;
+typedef unsigned int		__kernel_nlink_t;
+typedef long			__kernel_off_t;
+typedef int			__kernel_pid_t;
+typedef int 			__kernel_ipc_pid_t;
+typedef unsigned int		__kernel_uid_t;
+typedef unsigned int		__kernel_gid_t;
+typedef unsigned long		__kernel_size_t;
+typedef long			__kernel_ssize_t;
+typedef long			__kernel_ptrdiff_t;
+typedef long			__kernel_time_t;
+typedef long			__kernel_suseconds_t;
+typedef long			__kernel_clock_t;
+typedef int			__kernel_daddr_t;
+typedef char *			__kernel_caddr_t;
+typedef unsigned short		__kernel_uid16_t;
+typedef unsigned short		__kernel_gid16_t;
+typedef unsigned int		__kernel_uid32_t;
+typedef unsigned int		__kernel_gid32_t;
+typedef unsigned short 		__kernel_old_uid_t;
+typedef unsigned short 		__kernel_old_gid_t;
+typedef long long		__kernel_loff_t;
+typedef unsigned int		__kernel_old_dev_t;
+typedef long			__kernel_long_t;
+typedef unsigned long		__kernel_ulong_t;
+
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+
+#endif /* __ASM_GENERIC_POSIX_TYPES_H */
diff --git a/libc/sysdeps/linux/aarch64/bits/setjmp.h b/libc/sysdeps/linux/aarch64/bits/setjmp.h
new file mode 100644
index 0000000..fff8616
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/setjmp.h
@@ -0,0 +1,33 @@ 
+/* Copyright (C) 1997-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 _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#ifndef _ASM
+/* Jump buffer contains:
+   x19-x28, x29(fp), x30(lr), (x31)sp, d8-d15.  Other registers are not
+   saved.  */
+__extension__ typedef unsigned long long __jmp_buf [22];
+
+#endif
+#endif
diff --git a/libc/sysdeps/linux/aarch64/bits/stackinfo.h b/libc/sysdeps/linux/aarch64/bits/stackinfo.h
new file mode 100644
index 0000000..78f3262
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/stackinfo.h
@@ -0,0 +1,33 @@ 
+/* Copyright (C) 2001-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/>.  */
+
+/* This file contains a bit of information about the stack allocation
+   of the processor.  */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H	1
+
+#include <elf.h>
+
+/* On AArch64 the stack grows down.  */
+#define _STACK_GROWS_DOWN	1
+
+/* Default to a non-executable stack. */
+#define DEFAULT_STACK_PERMS (PF_R|PF_W)
+
+#endif	/* stackinfo.h */
diff --git a/libc/sysdeps/linux/aarch64/bits/syscalls.h b/libc/sysdeps/linux/aarch64/bits/syscalls.h
new file mode 100644
index 0000000..3c0d840
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/syscalls.h
@@ -0,0 +1,106 @@ 
+/*
+ * Copyright (C) 2016 by Waldemar Brodkorb <wbx@uclibc-ng.org>
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ * ported from GNU libc
+ */
+
+/* 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 _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
+#endif
+
+#ifndef __ASSEMBLER__
+#include <errno.h>
+
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...)	\
+  ({ long _sys_result;					\
+     {							\
+	register long _x8 __asm__ ("x8");		\
+	LOAD_ARGS_##nr (args)				\
+	_x8 = (name);					\
+							\
+        __asm__ volatile (				\
+		"svc       0       // syscall " # name  \
+		: "=r" (_x0) : "r"(_x8) ASM_ARGS_##nr  	\
+		: "memory"); 				\
+							\
+	_sys_result = _x0;				\
+     } 							\
+     _sys_result; })
+
+/* Macros for setting up inline __asm__ input regs */
+# define ASM_ARGS_0
+# define ASM_ARGS_1	, "r" (_x0)
+# define ASM_ARGS_2	ASM_ARGS_1, "r" (_x1)
+# define ASM_ARGS_3	ASM_ARGS_2, "r" (_x2)
+# define ASM_ARGS_4	ASM_ARGS_3, "r" (_x3)
+# define ASM_ARGS_5	ASM_ARGS_4, "r" (_x4)
+# define ASM_ARGS_6	ASM_ARGS_5, "r" (_x5)
+# define ASM_ARGS_7	ASM_ARGS_6, "r" (_x6)
+
+/* Macros for converting sys-call wrapper args into sys call args */
+# define LOAD_ARGS_0()				\
+  register long _x0 __asm__ ("x0");
+# define LOAD_ARGS_1(x0)			\
+  long _x0tmp;					\
+  LOAD_ARGS_0 ()				\
+  _x0tmp = (long) (x0);				\
+  _x0 = _x0tmp;
+# define LOAD_ARGS_2(x0, x1)			\
+  register long _x1 __asm__ ("x1");		\
+  long _x1tmp;					\
+  LOAD_ARGS_1 (x0)				\
+  _x1tmp = (long) (x1);				\
+  _x1 = _x1tmp;
+# define LOAD_ARGS_3(x0, x1, x2)		\
+  register long _x2 __asm__ ("x2");		\
+  long _x2tmp;					\
+  LOAD_ARGS_2 (x0, x1)				\
+  _x2tmp = (long) (x2);				\
+  _x2 = _x2tmp;
+# define LOAD_ARGS_4(x0, x1, x2, x3)		\
+  register long _x3 __asm__ ("x3");		\
+  long _x3tmp;					\
+  LOAD_ARGS_3 (x0, x1, x2)			\
+  _x3tmp = (long) (x3);				\
+  _x3 = _x3tmp;
+# define LOAD_ARGS_5(x0, x1, x2, x3, x4)	\
+  register long _x4 __asm__ ("x4");		\
+  long _x4tmp;					\
+  LOAD_ARGS_4 (x0, x1, x2, x3)			\
+  _x4tmp = (long) (x4);				\
+  _x4 = _x4tmp;
+# define LOAD_ARGS_6(x0, x1, x2, x3, x4, x5)	\
+  register long _x5 __asm__ ("x5");		\
+  long _x5tmp;					\
+  LOAD_ARGS_5 (x0, x1, x2, x3, x4)		\
+  _x5tmp = (long) (x5);				\
+  _x5 = _x5tmp;
+# define LOAD_ARGS_7(x0, x1, x2, x3, x4, x5, x6)\
+  register long _x6 __asm__ ("x6");		\
+  long _x6tmp;					\
+  LOAD_ARGS_6 (x0, x1, x2, x3, x4, x5)		\
+  _x6tmp = (long) (x6);				\
+  _x6 = _x6tmp;
+
+#endif /* ! __ASSEMBLER__  */
+#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/aarch64/bits/uClibc_arch_features.h b/libc/sysdeps/linux/aarch64/bits/uClibc_arch_features.h
new file mode 100644
index 0000000..7cae090
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/uClibc_arch_features.h
@@ -0,0 +1,38 @@ 
+/*
+ * Track misc arch-specific features that aren't config options
+ */
+
+#ifndef _BITS_UCLIBC_ARCH_FEATURES_H
+#define _BITS_UCLIBC_ARCH_FEATURES_H
+
+/* instruction used when calling abort() to kill yourself */
+#define __UCLIBC_ABORT_INSTRUCTION__ "bl abort"
+
+/* can your target use syscall6() for mmap ? */
+#define __UCLIBC_MMAP_HAS_6_ARGS__
+
+/* does your target have a broken create_module() ? */
+#define __UCLIBC_BROKEN_CREATE_MODULE__
+
+/* does your target have to worry about older [gs]etrlimit() ? */
+#undef __UCLIBC_HANDLE_OLDER_RLIMIT__
+
+/* does your target have an asm .set ? */
+#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__
+
+/* define if target supports .weak */
+#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__
+
+/* define if target supports .weakext */
+#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__
+
+/* define if target supports CFI pseudo ops */
+#define __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__
+
+/* define if target supports IEEE signed zero floats */
+#define __UCLIBC_HAVE_SIGNED_ZERO__
+
+/* only weird assemblers generally need this */
+#undef __UCLIBC_ASM_LINE_SEP__
+
+#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */
diff --git a/libc/sysdeps/linux/aarch64/bits/uClibc_page.h b/libc/sysdeps/linux/aarch64/bits/uClibc_page.h
new file mode 100755
index 0000000..4f92abc
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/uClibc_page.h
@@ -0,0 +1,25 @@ 
+/*
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+#ifndef _UCLIBC_PAGE_H
+#define _UCLIBC_PAGE_H
+
+/*
+ * AARCH64 supports 4k, 16k, 64k pages (build time).
+ */
+
+#include <features.h>
+
+#if defined(__CONFIG_AARCH64_PAGE_SIZE_64K__)
+#define PAGE_SHIFT		16
+#elif defined(__CONFIG_AARCH64_PAGE_SIZE_16K__)
+#define PAGE_SHIFT		14
+#else
+#define PAGE_SHIFT		12
+#endif
+
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#endif /* _UCLIBC_PAGE_H */
diff --git a/libc/sysdeps/linux/aarch64/bits/wordsize.h b/libc/sysdeps/linux/aarch64/bits/wordsize.h
new file mode 100644
index 0000000..0944f9e
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/wordsize.h
@@ -0,0 +1,18 @@ 
+/* Copyright (C) 1999-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/>.  */
+
+#define __WORDSIZE	64
diff --git a/libc/sysdeps/linux/xtensa/bsd-_setjmp.S b/libc/sysdeps/linux/aarch64/bsd-_setjmp.S
similarity index 100%
copy from libc/sysdeps/linux/xtensa/bsd-_setjmp.S
copy to libc/sysdeps/linux/aarch64/bsd-_setjmp.S
diff --git a/libc/sysdeps/linux/xtensa/bsd-setjmp.S b/libc/sysdeps/linux/aarch64/bsd-setjmp.S
similarity index 100%
copy from libc/sysdeps/linux/xtensa/bsd-setjmp.S
copy to libc/sysdeps/linux/aarch64/bsd-setjmp.S
diff --git a/libc/sysdeps/linux/aarch64/clone.S b/libc/sysdeps/linux/aarch64/clone.S
new file mode 100644
index 0000000..7437eec
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/clone.S
@@ -0,0 +1,85 @@ 
+/* Copyright (C) 1996-2017 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>
+
+#define CLONE_VM_BIT      8
+#define CLONE_VM          (1 << CLONE_VM_BIT)
+
+#define CLONE_THREAD_BIT  16
+#define CLONE_THREAD      (1 << CLONE_THREAD_BIT)
+
+/* int clone(int (*fn)(void *arg),            x0
+	     void *child_stack,               x1
+	     int flags,                       x2
+	     void *arg,                       x3
+	     pid_t *ptid,                     x4
+	     struct user_desc *tls,           x5
+             pid_t *ctid);                    x6
+ */
+        .text
+ENTRY(__clone)
+	/* Save args for the child.  */
+	mov	x10, x0
+	mov	x11, x2
+	mov	x12, x3
+
+	/* Sanity check args.  */
+	mov	x0, #-EINVAL
+	cbz	x10, .Lsyscall_error
+	cbz	x1, .Lsyscall_error
+
+	/* Do the system call.  */
+	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
+	mov	x0, x2                  /* flags  */
+	/* New sp is already in x1.  */
+	mov	x2, x4			/* ptid  */
+	mov	x3, x5			/* tls  */
+	mov	x4, x6			/* ctid  */
+	mov	x8, #SYS_ify(clone)
+	svc	0x0
+
+	cmp	x0, #0
+	beq	thread_start
+	blt	.Lsyscall_error
+	RET
+PSEUDO_END (__clone)
+
+	.align 4
+	.type thread_start, %function
+thread_start:
+	cfi_startproc
+	cfi_undefined (x30)
+	mov	x29, 0
+
+	/* Pick the function arg and execute.  */
+	mov	x0, x12
+	blr	x10
+
+	/* We are done, pass the return value through x0.  */
+	b	HIDDEN_JUMPTARGET(_exit)
+	cfi_endproc
+	.size thread_start, .-thread_start
+
+libc_hidden_def (__clone)
+weak_alias (__clone, clone)
diff --git a/libc/sysdeps/linux/aarch64/crt1.S b/libc/sysdeps/linux/aarch64/crt1.S
new file mode 100644
index 0000000..09d0327
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/crt1.S
@@ -0,0 +1,89 @@ 
+/* Copyright (C) 1995-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/>.  */
+
+/* This is the canonical entry point, usually the first thing in the text
+   segment.
+
+   Note that the code in the .init section has already been run.
+   This includes _init and _libc_init
+
+
+   At this entry point, most registers' values are unspecified, except:
+
+   x0		Contains a function pointer to be registered with `atexit'.
+		This is how the dynamic linker arranges to have DT_FINI
+		functions called for shared libraries that have been loaded
+		before this code runs.
+
+   sp		The stack contains the arguments and environment:
+		0(sp)			argc
+		8(sp)			argv[0]
+		...
+		(8*argc)(sp)		NULL
+		(8*(argc+1))(sp)	envp[0]
+		...
+					NULL
+ */
+
+	.text
+	.globl _start
+	.type _start,#function
+_start:
+	/* Create an initial frame with 0 LR and FP */
+	mov	x29, #0
+	mov	x30, #0
+
+	/* Setup _fini in argument register */
+	mov	x5, x0
+
+	/* Load argc and a pointer to argv */
+	ldr	x1, [sp, #0]
+	add	x2, sp, #8
+
+	/* Setup stack limit in argument register */
+	mov	x6, sp
+
+#ifdef __PIC__
+        adrp    x0, :got:main
+	ldr     x0, [x0, #:got_lo12:main]
+
+        adrp    x3, :got:_init
+	ldr     x3, [x3, #:got_lo12:_init]
+
+        adrp    x4, :got:_fini
+	ldr     x4, [x4, #:got_lo12:_fini]
+#else
+	/* Set up the other arguments in registers */
+	ldr	x0, =main
+	ldr	x3, =_init
+	ldr	x4, =_fini
+#endif
+
+	/* Let the libc call main and exit with its return code.  */
+	bl	__uClibc_main
+
+	/* should never get here....*/
+	bl	abort
+
+	/* Define a symbol for the first piece of initialized data.  */
+	.data
+	.globl __data_start
+__data_start:
+	.long 0
+	.weak data_start
+	data_start = __data_start
diff --git a/libc/sysdeps/linux/aarch64/crti.S b/libc/sysdeps/linux/aarch64/crti.S
new file mode 100644
index 0000000..49c57e4
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/crti.S
@@ -0,0 +1,59 @@ 
+/* Special .init and .fini section support for AArch64.
+   Copyright (C) 1995-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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file. (The GNU Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
+
+   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/>.  */
+
+/* crti.S puts a function prologue at the beginning of the .init and
+   .fini sections and defines global symbols for those addresses, so
+   they can be called as functions.  The symbols _init and _fini are
+   magic and cause the linker to emit DT_INIT and DT_FINI.  */
+
+#include <libc-symbols.h>
+
+
+	.section .init,"ax",%progbits
+	.align	2
+	.global	_init
+	.type	_init, %function
+_init:
+	stp	x29, x30, [sp, -16]!
+	mov	x29, sp
+
+	.section	.fini,"ax",%progbits
+	.align	2
+	.global	_fini
+	.type	_fini, %function
+_fini:
+	stp	x29, x30, [sp, -16]!
+	mov	x29, sp
diff --git a/libc/sysdeps/linux/aarch64/crtn.S b/libc/sysdeps/linux/aarch64/crtn.S
new file mode 100644
index 0000000..33d5f3d
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/crtn.S
@@ -0,0 +1,46 @@ 
+/* Special .init and .fini section support for AArch64.
+   Copyright (C) 1995-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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file. (The GNU Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
+
+   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/>.  */
+
+/* crtn.S puts function epilogues in the .init and .fini sections
+   corresponding to the prologues in crti.S. */
+
+	.section .init,"ax",%progbits
+	ldp	x29, x30, [sp], 16
+	RET
+
+	.section .fini,"ax",%progbits
+	ldp	x29, x30, [sp], 16
+	RET
diff --git a/libc/sysdeps/linux/aarch64/jmpbuf-offsets.h b/libc/sysdeps/linux/aarch64/jmpbuf-offsets.h
new file mode 100644
index 0000000..ab00cef
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/jmpbuf-offsets.h
@@ -0,0 +1,57 @@ 
+/* Copyright (C) 2006-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/>.  */
+
+#define JB_X19            0
+#define JB_X20            1
+#define JB_X21            2
+#define JB_X22            3
+#define JB_X23            4
+#define JB_X24            5
+#define JB_X25            6
+#define JB_X26            7
+#define JB_X27            8
+#define JB_X28            9
+#define JB_X29           10
+#define JB_LR            11
+#define JB_SP		 13
+
+#define JB_D8		 14
+#define JB_D9		 15
+#define JB_D10		 16
+#define JB_D11		 17
+#define JB_D12		 18
+#define JB_D13		 19
+#define JB_D14		 20
+#define JB_D15		 21
+
+#ifndef  __ASSEMBLER__
+#include <setjmp.h>
+#include <stdint.h>
+#include <sysdep.h>
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf jmpbuf)
+{
+  uintptr_t sp = jmpbuf[JB_SP];
+  return sp;
+}
+#endif
+
+/* Helper for generic ____longjmp_chk(). */
+#define JB_FRAME_ADDRESS(buf) \
+  ((void *) _jmpbuf_sp (buf))
diff --git a/libc/sysdeps/linux/aarch64/jmpbuf-unwind.h b/libc/sysdeps/linux/aarch64/jmpbuf-unwind.h
new file mode 100644
index 0000000..77bad1d
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/jmpbuf-unwind.h
@@ -0,0 +1,34 @@ 
+/* 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 <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+   containing a local variable at ADDRESS.  */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+  ((void *) (address) < (void *) demangle (jmpbuf[JB_SP]))
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(jmpbuf, context, adj) \
+  _JMPBUF_UNWINDS_ADJ (jmpbuf, (void *) _Unwind_GetCFA (context), adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
diff --git a/libc/sysdeps/linux/aarch64/setjmp.S b/libc/sysdeps/linux/aarch64/setjmp.S
new file mode 100644
index 0000000..b3d6162
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/setjmp.S
@@ -0,0 +1,59 @@ 
+/* Copyright (C) 1997-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 <jmpbuf-offsets.h>
+
+        /* Keep traditional entry points in with sigsetjmp(). */
+ENTRY (setjmp)
+	mov	x1, #1
+	b	1f
+END (setjmp)
+
+ENTRY (_setjmp)
+	mov	x1, #0
+	b	1f
+END (_setjmp)
+libc_hidden_def (_setjmp)
+
+ENTRY (__sigsetjmp)
+
+1:
+	stp	x19, x20, [x0, #JB_X19<<3]
+	stp	x21, x22, [x0, #JB_X21<<3]
+	stp	x23, x24, [x0, #JB_X23<<3]
+	stp	x25, x26, [x0, #JB_X25<<3]
+	stp	x27, x28, [x0, #JB_X27<<3]
+
+	stp	x29, x30, [x0, #JB_X29<<3]
+
+	/* setjmp probe takes 3 arguments, address of jump buffer
+	   first argument (8@x0), return value second argument (-4@x1),
+	   and target address (8@x30), respectively.  */
+	//LIBC_PROBE (setjmp, 3, 8@x0, -4@x1, 8@x30)
+	stp	 d8,  d9, [x0, #JB_D8<<3]
+	stp	d10, d11, [x0, #JB_D10<<3]
+	stp	d12, d13, [x0, #JB_D12<<3]
+	stp	d14, d15, [x0, #JB_D14<<3]
+	mov	x2,  sp
+	str	x2,  [x0, #JB_SP<<3]
+
+	b	C_SYMBOL_NAME(__sigjmp_save)
+
+END (__sigsetjmp)
+hidden_def (__sigsetjmp)
diff --git a/libc/sysdeps/linux/aarch64/sys/procfs.h b/libc/sysdeps/linux/aarch64/sys/procfs.h
new file mode 100644
index 0000000..7e408c3
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/sys/procfs.h
@@ -0,0 +1,123 @@ 
+/* 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/>.  */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H	1
+
+/* This is somewhat modelled after the file of the same name on SVR4
+   systems.  It provides a definition of the core file format for ELF
+   used on Linux.  It doesn't have anything to do with the /proc file
+   system, even though Linux has one.
+
+   Anyway, the whole purpose of this file is for GDB and GDB only.
+   Don't read too much into it.  Don't use it for anything other than
+   GDB unless you know what you are doing.  */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+/* Type for a general-purpose register.  */
+typedef unsigned long elf_greg_t;
+
+/* And the whole bunch of them.  We could have used `struct
+   pt_regs' directly in the typedef, but tradition says that
+   the register set is an array, which does have some peculiar
+   semantics, so leave it that way.  */
+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* Register set for the floating-point registers.  */
+typedef struct user_fpsimd_struct elf_fpregset_t;
+
+/* Signal info.  */
+struct elf_siginfo
+  {
+    int si_signo;			/* Signal number.  */
+    int si_code;			/* Extra code.  */
+    int si_errno;			/* Errno.  */
+  };
+
+/* Definitions to generate Intel SVR4-like core files.  These mostly
+   have the same names as the SVR4 types with "elf_" tacked on the
+   front to prevent clashes with Linux definitions, and the typedef
+   forms have been avoided.  This is mostly like the SVR4 structure,
+   but more Linuxy, with things that Linux does not support and which
+   GDB doesn't really use excluded.  */
+
+struct elf_prstatus
+  {
+    struct elf_siginfo pr_info;		/* Info associated with signal.  */
+    short int pr_cursig;		/* Current signal.  */
+    unsigned long int pr_sigpend;	/* Set of pending signals.  */
+    unsigned long int pr_sighold;	/* Set of held signals.  */
+    __pid_t pr_pid;
+    __pid_t pr_ppid;
+    __pid_t pr_pgrp;
+    __pid_t pr_sid;
+    struct timeval pr_utime;		/* User time.  */
+    struct timeval pr_stime;		/* System time.  */
+    struct timeval pr_cutime;		/* Cumulative user time.  */
+    struct timeval pr_cstime;		/* Cumulative system time.  */
+    elf_gregset_t pr_reg;		/* GP registers.  */
+    int pr_fpvalid;			/* True if math copro being used.  */
+  };
+
+
+#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
+
+struct elf_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long int pr_flag;		/* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* The rest of this file provides the types for emulation of the
+   Solaris <proc_service.h> interfaces that should be implemented by
+   users of libthread_db.  */
+
+/* Addresses.  */
+typedef void *psaddr_t;
+
+/* Register sets.  Linux has different names.  */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+   therefore have only one PID type.  */
+typedef __pid_t lwpid_t;
+
+/* Process status and info.  In the end we do provide typedefs for them.  */
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif	/* sys/procfs.h */
diff --git a/libc/sysdeps/linux/aarch64/sys/ucontext.h b/libc/sysdeps/linux/aarch64/sys/ucontext.h
new file mode 100644
index 0000000..d174588
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/sys/ucontext.h
@@ -0,0 +1,53 @@ 
+/* Copyright (C) 1998-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/>.  */
+
+/* System V/AArch64 ABI compliant context switching support.  */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H	1
+
+#include <features.h>
+#include <signal.h>
+
+#include <sys/procfs.h>
+
+typedef elf_greg_t greg_t;
+
+/* Container for all general registers.  */
+typedef elf_gregset_t gregset_t;
+
+/* Structure to describe FPU registers.  */
+typedef elf_fpregset_t	fpregset_t;
+
+/* Context to describe whole processor state.  This only describes
+   the core registers; coprocessor registers get saved elsewhere
+   (e.g. in uc_regspace, or somewhere unspecified on the stack
+   during non-RT signal handlers).  */
+typedef struct sigcontext mcontext_t;
+
+/* Userlevel context.  */
+typedef struct ucontext
+  {
+    unsigned long uc_flags;
+    struct ucontext *uc_link;
+    stack_t uc_stack;
+    __sigset_t uc_sigmask;
+    mcontext_t uc_mcontext;
+  } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/linux/aarch64/sys/user.h b/libc/sysdeps/linux/aarch64/sys/user.h
new file mode 100644
index 0000000..f6fc361
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/sys/user.h
@@ -0,0 +1,37 @@ 
+/* Copyright (C) 2009-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 _SYS_USER_H
+#define _SYS_USER_H	1
+
+struct user_regs_struct
+{
+  unsigned long long regs[31];
+  unsigned long long sp;
+  unsigned long long pc;
+  unsigned long long pstate;
+};
+
+struct user_fpsimd_struct
+{
+  __uint128_t  vregs[32];
+  unsigned int fpsr;
+  unsigned int fpcr;
+};
+
+#endif
diff --git a/libc/sysdeps/linux/aarch64/syscall.S b/libc/sysdeps/linux/aarch64/syscall.S
new file mode 100644
index 0000000..ac609a3
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/syscall.S
@@ -0,0 +1,42 @@ 
+/* Copyright (C) 2005-2017 Free Software Foundation, Inc.
+
+   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>
+
+/* syscall (int nr, ...)
+
+   AArch64 system calls take between 0 and 7 arguments. On entry here nr
+   is in w0 and any other system call arguments are in register x1..x7.
+
+   For kernel entry we need to move the system call nr to x8 then
+   load the remaining arguments to register. */
+
+ENTRY (syscall)
+	uxtw	x8, w0
+	mov	x0, x1
+	mov	x1, x2
+	mov	x2, x3
+	mov	x3, x4
+	mov	x4, x5
+	mov	x5, x6
+	mov	x6, x7
+	svc	0x0
+	cmn	x0, #4095
+	b.cs	1f
+	RET
+1:
+	b	SYSCALL_ERROR
+PSEUDO_END (syscall)
diff --git a/libc/sysdeps/linux/aarch64/sysdep.h b/libc/sysdeps/linux/aarch64/sysdep.h
new file mode 100644
index 0000000..cc2ffcb
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/sysdep.h
@@ -0,0 +1,140 @@ 
+/* Copyright (C) 2005-2016 Free Software Foundation, Inc.
+
+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 _LINUX_AARCH64_SYSDEP_H
+#define _LINUX_AARCH64_SYSDEP_H 1
+
+#include <common/sysdep.h>
+#include <sys/syscall.h>
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL.  */
+#ifndef __ASSEMBLER__
+#include <errno.h>
+#endif
+
+/* For Linux we can use the system call table in the header file
+/usr/include/asm/unistd.h
+of the kernel.  But these symbols do not follow the SYS_* syntax
+so we have to redefine the `SYS_ify' macro here.  */
+#undef SYS_ify
+#define SYS_ify(syscall_name)	(__NR_##syscall_name)
+
+#ifdef __ASSEMBLER__
+
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+/* Local label name for asm code.  */
+#ifndef L
+# define L(name)         .L##name
+#endif
+
+/* Define an entry point visible from C.  */
+#define ENTRY(name)						\
+  .globl C_SYMBOL_NAME(name);					\
+  .type C_SYMBOL_NAME(name),%function;				\
+  .align 4;							\
+  C_LABEL(name)							\
+  cfi_startproc;
+
+/* Define an entry point visible from C.  */
+#define ENTRY_ALIGN(name, align)				\
+  .globl C_SYMBOL_NAME(name);					\
+  .type C_SYMBOL_NAME(name),%function;				\
+  .p2align align;						\
+  C_LABEL(name)							\
+  cfi_startproc;
+
+#undef	END
+#define END(name)						\
+  cfi_endproc;							\
+  ASM_SIZE_DIRECTIVE(name)
+
+/* Linux uses a negative return value to indicate syscall errors,
+unlike most Unices, which use the condition codes' carry flag.
+
+Since version 2.1 the return value of a system call might be
+negative even if the call succeeded.  E.g., the `lseek' system call
+might return a large offset.  Therefore we must not anymore test
+for < 0, but test for a real error by making sure the value in R0
+is a real error number.  Linus said he will make sure the no syscall
+returns a value in -1 .. -4095 as a valid result so we can safely
+test with -4095.  */
+
+# undef	PSEUDO
+# define PSEUDO(name, syscall_name, args)			\
+.text;								\
+ENTRY (name);							\
+DO_CALL (syscall_name, args);					\
+cmn x0, #4095;							\
+b.cs .Lsyscall_error;
+
+# undef	PSEUDO_END
+# define PSEUDO_END(name)					\
+SYSCALL_ERROR_HANDLER						\
+END (name)
+
+# undef	PSEUDO_NOERRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args)		\
+.text;								\
+ENTRY (name);							\
+DO_CALL (syscall_name, args);
+
+# undef	PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name)				\
+END (name)
+
+# define ret_NOERRNO ret
+
+/* The function has to return the error code.  */
+# undef	PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args)		\
+.text;								\
+ENTRY (name)							\
+DO_CALL (syscall_name, args);					\
+neg x0, x0
+
+# undef	PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name) \
+END (name)
+
+# define ret_ERRVAL ret
+
+#if defined NOT_IN_libc
+# define SYSCALL_ERROR  .Lsyscall_error
+# define SYSCALL_ERROR_HANDLER					\
+.Lsyscall_error:						\
+	adrp	x1, :gottprel:errno;				\
+	neg	w2, w0;						\
+	ldr	x1, [x1, :gottprel_lo12:errno];			\
+	mrs	x3, tpidr_el0;					\
+	mov	x0, -1;						\
+	str	w2, [x1, x3];					\
+	ret;
+#else
+# define SYSCALL_ERROR __syscall_error
+# define SYSCALL_ERROR_HANDLER                                  \
+.Lsyscall_error:                                                \
+	b	__syscall_error;
+#endif
+
+# undef	DO_CALL
+# define DO_CALL(syscall_name, args)				\
+mov x8, SYS_ify (syscall_name);					\
+svc 0
+
+#endif	/* __ASSEMBLER__ */
+
+#endif /* linux/aarch64/sysdep.h */
diff --git a/libc/sysdeps/linux/aarch64/vfork.S b/libc/sysdeps/linux/aarch64/vfork.S
new file mode 100644
index 0000000..9a8fd46
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/vfork.S
@@ -0,0 +1,37 @@ 
+/* Copyright (C) 1999-2017 Free Software Foundation, Inc.
+
+   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.  */
+
+ENTRY (vfork)
+
+	mov	x0, #0x4111	/* CLONE_VM | CLONE_VFORK | SIGCHLD */
+	mov	x1, sp
+	DO_CALL (clone, 2)
+
+	cmn	x0, #4095
+	b.cs    .Lsyscall_error
+	RET
+
+PSEUDO_END (vfork)
+libc_hidden_def (vfork)
diff --git a/libc/sysdeps/linux/common-generic/bits/stat.h b/libc/sysdeps/linux/common-generic/bits/stat.h
index 945c408..0f66fc0 100644
--- a/libc/sysdeps/linux/common-generic/bits/stat.h
+++ b/libc/sysdeps/linux/common-generic/bits/stat.h
@@ -30,45 +30,6 @@ 
  */
 struct stat
   {
-#ifndef __USE_FILE_OFFSET64
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-    unsigned long st_dev;			/* Device.  */
-    unsigned long __pad1;
-    unsigned long st_ino;			/* 32bit file serial number.	*/
-    unsigned long __pad2;
-    unsigned int st_mode;			/* File mode.  */
-    unsigned int st_nlink;			/* Link count.  */
-    unsigned int st_uid;			/* User ID of the file's owner.	*/
-    unsigned int st_gid;			/* Group ID of the file's group.*/
-    unsigned long st_rdev;			/* Device number, if device.  */
-    unsigned long __pad3;
-    unsigned long long __pad4;
-    long st_size;				/* SIze of file, in bytes.  */
-    long __pad5;
-    int st_blksize;				/* Optimal block size for I/O. */
-    int __pad6;
-    long st_blocks;				/* Number 512-byte blocks allocated */
-    long __pad7;
-# else
-    unsigned long __pad1;
-    unsigned long st_dev;			/* Device. */
-    unsigned long __pad2;
-    unsigned long st_ino;			/* 32bit file serial number. */
-    unsigned int st_mode;			/* File mode.  */
-    unsigned int st_nlink;			/* Link count.  */
-    unsigned int st_uid;			/* User ID of the file's owner.	*/
-    unsigned int st_gid;			/* Group ID of the file's group.*/
-    unsigned long __pad3;
-    unsigned long st_rdev;			/* Device number, if device.  */
-    unsigned long long __pad4;
-    long __pad5;
-    long st_size;				/* Size of file, in bytes. */
-    int st_blksize;				/* Optimal block size for I/O. */
-    int __pad6;
-    long __pad7;
-    long st_blocks;				/* Number 512-byte blocks allocated */
-# endif /* __LITTLE_ENDIAN */
-#else
     unsigned long long st_dev;			/* Device. */
     unsigned long long st_ino;			/* 32bit file serial number. */
     unsigned int st_mode;			/* File mode.  */
@@ -81,7 +42,6 @@  struct stat
     int st_blksize;				/* Optimal block size for I/O. */
     int __pad2;
     long long st_blocks;			/* Number 512-byte blocks allocated */
-#endif
 #ifdef __USE_MISC
     /* Nanosecond resolution timestamps are stored in a format
        equivalent to 'struct timespec'.  This is the type used
@@ -96,21 +56,12 @@  struct stat
 # define st_mtime st_mtim.tv_sec
 # define st_ctime st_ctim.tv_sec
 #else
-# ifndef __USE_FILE_OFFSET64
-    long st_atime;				/* Time of last access. */
-    unsigned long st_atime_nsec;
-    long st_mtime;				/* Time of last modification. */
-    unsigned long st_mtime_nsec;
-    long st_ctime;				/* Time of last status change. */
-    unsigned long st_ctime_nsec;
-# else
     int st_atime;				/* Time of last access. */
     unsigned int st_atime_nsec;
     int st_mtime;				/* Time of last modification. */
     unsigned int st_mtime_nsec;
     int st_ctime;				/* Time of last status change. */
     unsigned int st_ctime_nsec;
-# endif
 #endif
     unsigned int __unused4;
     unsigned int __unused5;
diff --git a/libc/sysdeps/linux/common/fstat.c b/libc/sysdeps/linux/common/fstat.c
index eae3c80..ac77eb2 100644
--- a/libc/sysdeps/linux/common/fstat.c
+++ b/libc/sysdeps/linux/common/fstat.c
@@ -7,25 +7,26 @@ 
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#include <sys/syscall.h>
+#include <features.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <sys/syscall.h>
+
 #include "xstatconv.h"
 
 #if defined __NR_fstat64 && !defined __NR_fstat
 int fstat(int fd, struct stat *buf)
 {
-	int result = INLINE_SYSCALL(fstat64, 2, fd, buf);
-	if (result == 0) {
-		/* Did we overflow? */
-		if (buf->__pad1 || buf->__pad2 || buf->__pad3
-		    || buf->__pad4 || buf->__pad5
-		    || buf->__pad6 || buf->__pad7) {
-			__set_errno(EOVERFLOW);
-			return -1;
-		}
-	}
-	return result;
+	return INLINE_SYSCALL(fstat64, 2, fd, buf);
+}
+libc_hidden_def(fstat)
+
+#elif __WORDSIZE == 64 && defined __NR_newfstatat
+#include <fcntl.h>
+
+int fstat(int fd, struct stat *buf)
+{
+	return INLINE_SYSCALL(fstat, 2, fd, buf);
 }
 libc_hidden_def(fstat)
 
@@ -55,10 +56,9 @@  int fstat(int fd, struct stat *buf)
 	return result;
 }
 libc_hidden_def(fstat)
+#endif
 
 # if ! defined __NR_fstat64
 strong_alias_untyped(fstat,fstat64)
 libc_hidden_def(fstat64)
-# endif
-
 #endif
diff --git a/libc/sysdeps/linux/common/fstatat.c b/libc/sysdeps/linux/common/fstatat.c
index 4006814..13673d7 100644
--- a/libc/sysdeps/linux/common/fstatat.c
+++ b/libc/sysdeps/linux/common/fstatat.c
@@ -26,15 +26,6 @@  int fstatat(int fd, const char *file, struct stat *buf, int flag)
 		__xstat32_conv(&kbuf, buf);
 # else
 	ret = INLINE_SYSCALL(fstatat64, 4, fd, file, buf, flag);
-	if (ret == 0) {
-		/* Did we overflow */
-		if (buf->__pad1 || buf->__pad2 || buf->__pad3
-		    || buf->__pad4 || buf->__pad5 || buf->__pad6
-		    || buf->__pad7) {
-			__set_errno(EOVERFLOW);
-			return -1;
-		}
-	}
 # endif /* __ARCH_HAS_DEPRECATED_SYSCALLS__ */
 	return ret;
 }
diff --git a/libc/sysdeps/linux/common/lstat.c b/libc/sysdeps/linux/common/lstat.c
index 143cc19..cef9b46 100644
--- a/libc/sysdeps/linux/common/lstat.c
+++ b/libc/sysdeps/linux/common/lstat.c
@@ -20,6 +20,15 @@  int lstat(const char *file_name, struct stat *buf)
 }
 libc_hidden_def(lstat)
 
+#elif __WORDSIZE == 64 && defined __NR_newfstatat
+# include <fcntl.h>
+
+int lstat(const char *file_name, struct stat *buf)
+{
+	return fstatat(AT_FDCWD, file_name, buf, AT_SYMLINK_NOFOLLOW);
+}
+libc_hidden_def(lstat)
+
 /* For systems which have both, prefer the old one */
 #else
 # include "xstatconv.h"
diff --git a/libc/sysdeps/linux/common/lstat64.c b/libc/sysdeps/linux/common/lstat64.c
index c43e53e..76637b5 100644
--- a/libc/sysdeps/linux/common/lstat64.c
+++ b/libc/sysdeps/linux/common/lstat64.c
@@ -9,11 +9,19 @@ 
 
 #include <_lfs_64.h>
 #include <sys/syscall.h>
+#include <unistd.h>
+#include <sys/stat.h>
 
-# include <unistd.h>
-# include <sys/stat.h>
+#if defined __NR_fstatat64 && !defined __NR_lstat
+# include <fcntl.h>
+
+int lstat64(const char *file_name, struct stat64 *buf)
+{
+	return fstatat64(AT_FDCWD, file_name, buf, AT_SYMLINK_NOFOLLOW);
+}
+libc_hidden_def(lstat64)
 
-#if defined __NR_fstatat64 && !defined __NR_lstat64
+#elif __WORDSIZE == 64 && defined __NR_newfstatat
 # include <fcntl.h>
 
 int lstat64(const char *file_name, struct stat64 *buf)
diff --git a/libc/sysdeps/linux/common/stat.c b/libc/sysdeps/linux/common/stat.c
index b3c2a19..8e4542a 100644
--- a/libc/sysdeps/linux/common/stat.c
+++ b/libc/sysdeps/linux/common/stat.c
@@ -21,6 +21,14 @@  int stat(const char *file_name, struct stat *buf)
 	return fstatat(AT_FDCWD, file_name, buf, 0);
 }
 
+#elif __WORDSIZE == 64 && defined __NR_newfstatat
+# include <fcntl.h>
+
+int stat(const char *file_name, struct stat *buf)
+{
+	return fstatat64(AT_FDCWD, file_name, buf, 0);
+}
+
 #else
 # include "xstatconv.h"
 
diff --git a/libc/sysdeps/linux/i386/Makefile.arch b/libc/sysdeps/linux/i386/Makefile.arch
index 6c9eed8..3722fd5 100644
--- a/libc/sysdeps/linux/i386/Makefile.arch
+++ b/libc/sysdeps/linux/i386/Makefile.arch
@@ -6,8 +6,8 @@ 
 #
 
 CSRC-y := brk.c __syscall_error.c sigaction.c
-SSRC-y := __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \
-	sync_file_range.S syscall.S mmap.S mmap64.S vfork.S clone.S
+SSRC-y := __longjmp.S bsd-_setjmp.S bsd-setjmp.S clone.S mmap.S mmap64.S \
+	  setjmp.S sync_file_range.S syscall.S syscall6.S vfork.S
 
 SSRC-$(UCLIBC_HAS_ADVANCED_REALTIME) += posix_fadvise64.S
 SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.S setcontext.S getcontext.S swapcontext.S
diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h
index 5e92093..70ee825 100644
--- a/libc/sysdeps/linux/i386/bits/syscalls.h
+++ b/libc/sysdeps/linux/i386/bits/syscalls.h
@@ -14,7 +14,7 @@ 
 
 #include <errno.h>
 
-#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+#define INTERNAL_SYSCALL_NCS_X86_UPTOFIVE(name, err, nr, args...) \
 (__extension__ \
  ({ \
 	register unsigned int resultvar; \
@@ -30,7 +30,20 @@ 
   }) \
 )
 
-#if 1 /* defined __PIC__ || defined __pic__ */
+#define INTERNAL_SYSCALL_NCS_X86_0 INTERNAL_SYSCALL_NCS_X86_UPTOFIVE
+#define INTERNAL_SYSCALL_NCS_X86_1 INTERNAL_SYSCALL_NCS_X86_UPTOFIVE
+#define INTERNAL_SYSCALL_NCS_X86_2 INTERNAL_SYSCALL_NCS_X86_UPTOFIVE
+#define INTERNAL_SYSCALL_NCS_X86_3 INTERNAL_SYSCALL_NCS_X86_UPTOFIVE
+#define INTERNAL_SYSCALL_NCS_X86_4 INTERNAL_SYSCALL_NCS_X86_UPTOFIVE
+#define INTERNAL_SYSCALL_NCS_X86_5 INTERNAL_SYSCALL_NCS_X86_UPTOFIVE
+
+extern long __libc_i386_syscall6(unsigned long, ...)
+    __attribute__((__cdecl__));
+#define INTERNAL_SYSCALL_NCS_X86_6(name, err, nr, args...) \
+	__libc_i386_syscall6((unsigned long)name, args)
+
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+	INTERNAL_SYSCALL_NCS_X86_##nr(name, err, nr, args)
 
 /* This code avoids pushing/popping ebx as much as possible.
  * I think the main reason was that older GCCs had problems
@@ -95,7 +108,6 @@  __asm__ (
 #define LOADARGS_3  LOADARGS_1
 #define LOADARGS_4  LOADARGS_1
 #define LOADARGS_5  LOADARGS_1
-#define LOADARGS_6  LOADARGS_1 "push %%ebp\n\t" "movl %7, %%ebp\n\t"
 
 #define RESTOREARGS_0
 #define RESTOREARGS_1  "bpopl .L__X'%k2, %k2\n\t"
@@ -103,7 +115,6 @@  __asm__ (
 #define RESTOREARGS_3  RESTOREARGS_1
 #define RESTOREARGS_4  RESTOREARGS_1
 #define RESTOREARGS_5  RESTOREARGS_1
-#define RESTOREARGS_6  "pop %%ebp\n\t" RESTOREARGS_1
 
 #define ASMFMT_0()
 /* "acdSD" constraint would work too, but "SD" would use esi/edi and cause
@@ -123,59 +134,6 @@  __asm__ (
 	, "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
 #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
 	, "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
-#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
-	, "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "g" (arg6)
-
-#else /* !PIC */
-
-/* Simpler code which just uses "b" constraint to load ebx.
- * Seems to work with gc 4.2.x, and generates slightly smaller,
- * but slightly slower code. Example (time syscall):
- *
- * -	8b 4c 24 04            mov    0x4(%esp),%ecx
- * -	87 cb                  xchg   %ecx,%ebx
- * +	53                     push   %ebx
- * +	8b 5c 24 08            mov    0x8(%esp),%ebx
- *	b8 0d 00 00 00         mov    $0xd,%eax
- *	cd 80                  int    $0x80
- * -	87 cb                  xchg   %ecx,%ebx
- * +	5b                     pop    %ebx
- *	c3                     ret
- *
- * 2 bytes smaller, but uses stack via "push/pop ebx"
- */
-
-#define LOADARGS_0
-#define LOADARGS_1
-#define LOADARGS_2
-#define LOADARGS_3
-#define LOADARGS_4
-#define LOADARGS_5
-#define LOADARGS_6  "push %%ebp\n\t" "movl %7, %%ebp\n\t"
-
-#define RESTOREARGS_0
-#define RESTOREARGS_1
-#define RESTOREARGS_2
-#define RESTOREARGS_3
-#define RESTOREARGS_4
-#define RESTOREARGS_5
-#define RESTOREARGS_6  "pop %%ebp\n\t"
-
-#define ASMFMT_0()
-#define ASMFMT_1(arg1) \
-	, "b" (arg1)
-#define ASMFMT_2(arg1, arg2) \
-	, "b" (arg1), "c" (arg2)
-#define ASMFMT_3(arg1, arg2, arg3) \
-	, "b" (arg1), "c" (arg2), "d" (arg3)
-#define ASMFMT_4(arg1, arg2, arg3, arg4) \
-	, "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
-#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
-	, "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
-#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
-	, "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6)
-
-#endif /* !PIC */
 
 #endif /* __ASSEMBLER__ */
 #endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/i386/syscall6.S b/libc/sysdeps/linux/i386/syscall6.S
new file mode 100644
index 0000000..488f11a
--- /dev/null
+++ b/libc/sysdeps/linux/i386/syscall6.S
@@ -0,0 +1,67 @@ 
+/*-
+ * Copyright (c) 2017
+ *	mirabilos <m@mirbsd.org>
+ *
+ * Provided that these terms and disclaimer and all copyright notices
+ * are retained or reproduced in an accompanying document, permission
+ * is granted to deal in this work without restriction, including un-
+ * limited rights to use, publicly perform, distribute, sell, modify,
+ * merge, give away, or sublicence.
+ *
+ * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
+ * the utmost extent permitted by applicable law, neither express nor
+ * implied; without malicious intent or gross negligence. In no event
+ * may a licensor, author or contributor be held liable for indirect,
+ * direct, other damage, loss, or other issues arising in any way out
+ * of dealing in the work, even if advised of the possibility of such
+ * damage or existence of a defect, except proven that it results out
+ * of said person's immediate fault when using the work as intended.
+ */
+
+	.intel_syntax noprefix
+	.text
+
+/*-
+ * long __libc_i386_syscall6(unsigned long nr, ...) with six varargs
+ *
+ * C definition:
+ * extern long __libc_i386_syscall6(unsigned long, ...)
+ *    __attribute__((__cdecl__));
+ *
+ * Stack layout upon entry:		Offsets after saving:
+ * [esp + 28]	arg6	-> ebp !	[esp + 44]
+ * [esp + 24]	arg5	-> edi !	[esp + 40]
+ * [esp + 20]	arg4	-> esi !	[esp + 36]
+ * [esp + 16]	arg3	-> edx		[esp + 32]
+ * [esp + 12]	arg2	-> ecx		[esp + 28]
+ * [esp + 8]	arg1	-> ebx !	[esp + 24]
+ * [esp + 4]	nr	-> eax		[esp + 20]
+ * [esp]	return address		[esp + 16]
+ *					[esp + 12]	saved ebp
+ *					[esp + 8]	saved ebx
+ *					[esp + 4]	saved esi
+ *					[esp]		saved edi
+ */
+
+	.p2align 4,0x90
+	.globl	__libc_i386_syscall6
+	.type	__libc_i386_syscall6,@function
+__libc_i386_syscall6:
+	push	ebp
+	push	ebx
+	push	esi
+	push	edi
+	mov	eax,[esp + 20]	/* nr */
+	mov	ebx,[esp + 24]	/* arg1 */
+	mov	ecx,[esp + 28]	/* arg2 */
+	mov	edx,[esp + 32]	/* arg3 */
+	mov	esi,[esp + 36]	/* arg4 */
+	mov	edi,[esp + 40]	/* arg5 */
+	mov	ebp,[esp + 44]	/* arg6 */
+	int	0x80
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
+	.size	__libc_i386_syscall6,.-__libc_i386_syscall6
diff --git a/libc/sysdeps/linux/i386/sysdep.h b/libc/sysdeps/linux/i386/sysdep.h
index c15c1b4..0866894 100644
--- a/libc/sysdeps/linux/i386/sysdep.h
+++ b/libc/sysdeps/linux/i386/sysdep.h
@@ -189,11 +189,7 @@  __x86.get_pc_thunk.reg:						      \
 # if defined _LIBC_REENTRANT
 
 #  if defined USE___THREAD
-#   ifndef NOT_IN_libc
-#    define SYSCALL_ERROR_ERRNO __libc_errno
-#   else
 #    define SYSCALL_ERROR_ERRNO errno
-#   endif
 #   define SYSCALL_ERROR_HANDLER					      \
 0:SETUP_PIC_REG (cx);							      \
   addl $_GLOBAL_OFFSET_TABLE_, %ecx;					      \
diff --git a/libc/sysdeps/linux/sh/sysdep.h b/libc/sysdeps/linux/sh/sysdep.h
index 56fa3f7..42dc00e 100644
--- a/libc/sysdeps/linux/sh/sysdep.h
+++ b/libc/sysdeps/linux/sh/sysdep.h
@@ -134,11 +134,7 @@ 
 
 #  if defined USE___THREAD
 
-#   ifndef NOT_IN_libc
-#    define SYSCALL_ERROR_ERRNO __libc_errno
-#   else
 #    define SYSCALL_ERROR_ERRNO errno
-#   endif
 #   define SYSCALL_ERROR_HANDLER \
 	neg r0,r1; \
 	mov r12,r2; \
diff --git a/libc/sysdeps/linux/x86_64/sysdep.h b/libc/sysdeps/linux/x86_64/sysdep.h
index 61d2be8..34c0435 100644
--- a/libc/sysdeps/linux/x86_64/sysdep.h
+++ b/libc/sysdeps/linux/x86_64/sysdep.h
@@ -168,11 +168,7 @@  lose:									      \
 # ifndef __PIC__
 #  define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
 # elif USE___THREAD
-#  ifndef NOT_IN_libc
-#   define SYSCALL_ERROR_ERRNO __libc_errno
-#  else
 #   define SYSCALL_ERROR_ERRNO errno
-#  endif
 #  define SYSCALL_ERROR_HANDLER			\
 0:						\
   movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\
diff --git a/libc/sysdeps/linux/xtensa/sysdep.h b/libc/sysdeps/linux/xtensa/sysdep.h
index 8d1bfcf..0671f07 100644
--- a/libc/sysdeps/linux/xtensa/sysdep.h
+++ b/libc/sysdeps/linux/xtensa/sysdep.h
@@ -150,11 +150,7 @@ 
 
 #if defined _LIBC_REENTRANT
 # if defined USE___THREAD
-#  ifndef NOT_IN_libc
-#   define SYSCALL_ERROR_ERRNO __libc_errno
-#  else
 #   define SYSCALL_ERROR_ERRNO errno
-#  endif
 #  define SYSCALL_ERROR_HANDLER						      \
 0:	rur	a4, THREADPTR;						      \
 	movi	a3, SYSCALL_ERROR_ERRNO@TPOFF;				      \
diff --git a/libpthread/nptl/sysdeps/aarch64/Makefile.arch b/libpthread/nptl/sysdeps/aarch64/Makefile.arch
new file mode 100644
index 0000000..d6d3cbf
--- /dev/null
+++ b/libpthread/nptl/sysdeps/aarch64/Makefile.arch
@@ -0,0 +1,32 @@ 
+# Copyright (C) 2012 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; see the file COPYING.LIB.  If
+# not, see <http://www.gnu.org/licenses/>.
+
+ASFLAGS-dl-tlsdesc.S = -DNOT_IN_libc=1
+
+libc_arch_a_CSRC = libc-tls.c
+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)
+	$(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+$(libpthread_arch_OUT)/gen_tlsdesc.s: $(libpthread_arch_OUT)/gen_tlsdesc.c | headers
+	$(compile.c)
+libpthread-generated-y += $(libpthread_arch_OUT)/gen_tlsdesc.s
+$(libpthread_arch_OUT)/tlsdesc.h: $(libpthread_arch_OUT)/gen_tlsdesc.s
+	$(do_sed) $(PTHREAD_GENERATE_MANGLE) $< > $@
+	@if test ! -s $@ ; then rm -f $@ ; false ; fi
+pregen-headers-$(UCLIBC_HAS_THREADS_NATIVE) += $(libpthread_arch_OUT)/tlsdesc.h
diff --git a/libpthread/nptl/sysdeps/aarch64/dl-tls.h b/libpthread/nptl/sysdeps/aarch64/dl-tls.h
new file mode 100644
index 0000000..e5cd8cc
--- /dev/null
+++ b/libpthread/nptl/sysdeps/aarch64/dl-tls.h
@@ -0,0 +1,55 @@ 
+/* Copyright (C) 2005-2017 Free Software Foundation, Inc.
+
+   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 _AARCH64_DL_TLS_H
+#define _AARCH64_DL_TLS_H 1
+
+/* Type used to represent a TLS descriptor in the GOT.  */
+struct tlsdesc
+{
+  ptrdiff_t (*entry) (struct tlsdesc *);
+  void *arg;
+};
+
+typedef struct dl_tls_index
+{
+  unsigned long int ti_module;
+  unsigned long int ti_offset;
+} tls_index;
+
+/* Type used as the argument in a TLS descriptor for a symbol that
+   needs dynamic TLS offsets.  */
+struct tlsdesc_dynamic_arg
+{
+  tls_index tlsinfo;
+  size_t gen_count;
+};
+
+extern ptrdiff_t attribute_hidden
+_dl_tlsdesc_return (struct tlsdesc *);
+
+# ifdef SHARED
+extern void *_dl_make_tlsdesc_dynamic (struct link_map *, size_t);
+
+extern ptrdiff_t attribute_hidden
+_dl_tlsdesc_dynamic (struct tlsdesc *);
+# endif
+
+extern void *__tls_get_addr (tls_index *ti);
+
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
+
+#endif
diff --git a/libpthread/nptl/sysdeps/aarch64/libc-dl-tlsdesc.S b/libpthread/nptl/sysdeps/aarch64/libc-dl-tlsdesc.S
new file mode 100644
index 0000000..fd408d8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/aarch64/libc-dl-tlsdesc.S
@@ -0,0 +1 @@ 
+#include <ldso/ldso/aarch64/dl-tlsdesc.S>
diff --git a/libpthread/nptl/sysdeps/aarch64/libc-tls.c b/libpthread/nptl/sysdeps/aarch64/libc-tls.c
new file mode 100644
index 0000000..4e2bd37
--- /dev/null
+++ b/libpthread/nptl/sysdeps/aarch64/libc-tls.c
@@ -0,0 +1,35 @@ 
+/* Thread-local storage handling in the ELF dynamic linker.  AARCH64 version.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+   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 <sysdeps/generic/libc-tls.c>
+#include <dl-tls.h>
+
+#if defined(USE_TLS) && USE_TLS
+
+/* On AARCH64, 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.  */
+
+void *
+__tls_get_addr (tls_index *ti)
+{
+  dtv_t *dtv = THREAD_DTV ();
+  return (char *) dtv[1].pointer.val + ti->ti_offset;
+}
+
+#endif
diff --git a/libpthread/nptl/sysdeps/nds32/pthread_spin_lock.c b/libpthread/nptl/sysdeps/aarch64/pthread_spin_lock.c
similarity index 100%
copy from libpthread/nptl/sysdeps/nds32/pthread_spin_lock.c
copy to libpthread/nptl/sysdeps/aarch64/pthread_spin_lock.c
diff --git a/libpthread/nptl/sysdeps/nds32/pthread_spin_trylock.c b/libpthread/nptl/sysdeps/aarch64/pthread_spin_trylock.c
similarity index 100%
copy from libpthread/nptl/sysdeps/nds32/pthread_spin_trylock.c
copy to libpthread/nptl/sysdeps/aarch64/pthread_spin_trylock.c
diff --git a/libpthread/nptl/sysdeps/aarch64/pthreaddef.h b/libpthread/nptl/sysdeps/aarch64/pthreaddef.h
new file mode 100644
index 0000000..d9495f9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/aarch64/pthreaddef.h
@@ -0,0 +1,34 @@ 
+/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
+
+   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/>.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE	(2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  */
+#define STACK_ALIGN 16
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK 2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT 16
+
+/* Location of current stack frame.  */
+#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))
diff --git a/libpthread/nptl/sysdeps/aarch64/tcb-offsets.sym b/libpthread/nptl/sysdeps/aarch64/tcb-offsets.sym
new file mode 100644
index 0000000..238647d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/aarch64/tcb-offsets.sym
@@ -0,0 +1,6 @@ 
+#include <sysdep.h>
+#include <tls.h>
+
+PTHREAD_MULTIPLE_THREADS_OFFSET		offsetof (struct pthread, header.multiple_threads)
+PTHREAD_TID_OFFSET			offsetof (struct pthread, tid)
+PTHREAD_SIZEOF				sizeof (struct pthread)
diff --git a/libpthread/nptl/sysdeps/aarch64/tls.h b/libpthread/nptl/sysdeps/aarch64/tls.h
new file mode 100644
index 0000000..5a88f6e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/aarch64/tls.h
@@ -0,0 +1,149 @@ 
+/* Copyright (C) 2005-2017 Free Software Foundation, Inc.
+
+   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_TLS_MODEL_ATTRIBUTE        1
+#define HAVE___THREAD                   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;
+
+/* 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	__alignof__ (struct pthread)
+
+/* 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		__alignof__ (struct pthread)
+
+/* 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.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+# define TLS_INIT_TP(tcbp, secondcall) \
+  ({ __asm __volatile ("msr tpidr_el0, %0" : : "r" (tcbp)); NULL; })
+
+/* Value passed to 'clone' for initialization of the thread register.  */
+# 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 *) __builtin_thread_pointer ())->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+ ((struct pthread *)__builtin_thread_pointer () - 1)
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF \
+  CONST_THREAD_AREA (64, sizeof (struct pthread))
+
+/* Access to data in the thread descriptor is easy.  */
+# define THREAD_GETMEM(descr, member) \
+  descr->member
+# define THREAD_GETMEM_NC(descr, member, idx) \
+  descr->member[idx]
+# define THREAD_SETMEM(descr, member, value) \
+  descr->member = (value)
+# 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/aarch64/tlsdesc.sym b/libpthread/nptl/sysdeps/aarch64/tlsdesc.sym
new file mode 100644
index 0000000..4d2d137
--- /dev/null
+++ b/libpthread/nptl/sysdeps/aarch64/tlsdesc.sym
@@ -0,0 +1,17 @@ 
+#include <stddef.h>
+#include <sysdep.h>
+#include <tls.h>
+#include <link.h>
+#include <dl-tls.h>
+
+--
+
+-- Abuse tls.h macros to derive offsets relative to the thread register.
+
+TLSDESC_ARG		offsetof(struct tlsdesc, arg)
+TLSDESC_GEN_COUNT	offsetof(struct tlsdesc_dynamic_arg, gen_count)
+TLSDESC_MODID		offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module)
+TLSDESC_MODOFF		offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset)
+TCBHEAD_DTV		offsetof(tcbhead_t, dtv)
+DTV_COUNTER		offsetof(dtv_t, counter)
+TLS_DTV_UNALLOCATED     TLS_DTV_UNALLOCATED
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/Makefile
similarity index 100%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile
copy to libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/Makefile
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/Makefile.arch
new file mode 100644
index 0000000..7d31efb
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/Makefile.arch
@@ -0,0 +1,14 @@ 
+# 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
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/bits/pthreadtypes.h
new file mode 100644
index 0000000..47293a1
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/bits/pthreadtypes.h
@@ -0,0 +1,174 @@ 
+/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
+
+   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 _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H	1
+
+#include <endian.h>
+
+#define __SIZEOF_PTHREAD_ATTR_T        64
+#define __SIZEOF_PTHREAD_MUTEX_T       48
+#define __SIZEOF_PTHREAD_MUTEXATTR_T    8
+#define __SIZEOF_PTHREAD_COND_T        48
+#define __SIZEOF_PTHREAD_COND_COMPAT_T 48
+#define __SIZEOF_PTHREAD_CONDATTR_T     8
+#define __SIZEOF_PTHREAD_RWLOCK_T      56
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T   8
+#define __SIZEOF_PTHREAD_BARRIER_T     32
+#define __SIZEOF_PTHREAD_BARRIERATTR_T  8
+
+#define __PTHREAD_RWLOCK_INT_FLAGS_SHARED 1
+
+/* 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_t1
+#endif
+
+typedef struct __pthread_internal_list
+{
+  struct __pthread_internal_list *__prev;
+  struct __pthread_internal_list *__next;
+} __pthread_list_t;
+
+
+/* Data structures for mutex handling.  The structure of the attribute
+   type is not exposed on purpose.  */
+typedef union
+{
+  struct __pthread_mutex_s
+  {
+    int __lock;
+    unsigned int __count;
+    int __owner;
+    unsigned int __nusers;
+    /* KIND must stay at this position in the structure to maintain
+       binary compatibility with static initializers.  */
+    int __kind;
+    int __spins;
+    __pthread_list_t __list;
+#define __PTHREAD_MUTEX_HAVE_PREV	1
+  } __data;
+  char __size[__SIZEOF_PTHREAD_MUTEX_T];
+  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;
+} pthread_mutexattr_t;
+
+/* Data structure for conditional variable handling.  The structure of
+   the attribute type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __futex;
+    __extension__ unsigned long long int __total_seq;
+    __extension__ unsigned long long int __wakeup_seq;
+    __extension__ unsigned long long int __woken_seq;
+    void *__mutex;
+    unsigned int __nwaiters;
+    unsigned int __broadcast_seq;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_COND_T];
+  __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+  int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#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
+{
+  struct
+  {
+    int __lock;
+    unsigned int __nr_readers;
+    unsigned int __readers_wakeup;
+    unsigned int __writer_wakeup;
+    unsigned int __nr_readers_queued;
+    unsigned int __nr_writers_queued;
+    int __writer;
+    int __shared;
+    unsigned long int __pad1;
+    unsigned long int __pad2;
+    unsigned int __flags;
+  } __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
+
+
+#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
+{
+  char __size[__SIZEOF_PTHREAD_BARRIER_T];
+  long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+  int __align;
+} pthread_barrierattr_t;
+#endif
+
+#endif	/* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/bits/semaphore.h
new file mode 100644
index 0000000..15a01be
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/bits/semaphore.h
@@ -0,0 +1,30 @@ 
+/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
+
+   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 _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+#define __SIZEOF_SEM_T	32
+
+/* Value returned if `sem_open' failed.  */
+#define SEM_FAILED      ((sem_t *) 0)
+
+typedef union
+{
+  char __size[__SIZEOF_SEM_T];
+  long long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/createthread.c
new file mode 100644
index 0000000..8157435
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/createthread.c
@@ -0,0 +1,21 @@ 
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+
+   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/>.  */
+
+/* Value passed to 'clone' for initialization of the thread register.  */
+#define TLS_VALUE (pd + 1)
+
+/* Get the real implementation.	 */
+#include <sysdeps/pthread/createthread.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/fork.c
new file mode 100644
index 0000000..c5d963a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/fork.c
@@ -0,0 +1,11 @@ 
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+#define ARCH_FORK() \
+  INLINE_SYSCALL (clone, 5,                                                  \
+                 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0,     \
+                 NULL, NULL, &THREAD_SELF->tid)
+
+#include "../fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/lowlevellock.h
new file mode 100644
index 0000000..6b0e51e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/lowlevellock.h
@@ -0,0 +1,323 @@ 
+/* Copyright (C) 2005-2013 Free Software Foundation, Inc.
+
+   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 _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H	1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+
+
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_REQUEUE		3
+#define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
+#define FUTEX_WAIT_BITSET	9
+#define FUTEX_WAKE_BITSET	10
+#define FUTEX_WAIT_REQUEUE_PI   11
+#define FUTEX_CMP_REQUEUE_PI    12
+#define FUTEX_PRIVATE_FLAG	128
+#define FUTEX_CLOCK_REALTIME	256
+
+#define FUTEX_BITSET_MATCH_ANY	0xffffffff
+
+/* Values for 'private' parameter of locking macros.  Yes, the
+   definition seems to be backwards.  But it is not.  The bit will be
+   reversed before passing to the system call.  */
+#define LLL_PRIVATE	0
+#define LLL_SHARED	FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private.  */
+# ifdef __ASSUME_PRIVATE_FUTEX
+#  define __lll_private_flag(fl, private) \
+  ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+#  define __lll_private_flag(fl, private) \
+  ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+#  define __lll_private_flag(fl, private) \
+  (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+#  define __lll_private_flag(fl, private) \
+  (__builtin_constant_p (private)					      \
+   ? ((private) == 0							      \
+      ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))	      \
+      : (fl))								      \
+   : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG)				      \
+	      & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+
+#define lll_futex_wait(futexp, val, private) \
+  lll_futex_timed_wait(futexp, val, NULL, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+  ({									      \
+    long int __ret;							      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
+			      __lll_private_flag (FUTEX_WAIT, private),	      \
+			      (val), (timespec));			      \
+    __ret;								      \
+  })
+
+#define lll_futex_timed_wait_bitset(futexp, val, timespec, clockbit, private) \
+  ({									\
+    long int __ret;							\
+    INTERNAL_SYSCALL_DECL (__err);					\
+    int __op = FUTEX_WAIT_BITSET | clockbit;				\
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		\
+			      __lll_private_flag (__op, private),	\
+			      (val), (timespec), NULL /* Unused.  */,	\
+			      FUTEX_BITSET_MATCH_ANY);			\
+    __ret;								\
+  })
+
+#define lll_futex_wake(futexp, nr, private) \
+  ({									      \
+    long int __ret;							      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
+			      __lll_private_flag (FUTEX_WAKE, private),	      \
+			      (nr), 0);					      \
+    __ret;								      \
+  })
+
+#define lll_robust_dead(futexv, private) \
+  do									      \
+    {									      \
+      int *__futexp = &(futexv);					      \
+      atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
+      lll_futex_wake (__futexp, 1, private);				      \
+    }									      \
+  while (0)
+
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+  ({									      \
+    long int __ret;							      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    __ret = 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);				      \
+  })
+
+
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+  ({									      \
+    long int __ret;							      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    __ret = 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);				      \
+  })
+
+/* Priority Inheritance support.  */
+#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \
+  lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private)
+
+#define lll_futex_timed_wait_requeue_pi(futexp, val, timespec, clockbit,      \
+					mutex, private)			      \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    int __op = FUTEX_WAIT_REQUEUE_PI | clockbit;			      \
+									      \
+    INTERNAL_SYSCALL (futex, __err, 5, (futexp),			      \
+		      __lll_private_flag (__op, private),		      \
+		      (val), (timespec), mutex); 			      \
+  })
+
+#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, val, priv)  \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+									      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
+			      __lll_private_flag (FUTEX_CMP_REQUEUE_PI, priv),\
+			      (nr_wake), (nr_move), (mutex), (val));	      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+  })
+
+
+#define lll_trylock(lock)	\
+  atomic_compare_and_exchange_val_acq(&(lock), 1, 0)
+
+#define lll_cond_trylock(lock)	\
+  atomic_compare_and_exchange_val_acq(&(lock), 2, 0)
+
+#define __lll_robust_trylock(futex, id) \
+  (atomic_compare_and_exchange_val_acq (futex, id, 0) != 0)
+#define lll_robust_trylock(lock, id) \
+  __lll_robust_trylock (&(lock), id)
+
+extern void __lll_lock_wait_private (int *futex) attribute_hidden;
+extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
+
+#define __lll_lock(futex, private)					      \
+  ((void) ({								      \
+    int *__futex = (futex);						      \
+    if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex,       \
+								1, 0), 0))    \
+      {									      \
+	if (__builtin_constant_p (private) && (private) == LLL_PRIVATE)	      \
+	  __lll_lock_wait_private (__futex);				      \
+	else								      \
+	  __lll_lock_wait (__futex, private);				      \
+      }									      \
+  }))
+#define lll_lock(futex, private) __lll_lock (&(futex), private)
+
+
+#define __lll_robust_lock(futex, id, private)				      \
+  ({									      \
+    int *__futex = (futex);						      \
+    int __val = 0;							      \
+									      \
+    if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id,  \
+								0), 0))	      \
+      __val = __lll_robust_lock_wait (__futex, private);		      \
+    __val;								      \
+  })
+#define lll_robust_lock(futex, id, private) \
+  __lll_robust_lock (&(futex), id, private)
+
+
+#define __lll_cond_lock(futex, private)					      \
+  ((void) ({								      \
+    int *__futex = (futex);						      \
+    if (__builtin_expect (atomic_exchange_acq (__futex, 2), 0))		      \
+      __lll_lock_wait (__futex, private);				      \
+  }))
+#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
+
+
+#define lll_robust_cond_lock(futex, id, private) \
+  __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private)
+
+
+extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+				 int private) attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
+					int private) attribute_hidden;
+
+#define __lll_timedlock(futex, abstime, private)			      \
+  ({									      \
+     int *__futex = (futex);						      \
+     int __val = 0;							      \
+									      \
+     if (__builtin_expect (atomic_exchange_acq (__futex, 1), 0))	      \
+       __val = __lll_timedlock_wait (__futex, abstime, private);	      \
+     __val;								      \
+  })
+#define lll_timedlock(futex, abstime, private) \
+  __lll_timedlock (&(futex), abstime, private)
+
+
+#define __lll_robust_timedlock(futex, abstime, id, private)		      \
+  ({									      \
+    int *__futex = (futex);						      \
+    int __val = 0;							      \
+									      \
+    if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id,  \
+								0), 0))	      \
+      __val = __lll_robust_timedlock_wait (__futex, abstime, private);	      \
+    __val;								      \
+  })
+#define lll_robust_timedlock(futex, abstime, id, private) \
+  __lll_robust_timedlock (&(futex), abstime, id, private)
+
+
+#define __lll_unlock(futex, private) \
+  (void)							\
+    ({ int *__futex = (futex);					\
+       int __oldval = atomic_exchange_rel (__futex, 0);		\
+       if (__builtin_expect (__oldval > 1, 0))			\
+	 lll_futex_wake (__futex, 1, private);			\
+       lll_futex_wake (__futex, 1, private);			\
+    })
+#define lll_unlock(futex, private) __lll_unlock(&(futex), private)
+
+
+#define __lll_robust_unlock(futex, private) \
+  (void)							\
+    ({ int *__futex = (futex);					\
+       int __oldval = atomic_exchange_rel (__futex, 0);		\
+       if (__builtin_expect (__oldval & FUTEX_WAITERS, 0))	\
+	 lll_futex_wake (__futex, 1, private);			\
+       lll_futex_wake (__futex, 1, private);			\
+    })
+#define lll_robust_unlock(futex, private) \
+  __lll_robust_unlock(&(futex), private)
+
+
+#define lll_islocked(futex) \
+  (futex != 0)
+
+
+/* Our internal lock implementation is identical to the binary-compatible
+   mutex implementation. */
+
+/* Initializers for lock.  */
+#define LLL_LOCK_INITIALIZER		(0)
+#define LLL_LOCK_INITIALIZER_LOCKED	(1)
+
+/* The states of a lock are:
+    0  -  untaken
+    1  -  taken by one user
+   >1  -  taken by more users */
+
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
+   wakeup when the clone terminates.  The memory location contains the
+   thread ID while the clone is running and is reset to zero
+   afterwards.	*/
+#define lll_wait_tid(tid) \
+  do {					\
+    __typeof (tid) __tid;		\
+    while ((__tid = (tid)) != 0)	\
+      lll_futex_wait (&(tid), __tid, LLL_SHARED);\
+  } while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+     attribute_hidden;
+
+#define lll_timedwait_tid(tid, abstime) \
+  ({							\
+    int __res = 0;					\
+    if ((tid) != 0)					\
+      __res = __lll_timedwait_tid (&(tid), (abstime));	\
+    __res;						\
+  })
+
+#endif	/* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pt-raise.c b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/pt-raise.c
similarity index 100%
copy from libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pt-raise.c
copy to libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/pt-raise.c
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/pthread_once.c
new file mode 100644
index 0000000..b77939d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/pthread_once.c
@@ -0,0 +1,90 @@ 
+/* Copyright (C) 2003-2013 Free Software Foundation, Inc.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   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 "pthreadP.h"
+#include <lowlevellock.h>
+
+unsigned long int __fork_generation attribute_hidden;
+
+static void
+clear_once_control (void *arg)
+{
+  pthread_once_t *once_control = (pthread_once_t *) arg;
+
+  *once_control = 0;
+  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+}
+
+
+int
+__pthread_once (once_control, init_routine)
+     pthread_once_t *once_control;
+     void (*init_routine) (void);
+{
+  while (1)
+    {
+      int oldval, val, newval;
+
+      val = *once_control;
+      do
+	{
+	  /* Check if the initialized has already been done.  */
+	  if ((val & 2) != 0)
+	    return 0;
+
+	  oldval = val;
+	  newval = (oldval & 3) | __fork_generation | 1;
+	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
+						     oldval);
+	}
+      while (__builtin_expect (val != oldval, 0));
+
+      /* Check if another thread already runs the initializer.	*/
+      if ((oldval & 1) != 0)
+	{
+	  /* Check whether the initializer execution was interrupted
+	     by a fork.	 */
+	  if (((oldval ^ newval) & -4) == 0)
+	    {
+	      /* Same generation, some other thread was faster. Wait.  */
+	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
+	      continue;
+	    }
+	}
+
+      /* This thread is the first here.  Do the initialization.
+	 Register a cleanup handler so that in case the thread gets
+	 interrupted the initialization can be restarted.  */
+      pthread_cleanup_push (clear_once_control, once_control);
+
+      init_routine ();
+
+      pthread_cleanup_pop (0);
+
+
+      /* Add one to *once_control.  */
+      atomic_increment (once_control);
+
+      /* Wake up all other threads.  */
+      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+      break;
+    }
+
+  return 0;
+}
+weak_alias (__pthread_once, pthread_once)
+strong_alias (__pthread_once, __pthread_once_internal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h
new file mode 100644
index 0000000..0942e81
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h
@@ -0,0 +1,132 @@ 
+/* Copyright (C) 2003-2017 Free Software Foundation, Inc.
+
+   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
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+	.section ".text";						\
+ENTRY (__##syscall_name##_nocancel);					\
+.Lpseudo_nocancel:							\
+	DO_CALL (syscall_name, args);					\
+.Lpseudo_finish:							\
+	cmn	x0, 4095;						\
+	b.cs	.Lsyscall_error;					\
+	.subsection 2;							\
+	.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
+ENTRY (name);								\
+	SINGLE_THREAD_P(16);						\
+	cbz	w16, .Lpseudo_nocancel;					\
+	/* Setup common stack frame no matter the number of args.	\
+	   Also save the first arg, since it's basically free.  */	\
+	stp	x30, x0, [sp, -64]!;					\
+	cfi_adjust_cfa_offset (64);					\
+	cfi_rel_offset (x30, 0);					\
+	DOCARGS_##args;		/* save syscall args around CENABLE.  */ \
+	CENABLE;							\
+	mov	x16, x0;	/* save mask around syscall.  */	\
+	UNDOCARGS_##args;	/* restore syscall args.  */		\
+	DO_CALL (syscall_name, args);					\
+	str	x0, [sp, 8];	/* save result around CDISABLE.  */	\
+	mov	x0, x16;	/* restore mask for CDISABLE.  */	\
+	CDISABLE;							\
+	/* Break down the stack frame, restoring result at once.  */	\
+	ldp	x30, x0, [sp], 64;					\
+	cfi_adjust_cfa_offset (-64);					\
+	cfi_restore (x30);						\
+	b	.Lpseudo_finish;					\
+	cfi_endproc;							\
+	.size	name, .-name;						\
+	.previous
+
+# undef PSEUDO_END
+# define PSEUDO_END(name)						\
+	SYSCALL_ERROR_HANDLER;						\
+	cfi_endproc
+
+# define DOCARGS_0
+# define DOCARGS_1
+# define DOCARGS_2	str x1, [sp, 16]
+# define DOCARGS_3	stp x1, x2, [sp, 16]
+# define DOCARGS_4	DOCARGS_3; str x3, [sp, 32]
+# define DOCARGS_5	DOCARGS_3; stp x3, x4, [sp, 32]
+# define DOCARGS_6	DOCARGS_5; str x5, [sp, 48]
+
+# define UNDOCARGS_0
+# define UNDOCARGS_1	ldr x0, [sp, 8]
+# define UNDOCARGS_2	ldp x0, x1, [sp, 8]
+# define UNDOCARGS_3	UNDOCARGS_1; ldp x1, x2, [sp, 16]
+# define UNDOCARGS_4	UNDOCARGS_2; ldp x2, x3, [sp, 24]
+# define UNDOCARGS_5	UNDOCARGS_3; ldp x3, x4, [sp, 32]
+# define UNDOCARGS_6	UNDOCARGS_4; ldp x4, x5, [sp, 40]
+
+# if defined IS_IN_libpthread
+#  define CENABLE	bl __pthread_enable_asynccancel
+#  define CDISABLE	bl __pthread_disable_asynccancel
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define CENABLE	bl __libc_enable_asynccancel
+#  define CDISABLE	bl __libc_disable_asynccancel
+#  define __local_multiple_threads __libc_multiple_threads
+# elif defined IS_IN_librt
+#  define CENABLE	bl __librt_enable_asynccancel
+#  define CDISABLE	bl __librt_disable_asynccancel
+# else
+#  error Unsupported library
+# endif
+
+# if defined IS_IN_libpthread || !defined NOT_IN_libc
+#  ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+#  else
+#   define SINGLE_THREAD_P(R)						\
+	adrp	x##R, __local_multiple_threads;				\
+	ldr	w##R, [x##R, :lo12:__local_multiple_threads]
+#  endif
+# else
+/*  There is no __local_multiple_threads for librt, so use the TCB.  */
+#  ifndef __ASSEMBLER__
+#   define SINGLE_THREAD_P						\
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				\
+				   header.multiple_threads) == 0, 1)
+#  else
+#   define SINGLE_THREAD_P(R)						\
+	mrs     x##R, tpidr_el0;					\
+	sub	x##R, x##R, PTHREAD_SIZEOF;				\
+	ldr	w##R, [x##R, PTHREAD_MULTIPLE_THREADS_OFFSET]
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* For rtld, et cetera.  */
+# define SINGLE_THREAD_P 1
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/utils/ldd.c b/utils/ldd.c
index e7430fc..37a069b 100644
--- a/utils/ldd.c
+++ b/utils/ldd.c
@@ -15,6 +15,11 @@ 
 
 #include "porting.h"
 
+#if defined(__aarch64__)
+#define MATCH_MACHINE(x) (x == EM_AARCH64)
+#define ELFCLASSM	ELFCLASS64
+#endif
+
 #if defined(__alpha__)
 #define MATCH_MACHINE(x) (x == EM_ALPHA)
 #define ELFCLASSM	ELFCLASS64