This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


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

Various SH updates


Hi,

Attached patch is mainly to make SH TLS implementation to follow
the variant I correctly.
It includes also the changes of the syscall interface, clone and
vfork which are done for another architectures.
The change of sysdeps/unix/sysv/linux/sh/sys/user.h is needed for
nptl work and that of sh/pt-initfini.c in linuxthreads is simply
to remove an unnecessary definition.
The last logically independent change is to insert pad instructions
after trapa (which is a syscall instruction of linux/SH) for SH-4.
Hitachi says that 4 instruction cycles not accessing cache and TLB
are needed after trapa instruction to avoid an SH-4 silicon bug.
It would be better to send this as separated patches. Sorry for
this.

The patch was tested for both non-TLS and TLS.

Regards,
	kaz
--
[ChangeLog]
2003-02-07  Kaz Kojima  <kkojima@rr.iij4u.or.jp>

	* elf/tls-macros.h: Add non-PIC TLS macros and fix clobber list
	for SH.
	* sysdeps/unix/sysv/linux/sh/brk.c (): Add SYSCALL_INST_PAD
	after the trapa instruction.
	* sysdeps/unix/sysv/linux/sh/clone.S (__clone): Add additional
	parameters.
	* sysdeps/unix/sysv/linux/sh/sh4/sysdep.h: New file.
	(NEED_SYSCALL_INST_PAD): Define.
	* sysdeps/unix/sysv/linux/sh/sys/user.h (start_thread): Undef to
	avoid to use definition for the kernel.
	* sysdeps/unix/sysv/linux/sh/sysdep.h (SYSCALL_ERROR_HANDLER):
	Save and restore the frame pointer.
	(SYSCALL_INST_PAD): Define.
	(INLINE_SYSCALL): Make use of INTERNAL_SYSCALL.
	(INTERNAL_SYSCALL): Make use of ERR parameter. Add SYSCALL_INST_PAD
	after trapa instruction.
	(INTERNAL_SYSCALL_DECL, INTERNAL_SYSCALL_ERRNO,
        INTERNAL_SYSCALL_ERROR_P): Adjust accordingly.

[linuxthreads/ChangeLog]
2003-02-07  Kaz Kojima  <kkojima@rr.iij4u.or.jp>

	* sysdeps/sh/Makefile: New file.
	* sysdeps/sh/tcb-offsets.sym: Likewise.
	* sysdeps/sh/tls.h: Don't include sysdep.h. Move include
	of linuxthreads/descr.h after the definition of THREAD_SELF.
	(tcbhead_t): Use IA64 type tcbhead_t for TLS case.
	(TLS_TCB_SIZE): Set size of tcbhead_t.
	(TLS_PRE_TCB_SIZE): Define.
	(INSTALL_NEW_DTV): Set dtv of tcbhead_t structure instead of
	a member of thread structure.
	(THREAD_DTV): Likewise.
	(TLS_INIT_TP_EXPENSIVE): Remove.
	(TLS_INIT_TP): Set gbr register only.
	(THREAD_SELF): New.
	(INIT_THREAD_SELF): Likewise.
	(NONTLS_INIT_TP): New.
	* sysdeps/unix/sysv/linux/sh/pt-initfini.c (__fpscr_values):
	Remove.
	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (PSUEDO): Add
	SYSCALL_INST_PAD macro after DO_CALL.
	(SINGLE_THREAD_P): Fix non-PIC and TLS case so to read the
	correct	variable.
	* sysdeps/unix/sysv/linux/sh/vfork.S (__vfork): Branch to __fork
	whenever libpthread.so is loaded.

diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/elf/tls-macros.h LOCAL/libc/elf/tls-macros.h
--- ORIG/libc/elf/tls-macros.h	Thu Feb  6 23:18:40 2003
+++ LOCAL/libc/elf/tls-macros.h	Fri Feb  7 20:22:07 2003
@@ -145,9 +145,25 @@
 	  : "=r" (__l), "=r" (__tp));					      \
      __l; })
 
-# define TLS_IE(x) \
+# ifdef PIC
+#  define TLS_IE(x) \
   ({ int *__l; void *__tp;						      \
-     asm ("mova 0f,r0\n\t"						      \
+     register void *__gp __asm__("r12");				      \
+     asm ("mov.l 1f,r0\n\t"						      \
+	  "stc gbr,%1\n\t"						      \
+	  "mov.l @(r0,r12),%0\n\t"					      \
+	  "bra 2f\n\t"							      \
+	  " add %1,%0\n\t"						      \
+	  ".align 2\n\t"						      \
+	  "1: .long " #x "@gottpoff\n\t"				      \
+	  "2:"								      \
+	  : "=r" (__l), "=r" (__tp) : "r" (__gp) : "r0");		      \
+     __l; })
+# else
+#  define TLS_IE(x) \
+  ({ int *__l; void *__tp;						      \
+     asm ("mov.l r12,@-r15\n\t"						      \
+	  "mova 0f,r0\n\t"						      \
 	  "mov.l 0f,r12\n\t"						      \
 	  "add r0,r12\n\t"						      \
 	  "mov.l 1f,r0\n\t"						      \
@@ -158,13 +174,40 @@
 	  ".align 2\n\t"						      \
 	  "1: .long " #x "@gottpoff\n\t"				      \
 	  "0: .long _GLOBAL_OFFSET_TABLE_\n\t"				      \
-	  "2:"								      \
-	  : "=r" (__l), "=r" (__tp) : : "r0", "r12");			      \
+	  "2: mov.l @r15+,r12"						      \
+	  : "=r" (__l), "=r" (__tp) : : "r0");				      \
      __l; })
+#endif
 
-# define TLS_LD(x) \
+# ifdef PIC
+#  define TLS_LD(x) \
   ({ int *__l;								      \
-     asm ("mova 0f,r0\n\t"						      \
+     register void *__gp __asm__("r12");				      \
+     asm ("mov.l 1f,r4\n\t"						      \
+	  "mova 2f,r0\n\t"						      \
+	  "mov.l 2f,r1\n\t"						      \
+	  "add r0,r1\n\t"						      \
+	  "jsr @r1\n\t"							      \
+	  " add r12,r4\n\t"						      \
+	  "bra 4f\n\t"							      \
+	  " nop\n\t"							      \
+	  ".align 2\n\t"						      \
+	  "1: .long " #x "@tlsldm\n\t"					      \
+	  "2: .long __tls_get_addr@plt\n\t"				      \
+	  "4: mov.l 3f,%0\n\t"						      \
+	  "bra 5f\n\t"							      \
+	  " add r0,%0\n\t"						      \
+	  ".align 2\n\t"						      \
+	  "3: .long " #x "@dtpoff\n\t"					      \
+	  "5:"								      \
+	  : "=r" (__l) : "r" (__gp) : "r0", "r1", "r2", "r3", "r4", "r5",     \
+				      "r6", "r7", "pr", "t");		      \
+     __l; })
+# else
+#  define TLS_LD(x) \
+  ({ int *__l;								      \
+     asm ("mov.l r12,@-r15\n\t"						      \
+	  "mova 0f,r0\n\t"						      \
 	  "mov.l 0f,r12\n\t"						      \
 	  "add r0,r12\n\t"						      \
 	  "mov.l 1f,r4\n\t"						      \
@@ -184,14 +227,36 @@
 	  " add r0,%0\n\t"						      \
 	  ".align 2\n\t"						      \
 	  "3: .long " #x "@dtpoff\n\t"					      \
-	  "5:"								      \
+	  "5: mov.l @r15+,r12"						      \
 	  : "=r" (__l) : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",    \
-			   "r12", "pr", "t");				      \
+			   "pr", "t");					      \
      __l; })
+#endif
 
-# define TLS_GD(x) \
+# ifdef PIC
+#  define TLS_GD(x) \
   ({ int *__l;								      \
-     asm ("mova 0f,r0\n\t"						      \
+     register void *__gp __asm__("r12");				      \
+     asm ("mov.l 1f,r4\n\t"						      \
+	  "mova 2f,r0\n\t"						      \
+	  "mov.l 2f,r1\n\t"						      \
+	  "add r0,r1\n\t"						      \
+	  "jsr @r1\n\t"							      \
+	  " add r12,r4\n\t"						      \
+	  "bra 3f\n\t"							      \
+	  " mov r0,%0\n\t"						      \
+	  ".align 2\n\t"						      \
+	  "1: .long " #x "@tlsgd\n\t"					      \
+	  "2: .long __tls_get_addr@plt\n\t"				      \
+	  "3:"								      \
+	  : "=r" (__l) : "r" (__gp) : "r0", "r1", "r2", "r3", "r4", "r5",     \
+				      "r6", "r7", "pr", "t");		      \
+     __l; })
+# else
+#  define TLS_GD(x) \
+  ({ int *__l;								      \
+     asm ("mov.l r12,@-r15\n\t"						      \
+	  "mova 0f,r0\n\t"						      \
 	  "mov.l 0f,r12\n\t"						      \
 	  "add r0,r12\n\t"						      \
 	  "mov.l 1f,r4\n\t"						      \
@@ -206,10 +271,11 @@
 	  "1: .long " #x "@tlsgd\n\t"					      \
 	  "2: .long __tls_get_addr@plt\n\t"				      \
 	  "0: .long _GLOBAL_OFFSET_TABLE_\n\t"				      \
-	  "3:"								      \
+	  "3: mov.l @r15+,r12"						      \
 	  : "=r" (__l) : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",    \
-			   "r12", "pr", "t");				      \
+			   "pr", "t");					      \
      __l; })
+#endif
 
 #elif defined __alpha__
 
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/linuxthreads/sysdeps/sh/Makefile LOCAL/libc/linuxthreads/sysdeps/sh/Makefile
--- ORIG/libc/linuxthreads/sysdeps/sh/Makefile	Thu Jan  1 09:00:00 1970
+++ LOCAL/libc/linuxthreads/sysdeps/sh/Makefile	Fri Feb  7 20:22:07 2003
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/linuxthreads/sysdeps/sh/tcb-offsets.sym LOCAL/libc/linuxthreads/sysdeps/sh/tcb-offsets.sym
--- ORIG/libc/linuxthreads/sysdeps/sh/tcb-offsets.sym	Thu Jan  1 09:00:00 1970
+++ LOCAL/libc/linuxthreads/sysdeps/sh/tcb-offsets.sym	Fri Feb  7 20:22:07 2003
@@ -0,0 +1,10 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+#ifdef USE_TLS
+MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_header.data.multiple_threads)
+TLS_PRE_TCB_SIZE	sizeof (struct _pthread_descr_struct)
+#else
+MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
+#endif
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/linuxthreads/sysdeps/sh/tls.h LOCAL/libc/linuxthreads/sysdeps/sh/tls.h
--- ORIG/libc/linuxthreads/sysdeps/sh/tls.h	Wed Jan  8 08:37:17 2003
+++ LOCAL/libc/linuxthreads/sysdeps/sh/tls.h	Fri Feb  7 20:22:07 2003
@@ -34,15 +34,6 @@ typedef union dtv
   void *pointer;
 } dtv_t;
 
-
-typedef struct
-{
-  void *tcb;		/* Pointer to the TCB.  Not necessary the
-			   thread descriptor used by libpthread.  */
-  dtv_t *dtv;
-  void *self;		/* Pointer to the thread descriptor.  */
-  int multiple_threads;
-} tcbhead_t;
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
 #endif /* __ASSEMBLER__ */
@@ -55,73 +46,101 @@ typedef struct
 /* Signal that TLS support is available.  */
 # define USE_TLS	1
 
-#ifndef __ASSEMBLER__
-
-/* Get system call information.  */
-# include <sysdep.h>
+# ifndef __ASSEMBLER__
 
-/* Get the thread descriptor definition.  */
-# include <linuxthreads/descr.h>
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
 
 /* This is the size of the initial TCB.  */
-# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+#  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
 
 /* Alignment requirements for the initial TCB.  */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+#  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
 
 /* This is the size of the TCB.  */
-# define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
+#  define TLS_TCB_SIZE sizeof (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+#  define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
 
 /* Alignment requirements for the TCB.  */
-# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
+#  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
 
 /* The TLS blocks start right after the TCB.  */
-# define TLS_DTV_AT_TP	1
-
+#  define TLS_DTV_AT_TP	1
 
 /* Install the dtv pointer.  The pointer passed is to the element with
    index -1 which contain the length.  */
-# define INSTALL_DTV(descr, dtvp) \
-  ((tcbhead_t *) (descr))->dtv = dtvp + 1
+#  define INSTALL_DTV(tcbp, dtvp) \
+  ((tcbhead_t *) (tcbp))->dtv = dtvp + 1
 
 /* Install new dtv for current thread.  */
-# define INSTALL_NEW_DTV(dtv) \
-  ({ struct _pthread_descr_struct *__descr;				      \
-     THREAD_SETMEM (__descr, p_header.data.dtvp, (dtv)); })
+#  define INSTALL_NEW_DTV(dtv) \
+  ({ tcbhead_t *__tcbp;							      \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));			      \
+     __tcbp->dtv = (dtv);})
 
 /* Return dtv of given thread descriptor.  */
-# define GET_DTV(descr) \
-  (((tcbhead_t *) (descr))->dtv)
+#  define GET_DTV(tcbp) \
+  (((tcbhead_t *) (tcbp))->dtv)
 
 /* Code to initially initialize the thread pointer.  This might need
    special attention since 'errno' is not yet available and if the
    operation can cause a failure 'errno' must not be touched.  */
-# define TLS_INIT_TP(descr, secondcall) \
-  ({									      \
-    void *_descr = (descr);						      \
-    int result;								      \
-    tcbhead_t *head = _descr;						      \
-									      \
-    head->tcb = _descr;							      \
-    /* For now the thread descriptor is at the same address.  */	      \
-    head->self = _descr;						      \
-									      \
-    asm ("ldc %0,gbr" : : "r" (_descr));				      \
-									      \
-    0;									      \
-  })
-
-/* Indicate that dynamic linker shouldn't try to initialize TLS even
-   when no PT_TLS segments are found in the program and libraries
-   it is linked against.  */
-#  define TLS_INIT_TP_EXPENSIVE 1
+#  define TLS_INIT_TP(tcbp, secondcall) \
+  ({ __asm __volatile ("ldc %0,gbr" : : "r" (tcbp)); 0; })
 
 /* Return the address of the dtv for the current thread.  */
-# define THREAD_DTV() \
-  ({ struct _pthread_descr_struct *__descr;				      \
-     THREAD_GETMEM (__descr, p_header.data.dtvp); })
+#  define THREAD_DTV() \
+  ({ tcbhead_t *__tcbp;							      \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));			      \
+     __tcbp->dtv;})
+
+/* Return the thread descriptor for the current thread.  */
+#  undef THREAD_SELF
+#  define THREAD_SELF \
+  ({ struct _pthread_descr_struct *__self;				      \
+     __asm ("stc gbr,%0" : "=r" (__self));				      \
+     __self - 1;})
+
+#  undef INIT_THREAD_SELF
+#  define INIT_THREAD_SELF(descr, nr) \
+  ({ struct _pthread_descr_struct *__self = (void *) descr;		      \
+     __asm __volatile ("ldc %0,gbr" : : "r" (__self + 1));		      \
+     0; })
+
+/* Get the thread descriptor definition.  This must be after the
+   the definition of THREAD_SELF for TLS.  */
+#  include <linuxthreads/descr.h>
 
-# endif	/* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
-#endif /* __ASSEMBLER__ */
+# endif /* __ASSEMBLER__ */
+
+#else
+
+# ifndef __ASSEMBLER__
+
+typedef struct
+{
+  void *tcb;
+  dtv_t *dtv;
+  void *self;
+  int multiple_threads;
+} tcbhead_t;
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+#  define NONTLS_INIT_TP \
+  do { 									\
+    static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 };	\
+    __asm __volatile ("ldc %0,gbr" : : "r" (&nontls_init_tp));	        \
+  } while (0)
+
+# endif /* __ASSEMBLER__ */
+
+#endif	/* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
 
 #endif	/* tls.h */
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c LOCAL/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c
--- ORIG/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c	Wed Jan  8 08:37:20 2003
+++ LOCAL/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c	Fri Feb  7 20:22:07 2003
@@ -1,5 +1,5 @@
 /* Special .init and .fini section support for SH. Linuxthread version.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it
@@ -77,12 +77,6 @@ _init:\n\
 	.long	__gmon_start__@PLT\n\
 .L24:\n\
 	.long	__pthread_initialize_minimal@PLT\n\
-	.data\n\
-	.global __fpscr_values\n\
-__fpscr_values:\n\
-	.long   0\n\
-	.long   0x80000\n\
-	.previous\n\
 1:\n\
 	ALIGN\n\
 	END_INIT\n\
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h LOCAL/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
--- ORIG/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h	Sun Jan  5 20:04:57 2003
+++ LOCAL/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h	Fri Feb  7 20:22:07 2003
@@ -52,6 +52,7 @@
     add _IMP16,r15; \
     lds.l @r15+,pr; \
     DO_CALL(syscall_name, args); \
+    SYSCALL_INST_PAD; \
     sts.l pr,@-r15; \
     mov.l r0,@-r15; \
     CDISABLE; \
@@ -106,6 +107,7 @@
 	.align 2; \
      1: .long __local_enable_asynccancel - 0b; \
      2:
+
 # define CDISABLE \
 	mov.l 1f,r0; \
 	bsrf r0; \
@@ -129,6 +131,7 @@ extern int __local_multiple_threads attr
 #  if !defined PIC
 #   define SINGLE_THREAD_P \
 	mov.l 1f,r0; \
+	mov.l @r0,r0; \
 	bra 2f; \
 	 tst r0,r0; \
 	.align 2; \
@@ -136,7 +139,15 @@ extern int __local_multiple_threads attr
      2:
 #  elif defined FLOATING_STACKS && USE___THREAD
 #   define SINGLE_THREAD_P \
-	mov.l @(MULTIPLE_THREADS_OFFSET,gbr),r0; tst r0,r0
+	stc gbr,r0; \
+	mov.w 0f,r1; \
+	sub r1,r0; \
+	mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
+	bra 1f; \
+	 tst r0,r0; \
+     0: .word TLS_PRE_TCB_SIZE; \
+     1:
+
 #  else
 #   define SINGLE_THREAD_P \
 	mov r12,r2; \
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S LOCAL/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
--- ORIG/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S	Sun Jan 12 17:59:57 2003
+++ LOCAL/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S	Fri Feb  7 20:22:07 2003
@@ -26,8 +26,14 @@
    and the process ID of the new process to the old process.  */
 
 ENTRY (__vfork)
-	SINGLE_THREAD_P
-	bf .Lhidden_fork
+#ifdef SHARED
+	mov.l	.Lpthread_func, r0
+	mov.l	@(r0,r12), r0
+#else
+	mov.l	.Lpthread_fork, r0
+#endif
+	tst	r0, r0
+	bf	.Lhidden_fork
 
 	mov.w	.L1, r3
 	trapa	#0x10
@@ -42,6 +48,14 @@ ENTRY (__vfork)
 	rts
 	 nop
 .L1:	.word	__NR_vfork
+	.align	2
+#ifdef SHARED
+.Lpthread_func:
+	.long	__libc_pthread_functions@GOTOFF
+#else
+.Lpthread_fork:
+	.long	__pthread_fork
+#endif
 
 .Lhidden_fork:	
 	mov.l	.L2, r1
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/sysdeps/unix/sysv/linux/sh/brk.c LOCAL/libc/sysdeps/unix/sysv/linux/sh/brk.c
--- ORIG/libc/sysdeps/unix/sysv/linux/sh/brk.c	Fri Jul  6 13:56:20 2001
+++ LOCAL/libc/sysdeps/unix/sysv/linux/sh/brk.c	Fri Feb  7 20:22:07 2003
@@ -1,5 +1,5 @@
 /* brk system call for Linux/SH.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2003 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
@@ -31,7 +31,7 @@ __brk (void *addr)
   register long r3 asm ("%r3") = SYS_ify (brk);
   register long r4 asm ("%r4") = (long)addr;
 
-  asm volatile ("trapa #0x11"
+  asm volatile ("trapa #0x11\n\t" SYSCALL_INST_PAD
 		: "=z"(newbrk) 
 		: "r" (r3), "r" (r4));
 
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/sysdeps/unix/sysv/linux/sh/clone.S LOCAL/libc/sysdeps/unix/sysv/linux/sh/clone.S
--- ORIG/libc/sysdeps/unix/sysv/linux/sh/clone.S	Wed Jan  8 08:37:36 2003
+++ LOCAL/libc/sysdeps/unix/sysv/linux/sh/clone.S	Fri Feb  7 20:22:07 2003
@@ -23,7 +23,8 @@
 #define _ERRNO_H	1
 #include <bits/errno.h>
 
-/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+	     pid_t *ptid, void *tls, pid_t *ctid); */
 
         .text
 ENTRY(__clone)
@@ -43,8 +44,11 @@ ENTRY(__clone)
 
 	/* do the system call */
 	mov	r6, r4
+	mov.l	@r15, r6
+	mov.l	@(8,r15), r7
+	mov.l	@(4,r15), r0
 	mov	#+SYS_ify(clone), r3
-	trapa	#0x12
+	trapa	#0x15
 	mov     r0, r1
 	mov	#-12, r2
 	shad	r2, r1
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/sysdeps/unix/sysv/linux/sh/sh4/sysdep.h LOCAL/libc/sysdeps/unix/sysv/linux/sh/sh4/sysdep.h
--- ORIG/libc/sysdeps/unix/sysv/linux/sh/sh4/sysdep.h	Thu Jan  1 09:00:00 1970
+++ LOCAL/libc/sysdeps/unix/sysv/linux/sh/sh4/sysdep.h	Fri Feb  7 20:22:07 2003
@@ -0,0 +1,4 @@
+/*  4 instruction cycles not accessing cache and TLB are needed after
+    trapa instruction to avoid an SH-4 silicon bug.  */
+#define NEED_SYSCALL_INST_PAD
+#include <sysdeps/unix/sysv/linux/sh/sysdep.h>
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/sysdeps/unix/sysv/linux/sh/sys/user.h LOCAL/libc/sysdeps/unix/sysv/linux/sh/sys/user.h
--- ORIG/libc/sysdeps/unix/sysv/linux/sh/sys/user.h	Fri Jul  6 13:56:20 2001
+++ LOCAL/libc/sysdeps/unix/sysv/linux/sh/sys/user.h	Fri Feb  7 20:22:07 2003
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2000, 2003 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
@@ -22,5 +22,7 @@
 #include <features.h>
 
 #include <asm/user.h>
+
+#undef start_thread
 
 #endif  /* sys/user.h */
diff --exclude=nptl --exclude=nptl_db -u3prN ORIG/libc/sysdeps/unix/sysv/linux/sh/sysdep.h LOCAL/libc/sysdeps/unix/sysv/linux/sh/sysdep.h
--- ORIG/libc/sysdeps/unix/sysv/linux/sh/sysdep.h	Mon Jan 13 10:03:51 2003
+++ LOCAL/libc/sysdeps/unix/sysv/linux/sh/sysdep.h	Fri Feb  7 20:22:07 2003
@@ -115,19 +115,23 @@
 #  else
 #   define SYSCALL_ERROR_HANDLER \
 	neg r0,r1; \
+	mov.l r14,@-r15; \
 	mov.l r12,@-r15; \
 	mov.l r1,@-r15; \
 	mov.l 0f,r12; \
 	mova 0f,r0; \
 	add r0,r12; \
 	sts.l pr,@-r15; \
+	mov r15,r14; \
 	mov.l 1f,r1; \
 	bsrf r1; \
          nop; \
-     2: lds.l @r15+,pr; \
+     2: mov r14,r15; \
+	lds.l @r15+,pr; \
 	mov.l @r15+,r1; \
 	mov.l r1,@r0; \
 	mov.l @r15+,r12; \
+	mov.l @r15+,r14; \
 	bra .Lpseudo_end; \
 	 mov _IMM1,r0; \
 	.align 2; \
@@ -174,6 +178,13 @@
  1: .long SYS_ify (syscall_name);	\
  2:
 
+# ifdef NEED_SYSCALL_INST_PAD
+#  define SYSCALL_INST_PAD \
+	or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0
+# else
+#  define SYSCALL_INST_PAD
+# endif
+
 #else /* not __ASSEMBLER__ */
 
 #define SYSCALL_INST_STR0	"trapa #0x10\n\t"
@@ -184,6 +195,13 @@
 #define SYSCALL_INST_STR5	"trapa #0x15\n\t"
 #define SYSCALL_INST_STR6	"trapa #0x16\n\t"
 
+# ifdef NEED_SYSCALL_INST_PAD
+#  define SYSCALL_INST_PAD "\
+	or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0"
+# else
+#  define SYSCALL_INST_PAD
+# endif
+
 #define ASMFMT_0
 #define ASMFMT_1 \
 	, "r" (r4)
@@ -238,23 +256,39 @@
 	register long r2 asm ("%r2") = (long)(arg7)
 
 #undef INLINE_SYSCALL
-#define INLINE_SYSCALL(name, nr, args...) 			\
+#define INLINE_SYSCALL(name, nr, args...) \
+  ({                                                                          \
+    unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args);             \
+    if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0))         \
+      {                                                                       \
+        __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));                   \
+        resultvar = 0xffffffff;                                               \
+      }                                                                       \
+    (int) resultvar; })
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
   ({								\
     unsigned long resultvar;					\
     register long r3 asm ("%r3") = SYS_ify (name);		\
     SUBSTITUTE_ARGS_##nr(args);					\
 								\
-    asm volatile (SYSCALL_INST_STR##nr				\
+    asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD		\
 		  : "=z" (resultvar)				\
 		  : "r" (r3) ASMFMT_##nr 			\
 		  : "memory");					\
 								\
-    if (resultvar >= 0xfffff001)			        \
-      {							        \
-	__set_errno (-resultvar);				\
-	resultvar = 0xffffffff;					\
-      }								\
     (int) resultvar; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+  ((unsigned int) (val) >= 0xfffff001u)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err)        (-(val))
 
 #endif	/* __ASSEMBLER__ */
 


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