about summary refs log tree commit diff
path: root/sysdeps/unix
diff options
context:
space:
mode:
authorDavid Holsgrove <david.holsgrove@xilinx.com>2014-06-30 14:01:22 +1000
committerDavid Holsgrove <david.holsgrove@xilinx.com>2014-07-01 09:58:03 +1000
commit0cdcad1769a962583788841f6dc2df1efe989245 (patch)
treeced4105d8971e708b155b0e104679fec1fb38406 /sysdeps/unix
parent9b71d0e38c587dd1616eefd9d9ac09be90a28fe4 (diff)
downloadglibc-0cdcad1769a962583788841f6dc2df1efe989245.tar.gz
glibc-0cdcad1769a962583788841f6dc2df1efe989245.tar.xz
glibc-0cdcad1769a962583788841f6dc2df1efe989245.zip
MicroBlaze: Add missing sysdep-cancel.h implementation
And update socket.S, Makefile to use *_nocancel definitions.

Absence of sysdep-cancel.h was not apparent until Roland's
not-cancel.h unification.

2014-06-30  David Holsgrove  <david.holsgrove@xilinx.com>

  * sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h: New file
  * sysdeps/unix/sysv/linux/microblaze/socket.S: Update SINGLE_THREAD_P
  * sysdeps/unix/sysv/linux/microblaze/Makefile: Add to libpthread-routines

Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
Diffstat (limited to 'sysdeps/unix')
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/Makefile5
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/socket.S2
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h158
3 files changed, 164 insertions, 1 deletions
diff --git a/sysdeps/unix/sysv/linux/microblaze/Makefile b/sysdeps/unix/sysv/linux/microblaze/Makefile
index 614553204f..44a838fa11 100644
--- a/sysdeps/unix/sysv/linux/microblaze/Makefile
+++ b/sysdeps/unix/sysv/linux/microblaze/Makefile
@@ -1,3 +1,8 @@
 ifeq ($(subdir),resource)
 sysdep_routines += backtrace_linux
 endif
+
+ifeq ($(subdir),nptl)
+# pull in __syscall_error routine
+libpthread-routines += sysdep
+endif
\ No newline at end of file
diff --git a/sysdeps/unix/sysv/linux/microblaze/socket.S b/sysdeps/unix/sysv/linux/microblaze/socket.S
index ab1cb54070..a5b6ec4ac2 100644
--- a/sysdeps/unix/sysv/linux/microblaze/socket.S
+++ b/sysdeps/unix/sysv/linux/microblaze/socket.S
@@ -80,7 +80,7 @@ ENTRY(__socket)
 /* The rest of the args (if any) are on the caller's stack already.  */
 
 #if defined NEED_CANCELLATION && defined CENABLE
-	SINGLE_THREAD_P
+	SINGLE_THREAD_P(r12)
 	bnei	r12,L(socket_cancel)
 #endif
 
diff --git a/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h b/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h
new file mode 100644
index 0000000000..0080d8d4f9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h
@@ -0,0 +1,158 @@
+/* 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 <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# if !defined(IS_IN_librt) || !defined(PIC)
+#  define AC_STACK_SIZE  16  /* space for r15, async_cancel arg and 2 temp words */
+#  define AC_SET_GOT /* empty */
+#  define AC_RESTORE_GOT /* empty */
+# else
+#  define AC_STACK_SIZE  20  /* extra 4 bytes for r20 */
+#  define AC_SET_GOT                                                 \
+    swi   r20, r1, AC_STACK_SIZE-4;                                  \
+    mfs   r20, rpc;                                                  \
+    addik r20, r20, _GLOBAL_OFFSET_TABLE_+8;
+#  define AC_RESTORE_GOT                                             \
+    lwi   r20, r1, AC_STACK_SIZE-4;
+# endif
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)                            \
+  .text;                                                             \
+  ENTRY (name)                                                       \
+    SINGLE_THREAD_P(r12);                                            \
+    bnei r12, L(pseudo_cancel);                                      \
+  .globl __##syscall_name##_nocancel;                                \
+  .type __##syscall_name##_nocancel,@function;                       \
+__##syscall_name##_nocancel:                                         \
+    DO_CALL (syscall_name, args);                                    \
+    addik r4, r0, -4095;                                             \
+    cmpu  r4, r4, r3;                                                \
+    bgei  r4, SYSCALL_ERROR_LABEL;                                   \
+    rtsd  r15, 8;                                                    \
+    nop;                                                             \
+  .size __##syscall_name##_nocancel, .-__##syscall_name##_nocancel;  \
+L(pseudo_cancel):                                                    \
+    addik r1, r1, -AC_STACK_SIZE;                                    \
+    swi   r15, r1, 0;                                                \
+    AC_SET_GOT                                                       \
+    DOCARGS_##args                                                   \
+    CENABLE;                                                         \
+    swi   r3, r1, 8;                                                 \
+    UNDOCARGS_##args                                                 \
+    DO_CALL (syscall_name, args);                                    \
+    swi   r3, r1, 12;                                                \
+    lwi   r5, r1, 8;                                                 \
+    CDISABLE;                                                        \
+    lwi   r3, r1, 12;                                                \
+    lwi   r15, r1, 0;                                                \
+    AC_RESTORE_GOT                                                   \
+    addik r1, r1, AC_STACK_SIZE;                                     \
+    addik r4, r0, -4095;                                             \
+    cmpu  r4, r4, r3;                                                \
+    bgei  r4, SYSCALL_ERROR_LABEL;                                   \
+    rtsd  r15, 8;                                                    \
+    nop;
+
+/*
+ * Macros to save/restore syscall arguments across CENABLE
+ * The arguments are saved into the caller's stack (original r1 + 4)
+ */
+
+# define DOCARGS_0
+# define DOCARGS_1  swi   r5, r1, AC_STACK_SIZE + 4;
+# define DOCARGS_2  swi   r6, r1, AC_STACK_SIZE + 8; DOCARGS_1
+# define DOCARGS_3  swi   r7, r1, AC_STACK_SIZE + 12; DOCARGS_2
+# define DOCARGS_4  swi   r8, r1, AC_STACK_SIZE + 16; DOCARGS_3
+# define DOCARGS_5  swi   r9, r1, AC_STACK_SIZE + 20; DOCARGS_4
+# define DOCARGS_6  swi   r10, r1, AC_STACK_SIZE + 24; DOCARGS_5
+
+# define UNDOCARGS_0
+# define UNDOCARGS_1  lwi   r5, r1, AC_STACK_SIZE + 4;
+# define UNDOCARGS_2  UNDOCARGS_1 lwi   r6, r1, AC_STACK_SIZE + 8;
+# define UNDOCARGS_3  UNDOCARGS_2 lwi   r7, r1, AC_STACK_SIZE + 12;
+# define UNDOCARGS_4  UNDOCARGS_3 lwi   r8, r1, AC_STACK_SIZE + 16;
+# define UNDOCARGS_5  UNDOCARGS_4 lwi   r9, r1, AC_STACK_SIZE + 20;
+# define UNDOCARGS_6  UNDOCARGS_5 lwi   r10, r1, AC_STACK_SIZE + 24;
+
+# ifdef PIC
+#  define PSEUDO_JMP(sym)  brlid r15, sym##@PLTPC; addk r0, r0, r0
+# else
+#  define PSEUDO_JMP(sym)  brlid r15, sym; addk r0, r0, r0
+# endif
+
+# ifdef IS_IN_libpthread
+#  define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel)
+#  define CDISABLE  PSEUDO_JMP (__pthread_disable_asynccancel)
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define CENABLE PSEUDO_JMP (__libc_enable_asynccancel)
+#  define CDISABLE  PSEUDO_JMP (__libc_disable_asynccancel)
+#  define __local_multiple_threads __libc_multiple_threads
+# elif defined IS_IN_librt
+#  define CENABLE PSEUDO_JMP (__librt_enable_asynccancel)
+#  define CDISABLE  PSEUDO_JMP (__librt_disable_asynccancel)
+# else
+#  error Unsupported library
+# endif
+
+
+# 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
+#   if !defined PIC
+#    define SINGLE_THREAD_P(reg) lwi reg, r0, __local_multiple_threads;
+#   else
+#    define SINGLE_THREAD_P(reg)                                     \
+      mfs   reg, rpc;                                                \
+      addik reg, reg, _GLOBAL_OFFSET_TABLE_+8;                       \
+      lwi   reg, reg, __local_multiple_threads@GOT;                  \
+      lwi   reg, reg, 0;
+#   endif
+#  endif
+# else
+#  ifndef __ASSEMBLER__
+#   define SINGLE_THREAD_P                                           \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,                      \
+                                   header.multiple_threads) == 0, 1)
+#  else
+#   define SINGLE_THREAD_P(reg)                                      \
+     lwi reg, r0, MULTIPLE_THREADS_OFFSET(reg)
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+# 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