This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch rth/aa-opt created. glibc-2.19-477-gaad7cde


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 "GNU C Library master sources".

The branch, rth/aa-opt has been created
        at  aad7cde2d6329d3dd3eb43ce5f7212f2aa17bb5a (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=aad7cde2d6329d3dd3eb43ce5f7212f2aa17bb5a

commit aad7cde2d6329d3dd3eb43ce5f7212f2aa17bb5a
Author: Richard Henderson <rth@redhat.com>
Date:   Fri May 23 16:23:32 2014 -0400

    aarch64: Consolidate NPTL/non versions of vfork
    
    At the same time, incorporate the 0 -> 0x80000000 mapping
    of the pid expected by raise.c.

diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/pt-vfork.S b/sysdeps/unix/sysv/linux/aarch64/nptl/pt-vfork.S
deleted file mode 100644
index 2108347..0000000
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/pt-vfork.S
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (C) 2009-2014 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 <tcb-offsets.h>
-
-/* Save the PID value.  */
-#define SAVE_PID							\
-	mrs	x2, tpidr_el0;						\
-	sub	x2, x2, #PTHREAD_SIZEOF;				\
-	ldr	w3, [x2, #PTHREAD_PID_OFFSET];				\
-	neg	w0, w3;							\
-	str	w0, [x2, #PTHREAD_PID_OFFSET]
-
-/* Restore the old PID value in the parent.  */
-#define RESTORE_PID                                                     \
-	cbz	x0, 1f;							\
-	str	w3, [x2, #PTHREAD_PID_OFFSET];				\
-1:
-
-#include "../vfork.S"
diff --git a/sysdeps/unix/sysv/linux/aarch64/pt-vfork.c b/sysdeps/unix/sysv/linux/aarch64/pt-vfork.c
new file mode 100644
index 0000000..5dd23bf
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/pt-vfork.c
@@ -0,0 +1,54 @@
+/* vfork ABI-compatibility entry points for libpthread.
+   Copyright (C) 2014 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 <shlib-compat.h>
+
+/* libpthread used to have its own vfork implementation that differed
+   from libc's only in having a pointless micro-optimization.  There
+   is no longer any use to having a separate copy in libpthread, but
+   the historical ABI requires it.  For static linking, there is no
+   need to provide anything here--the libc version will be linked in.
+   For shared library ABI compatibility, there must be __vfork and
+   vfork symbols in libpthread.so.  */
+
+#if HAVE_IFUNC
+# include <nptl/pt-vfork.c>
+#elif (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \
+       || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20))
+
+/* Thankfully, on AArch64 we can rely on the compiler generating
+   a tail call here.  */
+
+extern void __libc_vfork (void);
+
+void
+vfork_compat (void)
+{
+  __libc_vfork ();
+}
+
+# if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20)
+compat_symbol (libpthread, vfork_compat, vfork, GLIBC_2_0);
+# endif
+
+# if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)
+strong_alias (vfork_compat, vfork_compat2)
+compat_symbol (libpthread, vfork_compat2, __vfork, GLIBC_2_1_2);
+# endif
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/vfork.S b/sysdeps/unix/sysv/linux/aarch64/vfork.S
index d9f2c70..316cb65 100644
--- a/sysdeps/unix/sysv/linux/aarch64/vfork.S
+++ b/sysdeps/unix/sysv/linux/aarch64/vfork.S
@@ -28,22 +28,33 @@
 
 ENTRY (__vfork)
 
-#ifdef SAVE_PID
-	SAVE_PID
-#endif
+	/* Save the TCB-cached PID away in w3, and then negate the TCB
+           field.  But if it's zero, set it to 0x80000000 instead.  See
+           raise.c for the logic that relies on this value.  */
+	mrs	x2, tpidr_el0
+	sub	x2, x2, #PTHREAD_SIZEOF
+	ldr	w3, [x2, #PTHREAD_PID_OFFSET]
+	mov	w1, #0x80000000
+	negs	w0, w3
+	csel	w0, w1, w0, eq
+	str	w0, [x2, #PTHREAD_PID_OFFSET]
+
 	mov	x0, #0x4111	/* CLONE_VM | CLONE_VFORK | SIGCHLD */
 	mov	x1, sp
 	DO_CALL (clone, 2)
-#ifdef RESTORE_PID
-	RESTORE_PID
-#endif
+
+	/* Restore the original value of the TCB cache of the PID, if we're
+	   the parent.  But in the child (syscall return value equals zero),
+	   leave things as they are.  */
+	cbz	x0, 1f
+	str	w3, [x2, #PTHREAD_PID_OFFSET]
+1:
 	cmn	x0, #4095
-	b.cs    1f
+	b.cs    .Lsyscall_error
 	RET
-1:
-	b	SYSCALL_ERROR
 
 PSEUDO_END (__vfork)
 libc_hidden_def (__vfork)
 
 weak_alias (__vfork, vfork)
+strong_alias (__vfork, __libc_vfork)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5c88aeadc83adec02d7126cea6aada0957fe67cf

commit 5c88aeadc83adec02d7126cea6aada0957fe67cf
Author: Richard Henderson <rth@redhat.com>
Date:   Fri May 23 15:44:23 2014 -0400

    aarch64: Consolidate NPTL/non versions of clone
    
    At the same time, rely on non-clobbered registers across syscall
    so that we eliminate the stack frame that we previously ignored
    in the unwind info.

diff --git a/sysdeps/unix/sysv/linux/aarch64/clone.S b/sysdeps/unix/sysv/linux/aarch64/clone.S
index f2964f4..a2b5a2b 100644
--- a/sysdeps/unix/sysv/linux/aarch64/clone.S
+++ b/sysdeps/unix/sysv/linux/aarch64/clone.S
@@ -39,47 +39,42 @@
  */
         .text
 ENTRY(__clone)
+	/* Save args for the child.  */
+	mov	x10, x0
+	mov	x11, x2
+	mov	x12, x3
+
 	/* Sanity check args.  */
-	cbz	x0, 1f
-	cbz	x1, 1f
-	/* Insert the args onto the new stack.  */
-	stp	x0, x3, [x1, #-16]!	/* Fn, arg.  */
+	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  */
-
-#ifdef RESET_PID
-	/* We rely on the kernel preserving the argument regsiters across a
-	   each system call so that we can inspect the flags against after
-	   the clone call.  */
-	mov	x5, x0
-#endif
-
 	mov	x8, #SYS_ify(clone)
-	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
 	svc	0x0
-	cfi_endproc
+
 	cmp	x0, #0
-	beq	2f
-	blt	3f
+	beq	thread_start
+	blt	.Lsyscall_error
 	RET
-1:	mov	x0, #-EINVAL
-3:
-	b	syscall_error
+PSEUDO_END (__clone)
 
-2:
+	.align 4
+	.type thread_start, %function
+thread_start:
 	cfi_startproc
 	cfi_undefined (x30)
 	mov	x29, 0
-#ifdef RESET_PID
-	tbnz	x5, #CLONE_THREAD_BIT, 3f
+
+	tbnz	x11, #CLONE_THREAD_BIT, 3f
 	mov	x0, #-1
-	tbnz	x5, #CLONE_VM_BIT, 2f
+	tbnz	x11, #CLONE_VM_BIT, 2f
 	mov	x8, #SYS_ify(getpid)
 	svc	0x0
 2:
@@ -87,18 +82,15 @@ ENTRY(__clone)
 	sub	x1, x1, #PTHREAD_SIZEOF
 	str	w0, [x1, #PTHREAD_PID_OFFSET]
 	str	w0, [x1, #PTHREAD_TID_OFFSET]
-
 3:
-#endif
-	/* Pick the function arg and call address from the stack and
-	   execute.  */
-	ldp	x1, x0, [sp], #16
-	blr	x1
+
+	/* 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
-	cfi_startproc
-PSEUDO_END (__clone)
+	.size thread_start, .-thread_start
 
 weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/clone.S b/sysdeps/unix/sysv/linux/aarch64/nptl/clone.S
deleted file mode 100644
index 281be3b..0000000
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/clone.S
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright (C) 2009-2014 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 RESET_PID
-#include <tcb-offsets.h>
-#include "../clone.S"

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b3fa06b9fd11d6de2019906d1200fb5fa00ba7ae

commit b3fa06b9fd11d6de2019906d1200fb5fa00ba7ae
Author: Richard Henderson <rth@redhat.com>
Date:   Thu May 22 16:57:20 2014 -0400

    aarch64: Rely on syscalls preserving registers
    
    In several cases we've had asm routines rely on syscalls not clobbering
    call-clobbered registers, and that's now deemed ABI.  So take advantage
    of this in the INLINE_SYSCALL path as well.
    
    Shrinks libc.so by about 1k.

diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index 8cce986..4686599 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
@@ -231,7 +231,7 @@
     LOAD_ARGS_##nr (args)					\
     asm volatile ("blr %1"					\
 		  : "=r" (_x0)					\
-		  : "r" (funcptr), ASM_ARGS_##nr		\
+		  : "r" (funcptr) ASM_ARGS_##nr			\
 		  : "x30", "memory");				\
     (long) _x0;							\
   })
@@ -254,17 +254,15 @@
 
 # undef INTERNAL_SYSCALL_RAW
 # define INTERNAL_SYSCALL_RAW(name, err, nr, args...)		\
-  ({ unsigned long _sys_result;					\
+  ({ long _sys_result;						\
      {								\
        LOAD_ARGS_##nr (args)					\
        register long _x8 asm ("x8") = (name);			\
        asm volatile ("svc	0	// syscall " # name     \
-		     : "+r" (_x0), "+r" (_x8)			\
-		     : ASM_ARGS_##nr				\
-		     : "memory", CLOBBER_ARGS_##nr);		\
+		     : "=r" (_x0) : "r"(_x8) ASM_ARGS_##nr : "memory");	\
        _sys_result = _x0;					\
      }								\
-     (long) _sys_result; })
+     _sys_result; })
 
 # undef INTERNAL_SYSCALL
 # define INTERNAL_SYSCALL(name, err, nr, args...)		\
@@ -281,54 +279,44 @@
 # undef INTERNAL_SYSCALL_ERRNO
 # define INTERNAL_SYSCALL_ERRNO(val, err)	(-(val))
 
-# define CLOBBER_ARGS_0       CLOBBER_ARGS_1
-# define CLOBBER_ARGS_1 "x1", CLOBBER_ARGS_2
-# define CLOBBER_ARGS_2 "x2", CLOBBER_ARGS_3
-# define CLOBBER_ARGS_3 "x3", CLOBBER_ARGS_4
-# define CLOBBER_ARGS_4 "x4", CLOBBER_ARGS_5
-# define CLOBBER_ARGS_5 "x5", CLOBBER_ARGS_6
-# define CLOBBER_ARGS_6 "x6", CLOBBER_ARGS_7
-# define CLOBBER_ARGS_7 \
-  "x7", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18"
-
 # define LOAD_ARGS_0()				\
   register long _x0 asm ("x0");
-
-# define ASM_ARGS_0
 # define LOAD_ARGS_1(x0)			\
   long _x0tmp = (long) (x0);			\
   LOAD_ARGS_0 ()				\
   _x0 = _x0tmp;
-# define ASM_ARGS_1	"r" (_x0)
 # define LOAD_ARGS_2(x0, x1)			\
   long _x1tmp = (long) (x1);			\
   LOAD_ARGS_1 (x0)				\
   register long _x1 asm ("x1") = _x1tmp;
-# define ASM_ARGS_2	ASM_ARGS_1, "r" (_x1)
 # define LOAD_ARGS_3(x0, x1, x2)		\
   long _x2tmp = (long) (x2);			\
   LOAD_ARGS_2 (x0, x1)				\
   register long _x2 asm ("x2") = _x2tmp;
-# define ASM_ARGS_3	ASM_ARGS_2, "r" (_x2)
 # define LOAD_ARGS_4(x0, x1, x2, x3)		\
   long _x3tmp = (long) (x3);			\
   LOAD_ARGS_3 (x0, x1, x2)			\
   register long _x3 asm ("x3") = _x3tmp;
-# define ASM_ARGS_4	ASM_ARGS_3, "r" (_x3)
 # define LOAD_ARGS_5(x0, x1, x2, x3, x4)	\
   long _x4tmp = (long) (x4);			\
   LOAD_ARGS_4 (x0, x1, x2, x3)			\
   register long _x4 asm ("x4") = _x4tmp;
-# define ASM_ARGS_5	ASM_ARGS_4, "r" (_x4)
 # define LOAD_ARGS_6(x0, x1, x2, x3, x4, x5)	\
   long _x5tmp = (long) (x5);			\
   LOAD_ARGS_5 (x0, x1, x2, x3, x4)		\
   register long _x5 asm ("x5") = _x5tmp;
-# define ASM_ARGS_6	ASM_ARGS_5, "r" (_x5)
 # define LOAD_ARGS_7(x0, x1, x2, x3, x4, x5, x6)\
   long _x6tmp = (long) (x6);			\
   LOAD_ARGS_6 (x0, x1, x2, x3, x4, x5)		\
   register long _x6 asm ("x6") = _x6tmp;
+
+# 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)
 
 # undef INTERNAL_SYSCALL_NCS

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=78a9fec1066d45d8326d62e4424c613d5f4626ac

commit 78a9fec1066d45d8326d62e4424c613d5f4626ac
Author: Richard Henderson <rth@redhat.com>
Date:   Tue May 20 16:34:59 2014 -0400

    aarch64: Use tpidr_el0 rather than __errno_location in librt

diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data b/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
index 84af95d..dfca9a7 100644
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
+++ b/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
@@ -12,4 +12,3 @@ libm.so: matherr
 libm.so: __signbit
 libm.so: __signbitf
 libm.so: __signbitl
-libpthread.so: __errno_location
diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index 0e91f83..8cce986 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
@@ -123,21 +123,12 @@
 
 #   define SYSCALL_ERROR_HANDLER				\
 .Lsyscall_error:						\
-	stp     x29, x30, [sp, -32]!;				\
-	cfi_adjust_cfa_offset (32);				\
-	cfi_rel_offset (x29, 0);				\
-	cfi_rel_offset (x30, 8);				\
-        add     x29, sp, 0;					\
-        str     x19, [sp,16];					\
-	neg	x19, x0;					\
-	bl	C_SYMBOL_NAME(__errno_location);		\
-	str	w19, [x0];					\
+	adrp	x1, :gottprel:errno;				\
+	neg	w2, w0;						\
+	ldr	x1, [x1, :gottprel_lo12:errno];			\
+	mrs	x3, tpidr_el0;					\
 	mov	x0, -1;						\
-        ldr     x19, [sp,16];					\
-        ldp     x29, x30, [sp], 32;				\
-	cfi_adjust_cfa_offset (-32);				\
-	cfi_restore (x29);					\
-	cfi_restore (x30);					\
+	str	w2, [x1, x3];					\
 	RET;
 #  endif
 # else

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e9bd3751a4120280d5bff365f717e9de2fc0d3f0

commit e9bd3751a4120280d5bff365f717e9de2fc0d3f0
Author: Richard Henderson <rth@redhat.com>
Date:   Tue May 20 16:17:20 2014 -0400

    aarch64: Use tpidr_el0 rather than __read_tp in librt

diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
index a78e2ad..3578650 100644
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+++ b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
@@ -108,8 +108,8 @@ 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]
+	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.  */
@@ -119,18 +119,9 @@ extern int __local_multiple_threads attribute_hidden;
 				   header.multiple_threads) == 0, 1)
 #  else
 #   define SINGLE_THREAD_P(R)						\
-  stp	x0, x30, [sp, -16]!;						\
-  cfi_adjust_cfa_offset (16);						\
-  cfi_rel_offset (x0, 0);						\
-  cfi_rel_offset (x30, 8);						\
-  bl	__read_tp;							\
-  sub	x0, x0, PTHREAD_SIZEOF;						\
-  ldr	w##R, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET];			\
-  ldp	x0, x30, [sp], 16;						\
-  cfi_restore (x0);							\
-  cfi_restore (x30);							\
-  cfi_adjust_cfa_offset (-16);						\
-  cmp	w16, 0
+	mrs     x##R, tpidr_el0;					\
+	sub	x##R, x##R, PTHREAD_SIZEOF;				\
+	ldr	w##R, [x##R, PTHREAD_MULTIPLE_THREADS_OFFSET]
 #  endif
 # endif
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e350932f4abe6b68b973b6f6205c29de26e6bf07

commit e350932f4abe6b68b973b6f6205c29de26e6bf07
Author: Richard Henderson <rth@redhat.com>
Date:   Tue May 20 15:31:14 2014 -0400

    aarch64: Improve sysdep-cancel.h
    
    Use a constant frame size, rather than pushing/popping for every saved
    register.  Use stp, ldp, cbz.  Share code with the _nocancel path.

diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
index c300b2d..a78e2ad 100644
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+++ b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
@@ -26,120 +26,66 @@
 
 # undef PSEUDO
 # define PSEUDO(name, syscall_name, args)				\
-  .section ".text";							\
-  .type __##syscall_name##_nocancel,%function;				\
-  .globl __##syscall_name##_nocancel;					\
-  __##syscall_name##_nocancel:						\
-    cfi_startproc;							\
-    DO_CALL (syscall_name, args);					\
-    cmn x0, 4095;							\
-    b.cs .Lsyscall_error;						\
-    PSEUDO_RET;								\
-    cfi_endproc;							\
-    .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	\
-  ENTRY (name);								\
-    SINGLE_THREAD_P;							\
-    bne .Lpseudo_cancel;						\
-    DO_CALL (syscall_name, 0);						\
-    cmn x0, 4095;							\
-    b.cs .Lsyscall_error;						\
-    PSEUDO_RET;								\
-  .Lpseudo_cancel:							\
-    DOCARGS_##args;	/* save syscall args etc. around CENABLE.  */	\
-    CENABLE;								\
-    mov x16, x0;	/* put mask in safe place.  */			\
-    UNDOCARGS_##args;	/* restore syscall args.  */			\
-    mov x8, SYS_ify (syscall_name);	/* do the call.  */		\
-    svc	0;								\
-    str x0, [sp, -16]!;	/* save syscall return value.  */		\
-    cfi_adjust_cfa_offset (16);						\
-    mov x0, x16;	 /* get mask back.  */				\
-    CDISABLE;								\
-    ldr x0, [sp], 16;							\
-    cfi_adjust_cfa_offset (-16);					\
-    ldr x30, [sp], 16;							\
-    cfi_adjust_cfa_offset (-16);					\
-    cfi_restore (x30);							\
-    cmn x0, 4095;							\
-    b.cs .Lsyscall_error;
-
-# define DOCARGS_0							\
-	str x30, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x30, 0)
-
+	.section ".text";						\
+ENTRY (__##syscall_name##_nocancel);					\
+.Lpseudo_nocancel:							\
+	DO_CALL (syscall_name, args);					\
+.Lpseudo_ret:								\
+	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.  */	\
+	stp	x19, x30, [sp, -64]!;					\
+	cfi_adjust_cfa_offset (64);					\
+	cfi_rel_offset (x19, 0);					\
+	cfi_rel_offset (x30, 8);					\
+	DOCARGS_##args;		/* save syscall args around CENABLE. */	\
+	CENABLE;							\
+	mov	x19, x0;	/* save mask around syscall. */		\
+	UNDOCARGS_##args;	/* restore syscall args.  */		\
+	DO_CALL (syscall_name, args);					\
+	str	x0, [sp, 16];	/* save syscall return value.  */	\
+	mov	x0, x19;	/* pass mask to CDISABLE. */		\
+	CDISABLE;							\
+	ldr	x0, [sp, 16];						\
+	ldp	x19, x30, [sp], 64;					\
+	cfi_adjust_cfa_offset (-64);					\
+	cfi_restore (x19);						\
+	cfi_restore (x30);						\
+	b	.Lpseudo_ret;						\
+	cfi_endproc;							\
+	.size name, .-name;						\
+	.previous
+
+# undef PSEUDO_END
+# define PSEUDO_END(name)						\
+	SYSCALL_ERROR_HANDLER;						\
+	cfi_endproc
+
+# define DOCARGS_0
 # define UNDOCARGS_0
 
-# define DOCARGS_1							\
-	DOCARGS_0;							\
-	str x0, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x0, 0)
-
-# define UNDOCARGS_1							\
-	ldr x0, [sp], 16;						\
-	cfi_restore (x0);						\
-	cfi_adjust_cfa_offset (-16);					\
-
-# define DOCARGS_2							\
-	DOCARGS_1;							\
-	str x1, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x1, 0)
-
-# define UNDOCARGS_2							\
-	ldr x1, [sp], 16;						\
-	cfi_restore (x1);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_1
-
-# define DOCARGS_3							\
-	DOCARGS_2;							\
-	str x2, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x2, 0)
-
-# define UNDOCARGS_3							\
-	ldr x2, [sp], 16;						\
-	cfi_restore (x2);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_2
-
-# define DOCARGS_4							\
-	DOCARGS_3;							\
-	str x3, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x3, 0)
-
-# define UNDOCARGS_4							\
-	ldr x3, [sp], 16;						\
-	cfi_restore (x3);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_3
-
-# define DOCARGS_5							\
-	DOCARGS_4;							\
-	str x4, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x4, 0)
-
-# define UNDOCARGS_5							\
-	ldr x4, [sp], 16;						\
-	cfi_restore (x4);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_4
-
-# define DOCARGS_6							\
-	DOCARGS_5;							\
-	str x5, [sp, -16]!;						\
-	cfi_adjust_cfa_offset (16);					\
-	cfi_rel_offset (x5, 0)
-
-# define UNDOCARGS_6							\
-	ldr x5, [sp], 16;						\
-	cfi_restore (x5);						\
-	cfi_adjust_cfa_offset (-16);					\
-	UNDOCARGS_5
+# define DOCARGS_1	str x0, [sp, 16]
+# define UNDOCARGS_1	ldr x0, [sp, 16]
+
+# define DOCARGS_2	stp x0, x1, [sp, 16]
+# define UNDOCARGS_2	ldp x0, x1, [sp, 16]
+
+# define DOCARGS_3	DOCARGS_2;   str x2, [sp, 32]
+# define UNDOCARGS_3	UNDOCARGS_2; ldr x2, [sp, 32]
+
+# define DOCARGS_4	DOCARGS_2;   stp x2, x3, [sp, 32]
+# define UNDOCARGS_4	UNDOCARGS_2; ldp x2, x3, [sp, 32]
+
+# define DOCARGS_5	DOCARGS_4;   str x4, [sp, 48]
+# define UNDOCARGS_5	UNDOCARGS_4; ldr x4, [sp, 48]
+
+# define DOCARGS_6	DOCARGS_4;   stp x4, x5, [sp, 48]
+# define UNDOCARGS_6	UNDOCARGS_4; ldp x4, x5, [sp, 48]
 
 # ifdef IS_IN_libpthread
 #  define CENABLE	bl __pthread_enable_asynccancel
@@ -161,10 +107,9 @@
 extern int __local_multiple_threads attribute_hidden;
 #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
 #  else
-#   define SINGLE_THREAD_P						\
-  adrp	x16, __local_multiple_threads;					\
-  ldr	w16, [x16, :lo12:__local_multiple_threads];			\
-  cmp	w16, 0;
+#   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.  */
@@ -173,14 +118,14 @@ extern int __local_multiple_threads attribute_hidden;
   __builtin_expect (THREAD_GETMEM (THREAD_SELF,				\
 				   header.multiple_threads) == 0, 1)
 #  else
-#   define SINGLE_THREAD_P						\
+#   define SINGLE_THREAD_P(R)						\
   stp	x0, x30, [sp, -16]!;						\
   cfi_adjust_cfa_offset (16);						\
   cfi_rel_offset (x0, 0);						\
   cfi_rel_offset (x30, 8);						\
   bl	__read_tp;							\
   sub	x0, x0, PTHREAD_SIZEOF;						\
-  ldr	w16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET];			\
+  ldr	w##R, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET];			\
   ldp	x0, x30, [sp], 16;						\
   cfi_restore (x0);							\
   cfi_restore (x30);							\

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=adf75ec15944cd3ee0a9401b9cf13339582ef5fb

commit adf75ec15944cd3ee0a9401b9cf13339582ef5fb
Author: Richard Henderson <rth@redhat.com>
Date:   Fri May 23 16:37:15 2014 -0400

    arm,aarch64: Remove SINGLE_THREAD_P_PIC
    
    This macro was removed by
    
    2005-11-16  Daniel Jacobowitz  <dan@codesourcery.com>
    
    but not applied to the (still separate) eabi port so necro'd
    when the eabi port superceded the old abi.  It was thence
    copied into the new AArch64 port.

diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
index 2d0ae5b..c300b2d 100644
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+++ b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
@@ -186,7 +186,6 @@ extern int __local_multiple_threads attribute_hidden;
   cfi_restore (x30);							\
   cfi_adjust_cfa_offset (-16);						\
   cmp	w16, 0
-#   define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
 #  endif
 # endif
 
diff --git a/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h b/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
index 118e6c3..a0a8696 100644
--- a/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
+++ b/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
@@ -223,7 +223,6 @@ extern int __local_multiple_threads attribute_hidden;
 	cfi_adjust_cfa_offset (-8);					\
 	cfi_restore (lr);						\
 	teq	ip, #0
-#   define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
 #  endif
 # endif
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2f8ead285e0e920755a6fba51db8ad3de55c8143

commit 2f8ead285e0e920755a6fba51db8ad3de55c8143
Author: Richard Henderson <rth@redhat.com>
Date:   Tue May 20 14:40:22 2014 -0400

    aarch64: Tidy syscall error check
    
    Move the error branch from the PSEUDO_RET macro to the PSEUDO macro.
    This is in line with other architectures, and will enable further improvments.

diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
index 957bb99..2d0ae5b 100644
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+++ b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
@@ -33,6 +33,7 @@
     cfi_startproc;							\
     DO_CALL (syscall_name, args);					\
     cmn x0, 4095;							\
+    b.cs .Lsyscall_error;						\
     PSEUDO_RET;								\
     cfi_endproc;							\
     .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	\
@@ -41,6 +42,7 @@
     bne .Lpseudo_cancel;						\
     DO_CALL (syscall_name, 0);						\
     cmn x0, 4095;							\
+    b.cs .Lsyscall_error;						\
     PSEUDO_RET;								\
   .Lpseudo_cancel:							\
     DOCARGS_##args;	/* save syscall args etc. around CENABLE.  */	\
@@ -58,7 +60,8 @@
     ldr x30, [sp], 16;							\
     cfi_adjust_cfa_offset (-16);					\
     cfi_restore (x30);							\
-    cmn x0, 4095;
+    cmn x0, 4095;							\
+    b.cs .Lsyscall_error;
 
 # define DOCARGS_0							\
 	str x30, [sp, -16]!;						\
diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index cffd008..0e91f83 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
@@ -58,17 +58,15 @@
   .text;								      \
   ENTRY (name);								      \
     DO_CALL (syscall_name, args);					      \
-    cmn x0, #4095;
+    cmn x0, #4095;							      \
+    b.cs .Lsyscall_error;
 
 /* Notice the use of 'RET' instead of 'ret' the assembler is case
    insensitive and eglibc already uses the preprocessor symbol 'ret'
    so we use the upper case 'RET' to force through a ret instruction
    to the assembler */
 # define PSEUDO_RET							      \
-    b.cs 1f;								      \
-    RET;								      \
-    1:                                                                        \
-    b SYSCALL_ERROR
+    RET;
 # undef ret
 # define ret PSEUDO_RET
 
@@ -112,10 +110,10 @@
 # define ret_ERRVAL PSEUDO_RET_NOERRNO
 
 # if NOT_IN_libc
-#  define SYSCALL_ERROR __local_syscall_error
+#  define SYSCALL_ERROR  .Lsyscall_error
 #  if RTLD_PRIVATE_ERRNO
 #   define SYSCALL_ERROR_HANDLER				\
-__local_syscall_error:						\
+.Lsyscall_error:						\
 	adrp	x1, C_SYMBOL_NAME(rtld_errno);			\
 	neg     w0, w0;						\
 	str     w0, [x1, :lo12:C_SYMBOL_NAME(rtld_errno)];	\
@@ -124,7 +122,7 @@ __local_syscall_error:						\
 #  else
 
 #   define SYSCALL_ERROR_HANDLER				\
-__local_syscall_error:						\
+.Lsyscall_error:						\
 	stp     x29, x30, [sp, -32]!;				\
 	cfi_adjust_cfa_offset (32);				\
 	cfi_rel_offset (x29, 0);				\
@@ -143,8 +141,10 @@ __local_syscall_error:						\
 	RET;
 #  endif
 # else
-#  define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
 #  define SYSCALL_ERROR __syscall_error
+#  define SYSCALL_ERROR_HANDLER                                 \
+.Lsyscall_error:                                                \
+	b	__syscall_error;
 # endif
 
 /* Linux takes system call args in registers:

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=3a2ff4d9fca3f447b83a99bdee4e26ded46b45a4

commit 3a2ff4d9fca3f447b83a99bdee4e26ded46b45a4
Author: Richard Henderson <rth@redhat.com>
Date:   Thu May 22 11:38:05 2014 -0400

    aarch64: Remove DOARGS/UNDOARGS macros
    
    While they do something for AArch32, they're useless for AArch64.

diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
index 24fae7b..957bb99 100644
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+++ b/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
@@ -38,10 +38,8 @@
     .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	\
   ENTRY (name);								\
     SINGLE_THREAD_P;							\
-    DOARGS_##args;							\
     bne .Lpseudo_cancel;						\
     DO_CALL (syscall_name, 0);						\
-    UNDOARGS_##args;							\
     cmn x0, 4095;							\
     PSEUDO_RET;								\
   .Lpseudo_cancel:							\
@@ -60,7 +58,6 @@
     ldr x30, [sp], 16;							\
     cfi_adjust_cfa_offset (-16);					\
     cfi_restore (x30);							\
-    UNDOARGS_##args;							\
     cmn x0, 4095;
 
 # define DOCARGS_0							\
diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index 8397ad3..cffd008 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
@@ -148,7 +148,7 @@ __local_syscall_error:						\
 # endif
 
 /* Linux takes system call args in registers:
-	syscall number	in the SVC instruction
+	syscall number	x8
 	arg 1		x0
 	arg 2		x1
 	arg 3		x2
@@ -172,28 +172,8 @@ __local_syscall_error:						\
 
 # undef	DO_CALL
 # define DO_CALL(syscall_name, args)		\
-    DOARGS_##args				\
     mov x8, SYS_ify (syscall_name);		\
-    svc 0;					\
-    UNDOARGS_##args
-
-# define DOARGS_0 /* nothing */
-# define DOARGS_1 /* nothing */
-# define DOARGS_2 /* nothing */
-# define DOARGS_3 /* nothing */
-# define DOARGS_4 /* nothing */
-# define DOARGS_5 /* nothing */
-# define DOARGS_6 /* nothing */
-# define DOARGS_7 /* nothing */
-
-# define UNDOARGS_0 /* nothing */
-# define UNDOARGS_1 /* nothing */
-# define UNDOARGS_2 /* nothing */
-# define UNDOARGS_3 /* nothing */
-# define UNDOARGS_4 /* nothing */
-# define UNDOARGS_5 /* nothing */
-# define UNDOARGS_6 /* nothing */
-# define UNDOARGS_7 /* nothing */
+    svc 0
 
 #else /* not __ASSEMBLER__ */
 

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


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]