Warning: That file was not part of the compilation database. It may have many parsing errors.

1/* Copyright (C) 2000-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library. If not, see
16 <https://www.gnu.org/licenses/>. */
17
18#ifndef _LINUX_MIPS_SYSDEP_H
19#define _LINUX_MIPS_SYSDEP_H 1
20
21/* There is some commonality. */
22#include <sysdeps/unix/sysv/linux/mips/sysdep.h>
23#include <sysdeps/unix/sysv/linux/sysdep.h>
24#include <sysdeps/unix/mips/mips64/sysdep.h>
25
26#include <tls.h>
27
28/* For Linux we can use the system call table in the header file
29 /usr/include/asm/unistd.h
30 of the kernel. But these symbols do not follow the SYS_* syntax
31 so we have to redefine the `SYS_ify' macro here. */
32#undef SYS_ify
33#define SYS_ify(syscall_name) __NR_##syscall_name
34
35#ifdef __ASSEMBLER__
36
37/* We don't want the label for the error handler to be visible in the symbol
38 table when we define it here. */
39# undef SYSCALL_ERROR_LABEL
40# define SYSCALL_ERROR_LABEL 99b
41
42#else /* ! __ASSEMBLER__ */
43
44#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
45#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
46
47#if _MIPS_SIM == _ABIN32
48/* Convert X to a long long, without losing any bits if it is one
49 already or warning if it is a 32-bit pointer. */
50# define ARGIFY(X) ((long long int) (__typeof__ ((X) - (X))) (X))
51typedef long long int __syscall_arg_t;
52#else
53# define ARGIFY(X) ((long int) (X))
54typedef long int __syscall_arg_t;
55#endif
56
57/* Note that the original Linux syscall restart convention required the
58 instruction immediately preceding SYSCALL to initialize $v0 with the
59 syscall number. Then if a restart triggered, $v0 would have been
60 clobbered by the syscall interrupted, and needed to be reinititalized.
61 The kernel would decrement the PC by 4 before switching back to the
62 user mode so that $v0 had been reloaded before SYSCALL was executed
63 again. This implied the place $v0 was loaded from must have been
64 preserved across a syscall, e.g. an immediate, static register, stack
65 slot, etc.
66
67 The convention was relaxed in Linux with a change applied to the kernel
68 GIT repository as commit 96187fb0bc30cd7919759d371d810e928048249d, that
69 first appeared in the 2.6.36 release. Since then the kernel has had
70 code that reloads $v0 upon syscall restart and resumes right at the
71 SYSCALL instruction, so no special arrangement is needed anymore.
72
73 For backwards compatibility with existing kernel binaries we support
74 the old convention by choosing the instruction preceding SYSCALL
75 carefully. This also means we have to force a 32-bit encoding of the
76 microMIPS MOVE instruction if one is used. */
77
78#ifdef __mips_micromips
79# define MOVE32 "move32"
80#else
81# define MOVE32 "move"
82#endif
83
84#undef INTERNAL_SYSCALL
85#define INTERNAL_SYSCALL(name, nr, args...) \
86 internal_syscall##nr ("li\t%0, %2\t\t\t# " #name "\n\t", \
87 "IK" (SYS_ify (name)), \
88 0, args)
89
90#undef INTERNAL_SYSCALL_NCS
91#define INTERNAL_SYSCALL_NCS(number, nr, args...) \
92 internal_syscall##nr (MOVE32 "\t%0, %2\n\t", \
93 "r" (__s0), \
94 number, args)
95
96#define internal_syscall0(v0_init, input, number, dummy...) \
97({ \
98 long int _sys_result; \
99 \
100 { \
101 register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
102 = (number); \
103 register __syscall_arg_t __v0 asm ("$2"); \
104 register __syscall_arg_t __a3 asm ("$7"); \
105 __asm__ volatile ( \
106 ".set\tnoreorder\n\t" \
107 v0_init \
108 "syscall\n\t" \
109 ".set reorder" \
110 : "=r" (__v0), "=r" (__a3) \
111 : input \
112 : __SYSCALL_CLOBBERS); \
113 _sys_result = __a3 != 0 ? -__v0 : __v0; \
114 } \
115 _sys_result; \
116})
117
118#define internal_syscall1(v0_init, input, number, arg1) \
119({ \
120 long int _sys_result; \
121 \
122 { \
123 __syscall_arg_t _arg1 = ARGIFY (arg1); \
124 register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
125 = (number); \
126 register __syscall_arg_t __v0 asm ("$2"); \
127 register __syscall_arg_t __a0 asm ("$4") = _arg1; \
128 register __syscall_arg_t __a3 asm ("$7"); \
129 __asm__ volatile ( \
130 ".set\tnoreorder\n\t" \
131 v0_init \
132 "syscall\n\t" \
133 ".set reorder" \
134 : "=r" (__v0), "=r" (__a3) \
135 : input, "r" (__a0) \
136 : __SYSCALL_CLOBBERS); \
137 _sys_result = __a3 != 0 ? -__v0 : __v0; \
138 } \
139 _sys_result; \
140})
141
142#define internal_syscall2(v0_init, input, number, arg1, arg2) \
143({ \
144 long int _sys_result; \
145 \
146 { \
147 __syscall_arg_t _arg1 = ARGIFY (arg1); \
148 __syscall_arg_t _arg2 = ARGIFY (arg2); \
149 register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
150 = (number); \
151 register __syscall_arg_t __v0 asm ("$2"); \
152 register __syscall_arg_t __a0 asm ("$4") = _arg1; \
153 register __syscall_arg_t __a1 asm ("$5") = _arg2; \
154 register __syscall_arg_t __a3 asm ("$7"); \
155 __asm__ volatile ( \
156 ".set\tnoreorder\n\t" \
157 v0_init \
158 "syscall\n\t" \
159 ".set\treorder" \
160 : "=r" (__v0), "=r" (__a3) \
161 : input, "r" (__a0), "r" (__a1) \
162 : __SYSCALL_CLOBBERS); \
163 _sys_result = __a3 != 0 ? -__v0 : __v0; \
164 } \
165 _sys_result; \
166})
167
168#define internal_syscall3(v0_init, input, number, arg1, arg2, arg3) \
169({ \
170 long int _sys_result; \
171 \
172 { \
173 __syscall_arg_t _arg1 = ARGIFY (arg1); \
174 __syscall_arg_t _arg2 = ARGIFY (arg2); \
175 __syscall_arg_t _arg3 = ARGIFY (arg3); \
176 register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
177 = (number); \
178 register __syscall_arg_t __v0 asm ("$2"); \
179 register __syscall_arg_t __a0 asm ("$4") = _arg1; \
180 register __syscall_arg_t __a1 asm ("$5") = _arg2; \
181 register __syscall_arg_t __a2 asm ("$6") = _arg3; \
182 register __syscall_arg_t __a3 asm ("$7"); \
183 __asm__ volatile ( \
184 ".set\tnoreorder\n\t" \
185 v0_init \
186 "syscall\n\t" \
187 ".set\treorder" \
188 : "=r" (__v0), "=r" (__a3) \
189 : input, "r" (__a0), "r" (__a1), "r" (__a2) \
190 : __SYSCALL_CLOBBERS); \
191 _sys_result = __a3 != 0 ? -__v0 : __v0; \
192 } \
193 _sys_result; \
194})
195
196#define internal_syscall4(v0_init, input, number, arg1, arg2, arg3, \
197 arg4) \
198({ \
199 long int _sys_result; \
200 \
201 { \
202 __syscall_arg_t _arg1 = ARGIFY (arg1); \
203 __syscall_arg_t _arg2 = ARGIFY (arg2); \
204 __syscall_arg_t _arg3 = ARGIFY (arg3); \
205 __syscall_arg_t _arg4 = ARGIFY (arg4); \
206 register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
207 = (number); \
208 register __syscall_arg_t __v0 asm ("$2"); \
209 register __syscall_arg_t __a0 asm ("$4") = _arg1; \
210 register __syscall_arg_t __a1 asm ("$5") = _arg2; \
211 register __syscall_arg_t __a2 asm ("$6") = _arg3; \
212 register __syscall_arg_t __a3 asm ("$7") = _arg4; \
213 __asm__ volatile ( \
214 ".set\tnoreorder\n\t" \
215 v0_init \
216 "syscall\n\t" \
217 ".set\treorder" \
218 : "=r" (__v0), "+r" (__a3) \
219 : input, "r" (__a0), "r" (__a1), "r" (__a2) \
220 : __SYSCALL_CLOBBERS); \
221 _sys_result = __a3 != 0 ? -__v0 : __v0; \
222 } \
223 _sys_result; \
224})
225
226#define internal_syscall5(v0_init, input, number, arg1, arg2, arg3, \
227 arg4, arg5) \
228({ \
229 long int _sys_result; \
230 \
231 { \
232 __syscall_arg_t _arg1 = ARGIFY (arg1); \
233 __syscall_arg_t _arg2 = ARGIFY (arg2); \
234 __syscall_arg_t _arg3 = ARGIFY (arg3); \
235 __syscall_arg_t _arg4 = ARGIFY (arg4); \
236 __syscall_arg_t _arg5 = ARGIFY (arg5); \
237 register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
238 = (number); \
239 register __syscall_arg_t __v0 asm ("$2"); \
240 register __syscall_arg_t __a0 asm ("$4") = _arg1; \
241 register __syscall_arg_t __a1 asm ("$5") = _arg2; \
242 register __syscall_arg_t __a2 asm ("$6") = _arg3; \
243 register __syscall_arg_t __a3 asm ("$7") = _arg4; \
244 register __syscall_arg_t __a4 asm ("$8") = _arg5; \
245 __asm__ volatile ( \
246 ".set\tnoreorder\n\t" \
247 v0_init \
248 "syscall\n\t" \
249 ".set\treorder" \
250 : "=r" (__v0), "+r" (__a3) \
251 : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4) \
252 : __SYSCALL_CLOBBERS); \
253 _sys_result = __a3 != 0 ? -__v0 : __v0; \
254 } \
255 _sys_result; \
256})
257
258#define internal_syscall6(v0_init, input, number, arg1, arg2, arg3, \
259 arg4, arg5, arg6) \
260({ \
261 long int _sys_result; \
262 \
263 { \
264 __syscall_arg_t _arg1 = ARGIFY (arg1); \
265 __syscall_arg_t _arg2 = ARGIFY (arg2); \
266 __syscall_arg_t _arg3 = ARGIFY (arg3); \
267 __syscall_arg_t _arg4 = ARGIFY (arg4); \
268 __syscall_arg_t _arg5 = ARGIFY (arg5); \
269 __syscall_arg_t _arg6 = ARGIFY (arg6); \
270 register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
271 = (number); \
272 register __syscall_arg_t __v0 asm ("$2"); \
273 register __syscall_arg_t __a0 asm ("$4") = _arg1; \
274 register __syscall_arg_t __a1 asm ("$5") = _arg2; \
275 register __syscall_arg_t __a2 asm ("$6") = _arg3; \
276 register __syscall_arg_t __a3 asm ("$7") = _arg4; \
277 register __syscall_arg_t __a4 asm ("$8") = _arg5; \
278 register __syscall_arg_t __a5 asm ("$9") = _arg6; \
279 __asm__ volatile ( \
280 ".set\tnoreorder\n\t" \
281 v0_init \
282 "syscall\n\t" \
283 ".set\treorder" \
284 : "=r" (__v0), "+r" (__a3) \
285 : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), \
286 "r" (__a5) \
287 : __SYSCALL_CLOBBERS); \
288 _sys_result = __a3 != 0 ? -__v0 : __v0; \
289 } \
290 _sys_result; \
291})
292
293#if __mips_isa_rev >= 6
294# define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
295 "$14", "$15", "$24", "$25", "memory"
296#else
297# define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
298 "$14", "$15", "$24", "$25", "hi", "lo", "memory"
299#endif
300
301#endif /* __ASSEMBLER__ */
302
303/* Pointer mangling is not yet supported for MIPS. */
304#define PTR_MANGLE(var) (void) (var)
305#define PTR_DEMANGLE(var) (void) (var)
306
307#endif /* linux/mips/sysdep.h */
308

Warning: That file was not part of the compilation database. It may have many parsing errors.

source code of glibc/sysdeps/unix/sysv/linux/mips/mips64/sysdep.h