INTERNAL_SYSCALL and function calls in arguments
Andreas Schwab
schwab@suse.de
Fri Apr 9 13:45:00 GMT 2004
Thorsten Kukuk <kukuk@suse.de> writes:
> Hi,
>
> sched_setaffinity has the following code:
>
> INTERNAL_SYSCALL (sched_getaffinity, err, 3, getpid(), psize, p)
Here is a patch to fix the INTERNAL_SYSCALL macro for x86_64 and ia64.
The definition on arm is probably also affected, but I can't test it.
Andreas.
2004-04-09 Andreas Schwab <schwab@suse.de>
* sysdeps/unix/sysv/linux/ia64/sysdep.h (DO_INLINE_SYSCALL): Move
LOAD_ARGS_##nr up front and add LOAD_REGS_##nr.
(LOAD_ARGS_0, LOAD_ARGS_1, LOAD_ARGS_2, LOAD_ARGS_3, LOAD_ARGS_4)
(LOAD_ARGS_5, LOAD_ARGS_6): Load argument values into temporary
variables.
(LOAD_REGS_0, LOAD_REGS_1, LOAD_REGS_2, LOAD_REGS_3, LOAD_REGS_4)
(LOAD_REGS_5, LOAD_REGS_6): New macros to actually load the
syscall argument registers.
* sysdeps/unix/sysv/linux/x86_64/sysdep.h (INTERNAL_SYSCALL): Add
LOAD_REGS_##nr.
(LOAD_ARGS_0, LOAD_ARGS_1, LOAD_ARGS_2, LOAD_ARGS_3, LOAD_ARGS_4)
(LOAD_ARGS_5, LOAD_ARGS_6): Load argument values into temporary
variables.
(LOAD_REGS_0, LOAD_REGS_1, LOAD_REGS_2, LOAD_REGS_3, LOAD_REGS_4)
(LOAD_REGS_5, LOAD_REGS_6): New macros to actually load the
syscall argument registers.
Index: sysdeps/unix/sysv/linux/ia64/sysdep.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/sysdep.h,v
retrieving revision 1.19
diff -u -p -a -u -p -a -r1.19 sysdeps/unix/sysv/linux/ia64/sysdep.h
--- sysdeps/unix/sysv/linux/ia64/sysdep.h 10 Dec 2003 23:00:21 -0000 1.19
+++ sysdeps/unix/sysv/linux/ia64/sysdep.h 9 Apr 2004 13:38:43 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
Based on code originally written by David Mosberger-Tang
@@ -200,12 +200,13 @@
#ifdef IA64_USE_NEW_STUB
#define DO_INLINE_SYSCALL(name, nr, args...) \
+ LOAD_ARGS_##nr (args) \
register long _r8 __asm ("r8"); \
register long _r10 __asm ("r10"); \
register long _r15 __asm ("r15") = __NR_##name; \
register void *_b7 __asm ("b7") = ((tcbhead_t *) __thread_self)->private; \
long _retval; \
- LOAD_ARGS_##nr (args); \
+ LOAD_REGS_##nr \
/* \
* Don't specify any unwind info here. We mark ar.pfs as \
* clobbered. This will force the compiler to save ar.pfs \
@@ -221,11 +222,12 @@
#else /* !IA64_USE_NEW_STUB */
#define DO_INLINE_SYSCALL(name, nr, args...) \
+ LOAD_ARGS_##nr (args) \
register long _r8 asm ("r8"); \
register long _r10 asm ("r10"); \
register long _r15 asm ("r15") = __NR_##name; \
long _retval; \
- LOAD_ARGS_##nr (args); \
+ LOAD_REGS_##nr \
__asm __volatile (BREAK_INSN (__BREAK_SYSCALL) \
: "=r" (_r8), "=r" (_r10), "=r" (_r15) \
ASM_OUTARGS_##nr \
@@ -262,25 +264,44 @@
#undef INTERNAL_SYSCALL_ERRNO
#define INTERNAL_SYSCALL_ERRNO(val, err) (val)
-#define LOAD_ARGS_0() do { } while (0)
-#define LOAD_ARGS_1(out0) \
- register long _out0 asm ("out0") = (long) (out0); \
+#define LOAD_ARGS_0()
+#define LOAD_REGS_0
+#define LOAD_ARGS_1(a1) \
+ long _arg1 = (long) (a1); \
LOAD_ARGS_0 ()
-#define LOAD_ARGS_2(out0, out1) \
- register long _out1 asm ("out1") = (long) (out1); \
- LOAD_ARGS_1 (out0)
-#define LOAD_ARGS_3(out0, out1, out2) \
- register long _out2 asm ("out2") = (long) (out2); \
- LOAD_ARGS_2 (out0, out1)
-#define LOAD_ARGS_4(out0, out1, out2, out3) \
- register long _out3 asm ("out3") = (long) (out3); \
- LOAD_ARGS_3 (out0, out1, out2)
-#define LOAD_ARGS_5(out0, out1, out2, out3, out4) \
- register long _out4 asm ("out4") = (long) (out4); \
- LOAD_ARGS_4 (out0, out1, out2, out3)
-#define LOAD_ARGS_6(out0, out1, out2, out3, out4, out5) \
- register long _out5 asm ("out5") = (long) (out5); \
- LOAD_ARGS_5 (out0, out1, out2, out3, out4)
+#define LOAD_REGS_1 \
+ register long _out0 asm ("out0") = _arg1; \
+ LOAD_REGS_0
+#define LOAD_ARGS_2(a1, a2) \
+ long _arg2 = (long) (a2); \
+ LOAD_ARGS_1 (a1)
+#define LOAD_REGS_2 \
+ register long _out1 asm ("out1") = _arg2; \
+ LOAD_REGS_1
+#define LOAD_ARGS_3(a1, a2, a3) \
+ long _arg3 = (long) (a3); \
+ LOAD_ARGS_2 (a1, a2)
+#define LOAD_REGS_3 \
+ register long _out2 asm ("out2") = _arg3; \
+ LOAD_REGS_2
+#define LOAD_ARGS_4(a1, a2, a3, a4) \
+ long _arg4 = (long) (a4); \
+ LOAD_ARGS_3 (a1, a2, a3)
+#define LOAD_REGS_4 \
+ register long _out3 asm ("out3") = _arg4; \
+ LOAD_REGS_3
+#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
+ long _arg5 = (long) (a5); \
+ LOAD_ARGS_4 (a1, a2, a3, a4)
+#define LOAD_REGS_5 \
+ register long _out4 asm ("out4") = _arg5; \
+ LOAD_REGS_4
+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
+ long _arg6 = (long) (a6); \
+ LOAD_ARGS_5 (a1, a2, a3, a4, a5)
+#define LOAD_REGS_6 \
+ register long _out5 asm ("out5") = _arg6; \
+ LOAD_REGS_5
#define ASM_OUTARGS_0
#define ASM_OUTARGS_1 ASM_OUTARGS_0, "=r" (_out0)
--- sysdeps/unix/sysv/linux/x86_64/sysdep.h.~1.21.~ 2003-08-19 10:50:34.000000000 +0200
+++ sysdeps/unix/sysv/linux/x86_64/sysdep.h 2004-04-09 12:06:15.000000000 +0200
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001,02,03 Free Software Foundation, Inc.
+/* Copyright (C) 2001,02,03,04 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
@@ -241,6 +241,7 @@
({ \
unsigned long resultvar; \
LOAD_ARGS_##nr (args) \
+ LOAD_REGS_##nr \
asm volatile ( \
"movq %1, %%rax\n\t" \
"syscall\n\t" \
@@ -256,36 +257,55 @@
#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
#define LOAD_ARGS_0()
+#define LOAD_REGS_0
#define ASM_ARGS_0
#define LOAD_ARGS_1(a1) \
- register long int _a1 asm ("rdi") = (long) (a1); \
+ long int __arg1 = (long) (a1); \
LOAD_ARGS_0 ()
+#define LOAD_REGS_1 \
+ register long int _a1 asm ("rdi") = __arg1; \
+ LOAD_REGS_0
#define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
#define LOAD_ARGS_2(a1, a2) \
- register long int _a2 asm ("rsi") = (long) (a2); \
+ long int __arg2 = (long) (a2); \
LOAD_ARGS_1 (a1)
+#define LOAD_REGS_2 \
+ register long int _a2 asm ("rsi") = __arg2; \
+ LOAD_REGS_1
#define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
#define LOAD_ARGS_3(a1, a2, a3) \
- register long int _a3 asm ("rdx") = (long) (a3); \
+ long int __arg3 = (long) (a3); \
LOAD_ARGS_2 (a1, a2)
+#define LOAD_REGS_3 \
+ register long int _a3 asm ("rdx") = __arg3; \
+ LOAD_REGS_2
#define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
#define LOAD_ARGS_4(a1, a2, a3, a4) \
- register long int _a4 asm ("r10") = (long) (a4); \
+ long int __arg4 = (long) (a4); \
LOAD_ARGS_3 (a1, a2, a3)
+#define LOAD_REGS_4 \
+ register long int _a4 asm ("r10") = __arg4; \
+ LOAD_REGS_3
#define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
- register long int _a5 asm ("r8") = (long) (a5); \
+ long int __arg5 = (long) (a5); \
LOAD_ARGS_4 (a1, a2, a3, a4)
+#define LOAD_REGS_5 \
+ register long int _a5 asm ("r8") = __arg5; \
+ LOAD_REGS_4
#define ASM_ARGS_5 ASM_ARGS_4, "r" (_a5)
#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
- register long int _a6 asm ("r9") = (long) (a6); \
+ long int __arg6 = (long) (a6); \
LOAD_ARGS_5 (a1, a2, a3, a4, a5)
+#define LOAD_REGS_6 \
+ register long int _a6 asm ("r9") = __arg6; \
+ LOAD_REGS_5
#define ASM_ARGS_6 ASM_ARGS_5, "r" (_a6)
#endif /* __ASSEMBLER__ */
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, MaxfeldstraÃe 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
More information about the Libc-hacker
mailing list