1 #ifndef _BITS_SYSCALLS_H
2 #define _BITS_SYSCALLS_H
4 # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
7 /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
8 * header files. It also defines the traditional `SYS_<name>' macros for older
10 #include <bits/sysnum.h>
13 # define __set_errno(val) (*__errno_location ()) = (val)
16 # define SYS_ify(syscall_name) (__NR_##syscall_name)
20 Some of the sneaky macros in the code were taken from
21 glibc-2.3.2/sysdeps/unix/sysv/linux/arm/sysdep.h
25 /* Call a given syscall, with arguments loaded. For EABI, we must
26 save and restore r7 for the syscall number. Unlike the DO_CALL
27 macro in glibc, this macro does not load syscall arguments. */
29 #if defined(__ARM_EABI__)
30 #define DO_CALL(syscall_name) \
32 ldr r7, =SYS_ify (syscall_name); \
36 #define DO_CALL(syscall_name) \
37 swi SYS_ify (syscall_name);
42 #define _syscall0(type,name) \
45 return (type) (INLINE_SYSCALL(name, 0)); \
49 #define _syscall1(type,name,type1,arg1) \
50 type name(type1 arg1) \
52 return (type) (INLINE_SYSCALL(name, 1, arg1)); \
56 #define _syscall2(type,name,type1,arg1,type2,arg2) \
57 type name(type1 arg1,type2 arg2) \
59 return (type) (INLINE_SYSCALL(name, 2, arg1, arg2)); \
63 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
64 type name(type1 arg1,type2 arg2,type3 arg3) \
66 return (type) (INLINE_SYSCALL(name, 3, arg1, arg2, arg3)); \
70 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
71 type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
73 return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
77 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
79 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
81 return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
85 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
86 type5,arg5,type6,arg6) \
87 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6) \
89 return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
93 #define _syscall7(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
94 type5,arg5,type6,arg6,type7,arg7) \
95 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6,type7 arg7) \
97 return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); \
101 #undef INLINE_SYSCALL
102 #define INLINE_SYSCALL(name, nr, args...) \
103 ({ unsigned int __sys_result = INTERNAL_SYSCALL (name, , nr, args); \
104 if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (__sys_result, ), 0)) \
106 __set_errno (INTERNAL_SYSCALL_ERRNO (__sys_result, )); \
107 __sys_result = (unsigned int) -1; \
109 (int) __sys_result; })
111 #undef INTERNAL_SYSCALL_DECL
112 #define INTERNAL_SYSCALL_DECL(err) do { } while (0)
114 #undef INTERNAL_SYSCALL
115 #if defined(__ARM_EABI__)
116 #define INTERNAL_SYSCALL(name, err, nr, args...) \
117 ({unsigned int _sys_result; \
119 register int _a1 asm ("r0"), _nr asm ("r7"); \
120 LOAD_ARGS_##nr (args) \
121 _nr = SYS_ify(name); \
122 asm volatile ("swi 0x0 @ syscall " #name \
124 : "r" (_nr) ASM_ARGS_##nr \
128 (int) _sys_result; })
129 #else /* !defined(__ARM_EABI__) */
130 #if !defined(__thumb__)
131 #define INTERNAL_SYSCALL(name, err, nr, args...) \
132 ({ unsigned int _sys_result; \
134 register int _a1 asm ("a1"); \
135 LOAD_ARGS_##nr (args) \
136 asm volatile ("swi %1 @ syscall " #name \
138 : "i" (SYS_ify(name)) ASM_ARGS_##nr \
142 (int) _sys_result; })
144 #define INTERNAL_SYSCALL(name, err, nr, args...) \
145 ({ unsigned int _sys_result; \
147 register int _a1 asm ("a1"); \
148 LOAD_ARGS_##nr (args) \
149 register int _r7 asm ("r7") = (int) (SYS_ify(name)); \
150 asm volatile ("swi 0 @ syscall " #name \
152 : "r" (_r7) ASM_ARGS_##nr \
156 (int) _sys_result; })
158 #endif /* !defined(__ARM_EABI__) */
160 #undef INTERNAL_SYSCALL_ERROR_P
161 #define INTERNAL_SYSCALL_ERROR_P(val, err) \
162 ((unsigned int) (val) >= 0xfffff001u)
164 #undef INTERNAL_SYSCALL_ERRNO
165 #define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
167 #define LOAD_ARGS_0()
169 #define LOAD_ARGS_1(a1) \
172 #define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
173 #define LOAD_ARGS_2(a1, a2) \
174 register int _a2 asm ("a2") = (int) (a2); \
176 #define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
177 #define LOAD_ARGS_3(a1, a2, a3) \
178 register int _a3 asm ("a3") = (int) (a3); \
180 #define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
181 #define LOAD_ARGS_4(a1, a2, a3, a4) \
182 register int _a4 asm ("a4") = (int) (a4); \
183 LOAD_ARGS_3 (a1, a2, a3)
184 #define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
185 #define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
186 register int _v1 asm ("v1") = (int) (a5); \
187 LOAD_ARGS_4 (a1, a2, a3, a4)
188 #define ASM_ARGS_5 ASM_ARGS_4, "r" (_v1)
189 #define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
190 register int _v2 asm ("v2") = (int) (a6); \
191 LOAD_ARGS_5 (a1, a2, a3, a4, a5)
192 #define ASM_ARGS_6 ASM_ARGS_5, "r" (_v2)
193 #define LOAD_ARGS_7(a1, a2, a3, a4, a5, a6, a7) \
194 register int _v3 asm ("v3") = (int) (a7); \
195 LOAD_ARGS_6 (a1, a2, a3, a4, a5, a6)
196 #define ASM_ARGS_7 ASM_ARGS_6, "r" (_v3)
199 #endif /* __ASSEMBLER__ */
200 #endif /* _BITS_SYSCALLS_H */