Blame SOURCES/glibc-aarch64-syscall-rewrite.patch

ce426f
From 9a7cb556eef7cb75b31d0bc05f73c6338dfd8e49 Mon Sep 17 00:00:00 2001
ce426f
From: Richard Henderson <rth@redhat.com>
ce426f
Date: Fri, 30 May 2014 13:57:04 -0400
ce426f
Subject: [PATCH] aarch64: Backport syscall rewrite
ce426f
ce426f
From commits:
ce426f
a60339aaff82beadea6f580e587d64052cb5e3b8 Fix handling of nocancel syscall...
ce426f
3612eb8f25d978e7e4ac536a34098091f737161c Merge rtld_errno offset w/ mem ref
ce426f
a6b3657be6bc5067aeec98d990f60765361c6557 Merge __local_multiple_threads ofs...
ce426f
c69abcee726a6f63d9e5e8f0d9dcc79374ee3ef8 Fix DO_CALL block comment
ce426f
6e6c2d01ebb1ef839675c7151d2a114f53663386 Remove DOARGS/UNDOARGS macros
ce426f
ca3cfa40c16ef34c74951a07a57cfcbcd58898b1 Tidy syscall error check
ce426f
af4e8ef9443e258ebeb0ddf3c5c9579f24dfacd5 Tabify sysdep-cancel.h
ce426f
a8b4f04ad7dff4f39797a7ab7f8babda54266026 Share code in sysdep-cancel.h
ce426f
645d44abe3ca6253a9d4762f092e4a1b9d294b11 Pass regno parameter to SINGLE_THREAD_P
ce426f
b5be4597716eff94149f5529c8eb2cd3b4296188 Improve syscall-cancel stack frame
ce426f
74f31c18593111725478a991b395ae45661985a3 Fix error return from __ioctl
ce426f
f0712b543eaddeca8fc6d7a8eb6b5b8d24105ce2 Remove PSEUDO_RET
ce426f
ce426f
And a not-yet-committed cleanup to clone.S.
ce426f
---
ce426f
 ports/sysdeps/unix/sysv/linux/aarch64/clone.S      |  51 +++---
ce426f
 ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S      |  13 +-
ce426f
 .../unix/sysv/linux/aarch64/nptl/localplt.data     |   1 -
ce426f
 .../unix/sysv/linux/aarch64/nptl/sysdep-cancel.h   | 189 +++++++--------------
ce426f
 ports/sysdeps/unix/sysv/linux/aarch64/syscall.S    |   4 +-
ce426f
 ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h     |  84 ++-------
ce426f
 ports/sysdeps/unix/sysv/linux/aarch64/vfork.S      |   4 +-
ce426f
 7 files changed, 108 insertions(+), 238 deletions(-)
ce426f
ce426f
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
ce426f
index 8be1464..d5c31f3 100644
ce426f
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
ce426f
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
ce426f
@@ -39,46 +39,43 @@
ce426f
  */
ce426f
         .text
ce426f
 ENTRY(__clone)
ce426f
+	/* Save args for the child.  */
ce426f
+	mov	x10, x0
ce426f
+	mov	x11, x2
ce426f
+	mov	x12, x3
ce426f
+	
ce426f
 	/* Sanity check args.  */
ce426f
-	cbz	x0, 1f
ce426f
-	cbz	x1, 1f
ce426f
-	/* Insert the args onto the new stack.  */
ce426f
-	stp	x0, x3, [x1, #-16]!	/* Fn, arg.  */
ce426f
+	mov	x0, #-EINVAL
ce426f
+	cbz	x10, .Lsyscall_error
ce426f
+	cbz	x1, .Lsyscall_error
ce426f
 
ce426f
 	/* Do the system call.  */
ce426f
+	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
ce426f
 	mov	x0, x2                  /* flags  */
ce426f
-
ce426f
 	/* New sp is already in x1.  */
ce426f
 	mov	x2, x4			/* ptid  */
ce426f
 	mov	x3, x5			/* tls  */
ce426f
 	mov	x4, x6			/* ctid  */
ce426f
 
ce426f
-#ifdef RESET_PID
ce426f
-	/* We rely on the kernel preserving the argument regsiters across a
ce426f
-	   each system call so that we can inspect the flags against after
ce426f
-	   the clone call.  */
ce426f
-	mov	x5, x0
ce426f
-#endif
ce426f
-
ce426f
 	mov	x8, #SYS_ify(clone)
ce426f
-	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
ce426f
 	svc	0x0
ce426f
-	cfi_endproc
ce426f
 	cmp	x0, #0
ce426f
-	beq	2f
ce426f
-	blt	C_SYMBOL_NAME(__syscall_error)
ce426f
+	beq	thread_start
ce426f
+	blt	.Lsyscall_error
ce426f
 	RET
ce426f
-1:	mov	x0, #-EINVAL
ce426f
-	b	syscall_error
ce426f
+PSEUDO_END (__clone)
ce426f
 
ce426f
-2:
ce426f
+	.align	4
ce426f
+	.type	thread_start, %function
ce426f
+thread_start:
ce426f
 	cfi_startproc
ce426f
 	cfi_undefined (x30)
ce426f
 	mov	x29, 0
ce426f
+
ce426f
 #ifdef RESET_PID
ce426f
-	tbnz	x5, #CLONE_THREAD_BIT, 3f
ce426f
+	tbnz	x11, #CLONE_THREAD_BIT, 3f
ce426f
 	mov	x0, #-1
ce426f
-	tbnz	x5, #CLONE_VM_BIT, 2f
ce426f
+	tbnz	x11, #CLONE_VM_BIT, 2f
ce426f
 	mov	x8, #SYS_ify(getpid)
ce426f
 	svc	0x0
ce426f
 2:
ce426f
@@ -86,18 +83,16 @@ ENTRY(__clone)
ce426f
 	sub	x1, x1, #PTHREAD_SIZEOF
ce426f
 	str	w0, [x1, #PTHREAD_PID_OFFSET]
ce426f
 	str	w0, [x1, #PTHREAD_TID_OFFSET]
ce426f
-
ce426f
 3:
ce426f
 #endif
ce426f
-	/* Pick the function arg and call address from the stack and
ce426f
-	   execute.  */
ce426f
-	ldp	x1, x0, [sp], #16
ce426f
-	blr	x1
ce426f
+
ce426f
+	/* Pick the function arg execute.  */
ce426f
+	mov	x0, x12
ce426f
+	blr	x10
ce426f
 
ce426f
 	/* We are done, pass the return value through x0.  */
ce426f
 	b	HIDDEN_JUMPTARGET(_exit)
ce426f
 	cfi_endproc
ce426f
-	cfi_startproc
ce426f
-PSEUDO_END (__clone)
ce426f
+	.size	thread_start, .-thread_start
ce426f
 
ce426f
 weak_alias (__clone, clone)
ce426f
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
ce426f
index f01fb84..be6c026 100644
ce426f
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
ce426f
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
ce426f
@@ -20,13 +20,12 @@
ce426f
 
ce426f
 	.text
ce426f
 ENTRY(__ioctl)
ce426f
-	movz	x8, #__NR_ioctl
ce426f
-        sxtw	x0, w0
ce426f
-        svc	#0x0
ce426f
-	cmn	x0, #0x1, lsl #12
ce426f
-	b.hi	C_SYMBOL_NAME(__syscall_error)
ce426f
+	mov	x8, #__NR_ioctl
ce426f
+	sxtw	x0, w0
ce426f
+	svc	#0x0
ce426f
+	cmn	x0, #4095
ce426f
+	b.cs	.Lsyscall_error
ce426f
 	ret
ce426f
-
ce426f
-	PSEUDO_END (__ioctl)
ce426f
+PSEUDO_END (__ioctl)
ce426f
 
ce426f
 weak_alias (__ioctl, ioctl)
ce426f
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
ce426f
index 84af95d..dfca9a7 100644
ce426f
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
ce426f
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
ce426f
@@ -12,4 +12,3 @@ libm.so: matherr
ce426f
 libm.so: __signbit
ce426f
 libm.so: __signbitf
ce426f
 libm.so: __signbitl
ce426f
-libpthread.so: __errno_location
ce426f
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
ce426f
index e0e5cc0..a3b9284 100644
ce426f
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
ce426f
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
ce426f
@@ -26,119 +26,60 @@
ce426f
 
ce426f
 # undef PSEUDO
ce426f
 # define PSEUDO(name, syscall_name, args)				\
ce426f
-  .section ".text";							\
ce426f
-  .type __##syscall_name##_nocancel,%function;				\
ce426f
-  .globl __##syscall_name##_nocancel;					\
ce426f
-  __##syscall_name##_nocancel:						\
ce426f
-    cfi_startproc;							\
ce426f
-    DO_CALL (syscall_name, args);					\
ce426f
-    PSEUDO_RET;								\
ce426f
-    cfi_endproc;							\
ce426f
-    .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	\
ce426f
-  ENTRY (name);								\
ce426f
-    SINGLE_THREAD_P;							\
ce426f
-    DOARGS_##args;							\
ce426f
-    bne .Lpseudo_cancel;						\
ce426f
-    DO_CALL (syscall_name, 0);						\
ce426f
-    UNDOARGS_##args;							\
ce426f
-    cmn x0, 4095;							\
ce426f
-    PSEUDO_RET;								\
ce426f
-  .Lpseudo_cancel:							\
ce426f
-    DOCARGS_##args;	/* save syscall args etc. around CENABLE.  */	\
ce426f
-    CENABLE;								\
ce426f
-    mov x16, x0;	/* put mask in safe place.  */			\
ce426f
-    UNDOCARGS_##args;	/* restore syscall args.  */			\
ce426f
-    mov x8, SYS_ify (syscall_name);	/* do the call.  */		\
ce426f
-    svc	0;								\
ce426f
-    str x0, [sp, -16]!;	/* save syscall return value.  */		\
ce426f
-    cfi_adjust_cfa_offset (16);						\
ce426f
-    mov x0, x16;	 /* get mask back.  */				\
ce426f
-    CDISABLE;								\
ce426f
-    ldr x0, [sp], 16;							\
ce426f
-    cfi_adjust_cfa_offset (-16);					\
ce426f
-    ldr x30, [sp], 16;							\
ce426f
-    cfi_adjust_cfa_offset (-16);					\
ce426f
-    cfi_restore (x30);							\
ce426f
-    UNDOARGS_##args;							\
ce426f
-    cmn x0, 4095;
ce426f
-
ce426f
-# define DOCARGS_0							\
ce426f
-	str x30, [sp, -16]!;						\
ce426f
-	cfi_adjust_cfa_offset (16);					\
ce426f
-	cfi_rel_offset (x30, 0)
ce426f
+	.section ".text";						\
ce426f
+ENTRY (__##syscall_name##_nocancel);					\
ce426f
+.Lpseudo_nocancel:							\
ce426f
+	DO_CALL (syscall_name, args);					\
ce426f
+.Lpseudo_finish:							\
ce426f
+	cmn	x0, 4095;						\
ce426f
+	b.cs	.Lsyscall_error;					\
ce426f
+	.subsection 2;							\
ce426f
+	.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
ce426f
+ENTRY (name);								\
ce426f
+	SINGLE_THREAD_P(16);						\
ce426f
+	cbz	w16, .Lpseudo_nocancel;					\
ce426f
+	/* Setup common stack frame no matter the number of args.	\
ce426f
+	   Also save the first arg, since it's basically free.  */	\
ce426f
+	stp	x30, x0, [sp, -64]!;					\
ce426f
+	cfi_adjust_cfa_offset (64);					\
ce426f
+	cfi_rel_offset (x30, 0);					\
ce426f
+	DOCARGS_##args;		/* save syscall args around CENABLE.  */ \
ce426f
+	CENABLE;							\
ce426f
+	mov	x16, x0;	/* save mask around syscall.  */	\
ce426f
+	UNDOCARGS_##args;	/* restore syscall args.  */		\
ce426f
+	DO_CALL (syscall_name, args);					\
ce426f
+	str	x0, [sp, 8];	/* save result around CDISABLE.  */	\
ce426f
+	mov	x0, x16;	/* restore mask for CDISABLE.  */	\
ce426f
+	CDISABLE;							\
ce426f
+	/* Break down the stack frame, restoring result at once.  */	\
ce426f
+	ldp	x30, x0, [sp], 64;					\
ce426f
+	cfi_adjust_cfa_offset (-64);					\
ce426f
+	cfi_restore (x30);						\
ce426f
+	b	.Lpseudo_finish;					\
ce426f
+	cfi_endproc;							\
ce426f
+	.size	name, .-name;						\
ce426f
+	.previous
ce426f
+
ce426f
+# undef PSEUDO_END
ce426f
+# define PSEUDO_END(name)						\
ce426f
+	SYSCALL_ERROR_HANDLER;						\
ce426f
+	cfi_endproc
ce426f
+
ce426f
+# define DOCARGS_0
ce426f
+# define DOCARGS_1
ce426f
+# define DOCARGS_2	str x1, [sp, 16]
ce426f
+# define DOCARGS_3	stp x1, x2, [sp, 16]
ce426f
+# define DOCARGS_4	DOCARGS_3; str x3, [sp, 32]
ce426f
+# define DOCARGS_5	DOCARGS_3; stp x3, x4, [sp, 32]
ce426f
+# define DOCARGS_6	DOCARGS_5; str x5, [sp, 48]
ce426f
 
ce426f
 # define UNDOCARGS_0
ce426f
-
ce426f
-# define DOCARGS_1							\
ce426f
-	DOCARGS_0;							\
ce426f
-	str x0, [sp, -16]!;						\
ce426f
-	cfi_adjust_cfa_offset (16);					\
ce426f
-	cfi_rel_offset (x0, 0)
ce426f
-
ce426f
-# define UNDOCARGS_1							\
ce426f
-	ldr x0, [sp], 16;						\
ce426f
-	cfi_restore (x0);						\
ce426f
-	cfi_adjust_cfa_offset (-16);					\
ce426f
-
ce426f
-# define DOCARGS_2							\
ce426f
-	DOCARGS_1;							\
ce426f
-	str x1, [sp, -16]!;						\
ce426f
-	cfi_adjust_cfa_offset (16);					\
ce426f
-	cfi_rel_offset (x1, 0)
ce426f
-
ce426f
-# define UNDOCARGS_2							\
ce426f
-	ldr x1, [sp], 16;						\
ce426f
-	cfi_restore (x1);						\
ce426f
-	cfi_adjust_cfa_offset (-16);					\
ce426f
-	UNDOCARGS_1
ce426f
-
ce426f
-# define DOCARGS_3							\
ce426f
-	DOCARGS_2;							\
ce426f
-	str x2, [sp, -16]!;						\
ce426f
-	cfi_adjust_cfa_offset (16);					\
ce426f
-	cfi_rel_offset (x2, 0)
ce426f
-
ce426f
-# define UNDOCARGS_3							\
ce426f
-	ldr x2, [sp], 16;						\
ce426f
-	cfi_restore (x2);						\
ce426f
-	cfi_adjust_cfa_offset (-16);					\
ce426f
-	UNDOCARGS_2
ce426f
-
ce426f
-# define DOCARGS_4							\
ce426f
-	DOCARGS_3;							\
ce426f
-	str x3, [sp, -16]!;						\
ce426f
-	cfi_adjust_cfa_offset (16);					\
ce426f
-	cfi_rel_offset (x3, 0)
ce426f
-
ce426f
-# define UNDOCARGS_4							\
ce426f
-	ldr x3, [sp], 16;						\
ce426f
-	cfi_restore (x3);						\
ce426f
-	cfi_adjust_cfa_offset (-16);					\
ce426f
-	UNDOCARGS_3
ce426f
-
ce426f
-# define DOCARGS_5							\
ce426f
-	DOCARGS_4;							\
ce426f
-	str x4, [sp, -16]!;						\
ce426f
-	cfi_adjust_cfa_offset (16);					\
ce426f
-	cfi_rel_offset (x4, 0)
ce426f
-
ce426f
-# define UNDOCARGS_5							\
ce426f
-	ldr x4, [sp], 16;						\
ce426f
-	cfi_restore (x4);						\
ce426f
-	cfi_adjust_cfa_offset (-16);					\
ce426f
-	UNDOCARGS_4
ce426f
-
ce426f
-# define DOCARGS_6							\
ce426f
-	DOCARGS_5;							\
ce426f
-	str x5, [sp, -16]!;						\
ce426f
-	cfi_adjust_cfa_offset (16);					\
ce426f
-	cfi_rel_offset (x5, 0)
ce426f
-
ce426f
-# define UNDOCARGS_6							\
ce426f
-	ldr x5, [sp], 16;						\
ce426f
-	cfi_restore (x5);						\
ce426f
-	cfi_adjust_cfa_offset (-16);					\
ce426f
-	UNDOCARGS_5
ce426f
+# define UNDOCARGS_1	ldr x0, [sp, 8]
ce426f
+# define UNDOCARGS_2	ldp x0, x1, [sp, 8]
ce426f
+# define UNDOCARGS_3	UNDOCARGS_1; ldp x1, x2, [sp, 16]
ce426f
+# define UNDOCARGS_4	UNDOCARGS_2; ldp x2, x3, [sp, 24]
ce426f
+# define UNDOCARGS_5	UNDOCARGS_3; ldp x3, x4, [sp, 32]
ce426f
+# define UNDOCARGS_6	UNDOCARGS_4; ldp x4, x5, [sp, 40]
ce426f
 
ce426f
 # ifdef IS_IN_libpthread
ce426f
 #  define CENABLE	bl __pthread_enable_asynccancel
ce426f
@@ -160,11 +101,9 @@
ce426f
 extern int __local_multiple_threads attribute_hidden;
ce426f
 #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
ce426f
 #  else
ce426f
-#   define SINGLE_THREAD_P						\
ce426f
-  adrp	x16, __local_multiple_threads;					\
ce426f
-  add	x16, x16, #:lo12:__local_multiple_threads;			\
ce426f
-  ldr	x16, [x16];							\
ce426f
-  cmp	x16, 0;
ce426f
+#   define SINGLE_THREAD_P(R)						\
ce426f
+	adrp	x##R, __local_multiple_threads;				\
ce426f
+	ldr	w##R, [x##R, :lo12:__local_multiple_threads]
ce426f
 #  endif
ce426f
 # else
ce426f
 /*  There is no __local_multiple_threads for librt, so use the TCB.  */
ce426f
@@ -173,20 +112,10 @@ extern int __local_multiple_threads attribute_hidden;
ce426f
   __builtin_expect (THREAD_GETMEM (THREAD_SELF,				\
ce426f
 				   header.multiple_threads) == 0, 1)
ce426f
 #  else
ce426f
-#   define SINGLE_THREAD_P						\
ce426f
-  stp	x0, x30, [sp, -16]!;						\
ce426f
-  cfi_adjust_cfa_offset (16);						\
ce426f
-  cfi_rel_offset (x0, 0);						\
ce426f
-  cfi_rel_offset (x30, 8);						\
ce426f
-  bl	__read_tp;							\
ce426f
-  sub	x0, x0, PTHREAD_SIZEOF;						\
ce426f
-  ldr	x16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET];			\
ce426f
-  ldp	x0, x30, [sp], 16;						\
ce426f
-  cfi_restore (x0);							\
ce426f
-  cfi_restore (x30);							\
ce426f
-  cfi_adjust_cfa_offset (-16);						\
ce426f
-  cmp	x16, 0
ce426f
-#   define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
ce426f
+#   define SINGLE_THREAD_P(R)						\
ce426f
+	mrs	x##R, tpidr_el0;					\
ce426f
+	sub	x##R, x##R, PTHREAD_SIZEOF;				\
ce426f
+	ldr	w##R, [x##R, PTHREAD_MULTIPLE_THREADS_OFFSET]
ce426f
 #  endif
ce426f
 # endif
ce426f
 
ce426f
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
ce426f
index 574fdf1..fac6416 100644
ce426f
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
ce426f
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
ce426f
@@ -37,8 +37,6 @@ ENTRY (syscall)
ce426f
 	mov	x6, x7
ce426f
 	svc	0x0
ce426f
 	cmn	x0, #4095
ce426f
-	b.cs	1f
ce426f
+	b.cs	.Lsyscall_error
ce426f
 	RET
ce426f
-1:
ce426f
-	b	SYSCALL_ERROR
ce426f
 PSEUDO_END (syscall)
ce426f
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
ce426f
index 713bf7d..9961c03 100644
ce426f
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
ce426f
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
ce426f
@@ -58,19 +58,8 @@
ce426f
   .text;								      \
ce426f
   ENTRY (name);								      \
ce426f
     DO_CALL (syscall_name, args);					      \
ce426f
-    cmn x0, #4095;
ce426f
-
ce426f
-/* Notice the use of 'RET' instead of 'ret' the assembler is case
ce426f
-   insensitive and eglibc already uses the preprocessor symbol 'ret'
ce426f
-   so we use the upper case 'RET' to force through a ret instruction
ce426f
-   to the assembler */
ce426f
-# define PSEUDO_RET							      \
ce426f
-    b.cs 1f;								      \
ce426f
-    RET;								      \
ce426f
-    1:                                                                        \
ce426f
-    b SYSCALL_ERROR
ce426f
-# undef ret
ce426f
-# define ret PSEUDO_RET
ce426f
+    cmn x0, #4095;							      \
ce426f
+    b.cs .Lsyscall_error
ce426f
 
ce426f
 # undef	PSEUDO_END
ce426f
 # define PSEUDO_END(name)						      \
ce426f
@@ -83,15 +72,7 @@
ce426f
   ENTRY (name);								      \
ce426f
     DO_CALL (syscall_name, args);
ce426f
 
ce426f
-/* Notice the use of 'RET' instead of 'ret' the assembler is case
ce426f
-   insensitive and eglibc already uses the preprocessor symbol 'ret'
ce426f
-   so we use the upper case 'RET' to force through a ret instruction
ce426f
-   to the assembler */
ce426f
-# define PSEUDO_RET_NOERRNO						      \
ce426f
-    RET;
ce426f
-
ce426f
-# undef ret_NOERRNO
ce426f
-# define ret_NOERRNO PSEUDO_RET_NOERRNO
ce426f
+# define ret_NOERRNO ret
ce426f
 
ce426f
 # undef	PSEUDO_END_NOERRNO
ce426f
 # define PSEUDO_END_NOERRNO(name)					      \
ce426f
@@ -109,47 +90,38 @@
ce426f
 # define PSEUDO_END_ERRVAL(name) \
ce426f
   END (name)
ce426f
 
ce426f
-# define ret_ERRVAL PSEUDO_RET_NOERRNO
ce426f
+# define ret_ERRVAL ret
ce426f
 
ce426f
+# define SYSCALL_ERROR  .Lsyscall_error
ce426f
 # if NOT_IN_libc
ce426f
-#  define SYSCALL_ERROR __local_syscall_error
ce426f
 #  if RTLD_PRIVATE_ERRNO
ce426f
 #   define SYSCALL_ERROR_HANDLER				\
ce426f
-__local_syscall_error:						\
ce426f
+.Lsyscall_error:						\
ce426f
 	adrp	x1, C_SYMBOL_NAME(rtld_errno);			\
ce426f
-	add	x1, x1, #:lo12:C_SYMBOL_NAME(rtld_errno);	\
ce426f
 	neg     w0, w0;						\
ce426f
-	str     w0, [x1];					\
ce426f
+	str     w0, [x1, :lo12:C_SYMBOL_NAME(rtld_errno)];	\
ce426f
 	mov	x0, -1;						\
ce426f
 	RET;
ce426f
 #  else
ce426f
 
ce426f
 #   define SYSCALL_ERROR_HANDLER				\
ce426f
-__local_syscall_error:						\
ce426f
-	stp     x29, x30, [sp, -32]!;				\
ce426f
-	cfi_adjust_cfa_offset (32);				\
ce426f
-	cfi_rel_offset (x29, 0);				\
ce426f
-	cfi_rel_offset (x30, 8);				\
ce426f
-        add     x29, sp, 0;					\
ce426f
-        str     x19, [sp,16];					\
ce426f
-	neg	x19, x0;					\
ce426f
-	bl	C_SYMBOL_NAME(__errno_location);		\
ce426f
-	str	x19, [x0];					\
ce426f
+.Lsyscall_error:						\
ce426f
+	adrp	x1, :gottprel:errno;				\
ce426f
+	neg	w2, w0;						\
ce426f
+	ldr	x1, [x1, :gottprel_lo12:errno];			\
ce426f
+	mrs	x3, tpidr_el0;					\
ce426f
 	mov	x0, -1;						\
ce426f
-        ldr     x19, [sp,16];					\
ce426f
-        ldp     x29, x30, [sp], 32;				\
ce426f
-	cfi_adjust_cfa_offset (-32);				\
ce426f
-	cfi_restore (x29);					\
ce426f
-	cfi_restore (x30);					\
ce426f
+	str	w2, [x1, x3];					\
ce426f
 	RET;
ce426f
 #  endif
ce426f
 # else
ce426f
-#  define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
ce426f
-#  define SYSCALL_ERROR __syscall_error
ce426f
+#  define SYSCALL_ERROR_HANDLER					\
ce426f
+.Lsyscall_error:						\
ce426f
+	b	__syscall_error;
ce426f
 # endif
ce426f
 
ce426f
 /* Linux takes system call args in registers:
ce426f
-	syscall number	in the SVC instruction
ce426f
+	syscall number	x8
ce426f
 	arg 1		x0
ce426f
 	arg 2		x1
ce426f
 	arg 3		x2
ce426f
@@ -177,28 +149,8 @@ __local_syscall_error:						\
ce426f
 
ce426f
 # undef	DO_CALL
ce426f
 # define DO_CALL(syscall_name, args)		\
ce426f
-    DOARGS_##args				\
ce426f
     mov x8, SYS_ify (syscall_name);		\
ce426f
-    svc 0;					\
ce426f
-    UNDOARGS_##args
ce426f
-
ce426f
-# define DOARGS_0 /* nothing */
ce426f
-# define DOARGS_1 /* nothing */
ce426f
-# define DOARGS_2 /* nothing */
ce426f
-# define DOARGS_3 /* nothing */
ce426f
-# define DOARGS_4 /* nothing */
ce426f
-# define DOARGS_5 /* nothing */
ce426f
-# define DOARGS_6 /* nothing */
ce426f
-# define DOARGS_7 /* nothing */
ce426f
-
ce426f
-# define UNDOARGS_0 /* nothing */
ce426f
-# define UNDOARGS_1 /* nothing */
ce426f
-# define UNDOARGS_2 /* nothing */
ce426f
-# define UNDOARGS_3 /* nothing */
ce426f
-# define UNDOARGS_4 /* nothing */
ce426f
-# define UNDOARGS_5 /* nothing */
ce426f
-# define UNDOARGS_6 /* nothing */
ce426f
-# define UNDOARGS_7 /* nothing */
ce426f
+    svc 0
ce426f
 
ce426f
 #else /* not __ASSEMBLER__ */
ce426f
 
ce426f
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
ce426f
index f2dc49b..3fb68b9 100644
ce426f
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
ce426f
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
ce426f
@@ -38,10 +38,8 @@ ENTRY (__vfork)
ce426f
 	RESTORE_PID
ce426f
 #endif
ce426f
 	cmn	x0, #4095
ce426f
-	b.cs    1f
ce426f
+	b.cs    .Lsyscall_error
ce426f
 	RET
ce426f
-1:
ce426f
-	b	SYSCALL_ERROR
ce426f
 
ce426f
 PSEUDO_END (__vfork)
ce426f
 libc_hidden_def (__vfork)
ce426f
-- 
ce426f
1.8.3.1
ce426f