summaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/arm/sysdep.h
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-04-01 09:15:07 +0000
committerUlrich Drepper <drepper@redhat.com>1998-04-01 09:15:07 +0000
commit652e8a1e1beaaab450f56e5cef67a0c15164a88b (patch)
treeedb1ea55cdddaaf2885d573aeaa725e0d2b703fb /sysdeps/unix/sysv/linux/arm/sysdep.h
parent1d97d6ac3bf8fa241535793b31acd685ee32d6c2 (diff)
Update.
1998-04-1 16:52 Philip Blundell <pb@nexus.co.uk> * sysdeps/unix/sysv/linux/arm/socket.S: Correct test for error and use PLTJMP() rather than explicit (PLT). * sysdeps/arm/elf/start.S: Leave most of the initialisation for __libc_start_main(). Based on patch from Pat Beirne: * sysdeps/unix/sysv/linux/arm/sysdep.h (SYSCALL_ERROR_HANDLER): Always define, not only #ifndef PIC. (DO_CALL): Pass fifth argument correctly in R4. (PSEUDO): Correct test for error, call syscall_error through PLT if PIC. 1998-03-31 10:51 Philip Blundell <pb@nexus.co.uk> * sysdeps/unix/sysv/linux/netash/ash.h: Fix typos and add new definitions.
Diffstat (limited to 'sysdeps/unix/sysv/linux/arm/sysdep.h')
-rw-r--r--sysdeps/unix/sysv/linux/arm/sysdep.h50
1 files changed, 43 insertions, 7 deletions
diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h
index 3b7ffe08d9..dd1b6f4115 100644
--- a/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -45,28 +45,64 @@
is a real error number. Linus said he will make sure the no syscall
returns a value in -1 .. -4095 as a valid result so we can savely
test with -4095. */
+
#undef PSEUDO
#define PSEUDO(name, syscall_name, args) \
.text; \
+ .type syscall_error,%function \
ENTRY (name) \
DO_CALL (args, syscall_name); \
cmn r0, $4096; \
- bgt syscall_error;
+ bhs PLTJMP(syscall_error);
#undef PSEUDO_END
#define PSEUDO_END(name) \
SYSCALL_ERROR_HANDLER \
END (name)
-#ifndef PIC
#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
-#else
-#error Aiee
-#endif /* PIC */
+
+/* Linux takes system call args in registers:
+ syscall number in the SWI instruction
+ arg 1 r0
+ arg 2 r1
+ arg 3 r2
+ arg 4 r3
+ arg 5 r4 (this is different from the APCS convention)
+
+ The compiler is going to form a call by coming here, through PSEUDO, with
+ arguments
+ syscall number in the DO_CALL macro
+ arg 1 r0
+ arg 2 r1
+ arg 3 r2
+ arg 4 r3
+ arg 5 [sp]
+
+ We need to shuffle values between R4 and the stack so that the caller's
+ R4 is not corrupted, and the kernel sees the right argument there.
+
+*/
#undef DO_CALL
-#define DO_CALL(args, syscall_name) \
- swi SYS_ify (syscall_name);
+#define DO_CALL(args, syscall_name) \
+ DOARGS_##args \
+ swi SYS_ify (syscall_name); \
+ UNDOARGS_##args
+
+#define DOARGS_0 /* nothing */
+#define DOARGS_1 /* nothing */
+#define DOARGS_2 /* nothing */
+#define DOARGS_3 /* nothing */
+#define DOARGS_4 /* nothing */
+#define DOARGS_5 ldr ip, [sp]; str r4, [sp]; mov r4, ip;
+
+#define UNDOARGS_0 /* nothing */
+#define UNDOARGS_1 /* nothing */
+#define UNDOARGS_2 /* nothing */
+#define UNDOARGS_3 /* nothing */
+#define UNDOARGS_4 /* nothing */
+#define UNDOARGS_5 ldr r4, [sp];
#endif /* ASSEMBLER */