aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-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
4 files changed, 171 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index ed66e5442a..8deb4eeb1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-07-01 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 use.
+ * sysdeps/unix/sysv/linux/microblaze/Makefile(libpthread-routines):
+ Add sysdep.
+
2014-06-30 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
* sysdeps/powerpc/fpu/libm-test-ulps: Update.
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