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]

arm patch for linuxthreads; vfork etc


This fixes a couple of bugs related to system call cancellation, and
adds the appropriate handling for vfork.

p.

2003-01-11  Philip Blundell  <philb@gnu.org>

	* sysdeps/unix/sysv/linux/arm/vfork.S: New file.
	* sysdeps/unix/sysv/linux/arm/sysdep-cancel.h (PSEUDO_RET):
	Correctly unstack lr.
	(UNDOARGS_5): Fix ordering of pushes and pops.
	(SINGLE_THREAD_P_PIC): New.
	(SINGLE_THREAD_P_INT): Likewise.
	(SINGLE_THREAD_P): Implement in terms of above.  Restore lr if it
	was stacked.
	(PSEUDO): Use SINGLE_THREAD_P_INT.

Index: sysdep-cancel.h
===================================================================
RCS file:
/cvs/glibc/libc/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h,v
retrieving revision 1.1
diff -u -r1.1 sysdep-cancel.h
--- sysdeps/unix/sysv/linux/arm/sysdep-cancel.h	7 Jan 2003 00:39:17
-0000	1.1
+++ sysdeps/unix/sysv/linux/arm/sysdep-cancel.h	11 Jan 2003 21:50:01
-0000
@@ -27,6 +27,7 @@
 # undef PSEUDO_RET
 # define PSEUDO_RET						        \
     ldrcc pc, [sp], $4;						        \
+    ldr	lr, [sp], $4;							\
     b PLTJMP(SYSCALL_ERROR)
 
 # undef PSEUDO
@@ -34,7 +35,7 @@
   .section ".text";							\
     PSEUDO_PROLOGUE;							\
   ENTRY (name)								\
-    SINGLE_THREAD_P;							\
+    SINGLE_THREAD_P_INT;						\
     bne .Lpseudo_cancel;						\
     DO_CALL (syscall_name, args);					\
     cmn r0, $4096;							\
@@ -74,7 +75,7 @@
 # define UNDOC2ARGS_4
 
 # define DOCARGS_5	stmfd sp!, {r0-r3}
-# define UNDOCARGS_5	str r4, [sp, #-4]!; ldmfd sp, {r0-r4}
+# define UNDOCARGS_5	ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4,
[sp, #24]
 # define UNDOC2ARGS_5   ldr r4, [sp], #20
 
 # ifdef IS_IN_libpthread
@@ -92,10 +93,11 @@
 #  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads ==
0, 1)
 # else
 #  if !defined PIC
-#   define SINGLE_THREAD_P						\
+#   define SINGLE_THREAD_P_INT						\
   ldr ip, =__local_multiple_threads;					\
   ldr ip, [ip];								\
   teq ip, #0;
+#   define SINGLE_THREAD_P SINGLE_THREAD_P_INT
 #   define MAYBE_SAVE_LR						\
   str lr, [sp, $-4]!;
 #   define PSEUDO_RET_MOV						\
@@ -103,15 +105,20 @@
   b PLTJMP(SYSCALL_ERROR)
 #   define PSEUDO_PROLOGUE
 #  else
-#   define SINGLE_THREAD_P						\
-  str lr, [sp, $-4]!;							\
+#   define SINGLE_THREAD_P_PIC(reg)					\
   ldr ip, 1b;								\
-  ldr lr, 2b;								\
+  ldr reg, 2b;								\
 3:									\
   add ip, pc, ip;							\
-  ldr ip, [ip, lr];							\
+  ldr ip, [ip, reg];							\
   teq ip, #0;
+#   define SINGLE_THREAD_P_INT						\
+  str lr, [sp, $-4]!;							\
+  SINGLE_THREAD_P_PIC(lr)
+#   define SINGLE_THREAD_P						\
+  SINGLE_THREAD_P_INT;							\
+  ldr lr, [sp], $4
 #   define PSEUDO_PROLOGUE						\
   1:  .word _GLOBAL_OFFSET_TABLE_ - 3f - 8;				\
   2:  .word __local_multiple_threads(GOTOFF);
--- /dev/null	2002-09-01 12:52:15.000000000 +0100
+++ sysdeps/unix/sysv/linux/arm/vfork.S	2003-01-11 15:11:09.000000000
+0000
@@ -0,0 +1,55 @@
+/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Philip Blundell <philb@gnu.org>.
+
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address
space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new
process,
+   and the process ID of the new process to the old process.  */
+
+	PSEUDO_PROLOGUE
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+	SINGLE_THREAD_P
+	bne	HIDDEN_JUMPTARGET (__fork)
+	swi	__NR_vfork
+	cmn	a1, #4096
+	RETINSTR(movcc, pc, lr)
+
+	/* Check if vfork syscall is known at all.  */
+	ldr	a2, =-ENOSYS
+	teq	a1, a2
+	bne	PLTJMP(C_SYMBOL_NAME(__syscall_error))
+#endif
+
+	/* If we don't have vfork, fork is close enough.  */
+	swi	__NR_fork
+	cmn	a1, #4096
+	RETINSTR(movcc, pc, lr)
+    	b	PLTJMP(C_SYMBOL_NAME(__syscall_error))
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)




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