diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/mmap.S | 22 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/socket.S | 35 |
3 files changed, 56 insertions, 11 deletions
@@ -1,3 +1,13 @@ +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. + 1999-04-14 Andreas Jaeger <aj@arthur.rhein-neckar.de> * wctype/wcfuncs.c (towlower): Use __ctype_tolower. diff --git a/sysdeps/unix/sysv/linux/arm/mmap.S b/sysdeps/unix/sysv/linux/arm/mmap.S index f9a773fc68..fcff57c55d 100644 --- a/sysdeps/unix/sysv/linux/arm/mmap.S +++ b/sysdeps/unix/sysv/linux/arm/mmap.S @@ -26,10 +26,26 @@ ENTRY (__mmap) mmap() takes six, we need to build a parameter block and pass its address instead. The 386 port does a similar trick. */ - mov ip, sp - stmdb ip!, {a1-a4} - mov a1, ip + /* 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 mmap call being interrupted + by a signal. If the signal handler uses any stack the arguments + to mmap will be trashed. The results of a restart of mmap are + then unpredictable. */ + + /* store args on the stack */ + stmdb sp!, {a1-a4} + + /* do the syscall */ + mov a1, sp swi SYS_ify (mmap) + + /* pop args off the stack. */ + add sp, sp, #16 + cmn r0, $4096 bhs PLTJMP(syscall_error); ret 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) |