This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch rth/aa-opt created. glibc-2.19-477-gaad7cde
- From: rth at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 24 May 2014 00:02:16 -0000
- Subject: 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