about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--sysdeps/unix/Makefile18
-rw-r--r--sysdeps/unix/make-syscalls.sh33
-rw-r--r--sysdeps/unix/syscall-template.S88
4 files changed, 124 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 76a0d1dd06..bc1c0f17a9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-08-24  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/unix/syscall-template.S: New file.
+	* sysdeps/unix/make-syscalls.sh: Generate rules to use it.
+	* sysdeps/unix/Makefile (omit-deps): Do not omit syscall stubs' deps.
+	(compile-syscall): Pass mkdep and -g options as normal.
+	(s-proto.d, s-proto-cancel.d): Don't "-include" these.
+	(common-generated): Don't add them here.
+
 2009-08-24  Ulrich Drepper  <drepper@redhat.com>
 
 	* math/s_fdim.c: In case of overflows set errno.
diff --git a/sysdeps/unix/Makefile b/sysdeps/unix/Makefile
index 2696e7fb62..f7140884a1 100644
--- a/sysdeps/unix/Makefile
+++ b/sysdeps/unix/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991,1992,1993,1994,1995,1996,1997,1998,1999,2003, 2006, 2008
+# Copyright (C) 1991,1992,1993,1994,1995,1996,1997,1998,1999,2003,2006,2008,2009
 #	Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
@@ -260,7 +260,6 @@ ifndef inhibit-unix-syscalls
 # which specifies objects to be compiled as simple Unix system calls.
 
 -include $(common-objpfx)sysd-syscalls
-omit-deps += $(foreach t,$(sysd-rules-targets),$(unix-syscalls:%=$t))
 
 ifeq (misc,$(subdir))
 sysdep_routines += $(unix-extra-syscalls)
@@ -306,9 +305,9 @@ endif
 endif
 
 # This is the end of the pipeline for compiling the syscall stubs.
-# The stdin in assembler with cpp using sysdep.h macros.
-# Be sure to disable debugging info since it would all just say "<stdin>".
-compile-syscall = $(filter-out -g%,$(COMPILE.S)) -x assembler-with-cpp -o $@ -
+# The stdin is assembler with cpp using sysdep.h macros.
+compile-syscall = $(COMPILE.S) -o $@ -x assembler-with-cpp - \
+			       $(compile-mkdep-flags)
 
 ifndef avoid-generated
 $(common-objpfx)sysd-syscalls: $(..)sysdeps/unix/make-syscalls.sh \
@@ -323,16 +322,13 @@ $(common-objpfx)sysd-syscalls: $(..)sysdeps/unix/make-syscalls.sh \
 	mv -f $@T $@
 endif
 
-# The syscall objects depend on s-proto.d or s-proto-cancel.d, which
-# are generated to specify dependencies generated syscalls have on
-# headers.
+# The $(bppfx)syscall.ob objects depend on s-proto-bp.d, which are
+# generated to specify dependencies generated BP stubs have on headers.
 # These deps use file names relative to a subdir, so don't
 # include them in the parent directory.
 ifneq (,$(filter $(unix-syscalls),$(routines) $(sysdep_routines) $(aux)))
 ifndef no_deps
--include $(common-objpfx)s-proto.d
 -include $(common-objpfx)s-proto-bp.d
--include $(common-objpfx)s-proto-cancel.d
 endif
 endif
 
@@ -340,7 +336,7 @@ $(common-objpfx)s-%.d: $(..)sysdeps/unix/s-%.S \
 		       $(wildcard $(+sysdep_dirs:%=%/syscalls.list))
 	$(+make-deps)
 
-common-generated += s-proto.d s-proto-bp.d s-proto-cancel.d
+common-generated += s-proto-bp.d
 postclean-generated += sysd-syscalls
 
 endif
diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
index 8abb0349bf..a8b8a262a7 100644
--- a/sysdeps/unix/make-syscalls.sh
+++ b/sysdeps/unix/make-syscalls.sh
@@ -83,12 +83,13 @@ while read file srcfile caller syscall args strong weak; do
   ;;
   esac
 
-  cancellable=
-  noerrno=
+  cancellable=0
+  noerrno=0
+  errval=0
   case $args in
-  C*) cancellable=-cancel; args=`echo $args | sed 's/C:\?//'`;;
-  E*) noerrno=_NOERRNO; args=`echo $args | sed 's/E:\?//'`;;
-  V*) noerrno=_ERRVAL; args=`echo $args | sed 's/V:\?//'`;;
+  C*) cancellable=1; args=`echo $args | sed 's/C:\?//'`;;
+  E*) noerrno=1; args=`echo $args | sed 's/E:\?//'`;;
+  V*) errval=1; args=`echo $args | sed 's/V:\?//'`;;
   esac
 
   # Derive the number of arguments from the argument signature
@@ -115,7 +116,7 @@ while read file srcfile caller syscall args strong weak; do
  x--)
   # Undefined callnum for an extra syscall.
   if [ x$caller != x- ]; then
-    if [ x$noerrno != x ]; then
+    if [ $noerrno != 0 ]; then
       echo >&2 "$0: no number for $fileno, no-error syscall ($strong $weak)"
       exit 2
     fi
@@ -151,7 +152,7 @@ shared-only-routines += $file
     ;;
   esac
 
-  echo "		\$(common-objpfx)s-proto$cancellable.d"
+  echo "		\$(..)sysdeps/unix/make-syscalls.sh"
   case x"$callnum" in
   x_)
   echo "\
@@ -161,11 +162,17 @@ shared-only-routines += $file
   x*)
   echo "\
 	\$(make-target-directory)
-	(echo '#include <sysdep$cancellable.h>'; \\
-	 echo 'PSEUDO$noerrno ($strong, $syscall, $nargs)'; \\
-	 echo '	ret$noerrno'; \\
-	 echo 'PSEUDO_END$noerrno($strong)'; \\
-	 echo 'libc_hidden_def ($strong)'; \\"
+	(echo '#define SYSCALL_NAME $syscall'; \\
+	 echo '#define SYSCALL_NARGS $nargs'; \\
+	 echo '#define SYSCALL_SYMBOL $strong'; \\"
+  [ $cancellable = 0 ] || echo "\
+	 echo '#define SYSCALL_CANCELLABLE 1'; \\"
+  [ $noerrno = 0 ] || echo "\
+	 echo '#define SYSCALL_NOERRNO 1'; \\"
+  [ $errval = 0 ] || echo "\
+	 echo '#define SYSCALL_ERRVAL 1'; \\"
+  echo "\
+	 echo '#include <syscall-template.S>'; \\"
   ;;
   esac
 
@@ -201,7 +208,7 @@ shared-only-routines += $file
 	  vcount=`expr $vcount + 1`
 	  echo "	 echo 'strong_alias ($strong, $source)'; \\"
 	fi
-	echo "	 echo 'symbol_version($source, $base, $ver)'; \\"
+	echo "	 echo 'symbol_version ($source, $base, $ver)'; \\"
 	;;
       !*)
 	name=`echo $name | sed 's/.//'`
diff --git a/sysdeps/unix/syscall-template.S b/sysdeps/unix/syscall-template.S
new file mode 100644
index 0000000000..66319f158b
--- /dev/null
+++ b/sysdeps/unix/syscall-template.S
@@ -0,0 +1,88 @@
+/* Assembly code template for system call stubs.
+   Copyright (C) 2009 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* The real guts of this work are in the macros defined in the
+   machine- and kernel-specific sysdep.h header file.  When we
+   are defining a cancellable system call, the sysdep-cancel.h
+   versions of those macros are what we really use.
+
+   Each system call's object is built by a rule in sysd-syscalls
+   generated by make-syscalls.sh that #include's this file after
+   defining a few macros:
+	SYSCALL_NAME		syscall name
+	SYSCALL_NARGS		number of arguments this call takes
+	SYSCALL_SYMBOL		primary symbol name
+	SYSCALL_CANCELLABLE	1 if the call is a cancelation point
+	SYSCALL_NOERRNO		1 to define a no-errno version (see below)
+	SYSCALL_ERRVAL		1 to define an error-value version (see below)
+
+   We used to simply pipe the correct three lines below through cpp into
+   the assembler.  The main reason to have this file instead is so that
+   stub objects can be assembled with -g and get source line information
+   that leads a user back to a source file and these fine comments.  The
+   average user otherwise has a hard time knowing which "syscall-like"
+   functions in libc are plain stubs and which have nontrivial C wrappers.
+   Some versions of the "plain" stub generation macros are more than a few
+   instructions long and the untrained eye might not distinguish them from
+   some compiled code that inexplicably lacks source line information.  */
+
+#if SYSCALL_CANCELLABLE
+# include <sysdep-cancel.h>
+#else
+# include <sysdep.h>
+#endif
+
+#define T_PSEUDO(SYMBOL, NAME, N)		PSEUDO (SYMBOL, NAME, N)
+#define T_PSEUDO_NOERRNO(SYMBOL, NAME, N)	PSEUDO_NOERRNO (SYMBOL, NAME, N)
+#define T_PSEUDO_ERRVAL(SYMBOL, NAME, N)	PSEUDO_ERRVAL (SYMBOL, NAME, N)
+#define T_PSEUDO_END(SYMBOL)			PSEUDO_END (SYMBOL)
+#define T_PSEUDO_END_NOERRNO(SYMBOL)		PSEUDO_END_NOERRNO (SYMBOL)
+#define T_PSEUDO_END_ERRVAL(SYMBOL)		PSEUDO_END_ERRVAL (SYMBOL)
+
+#if SYSCALL_NOERRNO
+
+/* This kind of system call stub never returns an error.
+   We return the return value register to the caller unexamined.  */
+
+T_PSEUDO_NOERRNO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
+	ret_NOERRNO
+T_PSEUDO_END_NOERRNO (SYSCALL_SYMBOL)
+
+#elif SYSCALL_ERRVAL
+
+/* This kind of system call stub returns the errno code as its return
+   value, or zero for success.  We may massage the kernel's return value
+   to meet that ABI, but we never set errno here.  */
+
+T_PSEUDO_ERRVAL (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
+	ret_ERRVAL
+T_PSEUDO_END_ERRVAL (SYSCALL_SYMBOL)
+
+#else
+
+/* This is a "normal" system call stub: if there is an error,
+   it returns -1 and sets errno.  */
+
+T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
+	ret
+T_PSEUDO_END (SYSCALL_SYMBOL)
+
+#endif
+
+libc_hidden_def (SYSCALL_SYMBOL)