summary refs log tree commit diff
path: root/sysdeps/unix
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-07-22 10:48:43 +0000
committerRoland McGrath <roland@gnu.org>1995-07-22 10:48:43 +0000
commit439d1d4560aa3e261c065c43e3995779809b4cb2 (patch)
tree82be4196b9f9a0567b4210d818cacc53780b3030 /sysdeps/unix
parent0bf9d0eb2bc40ee304e8ff0315112cde711fa1b2 (diff)
downloadglibc-439d1d4560aa3e261c065c43e3995779809b4cb2.tar.gz
glibc-439d1d4560aa3e261c065c43e3995779809b4cb2.tar.xz
glibc-439d1d4560aa3e261c065c43e3995779809b4cb2.zip
Sat Jul 22 01:56:03 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
	* sysdeps/unix/i386/sysdep.h (JUMPTARGET): New macro; use name@PLT
 	#ifdef PIC.
	(PSEUDO): Use JUMPTARGET(syscall_error) in jump insn.
	* sysdeps/unix/i386/syscall.S: Use JUMPTARGET(syscall_error) in
 	jump insn.

	* sysdeps/unix/sysv/sysv4/linux/i386/sysdep.h: Rewritten.
	* sysdeps/unix/sysv/sysv4/linux/i386/syscall.S: New file.
	* sysdeps/unix/sysv/sysv4/linux/i386/socket.S: Include
 	<sys/socketcall.h>.  Save %ebx in call-clobbered %edx instead of
 	stack.  Use JUMPTARGET(syscall_error) in jump insn.

	* Makeconfig (+gccwarn): Add -Wbad-function-cast -Wconversion.

	* sysdeps/unix/i386/sysdep.h (ENTRY): Use ASM_GLOBAL_DIRECTIVE and
 	ASM_TYPE_DIRECTIVE.
	(ASM_TYPE_DIRECTIVE): New macro; defined using `.type' #ifdef ELF.

	* sysdeps/unix/sysv/sysv4/linux/i386/sysdep.S (__syscall_error): 
	Rewritten, #include'ing unix/i386/sysdep.S for most of the code.
	* sysdeps/unix/i386/sysdep.S [PIC]: Store into `errno' through the GOT.

	Fixes to help Linux, inspired by drepper's work:
	* configure.in (os=linux*): Use unix/sysv/sysv4 for $base_os,
 	instead of unix/sysv.
	* sysdeps/posix/utimes.c: New file.
	* sysdeps/generic/getdomain.c: New file.
	* sysdeps/i386/init-first.c: Removed gratuitous #include <hurd.h>.
	* sysdeps/generic/dl-sysdep.c: Include <unistd.h> and declare
 	externals _dl_argc, _dl_argc, and _environ.
	* sysdeps/unix/sysv/linux/{accept,connect,getsockname,rename,
	socketpair,waitpid,bind,getpeername,listen,setsid,wait4}.S: Moved
	to new directory sysdeps/unix/sysv/sysv4/linux.
	* sysdeps/unix/sysv/linux: Directory removed.
	* sysdeps/unix/sysv/i386/linux/{socket.S,sysdep.h,sysdep.S}: Moved
	to new directory sysdeps/unix/sysv/sysv4/linux/i386.
	* sysdeps/unix/sysv/linux/i386: Directory removed.
Diffstat (limited to 'sysdeps/unix')
-rw-r--r--sysdeps/unix/i386/syscall.S4
-rw-r--r--sysdeps/unix/i386/sysdep.S14
-rw-r--r--sysdeps/unix/i386/sysdep.h19
-rw-r--r--sysdeps/unix/sysv/i386/linux/sysdep.S38
-rw-r--r--sysdeps/unix/sysv/i386/linux/sysdep.h57
-rw-r--r--sysdeps/unix/sysv/linux/Implies2
-rw-r--r--sysdeps/unix/sysv/linux/syscall.h124
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/accept.S (renamed from sysdeps/unix/sysv/linux/accept.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/bind.S (renamed from sysdeps/unix/sysv/linux/bind.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/connect.S (renamed from sysdeps/unix/sysv/linux/connect.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/getpeername.S (renamed from sysdeps/unix/sysv/linux/getpeername.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/getsockname.S (renamed from sysdeps/unix/sysv/linux/getsockname.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/i386/socket.S (renamed from sysdeps/unix/sysv/i386/linux/socket.S)17
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/i386/syscall.S (renamed from sysdeps/unix/sysv/i386/linux/wait.S)22
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/i386/sysdep.S (renamed from sysdeps/unix/sysv/linux/getpgrp.S)13
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/i386/sysdep.h86
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/listen.S (renamed from sysdeps/unix/sysv/linux/listen.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/rename.S (renamed from sysdeps/unix/sysv/linux/rename.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/setsid.S (renamed from sysdeps/unix/sysv/linux/setsid.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/socketpair.S (renamed from sysdeps/unix/sysv/linux/socketpair.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/wait4.S (renamed from sysdeps/unix/sysv/linux/wait4.S)0
-rw-r--r--sysdeps/unix/sysv/sysv4/linux/waitpid.S (renamed from sysdeps/unix/sysv/linux/waitpid.S)0
22 files changed, 144 insertions, 252 deletions
diff --git a/sysdeps/unix/i386/syscall.S b/sysdeps/unix/i386/syscall.S
index 5241ee4ac1..1db1e77d8d 100644
--- a/sysdeps/unix/i386/syscall.S
+++ b/sysdeps/unix/i386/syscall.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995 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
@@ -24,5 +24,5 @@ ENTRY (syscall)
 	popl %eax		/* Pop syscall number into %eax.  */
 	pushl %ecx		/* Push back return address.  */
 	.byte 0x9a, 0, 0, 0, 0, 7, 0 /* lcall $7, $0 -- gas bug */
-	jb syscall_error
+	jb JUMPTARGET(syscall_error)
 	ret
diff --git a/sysdeps/unix/i386/sysdep.S b/sysdeps/unix/i386/sysdep.S
index dae7153796..efe4f56e95 100644
--- a/sysdeps/unix/i386/sysdep.S
+++ b/sysdeps/unix/i386/sysdep.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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
@@ -37,6 +37,16 @@ syscall_error:
 	jne notb		/* Branch if not.  */
 	movl $EAGAIN, %eax	/* Yes; translate it to EAGAIN.  */
 #endif
-notb:	movl %eax, C_SYMBOL_NAME(errno)
+notb:
+#ifndef	PIC
+	movl %eax, C_SYMBOL_NAME(errno)
+#else
+	/* Standard PIC nonsense to store into `errno' through the GOT.  */
+	call here
+here:	popl %ecx
+	addl $_GLOBAL_OFFSET_TABLE_+[.-here], %ecx
+	movl C_SYMBOL_NAME(errno@GOT)(%ecx), %ecx
+	movl %eax, (%ecx)
+#endif
 	movl $-1, %eax
 	ret
diff --git a/sysdeps/unix/i386/sysdep.h b/sysdeps/unix/i386/sysdep.h
index 38dd2378b5..4e4b6e6ab5 100644
--- a/sysdeps/unix/i386/sysdep.h
+++ b/sysdeps/unix/i386/sysdep.h
@@ -20,11 +20,20 @@ Cambridge, MA 02139, USA.  */
 
 #ifdef	ASSEMBLER
 
+/* Define an entry point visible from C.  */
 #define	ENTRY(name)							      \
-  .globl C_SYMBOL_NAME(name);						      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
   .align 4;								      \
   C_LABEL(name)
 
+/* For ELF we need the `.type' directive to make shared libs work right.  */
+#ifdef HAVE_ELF
+#define ASM_TYPE_DIRECTIVE(name,type)	.type name,type;
+#else
+#define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified.  */
+#endif
+
 #ifdef	NO_UNDERSCORES
 /* Since C identifiers are not normally prefixed with an underscore
    on this system, the asm identifier `syscall_error' intrudes on the
@@ -36,7 +45,13 @@ Cambridge, MA 02139, USA.  */
   .globl syscall_error;							      \
   ENTRY (name)								      \
   DO_CALL (syscall_name, args);						      \
-  jb syscall_error
+  jb JUMPTARGET(syscall_error)
+
+#ifdef PIC
+#define JUMPTARGET(name) name@PLT
+#else
+#define JUMPTARGET(name) name
+#endif
 
 /* This is defined as a separate macro so that other sysdep.h files
    can include this one and then redefine DO_CALL.  */
diff --git a/sysdeps/unix/sysv/i386/linux/sysdep.S b/sysdeps/unix/sysv/i386/linux/sysdep.S
deleted file mode 100644
index ed3a2782a9..0000000000
--- a/sysdeps/unix/sysv/i386/linux/sysdep.S
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 1992, 1993, 1994 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <sysdep.h>
-#define _ERRNO_H
-#include <errnos.h>
-
-/* We jump here when a system call gets an error.
-   The error number is negated in %eax.  */
-.globl syscall_error
-syscall_error:
-	negl %eax		/* Make it positive.  */
-#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
-	/* We translate the system's EWOULDBLOCK error into EAGAIN.
-	   The GNU C library always defines EWOULDBLOCK==EAGAIN.
-	   EWOULDBLOCK_sys is the original number.  */
-	cmpl %eax, $EWOULDBLOCK_sys /* Is it the old EWOULDBLOCK?  */
-	jne 0f			/* Branch if not.  */
-	move $EAGAIN, %eax	/* Yes; translate it to EAGAIN.  */
-#endif
-0:	movl %eax, _errno	/* Store it in `errno'.  */
-	move $-1, %eax		/* Return -1.  */
-	ret
diff --git a/sysdeps/unix/sysv/i386/linux/sysdep.h b/sysdeps/unix/sysv/i386/linux/sysdep.h
deleted file mode 100644
index 298a0e4c5b..0000000000
--- a/sysdeps/unix/sysv/i386/linux/sysdep.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (C) 1992, 1993 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <sysdeps/unix/sysdep.h>
-
-#define	ENTRY(name)							      \
-  .globl _##name;							      \
-  .align 2;								      \
-  _##name##:
-
-#define	PSEUDO(name, syscall_name, args)				      \
-  .text;								      \
-  .globl syscall_error;							      \
-  ENTRY (name)								      \
-    XCHG_##args
-    movl $SYS_##syscall_name, %eax;					      \
-    int $0x80;								      \
-    test %eax, %eax;							      \
-    jl syscall_error;							      \
-    XCHG_##args
-
-/* Linux takes system call arguments in registers:
-   	1: %ebx
-	2: %ecx
-	3: %edx
-	4: %esi
-	5: %edi
-   We put the arguments into registers from the stack,
-   and save the registers, by using the 386 `xchg' instruction
-   to swap the values in both directions.  */
-
-#define	XCHG_0	/* No arguments to frob.  */
-#define	XCHG_1	xchg 8(%esp), %ebx; XCHG_0
-#define	XCHG_2	xchg 12(%esp), %ecx; XCHG_1
-#define	XCHG_3	xchg 16(%esp), %edx; XCHG_2
-#define	XCHG_4	xchg 20(%esp), %esi; XCHG_3
-#define	XCHG_5	xchg 24(%esp), %edi; XCHG_3
-
-#define	r0		%eax	/* Normal return-value register.  */
-#define	r1		%edx	/* Secondary return-value register.  */
-#define scratch 	%ecx	/* Call-clobbered register for random use.  */
-#define MOVE(x,y)	movl x, y
diff --git a/sysdeps/unix/sysv/linux/Implies b/sysdeps/unix/sysv/linux/Implies
deleted file mode 100644
index fe7e1fde5e..0000000000
--- a/sysdeps/unix/sysv/linux/Implies
+++ /dev/null
@@ -1,2 +0,0 @@
-# Linux has the set of things which are also common to BSD and SVR4.
-unix/common
diff --git a/sysdeps/unix/sysv/linux/syscall.h b/sysdeps/unix/sysv/linux/syscall.h
deleted file mode 100644
index b94d919e68..0000000000
--- a/sysdeps/unix/sysv/linux/syscall.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef	_SYSCALL_H
-#define	_SYSCALL_H
-
-#define	SYS_setup		0 /* Used only by init, to get system going. */
-#define SYS_exit		1
-#define SYS_fork		2
-#define SYS_read		3
-#define SYS_write		4
-#define SYS_open		5
-#define SYS_close		6
-#define SYS_waitpid		7
-#define SYS_creat		8
-#define SYS_link		9
-#define SYS_unlink		10
-#define SYS_execve		11
-#define SYS_chdir		12
-#define SYS_time		13
-#define SYS_mknod		14
-#define SYS_chmod		15
-#define SYS_chown		16
-#define SYS_brk			17
-#define SYS_oldstat		18
-#define SYS_lseek		19
-#define SYS_getpid		20
-#define SYS_mount		21
-#define SYS_umount		22
-#define SYS_setuid		23
-#define SYS_getuid		24
-#define SYS_stime		25
-#define SYS_ptrace		26
-#define SYS_alarm		27
-#define SYS_oldfstat		28
-#define SYS_pause		29
-#define SYS_utime		30
-#define SYS_stty		31
-#define SYS_gtty		32
-#define SYS_access		33
-#define SYS_nice		34
-#define SYS_ftime		35
-#define SYS_sync		36
-#define SYS_kill		37
-#define SYS_rename		38
-#define SYS_mkdir		39
-#define SYS_rmdir		40
-#define SYS_dup			41
-#define SYS_pipe		42
-#define SYS_times		43
-#define SYS_prof		44
-#if 0
-#define SYS_brk			45 /* Where did this bogosity crom from? */
-#endif
-#define SYS_setgid		46
-#define SYS_getgid		47
-#define SYS_signal		48
-#define SYS_geteuid		49
-#define SYS_getegid		50
-#define SYS_acct		51
-#define SYS_phys		52
-#define SYS_lock		53
-#define SYS_ioctl		54
-#define SYS_fcntl		55
-#define SYS_mpx			56
-#define SYS_setpgrp		57
-#define SYS_ulimit		58
-#define SYS_olduname		59
-#define SYS_umask		60
-#define SYS_chroot		61
-#define SYS_ustat		62
-#define SYS_dup2		63
-#define SYS_getppid		64
-#define SYS_getpgrp		65
-#define SYS_setsid		66
-#define SYS_sigaction		67
-#define SYS_siggetmask		68
-#define SYS_sigsetmask		69
-#define SYS_setreuid		70
-#define SYS_setregid		71
-#define SYS_sigsuspend		72
-#define SYS_sigpending		73
-#define SYS_sethostname		74
-#define SYS_setrlimit		75
-#define SYS_getrlimit		76
-#define SYS_getrusage		77
-#define SYS_gettimeofday	78
-#define SYS_settimeofday	79
-#define SYS_getgroups		80
-#define SYS_setgroups		81
-#define SYS_select		82
-#define SYS_symlink		83
-#define SYS_oldlstat		84
-#define SYS_readlink		85
-#define SYS_uselib		86
-#define SYS_swapon		87
-#define SYS_reboot		88
-#define SYS_readdir		89
-#define SYS_mmap		90
-#define SYS_munmap		91
-#define SYS_truncate		92
-#define SYS_ftruncate		93
-#define SYS_fchmod		94
-#define SYS_fchown		95
-#define SYS_getpriority		96
-#define SYS_setpriority		97
-#define SYS_profil		98
-#define SYS_statfs		99
-#define SYS_fstatfs		100
-#define SYS_ioperm		101
-#define SYS_socketcall		102
-#define SYS_syslog		103
-#define SYS_setitimer		104
-#define SYS_getitimer		105
-#define SYS_stat		106
-#define SYS_lstat		107
-#define SYS_fstat		108
-#define SYS_uname		109
-#define SYS_iopl		110
-#define SYS_vhangup		111
-#define SYS_idle		112
-#define SYS_vm86		113
-#define SYS_wait4		114
-#define SYS_swapoff		115
-
-
-#endif	/* syscall.h */
diff --git a/sysdeps/unix/sysv/linux/accept.S b/sysdeps/unix/sysv/sysv4/linux/accept.S
index 5936a0185b..5936a0185b 100644
--- a/sysdeps/unix/sysv/linux/accept.S
+++ b/sysdeps/unix/sysv/sysv4/linux/accept.S
diff --git a/sysdeps/unix/sysv/linux/bind.S b/sysdeps/unix/sysv/sysv4/linux/bind.S
index fc82b65a2f..fc82b65a2f 100644
--- a/sysdeps/unix/sysv/linux/bind.S
+++ b/sysdeps/unix/sysv/sysv4/linux/bind.S
diff --git a/sysdeps/unix/sysv/linux/connect.S b/sysdeps/unix/sysv/sysv4/linux/connect.S
index 3433043d8c..3433043d8c 100644
--- a/sysdeps/unix/sysv/linux/connect.S
+++ b/sysdeps/unix/sysv/sysv4/linux/connect.S
diff --git a/sysdeps/unix/sysv/linux/getpeername.S b/sysdeps/unix/sysv/sysv4/linux/getpeername.S
index 8429fcdf76..8429fcdf76 100644
--- a/sysdeps/unix/sysv/linux/getpeername.S
+++ b/sysdeps/unix/sysv/sysv4/linux/getpeername.S
diff --git a/sysdeps/unix/sysv/linux/getsockname.S b/sysdeps/unix/sysv/sysv4/linux/getsockname.S
index 6782707f88..6782707f88 100644
--- a/sysdeps/unix/sysv/linux/getsockname.S
+++ b/sysdeps/unix/sysv/sysv4/linux/getsockname.S
diff --git a/sysdeps/unix/sysv/i386/linux/socket.S b/sysdeps/unix/sysv/sysv4/linux/i386/socket.S
index 9f59bad095..7b8dd75ed8 100644
--- a/sysdeps/unix/sysv/i386/linux/socket.S
+++ b/sysdeps/unix/sysv/sysv4/linux/i386/socket.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1995 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
@@ -17,6 +17,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <sysdep.h>
+#include <sys/socketcall.h>
 
 .globl syscall_error
 
@@ -24,32 +25,30 @@ Cambridge, MA 02139, USA.  */
    They are all gated through the single `socketcall' system call number.
    `socketcall' takes two arguments: the first is the subcode, specifying
    which socket function is being called; and the second is a pointer to
-   the arguments to specific function.
+   the arguments to the specific function.
 
    The .S files for the other calls just #define socket and #include this.  */
 
 ENTRY (socket)
 
 	/* Save registers.  */
-	pushl %ebx
-	pushl %ecx
+	movl %ebx, %edx
 
-	movl $__NR_socketcall, %eax	/* System call number in %eax.  */
+	movl $SYS_socketcall, %eax	/* System call number in %eax.  */
 
 	/* Use ## so `socket' is a separate token that might be #define'd.  */
 	movl $SYS_##socket, %ebx	/* Subcode is first arg to syscall.  */
-	lea 12(%esp), %ecx		/* Address of args in 2nd arg.  */
+	lea 8(%esp), %ecx		/* Address of args is 2nd arg.  */
 
         /* Do the system call trap.  */
 	int $0x80
 
 	/* Restore registers.  */
-	popl %ecx
-	popl %ebx
+	movl %edx, %ebx
 
 	/* %eax is < 0 if there was an error.  */
 	testl %eax, %eax
-	jl syscall_error
+	jl JUMPTARGET(syscall_error)
 
 	/* Successful; return the syscall's value.  */
 	ret
diff --git a/sysdeps/unix/sysv/i386/linux/wait.S b/sysdeps/unix/sysv/sysv4/linux/i386/syscall.S
index 4be64c47c9..efe6d36086 100644
--- a/sysdeps/unix/sysv/i386/linux/wait.S
+++ b/sysdeps/unix/sysv/sysv4/linux/i386/syscall.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1995 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
@@ -18,14 +18,12 @@ Cambridge, MA 02139, USA.  */
 
 #include <sysdep.h>
 
-ENTRY (__wait)
-	movl 0(%esp), %eax	/* Fetch the return address.  */
-	movl $-1, 0(%esp)	/* First arg is -1.  */
-				/* Second arg is our arg at 4(%esp).  */
-	pushl $0		/* Third arg is 0.  */
-	pushl %eax		/* Push the return address.  */
-
-	/* Jump to waitpid; it will return to our caller.  */
-	jmp ___waitpid
-
-weak_alias (__wait, wait)
+ASM_GLOBAL_DIRECTIVE syscall_error
+ENTRY (syscall)
+	popl %ecx		/* Pop return address into %ecx.  */
+	popl %eax		/* Pop syscall number into %eax.  */
+	pushl %ecx		/* Push back return address.  */
+	DO_CALL (5)		/* Frob the args and do the system call.  */
+	testl %eax, %eax	/* Check %eax for error.  */
+	jl JUMPTARGET(syscall_error) /* Jump to error handler if negative.  */
+	ret			/* Return to caller.  */
diff --git a/sysdeps/unix/sysv/linux/getpgrp.S b/sysdeps/unix/sysv/sysv4/linux/i386/sysdep.S
index f8d6e07106..5cf29ec0cf 100644
--- a/sysdeps/unix/sysv/linux/getpgrp.S
+++ b/sysdeps/unix/sysv/sysv4/linux/i386/sysdep.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1995 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
@@ -16,7 +16,12 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <sysdep.h>
+/* The syscall stubs jump here when they detect an error.
+   The code for Linux is almost identical to the canonical Unix/i386
+   code, except that the error number in %eax is negated.  */
 
-SYSCALL (getpgrp, 0)
-	ret
+__syscall_error:
+	negl %eax
+
+#define __syscall_error __syscall_error_1
+#include <sysdeps/unix/i386/sysdep.S>
diff --git a/sysdeps/unix/sysv/sysv4/linux/i386/sysdep.h b/sysdeps/unix/sysv/sysv4/linux/i386/sysdep.h
new file mode 100644
index 0000000000..d0c1c10dba
--- /dev/null
+++ b/sysdeps/unix/sysv/sysv4/linux/i386/sysdep.h
@@ -0,0 +1,86 @@
+/* Copyright (C) 1992, 1993, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* In the Linux/ELF world, C symbols are asm symbols.  */
+#define NO_UNDERSCORES
+
+/* There is some commonality.  */
+#include <sysdeps/unix/i386/sysdep.h>
+
+#ifdef ASSEMBLER
+
+/* Linux uses a negative return value to indicate syscall errors, unlike
+   most Unices, which use the condition codes' carry flag.  */
+#undef	PSEUDO
+#define	PSEUDO(name, syscall_name, args)				      \
+  .text;								      \
+  .globl __syscall_error;						      \
+  ENTRY (name)								      \
+    movl $SYS_##syscall_name, %eax;					      \
+    DO_CALL (args)							      \
+    testl %eax, %eax;							      \
+    jl JUMPTARGET(__syscall_error)
+
+
+/* Linux takes system call arguments in registers:
+
+	syscall number	%eax	     call-clobbered
+	arg 1		%ebx	     call-saved
+	arg 2		%ecx	     call-clobbered
+	arg 3		%edx	     call-clobbered
+	arg 4		%esi	     call-saved
+	arg 5		%edi	     call-saved
+
+   The stack layout upon entering the function is:
+
+	24(%esp)	Arg# 5
+	20(%esp)	Arg# 4
+	16(%esp)	Arg# 3
+	12(%esp)	Arg# 2
+	 8(%esp)	Arg# 1
+	 4(%esp)	Return address
+	  (%esp)
+
+   (Of course a function with e.g. 3 argumentS does not have entries for
+   arguments 4 and 5.)
+
+   We put the arguments into registers from the stack, and save the
+   call-saved registers, by using the 386 `xchg' instruction to swap the
+   values in both directions.  */
+
+#undef	DO_CALL
+#define DO_CALL(args)					      		      \
+    DOARGS_##args							      \
+    int $0x80;								      \
+    UNDOARGS_##args							      \
+
+#define	DOARGS_0	/* No arguments to frob.  */
+#define	UNDOARGS_0	/* No arguments to unfrob.  */
+#define	DOARGS_1	xchg 8(%esp), %ebx; DOARGS_0 /* Save %ebx on stack.  */
+#define	UNDOARGS_1	xchg 8(%esp), %ebx; UNDOARGS_0 /* Restore %ebx */
+#define	DOARGS_2	movel 12(%esp), %ecx; DOARGS_1
+#define	UNDOARGS_2	UNDOARGS_1 /* %ecx is clobbered.  */
+#define	DOARGS_3	movel 16(%esp), %edx; DOARGS_2
+#define	UNDOARGS_3	UNDOARGS_2 /* %edx is clobbered.  */
+#define	DOARGS_4	xchg 20(%esp), %esi; DOARGS_3 /* Save %esi on stack. */
+#define	UNDOARGS_4	xchg 20(%esp), %esi; UNDOARGS_3	/* Restore %esi.  */
+#define	DOARGS_5	xchg 24(%esp), %edi; DOARGS_3 /* Save %edi on stack. */
+#define	UNDOARGS_5	xchg 24(%esp), %edi; UNDOARGS_3	/* Restore %edi.  */
+
+
+#endif	/* ASSEMBLER */
diff --git a/sysdeps/unix/sysv/linux/listen.S b/sysdeps/unix/sysv/sysv4/linux/listen.S
index d2cbec60a0..d2cbec60a0 100644
--- a/sysdeps/unix/sysv/linux/listen.S
+++ b/sysdeps/unix/sysv/sysv4/linux/listen.S
diff --git a/sysdeps/unix/sysv/linux/rename.S b/sysdeps/unix/sysv/sysv4/linux/rename.S
index a5a8dfeeef..a5a8dfeeef 100644
--- a/sysdeps/unix/sysv/linux/rename.S
+++ b/sysdeps/unix/sysv/sysv4/linux/rename.S
diff --git a/sysdeps/unix/sysv/linux/setsid.S b/sysdeps/unix/sysv/sysv4/linux/setsid.S
index 4930c56dcf..4930c56dcf 100644
--- a/sysdeps/unix/sysv/linux/setsid.S
+++ b/sysdeps/unix/sysv/sysv4/linux/setsid.S
diff --git a/sysdeps/unix/sysv/linux/socketpair.S b/sysdeps/unix/sysv/sysv4/linux/socketpair.S
index da71c57dea..da71c57dea 100644
--- a/sysdeps/unix/sysv/linux/socketpair.S
+++ b/sysdeps/unix/sysv/sysv4/linux/socketpair.S
diff --git a/sysdeps/unix/sysv/linux/wait4.S b/sysdeps/unix/sysv/sysv4/linux/wait4.S
index e4c322341d..e4c322341d 100644
--- a/sysdeps/unix/sysv/linux/wait4.S
+++ b/sysdeps/unix/sysv/sysv4/linux/wait4.S
diff --git a/sysdeps/unix/sysv/linux/waitpid.S b/sysdeps/unix/sysv/sysv4/linux/waitpid.S
index 20d9d669bb..20d9d669bb 100644
--- a/sysdeps/unix/sysv/linux/waitpid.S
+++ b/sysdeps/unix/sysv/sysv4/linux/waitpid.S