diff options
Diffstat (limited to 'sysdeps/unix')
-rw-r--r-- | sysdeps/unix/Makefile | 18 | ||||
-rw-r--r-- | sysdeps/unix/make-syscalls.sh | 33 | ||||
-rw-r--r-- | sysdeps/unix/syscall-template.S | 88 |
3 files changed, 115 insertions, 24 deletions
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) |