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