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