OLD | NEW |
| (Empty) |
1 /* Copyright (c) 2005-2010, Google Inc. | |
2 * Author: Markus Gutschke | |
3 * | |
4 * All rights reserved. | |
5 * Use of this source code is governed by a BSD-style license that can be | |
6 * found in the Chromium LICENSE file. | |
7 */ | |
8 | |
9 /* This file includes Linux-specific support functions common to the | |
10 * coredumper and the thread lister; primarily, this is a collection | |
11 * of direct system calls, and a couple of symbols missing from | |
12 * standard header files. | |
13 * There are a few options that the including file can set to control | |
14 * the behavior of this file: | |
15 * | |
16 * SYS_CPLUSPLUS: | |
17 * The entire header file will normally be wrapped in 'extern "C" { }", | |
18 * making it suitable for compilation as both C and C++ source. If you | |
19 * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit | |
20 * the wrapping. N.B. doing so will suppress inclusion of all prerequisite | |
21 * system header files, too. It is the caller's responsibility to provide | |
22 * the necessary definitions. | |
23 * | |
24 * SYS_ERRNO: | |
25 * All system calls will update "errno" unless overriden by setting the | |
26 * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be | |
27 * an l-value. | |
28 * | |
29 * SYS_INLINE: | |
30 * New symbols will be defined "static inline", unless overridden by | |
31 * the SYS_INLINE macro. | |
32 * | |
33 * SYS_LINUX_SYSCALL_SUPPORT_H | |
34 * This macro is used to avoid multiple inclusions of this header file. | |
35 * If you need to include this file more than once, make sure to | |
36 * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion. | |
37 * | |
38 * SYS_PREFIX: | |
39 * New system calls will have a prefix of "sys_" unless overridden by | |
40 * the SYS_PREFIX macro. Valid values for this macro are [0..9] which | |
41 * results in prefixes "sys[0..9]_". It is also possible to set this | |
42 * macro to -1, which avoids all prefixes. | |
43 * | |
44 * This file defines a few internal symbols that all start with "LSS_". | |
45 * Do not access these symbols from outside this file. They are not part | |
46 * of the supported API. | |
47 */ | |
48 #ifndef SYS_LINUX_SYSCALL_SUPPORT_H | |
49 #define SYS_LINUX_SYSCALL_SUPPORT_H | |
50 | |
51 /* We currently only support x86-32, x86-64, ARM, MIPS, and PPC on Linux. | |
52 * Porting to other related platforms should not be difficult. | |
53 */ | |
54 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \ | |
55 defined(__mips__) || defined(__PPC__)) && defined(__linux) | |
56 | |
57 #ifndef SYS_CPLUSPLUS | |
58 #ifdef __cplusplus | |
59 /* Some system header files in older versions of gcc neglect to properly | |
60 * handle being included from C++. As it appears to be harmless to have | |
61 * multiple nested 'extern "C"' blocks, just add another one here. | |
62 */ | |
63 extern "C" { | |
64 #endif | |
65 | |
66 #include <errno.h> | |
67 #include <signal.h> | |
68 #include <stdarg.h> | |
69 #include <stddef.h> | |
70 #include <string.h> | |
71 #include <sys/ptrace.h> | |
72 #include <sys/resource.h> | |
73 #include <sys/time.h> | |
74 #include <sys/types.h> | |
75 #include <syscall.h> | |
76 #include <unistd.h> | |
77 #include <linux/unistd.h> | |
78 #include <endian.h> | |
79 | |
80 #ifdef __mips__ | |
81 /* Include definitions of the ABI currently in use. */ | |
82 #include <sgidefs.h> | |
83 #endif | |
84 | |
85 #endif | |
86 | |
87 /* As glibc often provides subtly incompatible data structures (and implicit | |
88 * wrapper functions that convert them), we provide our own kernel data | |
89 * structures for use by the system calls. | |
90 * These structures have been developed by using Linux 2.6.23 headers for | |
91 * reference. Note though, we do not care about exact API compatibility | |
92 * with the kernel, and in fact the kernel often does not have a single | |
93 * API that works across architectures. Instead, we try to mimic the glibc | |
94 * API where reasonable, and only guarantee ABI compatibility with the | |
95 * kernel headers. | |
96 * Most notably, here are a few changes that were made to the structures | |
97 * defined by kernel headers: | |
98 * | |
99 * - we only define structures, but not symbolic names for kernel data | |
100 * types. For the latter, we directly use the native C datatype | |
101 * (i.e. "unsigned" instead of "mode_t"). | |
102 * - in a few cases, it is possible to define identical structures for | |
103 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by | |
104 * standardizing on the 64bit version of the data types. In particular, | |
105 * this means that we use "unsigned" where the 32bit headers say | |
106 * "unsigned long". | |
107 * - overall, we try to minimize the number of cases where we need to | |
108 * conditionally define different structures. | |
109 * - the "struct kernel_sigaction" class of structures have been | |
110 * modified to more closely mimic glibc's API by introducing an | |
111 * anonymous union for the function pointer. | |
112 * - a small number of field names had to have an underscore appended to | |
113 * them, because glibc defines a global macro by the same name. | |
114 */ | |
115 | |
116 /* include/linux/dirent.h */ | |
117 struct kernel_dirent64 { | |
118 unsigned long long d_ino; | |
119 long long d_off; | |
120 unsigned short d_reclen; | |
121 unsigned char d_type; | |
122 char d_name[256]; | |
123 }; | |
124 | |
125 /* include/linux/dirent.h */ | |
126 struct kernel_dirent { | |
127 long d_ino; | |
128 long d_off; | |
129 unsigned short d_reclen; | |
130 char d_name[256]; | |
131 }; | |
132 | |
133 /* include/linux/uio.h */ | |
134 struct kernel_iovec { | |
135 void *iov_base; | |
136 unsigned long iov_len; | |
137 }; | |
138 | |
139 /* include/linux/socket.h */ | |
140 struct kernel_msghdr { | |
141 void *msg_name; | |
142 int msg_namelen; | |
143 struct kernel_iovec*msg_iov; | |
144 unsigned long msg_iovlen; | |
145 void *msg_control; | |
146 unsigned long msg_controllen; | |
147 unsigned msg_flags; | |
148 }; | |
149 | |
150 /* include/asm-generic/poll.h */ | |
151 struct kernel_pollfd { | |
152 int fd; | |
153 short events; | |
154 short revents; | |
155 }; | |
156 | |
157 /* include/linux/resource.h */ | |
158 struct kernel_rlimit { | |
159 unsigned long rlim_cur; | |
160 unsigned long rlim_max; | |
161 }; | |
162 | |
163 /* include/linux/time.h */ | |
164 struct kernel_timespec { | |
165 long tv_sec; | |
166 long tv_nsec; | |
167 }; | |
168 | |
169 /* include/linux/time.h */ | |
170 struct kernel_timeval { | |
171 long tv_sec; | |
172 long tv_usec; | |
173 }; | |
174 | |
175 /* include/linux/resource.h */ | |
176 struct kernel_rusage { | |
177 struct kernel_timeval ru_utime; | |
178 struct kernel_timeval ru_stime; | |
179 long ru_maxrss; | |
180 long ru_ixrss; | |
181 long ru_idrss; | |
182 long ru_isrss; | |
183 long ru_minflt; | |
184 long ru_majflt; | |
185 long ru_nswap; | |
186 long ru_inblock; | |
187 long ru_oublock; | |
188 long ru_msgsnd; | |
189 long ru_msgrcv; | |
190 long ru_nsignals; | |
191 long ru_nvcsw; | |
192 long ru_nivcsw; | |
193 }; | |
194 | |
195 struct siginfo; | |
196 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__PPC__) | |
197 | |
198 /* include/asm-{arm,i386,mips,ppc}/signal.h */ | |
199 struct kernel_old_sigaction { | |
200 union { | |
201 void (*sa_handler_)(int); | |
202 void (*sa_sigaction_)(int, struct siginfo *, void *); | |
203 }; | |
204 unsigned long sa_mask; | |
205 unsigned long sa_flags; | |
206 void (*sa_restorer)(void); | |
207 } __attribute__((packed,aligned(4))); | |
208 #elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) | |
209 #define kernel_old_sigaction kernel_sigaction | |
210 #endif | |
211 | |
212 /* Some kernel functions (e.g. sigaction() in 2.6.23) require that the | |
213 * exactly match the size of the signal set, even though the API was | |
214 * intended to be extensible. We define our own KERNEL_NSIG to deal with | |
215 * this. | |
216 * Please note that glibc provides signals [1.._NSIG-1], whereas the | |
217 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The | |
218 * actual number of signals is obviously the same, but the constants | |
219 * differ by one. | |
220 */ | |
221 #ifdef __mips__ | |
222 #define KERNEL_NSIG 128 | |
223 #else | |
224 #define KERNEL_NSIG 64 | |
225 #endif | |
226 | |
227 /* include/asm-{arm,i386,mips,x86_64}/signal.h */ | |
228 struct kernel_sigset_t { | |
229 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/ | |
230 (8*sizeof(unsigned long))]; | |
231 }; | |
232 | |
233 /* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */ | |
234 struct kernel_sigaction { | |
235 #ifdef __mips__ | |
236 unsigned long sa_flags; | |
237 union { | |
238 void (*sa_handler_)(int); | |
239 void (*sa_sigaction_)(int, struct siginfo *, void *); | |
240 }; | |
241 struct kernel_sigset_t sa_mask; | |
242 #else | |
243 union { | |
244 void (*sa_handler_)(int); | |
245 void (*sa_sigaction_)(int, struct siginfo *, void *); | |
246 }; | |
247 unsigned long sa_flags; | |
248 void (*sa_restorer)(void); | |
249 struct kernel_sigset_t sa_mask; | |
250 #endif | |
251 }; | |
252 | |
253 /* include/linux/socket.h */ | |
254 struct kernel_sockaddr { | |
255 unsigned short sa_family; | |
256 char sa_data[14]; | |
257 }; | |
258 | |
259 /* include/asm-{arm,i386,mips,ppc}/stat.h */ | |
260 #ifdef __mips__ | |
261 #if _MIPS_SIM == _MIPS_SIM_ABI64 | |
262 struct kernel_stat { | |
263 #else | |
264 struct kernel_stat64 { | |
265 #endif | |
266 unsigned st_dev; | |
267 unsigned __pad0[3]; | |
268 unsigned long long st_ino; | |
269 unsigned st_mode; | |
270 unsigned st_nlink; | |
271 unsigned st_uid; | |
272 unsigned st_gid; | |
273 unsigned st_rdev; | |
274 unsigned __pad1[3]; | |
275 long long st_size; | |
276 unsigned st_atime_; | |
277 unsigned st_atime_nsec_; | |
278 unsigned st_mtime_; | |
279 unsigned st_mtime_nsec_; | |
280 unsigned st_ctime_; | |
281 unsigned st_ctime_nsec_; | |
282 unsigned st_blksize; | |
283 unsigned __pad2; | |
284 unsigned long long st_blocks; | |
285 }; | |
286 #elif defined __PPC__ | |
287 struct kernel_stat64 { | |
288 unsigned long long st_dev; | |
289 unsigned long long st_ino; | |
290 unsigned st_mode; | |
291 unsigned st_nlink; | |
292 unsigned st_uid; | |
293 unsigned st_gid; | |
294 unsigned long long st_rdev; | |
295 unsigned short int __pad2; | |
296 long long st_size; | |
297 long st_blksize; | |
298 long long st_blocks; | |
299 long st_atime_; | |
300 unsigned long st_atime_nsec_; | |
301 long st_mtime_; | |
302 unsigned long st_mtime_nsec_; | |
303 long st_ctime_; | |
304 unsigned long st_ctime_nsec_; | |
305 unsigned long __unused4; | |
306 unsigned long __unused5; | |
307 }; | |
308 #else | |
309 struct kernel_stat64 { | |
310 unsigned long long st_dev; | |
311 unsigned char __pad0[4]; | |
312 unsigned __st_ino; | |
313 unsigned st_mode; | |
314 unsigned st_nlink; | |
315 unsigned st_uid; | |
316 unsigned st_gid; | |
317 unsigned long long st_rdev; | |
318 unsigned char __pad3[4]; | |
319 long long st_size; | |
320 unsigned st_blksize; | |
321 unsigned long long st_blocks; | |
322 unsigned st_atime_; | |
323 unsigned st_atime_nsec_; | |
324 unsigned st_mtime_; | |
325 unsigned st_mtime_nsec_; | |
326 unsigned st_ctime_; | |
327 unsigned st_ctime_nsec_; | |
328 unsigned long long st_ino; | |
329 }; | |
330 #endif | |
331 | |
332 /* include/asm-{arm,i386,mips,x86_64,ppc}/stat.h */ | |
333 #if defined(__i386__) || defined(__ARM_ARCH_3__) | |
334 struct kernel_stat { | |
335 /* The kernel headers suggest that st_dev and st_rdev should be 32bit | |
336 * quantities encoding 12bit major and 20bit minor numbers in an interleaved | |
337 * format. In reality, we do not see useful data in the top bits. So, | |
338 * we'll leave the padding in here, until we find a better solution. | |
339 */ | |
340 unsigned short st_dev; | |
341 short pad1; | |
342 unsigned st_ino; | |
343 unsigned short st_mode; | |
344 unsigned short st_nlink; | |
345 unsigned short st_uid; | |
346 unsigned short st_gid; | |
347 unsigned short st_rdev; | |
348 short pad2; | |
349 unsigned st_size; | |
350 unsigned st_blksize; | |
351 unsigned st_blocks; | |
352 unsigned st_atime_; | |
353 unsigned st_atime_nsec_; | |
354 unsigned st_mtime_; | |
355 unsigned st_mtime_nsec_; | |
356 unsigned st_ctime_; | |
357 unsigned st_ctime_nsec_; | |
358 unsigned __unused4; | |
359 unsigned __unused5; | |
360 }; | |
361 #elif defined(__x86_64__) | |
362 struct kernel_stat { | |
363 unsigned long st_dev; | |
364 unsigned long st_ino; | |
365 unsigned long st_nlink; | |
366 unsigned st_mode; | |
367 unsigned st_uid; | |
368 unsigned st_gid; | |
369 unsigned __pad0; | |
370 unsigned long st_rdev; | |
371 long st_size; | |
372 long st_blksize; | |
373 long st_blocks; | |
374 unsigned long st_atime_; | |
375 unsigned long st_atime_nsec_; | |
376 unsigned long st_mtime_; | |
377 unsigned long st_mtime_nsec_; | |
378 unsigned long st_ctime_; | |
379 unsigned long st_ctime_nsec_; | |
380 long __unused[3]; | |
381 }; | |
382 #elif defined(__PPC__) | |
383 struct kernel_stat { | |
384 unsigned st_dev; | |
385 unsigned long st_ino; // ino_t | |
386 unsigned long st_mode; // mode_t | |
387 unsigned short st_nlink; // nlink_t | |
388 unsigned st_uid; // uid_t | |
389 unsigned st_gid; // gid_t | |
390 unsigned st_rdev; | |
391 long st_size; // off_t | |
392 unsigned long st_blksize; | |
393 unsigned long st_blocks; | |
394 unsigned long st_atime_; | |
395 unsigned long st_atime_nsec_; | |
396 unsigned long st_mtime_; | |
397 unsigned long st_mtime_nsec_; | |
398 unsigned long st_ctime_; | |
399 unsigned long st_ctime_nsec_; | |
400 unsigned long __unused4; | |
401 unsigned long __unused5; | |
402 }; | |
403 #elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) | |
404 struct kernel_stat { | |
405 unsigned st_dev; | |
406 int st_pad1[3]; | |
407 unsigned st_ino; | |
408 unsigned st_mode; | |
409 unsigned st_nlink; | |
410 unsigned st_uid; | |
411 unsigned st_gid; | |
412 unsigned st_rdev; | |
413 int st_pad2[2]; | |
414 long st_size; | |
415 int st_pad3; | |
416 long st_atime_; | |
417 long st_atime_nsec_; | |
418 long st_mtime_; | |
419 long st_mtime_nsec_; | |
420 long st_ctime_; | |
421 long st_ctime_nsec_; | |
422 int st_blksize; | |
423 int st_blocks; | |
424 int st_pad4[14]; | |
425 }; | |
426 #endif | |
427 | |
428 /* include/asm-{arm,i386,mips,x86_64,ppc}/statfs.h */ | |
429 #ifdef __mips__ | |
430 #if _MIPS_SIM != _MIPS_SIM_ABI64 | |
431 struct kernel_statfs64 { | |
432 unsigned long f_type; | |
433 unsigned long f_bsize; | |
434 unsigned long f_frsize; | |
435 unsigned long __pad; | |
436 unsigned long long f_blocks; | |
437 unsigned long long f_bfree; | |
438 unsigned long long f_files; | |
439 unsigned long long f_ffree; | |
440 unsigned long long f_bavail; | |
441 struct { int val[2]; } f_fsid; | |
442 unsigned long f_namelen; | |
443 unsigned long f_spare[6]; | |
444 }; | |
445 #endif | |
446 #elif !defined(__x86_64__) | |
447 struct kernel_statfs64 { | |
448 unsigned long f_type; | |
449 unsigned long f_bsize; | |
450 unsigned long long f_blocks; | |
451 unsigned long long f_bfree; | |
452 unsigned long long f_bavail; | |
453 unsigned long long f_files; | |
454 unsigned long long f_ffree; | |
455 struct { int val[2]; } f_fsid; | |
456 unsigned long f_namelen; | |
457 unsigned long f_frsize; | |
458 unsigned long f_spare[5]; | |
459 }; | |
460 #endif | |
461 | |
462 /* include/asm-{arm,i386,mips,x86_64,ppc,generic}/statfs.h */ | |
463 #ifdef __mips__ | |
464 struct kernel_statfs { | |
465 long f_type; | |
466 long f_bsize; | |
467 long f_frsize; | |
468 long f_blocks; | |
469 long f_bfree; | |
470 long f_files; | |
471 long f_ffree; | |
472 long f_bavail; | |
473 struct { int val[2]; } f_fsid; | |
474 long f_namelen; | |
475 long f_spare[6]; | |
476 }; | |
477 #else | |
478 struct kernel_statfs { | |
479 /* x86_64 actually defines all these fields as signed, whereas all other */ | |
480 /* platforms define them as unsigned. Leaving them at unsigned should not */ | |
481 /* cause any problems. */ | |
482 unsigned long f_type; | |
483 unsigned long f_bsize; | |
484 unsigned long f_blocks; | |
485 unsigned long f_bfree; | |
486 unsigned long f_bavail; | |
487 unsigned long f_files; | |
488 unsigned long f_ffree; | |
489 struct { int val[2]; } f_fsid; | |
490 unsigned long f_namelen; | |
491 unsigned long f_frsize; | |
492 unsigned long f_spare[5]; | |
493 }; | |
494 #endif | |
495 | |
496 | |
497 /* Definitions missing from the standard header files */ | |
498 #ifndef O_DIRECTORY | |
499 #if defined(__ARM_ARCH_3__) | |
500 #define O_DIRECTORY 0040000 | |
501 #else | |
502 #define O_DIRECTORY 0200000 | |
503 #endif | |
504 #endif | |
505 #ifndef NT_PRXFPREG | |
506 #define NT_PRXFPREG 0x46e62b7f | |
507 #endif | |
508 #ifndef PTRACE_GETFPXREGS | |
509 #define PTRACE_GETFPXREGS ((enum __ptrace_request)18) | |
510 #endif | |
511 #ifndef PR_GET_DUMPABLE | |
512 #define PR_GET_DUMPABLE 3 | |
513 #endif | |
514 #ifndef PR_SET_DUMPABLE | |
515 #define PR_SET_DUMPABLE 4 | |
516 #endif | |
517 #ifndef PR_GET_SECCOMP | |
518 #define PR_GET_SECCOMP 21 | |
519 #endif | |
520 #ifndef PR_SET_SECCOMP | |
521 #define PR_SET_SECCOMP 22 | |
522 #endif | |
523 #ifndef AT_FDCWD | |
524 #define AT_FDCWD (-100) | |
525 #endif | |
526 #ifndef AT_SYMLINK_NOFOLLOW | |
527 #define AT_SYMLINK_NOFOLLOW 0x100 | |
528 #endif | |
529 #ifndef AT_REMOVEDIR | |
530 #define AT_REMOVEDIR 0x200 | |
531 #endif | |
532 #ifndef MREMAP_FIXED | |
533 #define MREMAP_FIXED 2 | |
534 #endif | |
535 #ifndef SA_RESTORER | |
536 #define SA_RESTORER 0x04000000 | |
537 #endif | |
538 #ifndef CPUCLOCK_PROF | |
539 #define CPUCLOCK_PROF 0 | |
540 #endif | |
541 #ifndef CPUCLOCK_VIRT | |
542 #define CPUCLOCK_VIRT 1 | |
543 #endif | |
544 #ifndef CPUCLOCK_SCHED | |
545 #define CPUCLOCK_SCHED 2 | |
546 #endif | |
547 #ifndef CPUCLOCK_PERTHREAD_MASK | |
548 #define CPUCLOCK_PERTHREAD_MASK 4 | |
549 #endif | |
550 #ifndef MAKE_PROCESS_CPUCLOCK | |
551 #define MAKE_PROCESS_CPUCLOCK(pid, clock) \ | |
552 ((~(int)(pid) << 3) | (int)(clock)) | |
553 #endif | |
554 #ifndef MAKE_THREAD_CPUCLOCK | |
555 #define MAKE_THREAD_CPUCLOCK(tid, clock) \ | |
556 ((~(int)(tid) << 3) | (int)((clock) | CPUCLOCK_PERTHREAD_MASK)) | |
557 #endif | |
558 | |
559 #ifndef FUTEX_WAIT | |
560 #define FUTEX_WAIT 0 | |
561 #endif | |
562 #ifndef FUTEX_WAKE | |
563 #define FUTEX_WAKE 1 | |
564 #endif | |
565 #ifndef FUTEX_FD | |
566 #define FUTEX_FD 2 | |
567 #endif | |
568 #ifndef FUTEX_REQUEUE | |
569 #define FUTEX_REQUEUE 3 | |
570 #endif | |
571 #ifndef FUTEX_CMP_REQUEUE | |
572 #define FUTEX_CMP_REQUEUE 4 | |
573 #endif | |
574 #ifndef FUTEX_WAKE_OP | |
575 #define FUTEX_WAKE_OP 5 | |
576 #endif | |
577 #ifndef FUTEX_LOCK_PI | |
578 #define FUTEX_LOCK_PI 6 | |
579 #endif | |
580 #ifndef FUTEX_UNLOCK_PI | |
581 #define FUTEX_UNLOCK_PI 7 | |
582 #endif | |
583 #ifndef FUTEX_TRYLOCK_PI | |
584 #define FUTEX_TRYLOCK_PI 8 | |
585 #endif | |
586 #ifndef FUTEX_PRIVATE_FLAG | |
587 #define FUTEX_PRIVATE_FLAG 128 | |
588 #endif | |
589 #ifndef FUTEX_CMD_MASK | |
590 #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG | |
591 #endif | |
592 #ifndef FUTEX_WAIT_PRIVATE | |
593 #define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) | |
594 #endif | |
595 #ifndef FUTEX_WAKE_PRIVATE | |
596 #define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) | |
597 #endif | |
598 #ifndef FUTEX_REQUEUE_PRIVATE | |
599 #define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG) | |
600 #endif | |
601 #ifndef FUTEX_CMP_REQUEUE_PRIVATE | |
602 #define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG) | |
603 #endif | |
604 #ifndef FUTEX_WAKE_OP_PRIVATE | |
605 #define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG) | |
606 #endif | |
607 #ifndef FUTEX_LOCK_PI_PRIVATE | |
608 #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) | |
609 #endif | |
610 #ifndef FUTEX_UNLOCK_PI_PRIVATE | |
611 #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) | |
612 #endif | |
613 #ifndef FUTEX_TRYLOCK_PI_PRIVATE | |
614 #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) | |
615 #endif | |
616 | |
617 | |
618 #if defined(__x86_64__) | |
619 #ifndef ARCH_SET_GS | |
620 #define ARCH_SET_GS 0x1001 | |
621 #endif | |
622 #ifndef ARCH_GET_GS | |
623 #define ARCH_GET_GS 0x1004 | |
624 #endif | |
625 #endif | |
626 | |
627 #if defined(__i386__) | |
628 #ifndef __NR_quotactl | |
629 #define __NR_quotactl 131 | |
630 #endif | |
631 #ifndef __NR_setresuid | |
632 #define __NR_setresuid 164 | |
633 #define __NR_getresuid 165 | |
634 #define __NR_setresgid 170 | |
635 #define __NR_getresgid 171 | |
636 #endif | |
637 #ifndef __NR_rt_sigaction | |
638 #define __NR_rt_sigreturn 173 | |
639 #define __NR_rt_sigaction 174 | |
640 #define __NR_rt_sigprocmask 175 | |
641 #define __NR_rt_sigpending 176 | |
642 #define __NR_rt_sigsuspend 179 | |
643 #endif | |
644 #ifndef __NR_pread64 | |
645 #define __NR_pread64 180 | |
646 #endif | |
647 #ifndef __NR_pwrite64 | |
648 #define __NR_pwrite64 181 | |
649 #endif | |
650 #ifndef __NR_ugetrlimit | |
651 #define __NR_ugetrlimit 191 | |
652 #endif | |
653 #ifndef __NR_stat64 | |
654 #define __NR_stat64 195 | |
655 #endif | |
656 #ifndef __NR_fstat64 | |
657 #define __NR_fstat64 197 | |
658 #endif | |
659 #ifndef __NR_setresuid32 | |
660 #define __NR_setresuid32 208 | |
661 #define __NR_getresuid32 209 | |
662 #define __NR_setresgid32 210 | |
663 #define __NR_getresgid32 211 | |
664 #endif | |
665 #ifndef __NR_setfsuid32 | |
666 #define __NR_setfsuid32 215 | |
667 #define __NR_setfsgid32 216 | |
668 #endif | |
669 #ifndef __NR_getdents64 | |
670 #define __NR_getdents64 220 | |
671 #endif | |
672 #ifndef __NR_gettid | |
673 #define __NR_gettid 224 | |
674 #endif | |
675 #ifndef __NR_readahead | |
676 #define __NR_readahead 225 | |
677 #endif | |
678 #ifndef __NR_setxattr | |
679 #define __NR_setxattr 226 | |
680 #endif | |
681 #ifndef __NR_lsetxattr | |
682 #define __NR_lsetxattr 227 | |
683 #endif | |
684 #ifndef __NR_getxattr | |
685 #define __NR_getxattr 229 | |
686 #endif | |
687 #ifndef __NR_lgetxattr | |
688 #define __NR_lgetxattr 230 | |
689 #endif | |
690 #ifndef __NR_listxattr | |
691 #define __NR_listxattr 232 | |
692 #endif | |
693 #ifndef __NR_llistxattr | |
694 #define __NR_llistxattr 233 | |
695 #endif | |
696 #ifndef __NR_tkill | |
697 #define __NR_tkill 238 | |
698 #endif | |
699 #ifndef __NR_futex | |
700 #define __NR_futex 240 | |
701 #endif | |
702 #ifndef __NR_sched_setaffinity | |
703 #define __NR_sched_setaffinity 241 | |
704 #define __NR_sched_getaffinity 242 | |
705 #endif | |
706 #ifndef __NR_set_tid_address | |
707 #define __NR_set_tid_address 258 | |
708 #endif | |
709 #ifndef __NR_clock_gettime | |
710 #define __NR_clock_gettime 265 | |
711 #endif | |
712 #ifndef __NR_clock_getres | |
713 #define __NR_clock_getres 266 | |
714 #endif | |
715 #ifndef __NR_statfs64 | |
716 #define __NR_statfs64 268 | |
717 #endif | |
718 #ifndef __NR_fstatfs64 | |
719 #define __NR_fstatfs64 269 | |
720 #endif | |
721 #ifndef __NR_fadvise64_64 | |
722 #define __NR_fadvise64_64 272 | |
723 #endif | |
724 #ifndef __NR_ioprio_set | |
725 #define __NR_ioprio_set 289 | |
726 #endif | |
727 #ifndef __NR_ioprio_get | |
728 #define __NR_ioprio_get 290 | |
729 #endif | |
730 #ifndef __NR_openat | |
731 #define __NR_openat 295 | |
732 #endif | |
733 #ifndef __NR_fstatat64 | |
734 #define __NR_fstatat64 300 | |
735 #endif | |
736 #ifndef __NR_unlinkat | |
737 #define __NR_unlinkat 301 | |
738 #endif | |
739 #ifndef __NR_move_pages | |
740 #define __NR_move_pages 317 | |
741 #endif | |
742 #ifndef __NR_getcpu | |
743 #define __NR_getcpu 318 | |
744 #endif | |
745 #ifndef __NR_fallocate | |
746 #define __NR_fallocate 324 | |
747 #endif | |
748 /* End of i386 definitions */ | |
749 #elif defined(__ARM_ARCH_3__) | |
750 #ifndef __NR_setresuid | |
751 #define __NR_setresuid (__NR_SYSCALL_BASE + 164) | |
752 #define __NR_getresuid (__NR_SYSCALL_BASE + 165) | |
753 #define __NR_setresgid (__NR_SYSCALL_BASE + 170) | |
754 #define __NR_getresgid (__NR_SYSCALL_BASE + 171) | |
755 #endif | |
756 #ifndef __NR_rt_sigaction | |
757 #define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173) | |
758 #define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174) | |
759 #define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175) | |
760 #define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176) | |
761 #define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179) | |
762 #endif | |
763 #ifndef __NR_pread64 | |
764 #define __NR_pread64 (__NR_SYSCALL_BASE + 180) | |
765 #endif | |
766 #ifndef __NR_pwrite64 | |
767 #define __NR_pwrite64 (__NR_SYSCALL_BASE + 181) | |
768 #endif | |
769 #ifndef __NR_ugetrlimit | |
770 #define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191) | |
771 #endif | |
772 #ifndef __NR_stat64 | |
773 #define __NR_stat64 (__NR_SYSCALL_BASE + 195) | |
774 #endif | |
775 #ifndef __NR_fstat64 | |
776 #define __NR_fstat64 (__NR_SYSCALL_BASE + 197) | |
777 #endif | |
778 #ifndef __NR_setresuid32 | |
779 #define __NR_setresuid32 (__NR_SYSCALL_BASE + 208) | |
780 #define __NR_getresuid32 (__NR_SYSCALL_BASE + 209) | |
781 #define __NR_setresgid32 (__NR_SYSCALL_BASE + 210) | |
782 #define __NR_getresgid32 (__NR_SYSCALL_BASE + 211) | |
783 #endif | |
784 #ifndef __NR_setfsuid32 | |
785 #define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215) | |
786 #define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216) | |
787 #endif | |
788 #ifndef __NR_getdents64 | |
789 #define __NR_getdents64 (__NR_SYSCALL_BASE + 217) | |
790 #endif | |
791 #ifndef __NR_gettid | |
792 #define __NR_gettid (__NR_SYSCALL_BASE + 224) | |
793 #endif | |
794 #ifndef __NR_readahead | |
795 #define __NR_readahead (__NR_SYSCALL_BASE + 225) | |
796 #endif | |
797 #ifndef __NR_setxattr | |
798 #define __NR_setxattr (__NR_SYSCALL_BASE + 226) | |
799 #endif | |
800 #ifndef __NR_lsetxattr | |
801 #define __NR_lsetxattr (__NR_SYSCALL_BASE + 227) | |
802 #endif | |
803 #ifndef __NR_getxattr | |
804 #define __NR_getxattr (__NR_SYSCALL_BASE + 229) | |
805 #endif | |
806 #ifndef __NR_lgetxattr | |
807 #define __NR_lgetxattr (__NR_SYSCALL_BASE + 230) | |
808 #endif | |
809 #ifndef __NR_listxattr | |
810 #define __NR_listxattr (__NR_SYSCALL_BASE + 232) | |
811 #endif | |
812 #ifndef __NR_llistxattr | |
813 #define __NR_llistxattr (__NR_SYSCALL_BASE + 233) | |
814 #endif | |
815 #ifndef __NR_tkill | |
816 #define __NR_tkill (__NR_SYSCALL_BASE + 238) | |
817 #endif | |
818 #ifndef __NR_futex | |
819 #define __NR_futex (__NR_SYSCALL_BASE + 240) | |
820 #endif | |
821 #ifndef __NR_sched_setaffinity | |
822 #define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241) | |
823 #define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242) | |
824 #endif | |
825 #ifndef __NR_set_tid_address | |
826 #define __NR_set_tid_address (__NR_SYSCALL_BASE + 256) | |
827 #endif | |
828 #ifndef __NR_clock_gettime | |
829 #define __NR_clock_gettime (__NR_SYSCALL_BASE + 263) | |
830 #endif | |
831 #ifndef __NR_clock_getres | |
832 #define __NR_clock_getres (__NR_SYSCALL_BASE + 264) | |
833 #endif | |
834 #ifndef __NR_statfs64 | |
835 #define __NR_statfs64 (__NR_SYSCALL_BASE + 266) | |
836 #endif | |
837 #ifndef __NR_fstatfs64 | |
838 #define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267) | |
839 #endif | |
840 #ifndef __NR_ioprio_set | |
841 #define __NR_ioprio_set (__NR_SYSCALL_BASE + 314) | |
842 #endif | |
843 #ifndef __NR_ioprio_get | |
844 #define __NR_ioprio_get (__NR_SYSCALL_BASE + 315) | |
845 #endif | |
846 #ifndef __NR_move_pages | |
847 #define __NR_move_pages (__NR_SYSCALL_BASE + 344) | |
848 #endif | |
849 #ifndef __NR_getcpu | |
850 #define __NR_getcpu (__NR_SYSCALL_BASE + 345) | |
851 #endif | |
852 /* End of ARM 3 definitions */ | |
853 #elif defined(__x86_64__) | |
854 #ifndef __NR_pread64 | |
855 #define __NR_pread64 17 | |
856 #endif | |
857 #ifndef __NR_pwrite64 | |
858 #define __NR_pwrite64 18 | |
859 #endif | |
860 #ifndef __NR_setresuid | |
861 #define __NR_setresuid 117 | |
862 #define __NR_getresuid 118 | |
863 #define __NR_setresgid 119 | |
864 #define __NR_getresgid 120 | |
865 #endif | |
866 #ifndef __NR_quotactl | |
867 #define __NR_quotactl 179 | |
868 #endif | |
869 #ifndef __NR_gettid | |
870 #define __NR_gettid 186 | |
871 #endif | |
872 #ifndef __NR_readahead | |
873 #define __NR_readahead 187 | |
874 #endif | |
875 #ifndef __NR_setxattr | |
876 #define __NR_setxattr 188 | |
877 #endif | |
878 #ifndef __NR_lsetxattr | |
879 #define __NR_lsetxattr 189 | |
880 #endif | |
881 #ifndef __NR_getxattr | |
882 #define __NR_getxattr 191 | |
883 #endif | |
884 #ifndef __NR_lgetxattr | |
885 #define __NR_lgetxattr 192 | |
886 #endif | |
887 #ifndef __NR_listxattr | |
888 #define __NR_listxattr 194 | |
889 #endif | |
890 #ifndef __NR_llistxattr | |
891 #define __NR_llistxattr 195 | |
892 #endif | |
893 #ifndef __NR_tkill | |
894 #define __NR_tkill 200 | |
895 #endif | |
896 #ifndef __NR_futex | |
897 #define __NR_futex 202 | |
898 #endif | |
899 #ifndef __NR_sched_setaffinity | |
900 #define __NR_sched_setaffinity 203 | |
901 #define __NR_sched_getaffinity 204 | |
902 #endif | |
903 #ifndef __NR_getdents64 | |
904 #define __NR_getdents64 217 | |
905 #endif | |
906 #ifndef __NR_set_tid_address | |
907 #define __NR_set_tid_address 218 | |
908 #endif | |
909 #ifndef __NR_fadvise64 | |
910 #define __NR_fadvise64 221 | |
911 #endif | |
912 #ifndef __NR_clock_gettime | |
913 #define __NR_clock_gettime 228 | |
914 #endif | |
915 #ifndef __NR_clock_getres | |
916 #define __NR_clock_getres 229 | |
917 #endif | |
918 #ifndef __NR_ioprio_set | |
919 #define __NR_ioprio_set 251 | |
920 #endif | |
921 #ifndef __NR_ioprio_get | |
922 #define __NR_ioprio_get 252 | |
923 #endif | |
924 #ifndef __NR_openat | |
925 #define __NR_openat 257 | |
926 #endif | |
927 #ifndef __NR_newfstatat | |
928 #define __NR_newfstatat 262 | |
929 #endif | |
930 #ifndef __NR_unlinkat | |
931 #define __NR_unlinkat 263 | |
932 #endif | |
933 #ifndef __NR_move_pages | |
934 #define __NR_move_pages 279 | |
935 #endif | |
936 #ifndef __NR_fallocate | |
937 #define __NR_fallocate 285 | |
938 #endif | |
939 /* End of x86-64 definitions */ | |
940 #elif defined(__mips__) | |
941 #if _MIPS_SIM == _MIPS_SIM_ABI32 | |
942 #ifndef __NR_setresuid | |
943 #define __NR_setresuid (__NR_Linux + 185) | |
944 #define __NR_getresuid (__NR_Linux + 186) | |
945 #define __NR_setresgid (__NR_Linux + 190) | |
946 #define __NR_getresgid (__NR_Linux + 191) | |
947 #endif | |
948 #ifndef __NR_rt_sigaction | |
949 #define __NR_rt_sigreturn (__NR_Linux + 193) | |
950 #define __NR_rt_sigaction (__NR_Linux + 194) | |
951 #define __NR_rt_sigprocmask (__NR_Linux + 195) | |
952 #define __NR_rt_sigpending (__NR_Linux + 196) | |
953 #define __NR_rt_sigsuspend (__NR_Linux + 199) | |
954 #endif | |
955 #ifndef __NR_pread64 | |
956 #define __NR_pread64 (__NR_Linux + 200) | |
957 #endif | |
958 #ifndef __NR_pwrite64 | |
959 #define __NR_pwrite64 (__NR_Linux + 201) | |
960 #endif | |
961 #ifndef __NR_stat64 | |
962 #define __NR_stat64 (__NR_Linux + 213) | |
963 #endif | |
964 #ifndef __NR_fstat64 | |
965 #define __NR_fstat64 (__NR_Linux + 215) | |
966 #endif | |
967 #ifndef __NR_getdents64 | |
968 #define __NR_getdents64 (__NR_Linux + 219) | |
969 #endif | |
970 #ifndef __NR_gettid | |
971 #define __NR_gettid (__NR_Linux + 222) | |
972 #endif | |
973 #ifndef __NR_readahead | |
974 #define __NR_readahead (__NR_Linux + 223) | |
975 #endif | |
976 #ifndef __NR_setxattr | |
977 #define __NR_setxattr (__NR_Linux + 224) | |
978 #endif | |
979 #ifndef __NR_lsetxattr | |
980 #define __NR_lsetxattr (__NR_Linux + 225) | |
981 #endif | |
982 #ifndef __NR_getxattr | |
983 #define __NR_getxattr (__NR_Linux + 227) | |
984 #endif | |
985 #ifndef __NR_lgetxattr | |
986 #define __NR_lgetxattr (__NR_Linux + 228) | |
987 #endif | |
988 #ifndef __NR_listxattr | |
989 #define __NR_listxattr (__NR_Linux + 230) | |
990 #endif | |
991 #ifndef __NR_llistxattr | |
992 #define __NR_llistxattr (__NR_Linux + 231) | |
993 #endif | |
994 #ifndef __NR_tkill | |
995 #define __NR_tkill (__NR_Linux + 236) | |
996 #endif | |
997 #ifndef __NR_futex | |
998 #define __NR_futex (__NR_Linux + 238) | |
999 #endif | |
1000 #ifndef __NR_sched_setaffinity | |
1001 #define __NR_sched_setaffinity (__NR_Linux + 239) | |
1002 #define __NR_sched_getaffinity (__NR_Linux + 240) | |
1003 #endif | |
1004 #ifndef __NR_set_tid_address | |
1005 #define __NR_set_tid_address (__NR_Linux + 252) | |
1006 #endif | |
1007 #ifndef __NR_statfs64 | |
1008 #define __NR_statfs64 (__NR_Linux + 255) | |
1009 #endif | |
1010 #ifndef __NR_fstatfs64 | |
1011 #define __NR_fstatfs64 (__NR_Linux + 256) | |
1012 #endif | |
1013 #ifndef __NR_clock_gettime | |
1014 #define __NR_clock_gettime (__NR_Linux + 263) | |
1015 #endif | |
1016 #ifndef __NR_clock_getres | |
1017 #define __NR_clock_getres (__NR_Linux + 264) | |
1018 #endif | |
1019 #ifndef __NR_openat | |
1020 #define __NR_openat (__NR_Linux + 288) | |
1021 #endif | |
1022 #ifndef __NR_fstatat | |
1023 #define __NR_fstatat (__NR_Linux + 293) | |
1024 #endif | |
1025 #ifndef __NR_unlinkat | |
1026 #define __NR_unlinkat (__NR_Linux + 294) | |
1027 #endif | |
1028 #ifndef __NR_move_pages | |
1029 #define __NR_move_pages (__NR_Linux + 308) | |
1030 #endif | |
1031 #ifndef __NR_getcpu | |
1032 #define __NR_getcpu (__NR_Linux + 312) | |
1033 #endif | |
1034 #ifndef __NR_ioprio_set | |
1035 #define __NR_ioprio_set (__NR_Linux + 314) | |
1036 #endif | |
1037 #ifndef __NR_ioprio_get | |
1038 #define __NR_ioprio_get (__NR_Linux + 315) | |
1039 #endif | |
1040 /* End of MIPS (old 32bit API) definitions */ | |
1041 #elif _MIPS_SIM == _MIPS_SIM_ABI64 | |
1042 #ifndef __NR_pread64 | |
1043 #define __NR_pread64 (__NR_Linux + 16) | |
1044 #endif | |
1045 #ifndef __NR_pwrite64 | |
1046 #define __NR_pwrite64 (__NR_Linux + 17) | |
1047 #endif | |
1048 #ifndef __NR_setresuid | |
1049 #define __NR_setresuid (__NR_Linux + 115) | |
1050 #define __NR_getresuid (__NR_Linux + 116) | |
1051 #define __NR_setresgid (__NR_Linux + 117) | |
1052 #define __NR_getresgid (__NR_Linux + 118) | |
1053 #endif | |
1054 #ifndef __NR_gettid | |
1055 #define __NR_gettid (__NR_Linux + 178) | |
1056 #endif | |
1057 #ifndef __NR_readahead | |
1058 #define __NR_readahead (__NR_Linux + 179) | |
1059 #endif | |
1060 #ifndef __NR_setxattr | |
1061 #define __NR_setxattr (__NR_Linux + 180) | |
1062 #endif | |
1063 #ifndef __NR_lsetxattr | |
1064 #define __NR_lsetxattr (__NR_Linux + 181) | |
1065 #endif | |
1066 #ifndef __NR_getxattr | |
1067 #define __NR_getxattr (__NR_Linux + 183) | |
1068 #endif | |
1069 #ifndef __NR_lgetxattr | |
1070 #define __NR_lgetxattr (__NR_Linux + 184) | |
1071 #endif | |
1072 #ifndef __NR_listxattr | |
1073 #define __NR_listxattr (__NR_Linux + 186) | |
1074 #endif | |
1075 #ifndef __NR_llistxattr | |
1076 #define __NR_llistxattr (__NR_Linux + 187) | |
1077 #endif | |
1078 #ifndef __NR_tkill | |
1079 #define __NR_tkill (__NR_Linux + 192) | |
1080 #endif | |
1081 #ifndef __NR_futex | |
1082 #define __NR_futex (__NR_Linux + 194) | |
1083 #endif | |
1084 #ifndef __NR_sched_setaffinity | |
1085 #define __NR_sched_setaffinity (__NR_Linux + 195) | |
1086 #define __NR_sched_getaffinity (__NR_Linux + 196) | |
1087 #endif | |
1088 #ifndef __NR_set_tid_address | |
1089 #define __NR_set_tid_address (__NR_Linux + 212) | |
1090 #endif | |
1091 #ifndef __NR_clock_gettime | |
1092 #define __NR_clock_gettime (__NR_Linux + 222) | |
1093 #endif | |
1094 #ifndef __NR_clock_getres | |
1095 #define __NR_clock_getres (__NR_Linux + 223) | |
1096 #endif | |
1097 #ifndef __NR_openat | |
1098 #define __NR_openat (__NR_Linux + 247) | |
1099 #endif | |
1100 #ifndef __NR_fstatat | |
1101 #define __NR_fstatat (__NR_Linux + 252) | |
1102 #endif | |
1103 #ifndef __NR_unlinkat | |
1104 #define __NR_unlinkat (__NR_Linux + 253) | |
1105 #endif | |
1106 #ifndef __NR_move_pages | |
1107 #define __NR_move_pages (__NR_Linux + 267) | |
1108 #endif | |
1109 #ifndef __NR_getcpu | |
1110 #define __NR_getcpu (__NR_Linux + 271) | |
1111 #endif | |
1112 #ifndef __NR_ioprio_set | |
1113 #define __NR_ioprio_set (__NR_Linux + 273) | |
1114 #endif | |
1115 #ifndef __NR_ioprio_get | |
1116 #define __NR_ioprio_get (__NR_Linux + 274) | |
1117 #endif | |
1118 /* End of MIPS (64bit API) definitions */ | |
1119 #else | |
1120 #ifndef __NR_setresuid | |
1121 #define __NR_setresuid (__NR_Linux + 115) | |
1122 #define __NR_getresuid (__NR_Linux + 116) | |
1123 #define __NR_setresgid (__NR_Linux + 117) | |
1124 #define __NR_getresgid (__NR_Linux + 118) | |
1125 #endif | |
1126 #ifndef __NR_gettid | |
1127 #define __NR_gettid (__NR_Linux + 178) | |
1128 #endif | |
1129 #ifndef __NR_readahead | |
1130 #define __NR_readahead (__NR_Linux + 179) | |
1131 #endif | |
1132 #ifndef __NR_setxattr | |
1133 #define __NR_setxattr (__NR_Linux + 180) | |
1134 #endif | |
1135 #ifndef __NR_lsetxattr | |
1136 #define __NR_lsetxattr (__NR_Linux + 181) | |
1137 #endif | |
1138 #ifndef __NR_getxattr | |
1139 #define __NR_getxattr (__NR_Linux + 183) | |
1140 #endif | |
1141 #ifndef __NR_lgetxattr | |
1142 #define __NR_lgetxattr (__NR_Linux + 184) | |
1143 #endif | |
1144 #ifndef __NR_listxattr | |
1145 #define __NR_listxattr (__NR_Linux + 186) | |
1146 #endif | |
1147 #ifndef __NR_llistxattr | |
1148 #define __NR_llistxattr (__NR_Linux + 187) | |
1149 #endif | |
1150 #ifndef __NR_tkill | |
1151 #define __NR_tkill (__NR_Linux + 192) | |
1152 #endif | |
1153 #ifndef __NR_futex | |
1154 #define __NR_futex (__NR_Linux + 194) | |
1155 #endif | |
1156 #ifndef __NR_sched_setaffinity | |
1157 #define __NR_sched_setaffinity (__NR_Linux + 195) | |
1158 #define __NR_sched_getaffinity (__NR_Linux + 196) | |
1159 #endif | |
1160 #ifndef __NR_set_tid_address | |
1161 #define __NR_set_tid_address (__NR_Linux + 213) | |
1162 #endif | |
1163 #ifndef __NR_statfs64 | |
1164 #define __NR_statfs64 (__NR_Linux + 217) | |
1165 #endif | |
1166 #ifndef __NR_fstatfs64 | |
1167 #define __NR_fstatfs64 (__NR_Linux + 218) | |
1168 #endif | |
1169 #ifndef __NR_clock_gettime | |
1170 #define __NR_clock_gettime (__NR_Linux + 226) | |
1171 #endif | |
1172 #ifndef __NR_clock_getres | |
1173 #define __NR_clock_getres (__NR_Linux + 227) | |
1174 #endif | |
1175 #ifndef __NR_openat | |
1176 #define __NR_openat (__NR_Linux + 251) | |
1177 #endif | |
1178 #ifndef __NR_fstatat | |
1179 #define __NR_fstatat (__NR_Linux + 256) | |
1180 #endif | |
1181 #ifndef __NR_unlinkat | |
1182 #define __NR_unlinkat (__NR_Linux + 257) | |
1183 #endif | |
1184 #ifndef __NR_move_pages | |
1185 #define __NR_move_pages (__NR_Linux + 271) | |
1186 #endif | |
1187 #ifndef __NR_getcpu | |
1188 #define __NR_getcpu (__NR_Linux + 275) | |
1189 #endif | |
1190 #ifndef __NR_ioprio_set | |
1191 #define __NR_ioprio_set (__NR_Linux + 277) | |
1192 #endif | |
1193 #ifndef __NR_ioprio_get | |
1194 #define __NR_ioprio_get (__NR_Linux + 278) | |
1195 #endif | |
1196 /* End of MIPS (new 32bit API) definitions */ | |
1197 #endif | |
1198 /* End of MIPS definitions */ | |
1199 #elif defined(__PPC__) | |
1200 #ifndef __NR_setfsuid | |
1201 #define __NR_setfsuid 138 | |
1202 #define __NR_setfsgid 139 | |
1203 #endif | |
1204 #ifndef __NR_setresuid | |
1205 #define __NR_setresuid 164 | |
1206 #define __NR_getresuid 165 | |
1207 #define __NR_setresgid 169 | |
1208 #define __NR_getresgid 170 | |
1209 #endif | |
1210 #ifndef __NR_rt_sigaction | |
1211 #define __NR_rt_sigreturn 172 | |
1212 #define __NR_rt_sigaction 173 | |
1213 #define __NR_rt_sigprocmask 174 | |
1214 #define __NR_rt_sigpending 175 | |
1215 #define __NR_rt_sigsuspend 178 | |
1216 #endif | |
1217 #ifndef __NR_pread64 | |
1218 #define __NR_pread64 179 | |
1219 #endif | |
1220 #ifndef __NR_pwrite64 | |
1221 #define __NR_pwrite64 180 | |
1222 #endif | |
1223 #ifndef __NR_ugetrlimit | |
1224 #define __NR_ugetrlimit 190 | |
1225 #endif | |
1226 #ifndef __NR_readahead | |
1227 #define __NR_readahead 191 | |
1228 #endif | |
1229 #ifndef __NR_stat64 | |
1230 #define __NR_stat64 195 | |
1231 #endif | |
1232 #ifndef __NR_fstat64 | |
1233 #define __NR_fstat64 197 | |
1234 #endif | |
1235 #ifndef __NR_getdents64 | |
1236 #define __NR_getdents64 202 | |
1237 #endif | |
1238 #ifndef __NR_gettid | |
1239 #define __NR_gettid 207 | |
1240 #endif | |
1241 #ifndef __NR_tkill | |
1242 #define __NR_tkill 208 | |
1243 #endif | |
1244 #ifndef __NR_setxattr | |
1245 #define __NR_setxattr 209 | |
1246 #endif | |
1247 #ifndef __NR_lsetxattr | |
1248 #define __NR_lsetxattr 210 | |
1249 #endif | |
1250 #ifndef __NR_getxattr | |
1251 #define __NR_getxattr 212 | |
1252 #endif | |
1253 #ifndef __NR_lgetxattr | |
1254 #define __NR_lgetxattr 213 | |
1255 #endif | |
1256 #ifndef __NR_listxattr | |
1257 #define __NR_listxattr 215 | |
1258 #endif | |
1259 #ifndef __NR_llistxattr | |
1260 #define __NR_llistxattr 216 | |
1261 #endif | |
1262 #ifndef __NR_futex | |
1263 #define __NR_futex 221 | |
1264 #endif | |
1265 #ifndef __NR_sched_setaffinity | |
1266 #define __NR_sched_setaffinity 222 | |
1267 #define __NR_sched_getaffinity 223 | |
1268 #endif | |
1269 #ifndef __NR_set_tid_address | |
1270 #define __NR_set_tid_address 232 | |
1271 #endif | |
1272 #ifndef __NR_clock_gettime | |
1273 #define __NR_clock_gettime 246 | |
1274 #endif | |
1275 #ifndef __NR_clock_getres | |
1276 #define __NR_clock_getres 247 | |
1277 #endif | |
1278 #ifndef __NR_statfs64 | |
1279 #define __NR_statfs64 252 | |
1280 #endif | |
1281 #ifndef __NR_fstatfs64 | |
1282 #define __NR_fstatfs64 253 | |
1283 #endif | |
1284 #ifndef __NR_fadvise64_64 | |
1285 #define __NR_fadvise64_64 254 | |
1286 #endif | |
1287 #ifndef __NR_ioprio_set | |
1288 #define __NR_ioprio_set 273 | |
1289 #endif | |
1290 #ifndef __NR_ioprio_get | |
1291 #define __NR_ioprio_get 274 | |
1292 #endif | |
1293 #ifndef __NR_openat | |
1294 #define __NR_openat 286 | |
1295 #endif | |
1296 #ifndef __NR_fstatat64 | |
1297 #define __NR_fstatat64 291 | |
1298 #endif | |
1299 #ifndef __NR_unlinkat | |
1300 #define __NR_unlinkat 292 | |
1301 #endif | |
1302 #ifndef __NR_move_pages | |
1303 #define __NR_move_pages 301 | |
1304 #endif | |
1305 #ifndef __NR_getcpu | |
1306 #define __NR_getcpu 302 | |
1307 #endif | |
1308 /* End of powerpc defininitions */ | |
1309 #endif | |
1310 | |
1311 | |
1312 /* After forking, we must make sure to only call system calls. */ | |
1313 #if __BOUNDED_POINTERS__ | |
1314 #error "Need to port invocations of syscalls for bounded ptrs" | |
1315 #else | |
1316 /* The core dumper and the thread lister get executed after threads | |
1317 * have been suspended. As a consequence, we cannot call any functions | |
1318 * that acquire locks. Unfortunately, libc wraps most system calls | |
1319 * (e.g. in order to implement pthread_atfork, and to make calls | |
1320 * cancellable), which means we cannot call these functions. Instead, | |
1321 * we have to call syscall() directly. | |
1322 */ | |
1323 #undef LSS_ERRNO | |
1324 #ifdef SYS_ERRNO | |
1325 /* Allow the including file to override the location of errno. This can | |
1326 * be useful when using clone() with the CLONE_VM option. | |
1327 */ | |
1328 #define LSS_ERRNO SYS_ERRNO | |
1329 #else | |
1330 #define LSS_ERRNO errno | |
1331 #endif | |
1332 | |
1333 #undef LSS_INLINE | |
1334 #ifdef SYS_INLINE | |
1335 #define LSS_INLINE SYS_INLINE | |
1336 #else | |
1337 #define LSS_INLINE static inline | |
1338 #endif | |
1339 | |
1340 /* Allow the including file to override the prefix used for all new | |
1341 * system calls. By default, it will be set to "sys_". | |
1342 */ | |
1343 #undef LSS_NAME | |
1344 #ifndef SYS_PREFIX | |
1345 #define LSS_NAME(name) sys_##name | |
1346 #elif SYS_PREFIX < 0 | |
1347 #define LSS_NAME(name) name | |
1348 #elif SYS_PREFIX == 0 | |
1349 #define LSS_NAME(name) sys0_##name | |
1350 #elif SYS_PREFIX == 1 | |
1351 #define LSS_NAME(name) sys1_##name | |
1352 #elif SYS_PREFIX == 2 | |
1353 #define LSS_NAME(name) sys2_##name | |
1354 #elif SYS_PREFIX == 3 | |
1355 #define LSS_NAME(name) sys3_##name | |
1356 #elif SYS_PREFIX == 4 | |
1357 #define LSS_NAME(name) sys4_##name | |
1358 #elif SYS_PREFIX == 5 | |
1359 #define LSS_NAME(name) sys5_##name | |
1360 #elif SYS_PREFIX == 6 | |
1361 #define LSS_NAME(name) sys6_##name | |
1362 #elif SYS_PREFIX == 7 | |
1363 #define LSS_NAME(name) sys7_##name | |
1364 #elif SYS_PREFIX == 8 | |
1365 #define LSS_NAME(name) sys8_##name | |
1366 #elif SYS_PREFIX == 9 | |
1367 #define LSS_NAME(name) sys9_##name | |
1368 #endif | |
1369 | |
1370 #undef LSS_RETURN | |
1371 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__)) | |
1372 /* Failing system calls return a negative result in the range of | |
1373 * -1..-4095. These are "errno" values with the sign inverted. | |
1374 */ | |
1375 #define LSS_RETURN(type, res) \ | |
1376 do { \ | |
1377 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \ | |
1378 LSS_ERRNO = -(res); \ | |
1379 res = -1; \ | |
1380 } \ | |
1381 return (type) (res); \ | |
1382 } while (0) | |
1383 #elif defined(__mips__) | |
1384 /* On MIPS, failing system calls return -1, and set errno in a | |
1385 * separate CPU register. | |
1386 */ | |
1387 #define LSS_RETURN(type, res, err) \ | |
1388 do { \ | |
1389 if (err) { \ | |
1390 LSS_ERRNO = (res); \ | |
1391 res = -1; \ | |
1392 } \ | |
1393 return (type) (res); \ | |
1394 } while (0) | |
1395 #elif defined(__PPC__) | |
1396 /* On PPC, failing system calls return -1, and set errno in a | |
1397 * separate CPU register. See linux/unistd.h. | |
1398 */ | |
1399 #define LSS_RETURN(type, res, err) \ | |
1400 do { \ | |
1401 if (err & 0x10000000 ) { \ | |
1402 LSS_ERRNO = (res); \ | |
1403 res = -1; \ | |
1404 } \ | |
1405 return (type) (res); \ | |
1406 } while (0) | |
1407 #endif | |
1408 #if defined(__i386__) | |
1409 /* In PIC mode (e.g. when building shared libraries), gcc for i386 | |
1410 * reserves ebx. Unfortunately, most distribution ship with implementations | |
1411 * of _syscallX() which clobber ebx. | |
1412 * Also, most definitions of _syscallX() neglect to mark "memory" as being | |
1413 * clobbered. This causes problems with compilers, that do a better job | |
1414 * at optimizing across __asm__ calls. | |
1415 * So, we just have to redefine all of the _syscallX() macros. | |
1416 */ | |
1417 #undef LSS_BODY | |
1418 #define LSS_BODY(type,args...) \ | |
1419 long __res; \ | |
1420 __asm__ __volatile__("push %%ebx\n" \ | |
1421 "movl %2,%%ebx\n" \ | |
1422 "int $0x80\n" \ | |
1423 "pop %%ebx" \ | |
1424 args \ | |
1425 : "esp", "memory"); \ | |
1426 LSS_RETURN(type,__res) | |
1427 #undef _syscall0 | |
1428 #define _syscall0(type,name) \ | |
1429 type LSS_NAME(name)(void) { \ | |
1430 long __res; \ | |
1431 __asm__ volatile("int $0x80" \ | |
1432 : "=a" (__res) \ | |
1433 : "0" (__NR_##name) \ | |
1434 : "memory"); \ | |
1435 LSS_RETURN(type,__res); \ | |
1436 } | |
1437 #undef _syscall1 | |
1438 #define _syscall1(type,name,type1,arg1) \ | |
1439 type LSS_NAME(name)(type1 arg1) { \ | |
1440 LSS_BODY(type, \ | |
1441 : "=a" (__res) \ | |
1442 : "0" (__NR_##name), "ri" ((long)(arg1))); \ | |
1443 } | |
1444 #undef _syscall2 | |
1445 #define _syscall2(type,name,type1,arg1,type2,arg2) \ | |
1446 type LSS_NAME(name)(type1 arg1,type2 arg2) { \ | |
1447 LSS_BODY(type, \ | |
1448 : "=a" (__res) \ | |
1449 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \ | |
1450 } | |
1451 #undef _syscall3 | |
1452 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ | |
1453 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \ | |
1454 LSS_BODY(type, \ | |
1455 : "=a" (__res) \ | |
1456 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ | |
1457 "d" ((long)(arg3))); \ | |
1458 } | |
1459 #undef _syscall4 | |
1460 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ | |
1461 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ | |
1462 LSS_BODY(type, \ | |
1463 : "=a" (__res) \ | |
1464 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ | |
1465 "d" ((long)(arg3)),"S" ((long)(arg4))); \ | |
1466 } | |
1467 #undef _syscall5 | |
1468 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
1469 type5,arg5) \ | |
1470 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
1471 type5 arg5) { \ | |
1472 long __res; \ | |
1473 __asm__ __volatile__("push %%ebx\n" \ | |
1474 "movl %2,%%ebx\n" \ | |
1475 "movl %1,%%eax\n" \ | |
1476 "int $0x80\n" \ | |
1477 "pop %%ebx" \ | |
1478 : "=a" (__res) \ | |
1479 : "i" (__NR_##name), "ri" ((long)(arg1)), \ | |
1480 "c" ((long)(arg2)), "d" ((long)(arg3)), \ | |
1481 "S" ((long)(arg4)), "D" ((long)(arg5)) \ | |
1482 : "esp", "memory"); \ | |
1483 LSS_RETURN(type,__res); \ | |
1484 } | |
1485 #undef _syscall6 | |
1486 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
1487 type5,arg5,type6,arg6) \ | |
1488 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
1489 type5 arg5, type6 arg6) { \ | |
1490 long __res; \ | |
1491 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \ | |
1492 __asm__ __volatile__("push %%ebp\n" \ | |
1493 "push %%ebx\n" \ | |
1494 "movl 4(%2),%%ebp\n" \ | |
1495 "movl 0(%2), %%ebx\n" \ | |
1496 "movl %1,%%eax\n" \ | |
1497 "int $0x80\n" \ | |
1498 "pop %%ebx\n" \ | |
1499 "pop %%ebp" \ | |
1500 : "=a" (__res) \ | |
1501 : "i" (__NR_##name), "0" ((long)(&__s)), \ | |
1502 "c" ((long)(arg2)), "d" ((long)(arg3)), \ | |
1503 "S" ((long)(arg4)), "D" ((long)(arg5)) \ | |
1504 : "esp", "memory"); \ | |
1505 LSS_RETURN(type,__res); \ | |
1506 } | |
1507 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, | |
1508 int flags, void *arg, int *parent_tidptr, | |
1509 void *newtls, int *child_tidptr) { | |
1510 long __res; | |
1511 __asm__ __volatile__(/* if (fn == NULL) | |
1512 * return -EINVAL; | |
1513 */ | |
1514 "movl %3,%%ecx\n" | |
1515 "jecxz 1f\n" | |
1516 | |
1517 /* if (child_stack == NULL) | |
1518 * return -EINVAL; | |
1519 */ | |
1520 "movl %4,%%ecx\n" | |
1521 "jecxz 1f\n" | |
1522 | |
1523 /* Set up alignment of the child stack: | |
1524 * child_stack = (child_stack & ~0xF) - 20; | |
1525 */ | |
1526 "andl $-16,%%ecx\n" | |
1527 "subl $20,%%ecx\n" | |
1528 | |
1529 /* Push "arg" and "fn" onto the stack that will be | |
1530 * used by the child. | |
1531 */ | |
1532 "movl %6,%%eax\n" | |
1533 "movl %%eax,4(%%ecx)\n" | |
1534 "movl %3,%%eax\n" | |
1535 "movl %%eax,(%%ecx)\n" | |
1536 | |
1537 /* %eax = syscall(%eax = __NR_clone, | |
1538 * %ebx = flags, | |
1539 * %ecx = child_stack, | |
1540 * %edx = parent_tidptr, | |
1541 * %esi = newtls, | |
1542 * %edi = child_tidptr) | |
1543 * Also, make sure that %ebx gets preserved as it is | |
1544 * used in PIC mode. | |
1545 */ | |
1546 "movl %8,%%esi\n" | |
1547 "movl %7,%%edx\n" | |
1548 "movl %5,%%eax\n" | |
1549 "movl %9,%%edi\n" | |
1550 "pushl %%ebx\n" | |
1551 "movl %%eax,%%ebx\n" | |
1552 "movl %2,%%eax\n" | |
1553 "int $0x80\n" | |
1554 | |
1555 /* In the parent: restore %ebx | |
1556 * In the child: move "fn" into %ebx | |
1557 */ | |
1558 "popl %%ebx\n" | |
1559 | |
1560 /* if (%eax != 0) | |
1561 * return %eax; | |
1562 */ | |
1563 "test %%eax,%%eax\n" | |
1564 "jnz 1f\n" | |
1565 | |
1566 /* In the child, now. Terminate frame pointer chain. | |
1567 */ | |
1568 "movl $0,%%ebp\n" | |
1569 | |
1570 /* Call "fn". "arg" is already on the stack. | |
1571 */ | |
1572 "call *%%ebx\n" | |
1573 | |
1574 /* Call _exit(%ebx). Unfortunately older versions | |
1575 * of gcc restrict the number of arguments that can | |
1576 * be passed to asm(). So, we need to hard-code the | |
1577 * system call number. | |
1578 */ | |
1579 "movl %%eax,%%ebx\n" | |
1580 "movl $1,%%eax\n" | |
1581 "int $0x80\n" | |
1582 | |
1583 /* Return to parent. | |
1584 */ | |
1585 "1:\n" | |
1586 : "=a" (__res) | |
1587 : "0"(-EINVAL), "i"(__NR_clone), | |
1588 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg), | |
1589 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr) | |
1590 : "esp", "memory", "ecx", "edx", "esi", "edi"); | |
1591 LSS_RETURN(int, __res); | |
1592 } | |
1593 | |
1594 #define __NR__fadvise64_64 __NR_fadvise64_64 | |
1595 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd, | |
1596 unsigned, offset_lo, unsigned, offset_hi, | |
1597 unsigned, len_lo, unsigned, len_hi, | |
1598 int, advice) | |
1599 | |
1600 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, | |
1601 loff_t len, int advice) { | |
1602 return LSS_NAME(_fadvise64_64)(fd, | |
1603 (unsigned)offset, (unsigned)(offset >>32), | |
1604 (unsigned)len, (unsigned)(len >> 32), | |
1605 advice); | |
1606 } | |
1607 | |
1608 #define __NR__fallocate __NR_fallocate | |
1609 LSS_INLINE _syscall6(int, _fallocate, int, fd, | |
1610 int, mode, | |
1611 unsigned, offset_lo, unsigned, offset_hi, | |
1612 unsigned, len_lo, unsigned, len_hi) | |
1613 | |
1614 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode, | |
1615 loff_t offset, loff_t len) { | |
1616 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len }; | |
1617 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]); | |
1618 } | |
1619 | |
1620 LSS_INLINE _syscall1(int, set_thread_area, void *, u) | |
1621 LSS_INLINE _syscall1(int, get_thread_area, void *, u) | |
1622 | |
1623 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { | |
1624 /* On i386, the kernel does not know how to return from a signal | |
1625 * handler. Instead, it relies on user space to provide a | |
1626 * restorer function that calls the {rt_,}sigreturn() system call. | |
1627 * Unfortunately, we cannot just reference the glibc version of this | |
1628 * function, as glibc goes out of its way to make it inaccessible. | |
1629 */ | |
1630 void (*res)(void); | |
1631 __asm__ __volatile__("call 2f\n" | |
1632 "0:.align 16\n" | |
1633 "1:movl %1,%%eax\n" | |
1634 "int $0x80\n" | |
1635 "2:popl %0\n" | |
1636 "addl $(1b-0b),%0\n" | |
1637 : "=a" (res) | |
1638 : "i" (__NR_rt_sigreturn)); | |
1639 return res; | |
1640 } | |
1641 LSS_INLINE void (*LSS_NAME(restore)(void))(void) { | |
1642 /* On i386, the kernel does not know how to return from a signal | |
1643 * handler. Instead, it relies on user space to provide a | |
1644 * restorer function that calls the {rt_,}sigreturn() system call. | |
1645 * Unfortunately, we cannot just reference the glibc version of this | |
1646 * function, as glibc goes out of its way to make it inaccessible. | |
1647 */ | |
1648 void (*res)(void); | |
1649 __asm__ __volatile__("call 2f\n" | |
1650 "0:.align 16\n" | |
1651 "1:pop %%eax\n" | |
1652 "movl %1,%%eax\n" | |
1653 "int $0x80\n" | |
1654 "2:popl %0\n" | |
1655 "addl $(1b-0b),%0\n" | |
1656 : "=a" (res) | |
1657 : "i" (__NR_sigreturn)); | |
1658 return res; | |
1659 } | |
1660 #elif defined(__x86_64__) | |
1661 /* There are no known problems with any of the _syscallX() macros | |
1662 * currently shipping for x86_64, but we still need to be able to define | |
1663 * our own version so that we can override the location of the errno | |
1664 * location (e.g. when using the clone() system call with the CLONE_VM | |
1665 * option). | |
1666 */ | |
1667 #undef LSS_BODY | |
1668 #define LSS_BODY(type,name, ...) \ | |
1669 long __res; \ | |
1670 __asm__ __volatile__("syscall" : "=a" (__res) : "0" (__NR_##name), \ | |
1671 ##__VA_ARGS__ : "r11", "rcx", "memory"); \ | |
1672 LSS_RETURN(type, __res) | |
1673 #undef _syscall0 | |
1674 #define _syscall0(type,name) \ | |
1675 type LSS_NAME(name)() { \ | |
1676 LSS_BODY(type, name); \ | |
1677 } | |
1678 #undef _syscall1 | |
1679 #define _syscall1(type,name,type1,arg1) \ | |
1680 type LSS_NAME(name)(type1 arg1) { \ | |
1681 LSS_BODY(type, name, "D" ((long)(arg1))); \ | |
1682 } | |
1683 #undef _syscall2 | |
1684 #define _syscall2(type,name,type1,arg1,type2,arg2) \ | |
1685 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ | |
1686 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \ | |
1687 } | |
1688 #undef _syscall3 | |
1689 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ | |
1690 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ | |
1691 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \ | |
1692 "d" ((long)(arg3))); \ | |
1693 } | |
1694 #undef _syscall4 | |
1695 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ | |
1696 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ | |
1697 long __res; \ | |
1698 __asm__ __volatile__("movq %5,%%r10; syscall" : \ | |
1699 "=a" (__res) : "0" (__NR_##name), \ | |
1700 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | |
1701 "r" ((long)(arg4)) : "r10", "r11", "rcx", "memory"); \ | |
1702 LSS_RETURN(type, __res); \ | |
1703 } | |
1704 #undef _syscall5 | |
1705 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
1706 type5,arg5) \ | |
1707 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
1708 type5 arg5) { \ | |
1709 long __res; \ | |
1710 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; syscall" : \ | |
1711 "=a" (__res) : "0" (__NR_##name), \ | |
1712 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | |
1713 "r" ((long)(arg4)), "r" ((long)(arg5)) : \ | |
1714 "r8", "r10", "r11", "rcx", "memory"); \ | |
1715 LSS_RETURN(type, __res); \ | |
1716 } | |
1717 #undef _syscall6 | |
1718 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
1719 type5,arg5,type6,arg6) \ | |
1720 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
1721 type5 arg5, type6 arg6) { \ | |
1722 long __res; \ | |
1723 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \ | |
1724 "syscall" : \ | |
1725 "=a" (__res) : "0" (__NR_##name), \ | |
1726 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | |
1727 "r" ((long)(arg4)), "r" ((long)(arg5)), "r" ((long)(arg6)) : \ | |
1728 "r8", "r9", "r10", "r11", "rcx", "memory"); \ | |
1729 LSS_RETURN(type, __res); \ | |
1730 } | |
1731 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, | |
1732 int flags, void *arg, int *parent_tidptr, | |
1733 void *newtls, int *child_tidptr) { | |
1734 long __res; | |
1735 { | |
1736 register void *__tls __asm__("r8") = newtls; | |
1737 register int *__ctid __asm__("r10") = child_tidptr; | |
1738 __asm__ __volatile__(/* if (fn == NULL) | |
1739 * return -EINVAL; | |
1740 */ | |
1741 "testq %4,%4\n" | |
1742 "jz 1f\n" | |
1743 | |
1744 /* if (child_stack == NULL) | |
1745 * return -EINVAL; | |
1746 */ | |
1747 "testq %5,%5\n" | |
1748 "jz 1f\n" | |
1749 | |
1750 /* childstack -= 2*sizeof(void *); | |
1751 */ | |
1752 "subq $16,%5\n" | |
1753 | |
1754 /* Push "arg" and "fn" onto the stack that will be | |
1755 * used by the child. | |
1756 */ | |
1757 "movq %7,8(%5)\n" | |
1758 "movq %4,0(%5)\n" | |
1759 | |
1760 /* %rax = syscall(%rax = __NR_clone, | |
1761 * %rdi = flags, | |
1762 * %rsi = child_stack, | |
1763 * %rdx = parent_tidptr, | |
1764 * %r8 = new_tls, | |
1765 * %r10 = child_tidptr) | |
1766 */ | |
1767 "movq %2,%%rax\n" | |
1768 "syscall\n" | |
1769 | |
1770 /* if (%rax != 0) | |
1771 * return; | |
1772 */ | |
1773 "testq %%rax,%%rax\n" | |
1774 "jnz 1f\n" | |
1775 | |
1776 /* In the child. Terminate frame pointer chain. | |
1777 */ | |
1778 "xorq %%rbp,%%rbp\n" | |
1779 | |
1780 /* Call "fn(arg)". | |
1781 */ | |
1782 "popq %%rax\n" | |
1783 "popq %%rdi\n" | |
1784 "call *%%rax\n" | |
1785 | |
1786 /* Call _exit(%ebx). | |
1787 */ | |
1788 "movq %%rax,%%rdi\n" | |
1789 "movq %3,%%rax\n" | |
1790 "syscall\n" | |
1791 | |
1792 /* Return to parent. | |
1793 */ | |
1794 "1:\n" | |
1795 : "=a" (__res) | |
1796 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), | |
1797 "r"(fn), "S"(child_stack), "D"(flags), "r"(arg), | |
1798 "d"(parent_tidptr), "r"(__tls), "r"(__ctid) | |
1799 : "rsp", "memory", "r11", "rcx"); | |
1800 } | |
1801 LSS_RETURN(int, __res); | |
1802 } | |
1803 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) | |
1804 LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len, | |
1805 int, advice) | |
1806 | |
1807 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { | |
1808 /* On x86-64, the kernel does not know how to return from | |
1809 * a signal handler. Instead, it relies on user space to provide a | |
1810 * restorer function that calls the rt_sigreturn() system call. | |
1811 * Unfortunately, we cannot just reference the glibc version of this | |
1812 * function, as glibc goes out of its way to make it inaccessible. | |
1813 */ | |
1814 void (*res)(void); | |
1815 __asm__ __volatile__("call 2f\n" | |
1816 "0:.align 16\n" | |
1817 "1:movq %1,%%rax\n" | |
1818 "syscall\n" | |
1819 "2:popq %0\n" | |
1820 "addq $(1b-0b),%0\n" | |
1821 : "=a" (res) | |
1822 : "i" (__NR_rt_sigreturn)); | |
1823 return res; | |
1824 } | |
1825 #elif defined(__ARM_ARCH_3__) | |
1826 /* Most definitions of _syscallX() neglect to mark "memory" as being | |
1827 * clobbered. This causes problems with compilers, that do a better job | |
1828 * at optimizing across __asm__ calls. | |
1829 * So, we just have to redefine all fo the _syscallX() macros. | |
1830 */ | |
1831 #undef LSS_REG | |
1832 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a | |
1833 #undef LSS_BODY | |
1834 #define LSS_BODY(type,name,args...) \ | |
1835 register long __res_r0 __asm__("r0"); \ | |
1836 long __res; \ | |
1837 __asm__ __volatile__ (__syscall(name) \ | |
1838 : "=r"(__res_r0) : args : "lr", "memory"); \ | |
1839 __res = __res_r0; \ | |
1840 LSS_RETURN(type, __res) | |
1841 #undef _syscall0 | |
1842 #define _syscall0(type, name) \ | |
1843 type LSS_NAME(name)() { \ | |
1844 LSS_BODY(type, name); \ | |
1845 } | |
1846 #undef _syscall1 | |
1847 #define _syscall1(type, name, type1, arg1) \ | |
1848 type LSS_NAME(name)(type1 arg1) { \ | |
1849 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ | |
1850 } | |
1851 #undef _syscall2 | |
1852 #define _syscall2(type, name, type1, arg1, type2, arg2) \ | |
1853 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ | |
1854 LSS_REG(0, arg1); LSS_REG(1, arg2); \ | |
1855 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ | |
1856 } | |
1857 #undef _syscall3 | |
1858 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ | |
1859 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ | |
1860 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ | |
1861 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ | |
1862 } | |
1863 #undef _syscall4 | |
1864 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ | |
1865 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ | |
1866 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ | |
1867 LSS_REG(3, arg4); \ | |
1868 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ | |
1869 } | |
1870 #undef _syscall5 | |
1871 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
1872 type5,arg5) \ | |
1873 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
1874 type5 arg5) { \ | |
1875 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ | |
1876 LSS_REG(3, arg4); LSS_REG(4, arg5); \ | |
1877 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ | |
1878 "r"(__r4)); \ | |
1879 } | |
1880 #undef _syscall6 | |
1881 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
1882 type5,arg5,type6,arg6) \ | |
1883 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
1884 type5 arg5, type6 arg6) { \ | |
1885 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ | |
1886 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ | |
1887 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ | |
1888 "r"(__r4), "r"(__r5)); \ | |
1889 } | |
1890 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, | |
1891 int flags, void *arg, int *parent_tidptr, | |
1892 void *newtls, int *child_tidptr) { | |
1893 long __res; | |
1894 { | |
1895 register int __flags __asm__("r0") = flags; | |
1896 register void *__stack __asm__("r1") = child_stack; | |
1897 register void *__ptid __asm__("r2") = parent_tidptr; | |
1898 register void *__tls __asm__("r3") = newtls; | |
1899 register int *__ctid __asm__("r4") = child_tidptr; | |
1900 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL) | |
1901 * return -EINVAL; | |
1902 */ | |
1903 "cmp %2,#0\n" | |
1904 "cmpne %3,#0\n" | |
1905 "moveq %0,%1\n" | |
1906 "beq 1f\n" | |
1907 | |
1908 /* Push "arg" and "fn" onto the stack that will be | |
1909 * used by the child. | |
1910 */ | |
1911 "str %5,[%3,#-4]!\n" | |
1912 "str %2,[%3,#-4]!\n" | |
1913 | |
1914 /* %r0 = syscall(%r0 = flags, | |
1915 * %r1 = child_stack, | |
1916 * %r2 = parent_tidptr, | |
1917 * %r3 = newtls, | |
1918 * %r4 = child_tidptr) | |
1919 */ | |
1920 __syscall(clone)"\n" | |
1921 | |
1922 /* if (%r0 != 0) | |
1923 * return %r0; | |
1924 */ | |
1925 "movs %0,r0\n" | |
1926 "bne 1f\n" | |
1927 | |
1928 /* In the child, now. Call "fn(arg)". | |
1929 */ | |
1930 "ldr r0,[sp, #4]\n" | |
1931 "mov lr,pc\n" | |
1932 "ldr pc,[sp]\n" | |
1933 | |
1934 /* Call _exit(%r0). | |
1935 */ | |
1936 __syscall(exit)"\n" | |
1937 "1:\n" | |
1938 : "=r" (__res) | |
1939 : "i"(-EINVAL), | |
1940 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), | |
1941 "r"(__ptid), "r"(__tls), "r"(__ctid) | |
1942 : "lr", "memory"); | |
1943 } | |
1944 LSS_RETURN(int, __res); | |
1945 } | |
1946 #elif defined(__mips__) | |
1947 #undef LSS_REG | |
1948 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \ | |
1949 (unsigned long)(a) | |
1950 #undef LSS_BODY | |
1951 #define LSS_BODY(type,name,r7,...) \ | |
1952 register unsigned long __v0 __asm__("$2") = __NR_##name; \ | |
1953 __asm__ __volatile__ ("syscall\n" \ | |
1954 : "=&r"(__v0), r7 (__r7) \ | |
1955 : "0"(__v0), ##__VA_ARGS__ \ | |
1956 : "$8", "$9", "$10", "$11", "$12", \ | |
1957 "$13", "$14", "$15", "$24", "memory"); \ | |
1958 LSS_RETURN(type, __v0, __r7) | |
1959 #undef _syscall0 | |
1960 #define _syscall0(type, name) \ | |
1961 type LSS_NAME(name)() { \ | |
1962 register unsigned long __r7 __asm__("$7"); \ | |
1963 LSS_BODY(type, name, "=r"); \ | |
1964 } | |
1965 #undef _syscall1 | |
1966 #define _syscall1(type, name, type1, arg1) \ | |
1967 type LSS_NAME(name)(type1 arg1) { \ | |
1968 register unsigned long __r7 __asm__("$7"); \ | |
1969 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \ | |
1970 } | |
1971 #undef _syscall2 | |
1972 #define _syscall2(type, name, type1, arg1, type2, arg2) \ | |
1973 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ | |
1974 register unsigned long __r7 __asm__("$7"); \ | |
1975 LSS_REG(4, arg1); LSS_REG(5, arg2); \ | |
1976 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \ | |
1977 } | |
1978 #undef _syscall3 | |
1979 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ | |
1980 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ | |
1981 register unsigned long __r7 __asm__("$7"); \ | |
1982 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ | |
1983 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \ | |
1984 } | |
1985 #undef _syscall4 | |
1986 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ | |
1987 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ | |
1988 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ | |
1989 LSS_REG(7, arg4); \ | |
1990 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \ | |
1991 } | |
1992 #undef _syscall5 | |
1993 #if _MIPS_SIM == _MIPS_SIM_ABI32 | |
1994 /* The old 32bit MIPS system call API passes the fifth and sixth argument | |
1995 * on the stack, whereas the new APIs use registers "r8" and "r9". | |
1996 */ | |
1997 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
1998 type5,arg5) \ | |
1999 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
2000 type5 arg5) { \ | |
2001 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ | |
2002 LSS_REG(7, arg4); \ | |
2003 register unsigned long __v0 __asm__("$2"); \ | |
2004 __asm__ __volatile__ (".set noreorder\n" \ | |
2005 "lw $2, %6\n" \ | |
2006 "subu $29, 32\n" \ | |
2007 "sw $2, 16($29)\n" \ | |
2008 "li $2, %2\n" \ | |
2009 "syscall\n" \ | |
2010 "addiu $29, 32\n" \ | |
2011 ".set reorder\n" \ | |
2012 : "=&r"(__v0), "+r" (__r7) \ | |
2013 : "i" (__NR_##name), "r"(__r4), "r"(__r5), \ | |
2014 "r"(__r6), "m" ((unsigned long)arg5) \ | |
2015 : "$8", "$9", "$10", "$11", "$12", \ | |
2016 "$13", "$14", "$15", "$24", "memory"); \ | |
2017 LSS_RETURN(type, __v0, __r7); \ | |
2018 } | |
2019 #else | |
2020 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
2021 type5,arg5) \ | |
2022 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
2023 type5 arg5) { \ | |
2024 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ | |
2025 LSS_REG(7, arg4); LSS_REG(8, arg5); \ | |
2026 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ | |
2027 "r"(__r8)); \ | |
2028 } | |
2029 #endif | |
2030 #undef _syscall6 | |
2031 #if _MIPS_SIM == _MIPS_SIM_ABI32 | |
2032 /* The old 32bit MIPS system call API passes the fifth and sixth argument | |
2033 * on the stack, whereas the new APIs use registers "r8" and "r9". | |
2034 */ | |
2035 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
2036 type5,arg5,type6,arg6) \ | |
2037 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
2038 type5 arg5, type6 arg6) { \ | |
2039 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ | |
2040 LSS_REG(7, arg4); \ | |
2041 register unsigned long __v0 __asm__("$2"); \ | |
2042 __asm__ __volatile__ (".set noreorder\n" \ | |
2043 "lw $2, %6\n" \ | |
2044 "lw $8, %7\n" \ | |
2045 "subu $29, 32\n" \ | |
2046 "sw $2, 16($29)\n" \ | |
2047 "sw $8, 20($29)\n" \ | |
2048 "li $2, %2\n" \ | |
2049 "syscall\n" \ | |
2050 "addiu $29, 32\n" \ | |
2051 ".set reorder\n" \ | |
2052 : "=&r"(__v0), "+r" (__r7) \ | |
2053 : "i" (__NR_##name), "r"(__r4), "r"(__r5), \ | |
2054 "r"(__r6), "r" ((unsigned long)arg5), \ | |
2055 "r" ((unsigned long)arg6) \ | |
2056 : "$8", "$9", "$10", "$11", "$12", \ | |
2057 "$13", "$14", "$15", "$24", "memory"); \ | |
2058 LSS_RETURN(type, __v0, __r7); \ | |
2059 } | |
2060 #else | |
2061 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | |
2062 type5,arg5,type6,arg6) \ | |
2063 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
2064 type5 arg5,type6 arg6) { \ | |
2065 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ | |
2066 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \ | |
2067 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ | |
2068 "r"(__r8), "r"(__r9)); \ | |
2069 } | |
2070 #endif | |
2071 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, | |
2072 int flags, void *arg, int *parent_tidptr, | |
2073 void *newtls, int *child_tidptr) { | |
2074 register unsigned long __v0 __asm__("$2"); | |
2075 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls; | |
2076 { | |
2077 register int __flags __asm__("$4") = flags; | |
2078 register void *__stack __asm__("$5") = child_stack; | |
2079 register void *__ptid __asm__("$6") = parent_tidptr; | |
2080 register int *__ctid __asm__("$8") = child_tidptr; | |
2081 __asm__ __volatile__( | |
2082 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 | |
2083 "subu $29,24\n" | |
2084 #elif _MIPS_SIM == _MIPS_SIM_NABI32 | |
2085 "sub $29,16\n" | |
2086 #else | |
2087 "dsubu $29,16\n" | |
2088 #endif | |
2089 | |
2090 /* if (fn == NULL || child_stack == NULL) | |
2091 * return -EINVAL; | |
2092 */ | |
2093 "li %0,%2\n" | |
2094 "beqz %5,1f\n" | |
2095 "beqz %6,1f\n" | |
2096 | |
2097 /* Push "arg" and "fn" onto the stack that will be | |
2098 * used by the child. | |
2099 */ | |
2100 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 | |
2101 "subu %6,32\n" | |
2102 "sw %5,0(%6)\n" | |
2103 "sw %8,4(%6)\n" | |
2104 #elif _MIPS_SIM == _MIPS_SIM_NABI32 | |
2105 "sub %6,32\n" | |
2106 "sw %5,0(%6)\n" | |
2107 "sw %8,8(%6)\n" | |
2108 #else | |
2109 "dsubu %6,32\n" | |
2110 "sd %5,0(%6)\n" | |
2111 "sd %8,8(%6)\n" | |
2112 #endif | |
2113 | |
2114 /* $7 = syscall($4 = flags, | |
2115 * $5 = child_stack, | |
2116 * $6 = parent_tidptr, | |
2117 * $7 = newtls, | |
2118 * $8 = child_tidptr) | |
2119 */ | |
2120 "li $2,%3\n" | |
2121 "syscall\n" | |
2122 | |
2123 /* if ($7 != 0) | |
2124 * return $2; | |
2125 */ | |
2126 "bnez $7,1f\n" | |
2127 "bnez $2,1f\n" | |
2128 | |
2129 /* In the child, now. Call "fn(arg)". | |
2130 */ | |
2131 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 | |
2132 "lw $25,0($29)\n" | |
2133 "lw $4,4($29)\n" | |
2134 #elif _MIPS_SIM == _MIPS_SIM_NABI32 | |
2135 "lw $25,0($29)\n" | |
2136 "lw $4,8($29)\n" | |
2137 #else | |
2138 "ld $25,0($29)\n" | |
2139 "ld $4,8($29)\n" | |
2140 #endif | |
2141 "jalr $25\n" | |
2142 | |
2143 /* Call _exit($2) | |
2144 */ | |
2145 "move $4,$2\n" | |
2146 "li $2,%4\n" | |
2147 "syscall\n" | |
2148 | |
2149 "1:\n" | |
2150 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 | |
2151 "addu $29, 24\n" | |
2152 #elif _MIPS_SIM == _MIPS_SIM_NABI32 | |
2153 "add $29, 16\n" | |
2154 #else | |
2155 "daddu $29,16\n" | |
2156 #endif | |
2157 : "=&r" (__v0), "=r" (__r7) | |
2158 : "i"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), | |
2159 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), | |
2160 "r"(__ptid), "r"(__r7), "r"(__ctid) | |
2161 : "$9", "$10", "$11", "$12", "$13", "$14", "$15", | |
2162 "$24", "memory"); | |
2163 } | |
2164 LSS_RETURN(int, __v0, __r7); | |
2165 } | |
2166 #elif defined (__PPC__) | |
2167 #undef LSS_LOADARGS_0 | |
2168 #define LSS_LOADARGS_0(name, dummy...) \ | |
2169 __sc_0 = __NR_##name | |
2170 #undef LSS_LOADARGS_1 | |
2171 #define LSS_LOADARGS_1(name, arg1) \ | |
2172 LSS_LOADARGS_0(name); \ | |
2173 __sc_3 = (unsigned long) (arg1) | |
2174 #undef LSS_LOADARGS_2 | |
2175 #define LSS_LOADARGS_2(name, arg1, arg2) \ | |
2176 LSS_LOADARGS_1(name, arg1); \ | |
2177 __sc_4 = (unsigned long) (arg2) | |
2178 #undef LSS_LOADARGS_3 | |
2179 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \ | |
2180 LSS_LOADARGS_2(name, arg1, arg2); \ | |
2181 __sc_5 = (unsigned long) (arg3) | |
2182 #undef LSS_LOADARGS_4 | |
2183 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \ | |
2184 LSS_LOADARGS_3(name, arg1, arg2, arg3); \ | |
2185 __sc_6 = (unsigned long) (arg4) | |
2186 #undef LSS_LOADARGS_5 | |
2187 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \ | |
2188 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \ | |
2189 __sc_7 = (unsigned long) (arg5) | |
2190 #undef LSS_LOADARGS_6 | |
2191 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ | |
2192 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \ | |
2193 __sc_8 = (unsigned long) (arg6) | |
2194 #undef LSS_ASMINPUT_0 | |
2195 #define LSS_ASMINPUT_0 "0" (__sc_0) | |
2196 #undef LSS_ASMINPUT_1 | |
2197 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3) | |
2198 #undef LSS_ASMINPUT_2 | |
2199 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4) | |
2200 #undef LSS_ASMINPUT_3 | |
2201 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5) | |
2202 #undef LSS_ASMINPUT_4 | |
2203 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6) | |
2204 #undef LSS_ASMINPUT_5 | |
2205 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7) | |
2206 #undef LSS_ASMINPUT_6 | |
2207 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8) | |
2208 #undef LSS_BODY | |
2209 #define LSS_BODY(nr, type, name, args...) \ | |
2210 long __sc_ret, __sc_err; \ | |
2211 { \ | |
2212 register unsigned long __sc_0 __asm__ ("r0"); \ | |
2213 register unsigned long __sc_3 __asm__ ("r3"); \ | |
2214 register unsigned long __sc_4 __asm__ ("r4"); \ | |
2215 register unsigned long __sc_5 __asm__ ("r5"); \ | |
2216 register unsigned long __sc_6 __asm__ ("r6"); \ | |
2217 register unsigned long __sc_7 __asm__ ("r7"); \ | |
2218 register unsigned long __sc_8 __asm__ ("r8"); \ | |
2219 \ | |
2220 LSS_LOADARGS_##nr(name, args); \ | |
2221 __asm__ __volatile__ \ | |
2222 ("sc\n\t" \ | |
2223 "mfcr %0" \ | |
2224 : "=&r" (__sc_0), \ | |
2225 "=&r" (__sc_3), "=&r" (__sc_4), \ | |
2226 "=&r" (__sc_5), "=&r" (__sc_6), \ | |
2227 "=&r" (__sc_7), "=&r" (__sc_8) \ | |
2228 : LSS_ASMINPUT_##nr \ | |
2229 : "cr0", "ctr", "memory", \ | |
2230 "r9", "r10", "r11", "r12"); \ | |
2231 __sc_ret = __sc_3; \ | |
2232 __sc_err = __sc_0; \ | |
2233 } \ | |
2234 LSS_RETURN(type, __sc_ret, __sc_err) | |
2235 #undef _syscall0 | |
2236 #define _syscall0(type, name) \ | |
2237 type LSS_NAME(name)(void) { \ | |
2238 LSS_BODY(0, type, name); \ | |
2239 } | |
2240 #undef _syscall1 | |
2241 #define _syscall1(type, name, type1, arg1) \ | |
2242 type LSS_NAME(name)(type1 arg1) { \ | |
2243 LSS_BODY(1, type, name, arg1); \ | |
2244 } | |
2245 #undef _syscall2 | |
2246 #define _syscall2(type, name, type1, arg1, type2, arg2) \ | |
2247 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ | |
2248 LSS_BODY(2, type, name, arg1, arg2); \ | |
2249 } | |
2250 #undef _syscall3 | |
2251 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ | |
2252 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ | |
2253 LSS_BODY(3, type, name, arg1, arg2, arg3); \ | |
2254 } | |
2255 #undef _syscall4 | |
2256 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ | |
2257 type4, arg4) \ | |
2258 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ | |
2259 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \ | |
2260 } | |
2261 #undef _syscall5 | |
2262 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ | |
2263 type4, arg4, type5, arg5) \ | |
2264 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
2265 type5 arg5) { \ | |
2266 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \ | |
2267 } | |
2268 #undef _syscall6 | |
2269 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ | |
2270 type4, arg4, type5, arg5, type6, arg6) \ | |
2271 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | |
2272 type5 arg5, type6 arg6) { \ | |
2273 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ | |
2274 } | |
2275 /* clone function adapted from glibc 2.3.6 clone.S */ | |
2276 /* TODO(csilvers): consider wrapping some args up in a struct, like we | |
2277 * do for i386's _syscall6, so we can compile successfully on gcc 2.95 | |
2278 */ | |
2279 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, | |
2280 int flags, void *arg, int *parent_tidptr, | |
2281 void *newtls, int *child_tidptr) { | |
2282 long __ret, __err; | |
2283 { | |
2284 register int (*__fn)(void *) __asm__ ("r8") = fn; | |
2285 register void *__cstack __asm__ ("r4") = child_stack; | |
2286 register int __flags __asm__ ("r3") = flags; | |
2287 register void * __arg __asm__ ("r9") = arg; | |
2288 register int * __ptidptr __asm__ ("r5") = parent_tidptr; | |
2289 register void * __newtls __asm__ ("r6") = newtls; | |
2290 register int * __ctidptr __asm__ ("r7") = child_tidptr; | |
2291 __asm__ __volatile__( | |
2292 /* check for fn == NULL | |
2293 * and child_stack == NULL | |
2294 */ | |
2295 "cmpwi cr0, %6, 0\n\t" | |
2296 "cmpwi cr1, %7, 0\n\t" | |
2297 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t" | |
2298 "beq- cr0, 1f\n\t" | |
2299 | |
2300 /* set up stack frame for child */ | |
2301 "clrrwi %7, %7, 4\n\t" | |
2302 "li 0, 0\n\t" | |
2303 "stwu 0, -16(%7)\n\t" | |
2304 | |
2305 /* fn, arg, child_stack are saved across the syscall: r28-30 */ | |
2306 "mr 28, %6\n\t" | |
2307 "mr 29, %7\n\t" | |
2308 "mr 27, %9\n\t" | |
2309 | |
2310 /* syscall */ | |
2311 "li 0, %4\n\t" | |
2312 /* flags already in r3 | |
2313 * child_stack already in r4 | |
2314 * ptidptr already in r5 | |
2315 * newtls already in r6 | |
2316 * ctidptr already in r7 | |
2317 */ | |
2318 "sc\n\t" | |
2319 | |
2320 /* Test if syscall was successful */ | |
2321 "cmpwi cr1, 3, 0\n\t" | |
2322 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" | |
2323 "bne- cr1, 1f\n\t" | |
2324 | |
2325 /* Do the function call */ | |
2326 "mtctr 28\n\t" | |
2327 "mr 3, 27\n\t" | |
2328 "bctrl\n\t" | |
2329 | |
2330 /* Call _exit(r3) */ | |
2331 "li 0, %5\n\t" | |
2332 "sc\n\t" | |
2333 | |
2334 /* Return to parent */ | |
2335 "1:\n" | |
2336 "mfcr %1\n\t" | |
2337 "mr %0, 3\n\t" | |
2338 : "=r" (__ret), "=r" (__err) | |
2339 : "0" (-1), "1" (EINVAL), | |
2340 "i" (__NR_clone), "i" (__NR_exit), | |
2341 "r" (__fn), "r" (__cstack), "r" (__flags), | |
2342 "r" (__arg), "r" (__ptidptr), "r" (__newtls), | |
2343 "r" (__ctidptr) | |
2344 : "cr0", "cr1", "memory", "ctr", | |
2345 "r0", "r29", "r27", "r28"); | |
2346 } | |
2347 LSS_RETURN(int, __ret, __err); | |
2348 } | |
2349 #endif | |
2350 #define __NR__exit __NR_exit | |
2351 #define __NR__gettid __NR_gettid | |
2352 #define __NR__mremap __NR_mremap | |
2353 LSS_INLINE _syscall1(int, brk, void *, e) | |
2354 LSS_INLINE _syscall1(int, chdir, const char *,p) | |
2355 LSS_INLINE _syscall1(int, close, int, f) | |
2356 LSS_INLINE _syscall2(int, clock_getres, int, c, | |
2357 struct kernel_timespec*, t) | |
2358 LSS_INLINE _syscall2(int, clock_gettime, int, c, | |
2359 struct kernel_timespec*, t) | |
2360 LSS_INLINE _syscall1(int, dup, int, f) | |
2361 LSS_INLINE _syscall2(int, dup2, int, s, | |
2362 int, d) | |
2363 LSS_INLINE _syscall3(int, execve, const char*, f, | |
2364 const char*const*,a,const char*const*, e) | |
2365 LSS_INLINE _syscall1(int, _exit, int, e) | |
2366 LSS_INLINE _syscall1(int, exit_group, int, e) | |
2367 LSS_INLINE _syscall3(int, fcntl, int, f, | |
2368 int, c, long, a) | |
2369 LSS_INLINE _syscall0(pid_t, fork) | |
2370 LSS_INLINE _syscall2(int, fstat, int, f, | |
2371 struct kernel_stat*, b) | |
2372 LSS_INLINE _syscall2(int, fstatfs, int, f, | |
2373 struct kernel_statfs*, b) | |
2374 LSS_INLINE _syscall2(int, ftruncate, int, f, | |
2375 off_t, l) | |
2376 LSS_INLINE _syscall4(int, futex, int*, a, | |
2377 int, o, int, v, | |
2378 struct kernel_timespec*, t) | |
2379 LSS_INLINE _syscall3(int, getdents, int, f, | |
2380 struct kernel_dirent*, d, int, c) | |
2381 LSS_INLINE _syscall3(int, getdents64, int, f, | |
2382 struct kernel_dirent64*, d, int, c) | |
2383 LSS_INLINE _syscall0(gid_t, getegid) | |
2384 LSS_INLINE _syscall0(uid_t, geteuid) | |
2385 LSS_INLINE _syscall0(pid_t, getpgrp) | |
2386 LSS_INLINE _syscall0(pid_t, getpid) | |
2387 LSS_INLINE _syscall0(pid_t, getppid) | |
2388 LSS_INLINE _syscall2(int, getpriority, int, a, | |
2389 int, b) | |
2390 LSS_INLINE _syscall3(int, getresgid, gid_t *, r, | |
2391 gid_t *, e, gid_t *, s) | |
2392 LSS_INLINE _syscall3(int, getresuid, uid_t *, r, | |
2393 uid_t *, e, uid_t *, s) | |
2394 LSS_INLINE _syscall2(int, getrlimit, int, r, | |
2395 struct kernel_rlimit*, l) | |
2396 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p) | |
2397 LSS_INLINE _syscall0(pid_t, _gettid) | |
2398 LSS_INLINE _syscall2(int, gettimeofday, struct timeval *, v, | |
2399 struct timezone *, z) | |
2400 LSS_INLINE _syscall5(int, setxattr, const char *,p, | |
2401 const char *, n, const void *,v, | |
2402 size_t, s, int, f) | |
2403 LSS_INLINE _syscall5(int, lsetxattr, const char *,p, | |
2404 const char *, n, const void *,v, | |
2405 size_t, s, int, f) | |
2406 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p, | |
2407 const char *, n, void *, v, size_t, s) | |
2408 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p, | |
2409 const char *, n, void *, v, size_t, s) | |
2410 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p, | |
2411 char *, l, size_t, s) | |
2412 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p, | |
2413 char *, l, size_t, s) | |
2414 LSS_INLINE _syscall3(int, ioctl, int, d, | |
2415 int, r, void *, a) | |
2416 LSS_INLINE _syscall2(int, ioprio_get, int, which, | |
2417 int, who) | |
2418 LSS_INLINE _syscall3(int, ioprio_set, int, which, | |
2419 int, who, int, ioprio) | |
2420 LSS_INLINE _syscall2(int, kill, pid_t, p, | |
2421 int, s) | |
2422 LSS_INLINE _syscall3(off_t, lseek, int, f, | |
2423 off_t, o, int, w) | |
2424 LSS_INLINE _syscall2(int, munmap, void*, s, | |
2425 size_t, l) | |
2426 LSS_INLINE _syscall6(long, move_pages, pid_t, p, | |
2427 unsigned long, n, void **,g, int *, d, | |
2428 int *, s, int, f) | |
2429 LSS_INLINE _syscall3(int, mprotect, const void *,a, | |
2430 size_t, l, int, p) | |
2431 LSS_INLINE _syscall5(void*, _mremap, void*, o, | |
2432 size_t, os, size_t, ns, | |
2433 unsigned long, f, void *, a) | |
2434 LSS_INLINE _syscall3(int, open, const char*, p, | |
2435 int, f, int, m) | |
2436 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u, | |
2437 unsigned int, n, int, t) | |
2438 LSS_INLINE _syscall2(int, prctl, int, o, | |
2439 long, a) | |
2440 LSS_INLINE _syscall4(long, ptrace, int, r, | |
2441 pid_t, p, void *, a, void *, d) | |
2442 #if defined(__NR_quotactl) | |
2443 // Defined on x86_64 / i386 only | |
2444 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special, | |
2445 int, id, caddr_t, addr) | |
2446 #endif | |
2447 LSS_INLINE _syscall3(ssize_t, read, int, f, | |
2448 void *, b, size_t, c) | |
2449 LSS_INLINE _syscall3(int, readlink, const char*, p, | |
2450 char*, b, size_t, s) | |
2451 LSS_INLINE _syscall4(int, rt_sigaction, int, s, | |
2452 const struct kernel_sigaction*, a, | |
2453 struct kernel_sigaction*, o, size_t, c) | |
2454 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s, | |
2455 size_t, c) | |
2456 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h, | |
2457 const struct kernel_sigset_t*, s, | |
2458 struct kernel_sigset_t*, o, size_t, c); | |
2459 LSS_INLINE _syscall1(int, rt_sigreturn, unsigned long, u); | |
2460 LSS_INLINE _syscall2(int, rt_sigsuspend, | |
2461 const struct kernel_sigset_t*, s, size_t, c); | |
2462 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p, | |
2463 unsigned int, l, unsigned long *, m) | |
2464 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p, | |
2465 unsigned int, l, unsigned long *, m) | |
2466 LSS_INLINE _syscall0(int, sched_yield) | |
2467 LSS_INLINE _syscall1(long, set_tid_address, int *, t) | |
2468 LSS_INLINE _syscall1(int, setfsgid, gid_t, g) | |
2469 LSS_INLINE _syscall1(int, setfsuid, uid_t, u) | |
2470 LSS_INLINE _syscall1(int, setuid, uid_t, u) | |
2471 LSS_INLINE _syscall1(int, setgid, gid_t, g) | |
2472 LSS_INLINE _syscall2(int, setpgid, pid_t, p, | |
2473 pid_t, g) | |
2474 LSS_INLINE _syscall3(int, setpriority, int, a, | |
2475 int, b, int, p) | |
2476 LSS_INLINE _syscall3(int, setresgid, gid_t, r, | |
2477 gid_t, e, gid_t, s) | |
2478 LSS_INLINE _syscall3(int, setresuid, uid_t, r, | |
2479 uid_t, e, uid_t, s) | |
2480 LSS_INLINE _syscall2(int, setrlimit, int, r, | |
2481 const struct kernel_rlimit*, l) | |
2482 LSS_INLINE _syscall0(pid_t, setsid) | |
2483 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s, | |
2484 const stack_t*, o) | |
2485 #if defined(__NR_sigreturn) | |
2486 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u); | |
2487 #endif | |
2488 LSS_INLINE _syscall2(int, stat, const char*, f, | |
2489 struct kernel_stat*, b) | |
2490 LSS_INLINE _syscall2(int, statfs, const char*, f, | |
2491 struct kernel_statfs*, b) | |
2492 LSS_INLINE _syscall3(int, tgkill, pid_t, p, | |
2493 pid_t, t, int, s) | |
2494 LSS_INLINE _syscall2(int, tkill, pid_t, p, | |
2495 int, s) | |
2496 LSS_INLINE _syscall3(ssize_t, write, int, f, | |
2497 const void *, b, size_t, c) | |
2498 LSS_INLINE _syscall3(ssize_t, writev, int, f, | |
2499 const struct kernel_iovec*, v, size_t, c) | |
2500 LSS_INLINE _syscall1(int, unlink, const char*, f) | |
2501 #if defined(__NR_getcpu) | |
2502 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu, | |
2503 unsigned *, node, void *, unused); | |
2504 #endif | |
2505 #if defined(__x86_64__) || \ | |
2506 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) | |
2507 LSS_INLINE _syscall3(int, recvmsg, int, s, | |
2508 struct kernel_msghdr*, m, int, f) | |
2509 LSS_INLINE _syscall3(int, sendmsg, int, s, | |
2510 const struct kernel_msghdr*, m, int, f) | |
2511 LSS_INLINE _syscall6(int, sendto, int, s, | |
2512 const void*, m, size_t, l, | |
2513 int, f, | |
2514 const struct kernel_sockaddr*, a, int, t) | |
2515 LSS_INLINE _syscall2(int, shutdown, int, s, | |
2516 int, h) | |
2517 LSS_INLINE _syscall3(int, socket, int, d, | |
2518 int, t, int, p) | |
2519 LSS_INLINE _syscall4(int, socketpair, int, d, | |
2520 int, t, int, p, int*, s) | |
2521 #endif | |
2522 #if defined(__x86_64__) | |
2523 LSS_INLINE _syscall4(int, fallocate, int, fd, int, mode, | |
2524 loff_t, offset, loff_t, len) | |
2525 | |
2526 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, | |
2527 gid_t *egid, | |
2528 gid_t *sgid) { | |
2529 return LSS_NAME(getresgid)(rgid, egid, sgid); | |
2530 } | |
2531 | |
2532 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, | |
2533 uid_t *euid, | |
2534 uid_t *suid) { | |
2535 return LSS_NAME(getresuid)(ruid, euid, suid); | |
2536 } | |
2537 | |
2538 LSS_INLINE _syscall6(void*, mmap, void*, s, | |
2539 size_t, l, int, p, | |
2540 int, f, int, d, | |
2541 __off64_t, o) | |
2542 | |
2543 LSS_INLINE _syscall4(int, newfstatat, int, d, | |
2544 const char *, p, | |
2545 struct kernel_stat*, b, int, f) | |
2546 | |
2547 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { | |
2548 return LSS_NAME(setfsgid)(gid); | |
2549 } | |
2550 | |
2551 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { | |
2552 return LSS_NAME(setfsuid)(uid); | |
2553 } | |
2554 | |
2555 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { | |
2556 return LSS_NAME(setresgid)(rgid, egid, sgid); | |
2557 } | |
2558 | |
2559 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { | |
2560 return LSS_NAME(setresuid)(ruid, euid, suid); | |
2561 } | |
2562 | |
2563 LSS_INLINE int LSS_NAME(sigaction)(int signum, | |
2564 const struct kernel_sigaction *act, | |
2565 struct kernel_sigaction *oldact) { | |
2566 /* On x86_64, the kernel requires us to always set our own | |
2567 * SA_RESTORER in order to be able to return from a signal handler. | |
2568 * This function must have a "magic" signature that the "gdb" | |
2569 * (and maybe the kernel?) can recognize. | |
2570 */ | |
2571 if (act != NULL && !(act->sa_flags & SA_RESTORER)) { | |
2572 struct kernel_sigaction a = *act; | |
2573 a.sa_flags |= SA_RESTORER; | |
2574 a.sa_restorer = LSS_NAME(restore_rt)(); | |
2575 return LSS_NAME(rt_sigaction)(signum, &a, oldact, | |
2576 (KERNEL_NSIG+7)/8); | |
2577 } else { | |
2578 return LSS_NAME(rt_sigaction)(signum, act, oldact, | |
2579 (KERNEL_NSIG+7)/8); | |
2580 } | |
2581 } | |
2582 | |
2583 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { | |
2584 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); | |
2585 } | |
2586 | |
2587 LSS_INLINE int LSS_NAME(sigprocmask)(int how, | |
2588 const struct kernel_sigset_t *set, | |
2589 struct kernel_sigset_t *oldset) { | |
2590 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); | |
2591 } | |
2592 | |
2593 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { | |
2594 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); | |
2595 } | |
2596 #endif | |
2597 #if defined(__x86_64__) || defined(__ARM_ARCH_3__) || \ | |
2598 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) | |
2599 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p, | |
2600 int*, s, int, o, | |
2601 struct kernel_rusage*, r) | |
2602 | |
2603 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){ | |
2604 return LSS_NAME(wait4)(pid, status, options, 0); | |
2605 } | |
2606 #endif | |
2607 #if defined(__i386__) || defined(__x86_64__) | |
2608 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m) | |
2609 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f) | |
2610 #endif | |
2611 #if defined(__i386__) || defined(__ARM_ARCH_3__) | |
2612 #define __NR__getresgid32 __NR_getresgid32 | |
2613 #define __NR__getresuid32 __NR_getresuid32 | |
2614 #define __NR__setfsgid32 __NR_setfsgid32 | |
2615 #define __NR__setfsuid32 __NR_setfsuid32 | |
2616 #define __NR__setresgid32 __NR_setresgid32 | |
2617 #define __NR__setresuid32 __NR_setresuid32 | |
2618 LSS_INLINE _syscall2(int, ugetrlimit, int, r, | |
2619 struct kernel_rlimit*, l) | |
2620 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r, | |
2621 gid_t *, e, gid_t *, s) | |
2622 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r, | |
2623 uid_t *, e, uid_t *, s) | |
2624 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f) | |
2625 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f) | |
2626 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r, | |
2627 gid_t, e, gid_t, s) | |
2628 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r, | |
2629 uid_t, e, uid_t, s) | |
2630 | |
2631 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, | |
2632 gid_t *egid, | |
2633 gid_t *sgid) { | |
2634 int rc; | |
2635 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 && | |
2636 LSS_ERRNO == ENOSYS) { | |
2637 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) { | |
2638 return EFAULT; | |
2639 } | |
2640 // Clear the high bits first, since getresgid only sets 16 bits | |
2641 *rgid = *egid = *sgid = 0; | |
2642 rc = LSS_NAME(getresgid)(rgid, egid, sgid); | |
2643 } | |
2644 return rc; | |
2645 } | |
2646 | |
2647 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, | |
2648 uid_t *euid, | |
2649 uid_t *suid) { | |
2650 int rc; | |
2651 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 && | |
2652 LSS_ERRNO == ENOSYS) { | |
2653 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) { | |
2654 return EFAULT; | |
2655 } | |
2656 // Clear the high bits first, since getresuid only sets 16 bits | |
2657 *ruid = *euid = *suid = 0; | |
2658 rc = LSS_NAME(getresuid)(ruid, euid, suid); | |
2659 } | |
2660 return rc; | |
2661 } | |
2662 | |
2663 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { | |
2664 int rc; | |
2665 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 && | |
2666 LSS_ERRNO == ENOSYS) { | |
2667 if ((unsigned int)gid & ~0xFFFFu) { | |
2668 rc = EINVAL; | |
2669 } else { | |
2670 rc = LSS_NAME(setfsgid)(gid); | |
2671 } | |
2672 } | |
2673 return rc; | |
2674 } | |
2675 | |
2676 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { | |
2677 int rc; | |
2678 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 && | |
2679 LSS_ERRNO == ENOSYS) { | |
2680 if ((unsigned int)uid & ~0xFFFFu) { | |
2681 rc = EINVAL; | |
2682 } else { | |
2683 rc = LSS_NAME(setfsuid)(uid); | |
2684 } | |
2685 } | |
2686 return rc; | |
2687 } | |
2688 | |
2689 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { | |
2690 int rc; | |
2691 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 && | |
2692 LSS_ERRNO == ENOSYS) { | |
2693 if ((unsigned int)rgid & ~0xFFFFu || | |
2694 (unsigned int)egid & ~0xFFFFu || | |
2695 (unsigned int)sgid & ~0xFFFFu) { | |
2696 rc = EINVAL; | |
2697 } else { | |
2698 rc = LSS_NAME(setresgid)(rgid, egid, sgid); | |
2699 } | |
2700 } | |
2701 return rc; | |
2702 } | |
2703 | |
2704 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { | |
2705 int rc; | |
2706 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 && | |
2707 LSS_ERRNO == ENOSYS) { | |
2708 if ((unsigned int)ruid & ~0xFFFFu || | |
2709 (unsigned int)euid & ~0xFFFFu || | |
2710 (unsigned int)suid & ~0xFFFFu) { | |
2711 rc = EINVAL; | |
2712 } else { | |
2713 rc = LSS_NAME(setresuid)(ruid, euid, suid); | |
2714 } | |
2715 } | |
2716 return rc; | |
2717 } | |
2718 #endif | |
2719 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) { | |
2720 memset(&set->sig, 0, sizeof(set->sig)); | |
2721 return 0; | |
2722 } | |
2723 | |
2724 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) { | |
2725 memset(&set->sig, -1, sizeof(set->sig)); | |
2726 return 0; | |
2727 } | |
2728 | |
2729 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set, | |
2730 int signum) { | |
2731 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { | |
2732 LSS_ERRNO = EINVAL; | |
2733 return -1; | |
2734 } else { | |
2735 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] | |
2736 |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0]))); | |
2737 return 0; | |
2738 } | |
2739 } | |
2740 | |
2741 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set, | |
2742 int signum) { | |
2743 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { | |
2744 LSS_ERRNO = EINVAL; | |
2745 return -1; | |
2746 } else { | |
2747 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] | |
2748 &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0])))); | |
2749 return 0; | |
2750 } | |
2751 } | |
2752 | |
2753 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set, | |
2754 int signum) { | |
2755 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { | |
2756 LSS_ERRNO = EINVAL; | |
2757 return -1; | |
2758 } else { | |
2759 return !!(set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] & | |
2760 (1UL << ((signum - 1) % (8*sizeof(set->sig[0]))))); | |
2761 } | |
2762 } | |
2763 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ | |
2764 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || defined(__PPC__) | |
2765 #define __NR__sigaction __NR_sigaction | |
2766 #define __NR__sigpending __NR_sigpending | |
2767 #define __NR__sigprocmask __NR_sigprocmask | |
2768 #define __NR__sigsuspend __NR_sigsuspend | |
2769 #define __NR__socketcall __NR_socketcall | |
2770 LSS_INLINE _syscall2(int, fstat64, int, f, | |
2771 struct kernel_stat64 *, b) | |
2772 LSS_INLINE _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, | |
2773 loff_t *, res, uint, wh) | |
2774 LSS_INLINE _syscall1(void*, mmap, void*, a) | |
2775 LSS_INLINE _syscall6(void*, mmap2, void*, s, | |
2776 size_t, l, int, p, | |
2777 int, f, int, d, | |
2778 __off64_t, o) | |
2779 LSS_INLINE _syscall3(int, _sigaction, int, s, | |
2780 const struct kernel_old_sigaction*, a, | |
2781 struct kernel_old_sigaction*, o) | |
2782 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s) | |
2783 LSS_INLINE _syscall3(int, _sigprocmask, int, h, | |
2784 const unsigned long*, s, | |
2785 unsigned long*, o) | |
2786 #ifdef __PPC__ | |
2787 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s) | |
2788 #else | |
2789 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a, | |
2790 int, b, | |
2791 unsigned long, s) | |
2792 #endif | |
2793 LSS_INLINE _syscall2(int, stat64, const char *, p, | |
2794 struct kernel_stat64 *, b) | |
2795 | |
2796 LSS_INLINE int LSS_NAME(sigaction)(int signum, | |
2797 const struct kernel_sigaction *act, | |
2798 struct kernel_sigaction *oldact) { | |
2799 int old_errno = LSS_ERRNO; | |
2800 int rc; | |
2801 struct kernel_sigaction a; | |
2802 if (act != NULL) { | |
2803 a = *act; | |
2804 #ifdef __i386__ | |
2805 /* On i386, the kernel requires us to always set our own | |
2806 * SA_RESTORER when using realtime signals. Otherwise, it does not | |
2807 * know how to return from a signal handler. This function must have | |
2808 * a "magic" signature that the "gdb" (and maybe the kernel?) can | |
2809 * recognize. | |
2810 * Apparently, a SA_RESTORER is implicitly set by the kernel, when | |
2811 * using non-realtime signals. | |
2812 * | |
2813 * TODO: Test whether ARM needs a restorer | |
2814 */ | |
2815 if (!(a.sa_flags & SA_RESTORER)) { | |
2816 a.sa_flags |= SA_RESTORER; | |
2817 a.sa_restorer = (a.sa_flags & SA_SIGINFO) | |
2818 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)(); | |
2819 } | |
2820 #endif | |
2821 } | |
2822 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact, | |
2823 (KERNEL_NSIG+7)/8); | |
2824 if (rc < 0 && LSS_ERRNO == ENOSYS) { | |
2825 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa; | |
2826 if (!act) { | |
2827 ptr_a = NULL; | |
2828 } else { | |
2829 oa.sa_handler_ = act->sa_handler_; | |
2830 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask)); | |
2831 #ifndef __mips__ | |
2832 oa.sa_restorer = act->sa_restorer; | |
2833 #endif | |
2834 oa.sa_flags = act->sa_flags; | |
2835 } | |
2836 if (!oldact) { | |
2837 ptr_oa = NULL; | |
2838 } | |
2839 LSS_ERRNO = old_errno; | |
2840 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa); | |
2841 if (rc == 0 && oldact) { | |
2842 if (act) { | |
2843 memcpy(oldact, act, sizeof(*act)); | |
2844 } else { | |
2845 memset(oldact, 0, sizeof(*oldact)); | |
2846 } | |
2847 oldact->sa_handler_ = ptr_oa->sa_handler_; | |
2848 oldact->sa_flags = ptr_oa->sa_flags; | |
2849 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask)); | |
2850 #ifndef __mips__ | |
2851 oldact->sa_restorer = ptr_oa->sa_restorer; | |
2852 #endif | |
2853 } | |
2854 } | |
2855 return rc; | |
2856 } | |
2857 | |
2858 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { | |
2859 int old_errno = LSS_ERRNO; | |
2860 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); | |
2861 if (rc < 0 && LSS_ERRNO == ENOSYS) { | |
2862 LSS_ERRNO = old_errno; | |
2863 LSS_NAME(sigemptyset)(set); | |
2864 rc = LSS_NAME(_sigpending)(&set->sig[0]); | |
2865 } | |
2866 return rc; | |
2867 } | |
2868 | |
2869 LSS_INLINE int LSS_NAME(sigprocmask)(int how, | |
2870 const struct kernel_sigset_t *set, | |
2871 struct kernel_sigset_t *oldset) { | |
2872 int olderrno = LSS_ERRNO; | |
2873 int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); | |
2874 if (rc < 0 && LSS_ERRNO == ENOSYS) { | |
2875 LSS_ERRNO = olderrno; | |
2876 if (oldset) { | |
2877 LSS_NAME(sigemptyset)(oldset); | |
2878 } | |
2879 rc = LSS_NAME(_sigprocmask)(how, | |
2880 set ? &set->sig[0] : NULL, | |
2881 oldset ? &oldset->sig[0] : NULL); | |
2882 } | |
2883 return rc; | |
2884 } | |
2885 | |
2886 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { | |
2887 int olderrno = LSS_ERRNO; | |
2888 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); | |
2889 if (rc < 0 && LSS_ERRNO == ENOSYS) { | |
2890 LSS_ERRNO = olderrno; | |
2891 rc = LSS_NAME(_sigsuspend)( | |
2892 #ifndef __PPC__ | |
2893 set, 0, | |
2894 #endif | |
2895 set->sig[0]); | |
2896 } | |
2897 return rc; | |
2898 } | |
2899 #endif | |
2900 #if defined(__PPC__) | |
2901 #undef LSS_SC_LOADARGS_0 | |
2902 #define LSS_SC_LOADARGS_0(dummy...) | |
2903 #undef LSS_SC_LOADARGS_1 | |
2904 #define LSS_SC_LOADARGS_1(arg1) \ | |
2905 __sc_4 = (unsigned long) (arg1) | |
2906 #undef LSS_SC_LOADARGS_2 | |
2907 #define LSS_SC_LOADARGS_2(arg1, arg2) \ | |
2908 LSS_SC_LOADARGS_1(arg1); \ | |
2909 __sc_5 = (unsigned long) (arg2) | |
2910 #undef LSS_SC_LOADARGS_3 | |
2911 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \ | |
2912 LSS_SC_LOADARGS_2(arg1, arg2); \ | |
2913 __sc_6 = (unsigned long) (arg3) | |
2914 #undef LSS_SC_LOADARGS_4 | |
2915 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \ | |
2916 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \ | |
2917 __sc_7 = (unsigned long) (arg4) | |
2918 #undef LSS_SC_LOADARGS_5 | |
2919 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \ | |
2920 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \ | |
2921 __sc_8 = (unsigned long) (arg5) | |
2922 #undef LSS_SC_BODY | |
2923 #define LSS_SC_BODY(nr, type, opt, args...) \ | |
2924 long __sc_ret, __sc_err; \ | |
2925 { \ | |
2926 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \ | |
2927 register unsigned long __sc_3 __asm__ ("r3") = opt; \ | |
2928 register unsigned long __sc_4 __asm__ ("r4"); \ | |
2929 register unsigned long __sc_5 __asm__ ("r5"); \ | |
2930 register unsigned long __sc_6 __asm__ ("r6"); \ | |
2931 register unsigned long __sc_7 __asm__ ("r7"); \ | |
2932 register unsigned long __sc_8 __asm__ ("r8"); \ | |
2933 LSS_SC_LOADARGS_##nr(args); \ | |
2934 __asm__ __volatile__ \ | |
2935 ("stwu 1, -48(1)\n\t" \ | |
2936 "stw 4, 20(1)\n\t" \ | |
2937 "stw 5, 24(1)\n\t" \ | |
2938 "stw 6, 28(1)\n\t" \ | |
2939 "stw 7, 32(1)\n\t" \ | |
2940 "stw 8, 36(1)\n\t" \ | |
2941 "addi 4, 1, 20\n\t" \ | |
2942 "sc\n\t" \ | |
2943 "mfcr %0" \ | |
2944 : "=&r" (__sc_0), \ | |
2945 "=&r" (__sc_3), "=&r" (__sc_4), \ | |
2946 "=&r" (__sc_5), "=&r" (__sc_6), \ | |
2947 "=&r" (__sc_7), "=&r" (__sc_8) \ | |
2948 : LSS_ASMINPUT_##nr \ | |
2949 : "cr0", "ctr", "memory"); \ | |
2950 __sc_ret = __sc_3; \ | |
2951 __sc_err = __sc_0; \ | |
2952 } \ | |
2953 LSS_RETURN(type, __sc_ret, __sc_err) | |
2954 | |
2955 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, | |
2956 int flags){ | |
2957 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags); | |
2958 } | |
2959 | |
2960 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, | |
2961 const struct kernel_msghdr *msg, | |
2962 int flags) { | |
2963 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags); | |
2964 } | |
2965 | |
2966 // TODO(csilvers): why is this ifdef'ed out? | |
2967 #if 0 | |
2968 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, | |
2969 int flags, | |
2970 const struct kernel_sockaddr *to, | |
2971 unsigned int tolen) { | |
2972 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen); | |
2973 } | |
2974 #endif | |
2975 | |
2976 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { | |
2977 LSS_SC_BODY(2, int, 13, s, how); | |
2978 } | |
2979 | |
2980 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { | |
2981 LSS_SC_BODY(3, int, 1, domain, type, protocol); | |
2982 } | |
2983 | |
2984 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, | |
2985 int sv[2]) { | |
2986 LSS_SC_BODY(4, int, 8, d, type, protocol, sv); | |
2987 } | |
2988 #endif | |
2989 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ | |
2990 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) | |
2991 #define __NR__socketcall __NR_socketcall | |
2992 LSS_INLINE _syscall2(int, _socketcall, int, c, | |
2993 va_list, a) | |
2994 | |
2995 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) { | |
2996 int rc; | |
2997 va_list ap; | |
2998 va_start(ap, op); | |
2999 rc = LSS_NAME(_socketcall)(op, ap); | |
3000 va_end(ap); | |
3001 return rc; | |
3002 } | |
3003 | |
3004 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, | |
3005 int flags){ | |
3006 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags); | |
3007 } | |
3008 | |
3009 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, | |
3010 const struct kernel_msghdr *msg, | |
3011 int flags) { | |
3012 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags); | |
3013 } | |
3014 | |
3015 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, | |
3016 int flags, | |
3017 const struct kernel_sockaddr *to, | |
3018 unsigned int tolen) { | |
3019 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen); | |
3020 } | |
3021 | |
3022 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { | |
3023 return LSS_NAME(socketcall)(13, s, how); | |
3024 } | |
3025 | |
3026 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { | |
3027 return LSS_NAME(socketcall)(1, domain, type, protocol); | |
3028 } | |
3029 | |
3030 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, | |
3031 int sv[2]) { | |
3032 return LSS_NAME(socketcall)(8, d, type, protocol, sv); | |
3033 } | |
3034 #endif | |
3035 #if defined(__i386__) || defined(__PPC__) | |
3036 LSS_INLINE _syscall4(int, fstatat64, int, d, | |
3037 const char *, p, | |
3038 struct kernel_stat64 *, b, int, f) | |
3039 #endif | |
3040 #if defined(__i386__) || defined(__PPC__) || \ | |
3041 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) | |
3042 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p, | |
3043 int*, s, int, o) | |
3044 #endif | |
3045 #if defined(__mips__) | |
3046 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns | |
3047 * both file handles through CPU registers. | |
3048 */ | |
3049 LSS_INLINE int LSS_NAME(pipe)(int *p) { | |
3050 register unsigned long __v0 __asm__("$2") = __NR_pipe; | |
3051 register unsigned long __v1 __asm__("$3"); | |
3052 register unsigned long __r7 __asm__("$7"); | |
3053 __asm__ __volatile__ ("syscall\n" | |
3054 : "=&r"(__v0), "=&r"(__v1), "+r" (__r7) | |
3055 : "0"(__v0) | |
3056 : "$8", "$9", "$10", "$11", "$12", | |
3057 "$13", "$14", "$15", "$24", "memory"); | |
3058 if (__r7) { | |
3059 LSS_ERRNO = __v0; | |
3060 return -1; | |
3061 } else { | |
3062 p[0] = __v0; | |
3063 p[1] = __v1; | |
3064 return 0; | |
3065 } | |
3066 } | |
3067 #else | |
3068 LSS_INLINE _syscall1(int, pipe, int *, p) | |
3069 #endif | |
3070 /* TODO(csilvers): see if ppc can/should support this as well */ | |
3071 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ | |
3072 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) | |
3073 #define __NR__statfs64 __NR_statfs64 | |
3074 #define __NR__fstatfs64 __NR_fstatfs64 | |
3075 LSS_INLINE _syscall3(int, _statfs64, const char*, p, | |
3076 size_t, s,struct kernel_statfs64*, b) | |
3077 LSS_INLINE _syscall3(int, _fstatfs64, int, f, | |
3078 size_t, s,struct kernel_statfs64*, b) | |
3079 LSS_INLINE int LSS_NAME(statfs64)(const char *p, | |
3080 struct kernel_statfs64 *b) { | |
3081 return LSS_NAME(_statfs64)(p, sizeof(*b), b); | |
3082 } | |
3083 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) { | |
3084 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b); | |
3085 } | |
3086 #endif | |
3087 | |
3088 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) { | |
3089 extern char **environ; | |
3090 return LSS_NAME(execve)(path, argv, (const char *const *)environ); | |
3091 } | |
3092 | |
3093 LSS_INLINE pid_t LSS_NAME(gettid)() { | |
3094 pid_t tid = LSS_NAME(_gettid)(); | |
3095 if (tid != -1) { | |
3096 return tid; | |
3097 } | |
3098 return LSS_NAME(getpid)(); | |
3099 } | |
3100 | |
3101 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size, | |
3102 size_t new_size, int flags, ...) { | |
3103 va_list ap; | |
3104 void *new_address, *rc; | |
3105 va_start(ap, flags); | |
3106 new_address = va_arg(ap, void *); | |
3107 rc = LSS_NAME(_mremap)(old_address, old_size, new_size, | |
3108 flags, new_address); | |
3109 va_end(ap); | |
3110 return rc; | |
3111 } | |
3112 | |
3113 LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) { | |
3114 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it | |
3115 * then sends job control signals to the real parent, rather than to | |
3116 * the tracer. We reduce the risk of this happening by starting a | |
3117 * whole new time slice, and then quickly sending a SIGCONT signal | |
3118 * right after detaching from the tracee. | |
3119 * | |
3120 * We use tkill to ensure that we only issue a wakeup for the thread being | |
3121 * detached. Large multi threaded apps can take a long time in the kernel | |
3122 * processing SIGCONT. | |
3123 */ | |
3124 int rc, err; | |
3125 LSS_NAME(sched_yield)(); | |
3126 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0); | |
3127 err = LSS_ERRNO; | |
3128 LSS_NAME(tkill)(pid, SIGCONT); | |
3129 /* Old systems don't have tkill */ | |
3130 if (LSS_ERRNO == ENOSYS) | |
3131 LSS_NAME(kill)(pid, SIGCONT); | |
3132 LSS_ERRNO = err; | |
3133 return rc; | |
3134 } | |
3135 | |
3136 LSS_INLINE int LSS_NAME(raise)(int sig) { | |
3137 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig); | |
3138 } | |
3139 | |
3140 LSS_INLINE int LSS_NAME(setpgrp)() { | |
3141 return LSS_NAME(setpgid)(0, 0); | |
3142 } | |
3143 | |
3144 LSS_INLINE int LSS_NAME(sysconf)(int name) { | |
3145 extern int __getpagesize(void); | |
3146 switch (name) { | |
3147 case _SC_OPEN_MAX: { | |
3148 struct kernel_rlimit limit; | |
3149 return LSS_NAME(getrlimit)(RLIMIT_NOFILE, &limit) < 0 | |
3150 ? 8192 : limit.rlim_cur; | |
3151 } | |
3152 case _SC_PAGESIZE: | |
3153 return __getpagesize(); | |
3154 default: | |
3155 LSS_ERRNO = ENOSYS; | |
3156 return -1; | |
3157 } | |
3158 } | |
3159 #if defined(__x86_64__) || \ | |
3160 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64) | |
3161 LSS_INLINE _syscall4(ssize_t, pread64, int, f, | |
3162 void *, b, size_t, c, | |
3163 loff_t, o) | |
3164 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f, | |
3165 const void *, b, size_t, c, | |
3166 loff_t, o) | |
3167 LSS_INLINE _syscall3(int, readahead, int, f, | |
3168 loff_t, o, unsigned, c) | |
3169 #else | |
3170 #define __NR__pread64 __NR_pread64 | |
3171 #define __NR__pwrite64 __NR_pwrite64 | |
3172 #define __NR__readahead __NR_readahead | |
3173 LSS_INLINE _syscall5(ssize_t, _pread64, int, f, | |
3174 void *, b, size_t, c, unsigned, o1, | |
3175 unsigned, o2) | |
3176 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f, | |
3177 const void *, b, size_t, c, unsigned, o1, | |
3178 long, o2) | |
3179 LSS_INLINE _syscall4(int, _readahead, int, f, | |
3180 unsigned, o1, unsigned, o2, size_t, c); | |
3181 /* We force 64bit-wide parameters onto the stack, then access each | |
3182 * 32-bit component individually. This guarantees that we build the | |
3183 * correct parameters independent of the native byte-order of the | |
3184 * underlying architecture. | |
3185 */ | |
3186 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count, | |
3187 loff_t off) { | |
3188 union { loff_t off; unsigned arg[2]; } o = { off }; | |
3189 return LSS_NAME(_pread64)(fd, buf, count, o.arg[0], o.arg[1]); | |
3190 } | |
3191 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf, | |
3192 size_t count, loff_t off) { | |
3193 union { loff_t off; unsigned arg[2]; } o = { off }; | |
3194 return LSS_NAME(_pwrite64)(fd, buf, count, o.arg[0], o.arg[1]); | |
3195 } | |
3196 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) { | |
3197 union { loff_t off; unsigned arg[2]; } o = { off }; | |
3198 return LSS_NAME(_readahead)(fd, o.arg[0], o.arg[1], len); | |
3199 } | |
3200 #endif | |
3201 #endif | |
3202 | |
3203 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) | |
3204 } | |
3205 #endif | |
3206 | |
3207 #endif | |
3208 #endif | |
OLD | NEW |