about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/arm/socket.S
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-04-14 13:42:55 +0000
committerUlrich Drepper <drepper@redhat.com>1999-04-14 13:42:55 +0000
commit9b2446e825d9c998b270a1dcca1dfd3262e487e0 (patch)
treee34382ebd0c2c1c72f680b598c129876f8cd4868 /sysdeps/unix/sysv/linux/arm/socket.S
parent1156499baede7abd7ccf1b3b9fb3c587c941b915 (diff)
downloadglibc-9b2446e825d9c998b270a1dcca1dfd3262e487e0.tar.gz
glibc-9b2446e825d9c998b270a1dcca1dfd3262e487e0.tar.xz
glibc-9b2446e825d9c998b270a1dcca1dfd3262e487e0.zip
Update.
1999-04-14 Scott Bambrough  <scottb@netwinder.org>

	* sysdeps/unix/sysv/linux/arm/socket.S: Socket calls could not be
	restarted after being interrupted by a signal.  The parameters on
	the stack were corrupted by the signal handler.

	* sysdeps/unix/sysv/linux/arm/mmap.S: mmap calls could not be
	restarted after being interrupted by a signal.  The parameters on
	the stack were corrupted by the signal handler.
Diffstat (limited to 'sysdeps/unix/sysv/linux/arm/socket.S')
-rw-r--r--sysdeps/unix/sysv/linux/arm/socket.S35
1 files changed, 27 insertions, 8 deletions
diff --git a/sysdeps/unix/sysv/linux/arm/socket.S b/sysdeps/unix/sysv/linux/arm/socket.S
index b51d887a7f..92c7e907a2 100644
--- a/sysdeps/unix/sysv/linux/arm/socket.S
+++ b/sysdeps/unix/sysv/linux/arm/socket.S
@@ -35,12 +35,19 @@
 #define __socket P(__,socket)
 #endif
 
-#define PUSHARGS_1	stmfd ip!, {a1}
-#define PUSHARGS_2	stmfd ip!, {a1, a2}
-#define PUSHARGS_3	stmfd ip!, {a1, a2, a3}
-#define PUSHARGS_4	stmfd ip!, {a1, a2, a3, a4}
-#define PUSHARGS_5	stmfd ip!, {a1, a2, a3, a4}	/* Caller has already pushed arg 5 */
-#define PUSHARGS_6	stmfd ip!, {a1, a2, a3, a4}
+#define PUSHARGS_1	stmfd sp!, {a1}
+#define PUSHARGS_2	stmfd sp!, {a1, a2}
+#define PUSHARGS_3	stmfd sp!, {a1, a2, a3}
+#define PUSHARGS_4	stmfd sp!, {a1, a2, a3, a4}
+#define PUSHARGS_5	stmfd sp!, {a1, a2, a3, a4}	/* Caller has already pushed arg 5 */
+#define PUSHARGS_6	stmfd sp!, {a1, a2, a3, a4}
+
+#define POPARGS_1	add sp, sp, #4
+#define POPARGS_2	add sp, sp, #8
+#define POPARGS_3	add sp, sp, #12
+#define POPARGS_4	add sp, sp, #16
+#define POPARGS_5	add sp, sp, #16
+#define POPARGS_6	add sp, sp, #16 
 
 #ifndef NARGS
 #define NARGS 3			/* If we were called with no wrapper, this is really socket() */
@@ -48,15 +55,27 @@
 
 .globl __socket
 ENTRY (__socket)
+	/* This code previously moved sp into ip and stored the args using
+	   stmdb ip!, {a1-a4}.  It did not modify sp, so the stack never had 
+	   to be restored after the syscall completed.  It saved an 
+	   instruction and meant no stack cleanup work was required.
+
+	   This will not work in the case of a socket call being interrupted
+	   by a signal.  If the signal handler uses any stack the arguments
+	   to socket will be trashed.  The results of a restart of any
+	   socket call are then unpredictable. */
+
 	/* Push args onto the stack.  */
-	mov ip, sp
 	P(PUSHARGS_,NARGS)
 
         /* Do the system call trap.  */
 	mov a1, $P(SOCKOP_,socket)
-	mov a2, ip
+	mov a2, sp
 	swi SYS_ify(socketcall)
 
+	/* Pop args off the stack */
+	P(POPARGS_,NARGS)
+
 	/* r0 is < 0 if there was an error.  */
 	cmn r0, $124
 	bhs PLTJMP(syscall_error)