1 #ifndef _BITS_SYSCALLS_H
2 #define _BITS_SYSCALLS_H
4 # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
8 Some of the sneaky macros in the code were taken from
9 glibc-2.2.5/sysdeps/unix/sysv/linux/x86_64/sysdep.h
16 #define SYS_ify(syscall_name) (__NR_##syscall_name)
19 #define _syscall0(type,name) \
22 return (type) (INLINE_SYSCALL(name, 0)); \
26 #define _syscall1(type,name,type1,arg1) \
27 type name(type1 arg1) \
29 return (type) (INLINE_SYSCALL(name, 1, arg1)); \
33 #define _syscall2(type,name,type1,arg1,type2,arg2) \
34 type name(type1 arg1,type2 arg2) \
36 return (type) (INLINE_SYSCALL(name, 2, arg1, arg2)); \
40 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
41 type name(type1 arg1,type2 arg2,type3 arg3) \
43 return (type) (INLINE_SYSCALL(name, 3, arg1, arg2, arg3)); \
47 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
48 type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
50 return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
54 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
56 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
58 return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
62 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
63 type5,arg5,type6,arg6) \
64 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
66 return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
69 /* The Linux/x86-64 kernel expects the system call parameters in
70 registers according to the following table:
80 The Linux kernel uses and destroys internally these registers:
83 additionally clobered: r12-r15,rbx,rbp
84 eflags from syscall r11
86 Normal function call, including calls to the system call stub
87 functions in the libc, get the first six parameters passed in
88 registers and the seventh parameter and later on the stack. The
89 register use is as follows:
91 system call number in the DO_CALL macro
99 We have to take care that the stack is aligned to 16 bytes. When
100 called the stack is not aligned since the return address has just
104 Syscalls of more than 6 arguments are not supported. */
107 #define SYS_ify(syscall_name) __NR_##syscall_name
110 #define DO_CALL(syscall_name, args) \
112 movq $SYS_ify (syscall_name), %rax; \
115 #define DOARGS_0 /* nothing */
116 #define DOARGS_1 /* nothing */
117 #define DOARGS_2 /* nothing */
118 #define DOARGS_3 /* nothing */
119 #define DOARGS_4 movq %rcx, %r10;
120 #define DOARGS_5 DOARGS_4
121 #define DOARGS_6 DOARGS_5
123 /* Define a macro which expands inline into the wrapper code for a system
125 #undef INLINE_SYSCALL
126 #define INLINE_SYSCALL(name, nr, args...) \
128 unsigned long _resultvar = INTERNAL_SYSCALL (name, , nr, args); \
129 if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_resultvar, ), 0)) \
131 __set_errno (INTERNAL_SYSCALL_ERRNO (_resultvar, )); \
132 _resultvar = (unsigned long) -1; \
134 (long) _resultvar; })
136 #undef INTERNAL_SYSCALL_DECL
137 #define INTERNAL_SYSCALL_DECL(err) do { } while (0)
139 #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
141 unsigned long resultvar; \
142 LOAD_ARGS_##nr (args) \
147 : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \
149 #undef INTERNAL_SYSCALL
150 #define INTERNAL_SYSCALL(name, err, nr, args...) \
151 INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
153 #undef INTERNAL_SYSCALL_ERROR_P
154 #define INTERNAL_SYSCALL_ERROR_P(val, err) \
155 ((unsigned long) (val) >= -4095L)
157 #undef INTERNAL_SYSCALL_ERRNO
158 #define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
160 #define LOAD_ARGS_0()
164 #define LOAD_ARGS_1(a1) \
165 long int __arg1 = (long) (a1); \
167 #define LOAD_REGS_1 \
168 register long int _a1 asm ("rdi") = __arg1; \
170 #define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
172 #define LOAD_ARGS_2(a1, a2) \
173 long int __arg2 = (long) (a2); \
175 #define LOAD_REGS_2 \
176 register long int _a2 asm ("rsi") = __arg2; \
178 #define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
180 #define LOAD_ARGS_3(a1, a2, a3) \
181 long int __arg3 = (long) (a3); \
183 #define LOAD_REGS_3 \
184 register long int _a3 asm ("rdx") = __arg3; \
186 #define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
188 #define LOAD_ARGS_4(a1, a2, a3, a4) \
189 long int __arg4 = (long) (a4); \
190 LOAD_ARGS_3 (a1, a2, a3)
191 #define LOAD_REGS_4 \
192 register long int _a4 asm ("r10") = __arg4; \
194 #define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
196 #define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
197 long int __arg5 = (long) (a5); \
198 LOAD_ARGS_4 (a1, a2, a3, a4)
199 #define LOAD_REGS_5 \
200 register long int _a5 asm ("r8") = __arg5; \
202 #define ASM_ARGS_5 ASM_ARGS_4, "r" (_a5)
204 #define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
205 long int __arg6 = (long) (a6); \
206 LOAD_ARGS_5 (a1, a2, a3, a4, a5)
207 #define LOAD_REGS_6 \
208 register long int _a6 asm ("r9") = __arg6; \
210 #define ASM_ARGS_6 ASM_ARGS_5, "r" (_a6)
212 #endif /* __ASSEMBLER__ */
213 #endif /* _BITS_SYSCALLS_H */