about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--nptl/ChangeLog4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/clone.S2
-rw-r--r--sysdeps/unix/sysv/linux/sh/clone.S39
4 files changed, 48 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 42b924247d..bc8ad625e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2004-12-07  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/clone.S: Clear the frame pointer when
+	starting a new thread.  Add support for NPTL where the PID is stored
+	at userlevel and needs to be reset when CLONE_THREAD is not used.
+
 2004-12-01  Jakub Jelinek  <jakub@redhat.com>
 
 	* elf/rtld.c (process_envvars): Don't consider LD_SHOW_AUXV
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index f58709eff9..94764f1535 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,7 @@
+2004-12-07  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/clone.S: New file.
+
 2004-12-04  Ulrich Drepper  <drepper@redhat.com>
 
 	* Makefile (tests): Add tst-getpid1.
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/clone.S b/nptl/sysdeps/unix/sysv/linux/sh/clone.S
new file mode 100644
index 0000000000..62a11972d8
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sh/clone.S
@@ -0,0 +1,2 @@
+#define RESET_PID
+#include <sysdeps/unix/sysv/linux/sh/clone.S>
diff --git a/sysdeps/unix/sysv/linux/sh/clone.S b/sysdeps/unix/sysv/linux/sh/clone.S
index 713b0f9c3b..7941c6b3ad 100644
--- a/sysdeps/unix/sysv/linux/sh/clone.S
+++ b/sysdeps/unix/sysv/linux/sh/clone.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2003, 2004 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,11 +22,13 @@
 #include <sysdep.h>
 #define _ERRNO_H	1
 #include <bits/errno.h>
-
+#ifdef RESET_PID
+#include <tcb-offsets.h>
+#endif
 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
 	     pid_t *ptid, void *tls, pid_t *ctid); */
 
-        .text
+	.text
 ENTRY(__clone)
 	/* sanity check arguments.  */
 	tst	r4, r4
@@ -64,6 +66,31 @@ ENTRY(__clone)
 	rts
 	 nop
 2:
+	/* terminate the stack frame */
+	mov	#0, r14
+#ifdef RESET_PID
+	mov	r4, r0
+	shlr16	r0
+	tst	#1, r0			// CLONE_THREAD = (1 << 16)
+	bf/s	4f
+	 mov	r4, r0
+	/* new pid */
+	shlr8	r0
+	tst	#1, r0			// CLONE_VM = (1 << 8)
+	bf/s	3f
+	 mov	#-1, r0
+	mov	#+SYS_ify(getpid), r3
+	trapa	#0x15
+3:
+	stc	gbr, r1
+	mov.w	.Lpidoff, r2
+	add	r1, r2
+	mov.l	r0, @r2	
+	mov.w	.Ltidoff, r2
+	add	r1, r2
+	mov.l	r0, @r2	
+4:
+#endif
 	/* thread starts */
 	mov.l	@r15, r1
 	jsr	@r1
@@ -94,6 +121,12 @@ ENTRY(__clone)
 	.long	_GLOBAL_OFFSET_TABLE_
 .L3:
 	.long	PLTJMP(C_SYMBOL_NAME(_exit))
+#ifdef RESET_PID
+.Lpidoff:
+	.word	PID - TLS_PRE_TCB_SIZE
+.Ltidoff:
+	.word	TID - TLS_PRE_TCB_SIZE
+#endif
 PSEUDO_END (__clone)
 
 weak_alias (__clone, clone)