blob: 8a42c1c8687b2af252811c28581cabfd89a3a3ae [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__) || \
anton@chromium.org2f724fc2014-04-15 13:05:20 +000089 defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__) || \
90 defined(__aarch64__)) \
zodiac@gmail.com4f470182010-10-13 03:47:54 +000091 && (defined(__linux) || defined(__ANDROID__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000092
93#ifndef SYS_CPLUSPLUS
94#ifdef __cplusplus
95/* Some system header files in older versions of gcc neglect to properly
96 * handle being included from C++. As it appears to be harmless to have
97 * multiple nested 'extern "C"' blocks, just add another one here.
98 */
99extern "C" {
100#endif
101
102#include <errno.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000103#include <fcntl.h>
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000104#include <sched.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000105#include <signal.h>
106#include <stdarg.h>
107#include <stddef.h>
vapier@chromium.org2273e812013-04-01 17:52:44 +0000108#include <stdint.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000109#include <string.h>
110#include <sys/ptrace.h>
111#include <sys/resource.h>
112#include <sys/time.h>
113#include <sys/types.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000114#include <sys/syscall.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000115#include <unistd.h>
116#include <linux/unistd.h>
117#include <endian.h>
118
119#ifdef __mips__
120/* Include definitions of the ABI currently in use. */
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000121#ifdef __ANDROID__
122/* Android doesn't have sgidefs.h, but does have asm/sgidefs.h,
123 * which has the definitions we need.
124 */
125#include <asm/sgidefs.h>
126#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000127#include <sgidefs.h>
128#endif
129#endif
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000130#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000131
mseaborn@chromium.orgca749372012-09-05 18:26:20 +0000132/* The Android NDK's <sys/stat.h> #defines these macros as aliases
133 * to their non-64 counterparts. To avoid naming conflict, remove them. */
134#ifdef __ANDROID__
135 /* These are restored by the corresponding #pragma pop_macro near
136 * the end of this file. */
137# pragma push_macro("stat64")
138# pragma push_macro("fstat64")
139# pragma push_macro("lstat64")
140# undef stat64
141# undef fstat64
142# undef lstat64
143#endif
144
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000145/* As glibc often provides subtly incompatible data structures (and implicit
146 * wrapper functions that convert them), we provide our own kernel data
147 * structures for use by the system calls.
148 * These structures have been developed by using Linux 2.6.23 headers for
149 * reference. Note though, we do not care about exact API compatibility
150 * with the kernel, and in fact the kernel often does not have a single
151 * API that works across architectures. Instead, we try to mimic the glibc
152 * API where reasonable, and only guarantee ABI compatibility with the
153 * kernel headers.
154 * Most notably, here are a few changes that were made to the structures
155 * defined by kernel headers:
156 *
157 * - we only define structures, but not symbolic names for kernel data
158 * types. For the latter, we directly use the native C datatype
159 * (i.e. "unsigned" instead of "mode_t").
160 * - in a few cases, it is possible to define identical structures for
161 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
162 * standardizing on the 64bit version of the data types. In particular,
163 * this means that we use "unsigned" where the 32bit headers say
164 * "unsigned long".
165 * - overall, we try to minimize the number of cases where we need to
166 * conditionally define different structures.
167 * - the "struct kernel_sigaction" class of structures have been
168 * modified to more closely mimic glibc's API by introducing an
169 * anonymous union for the function pointer.
170 * - a small number of field names had to have an underscore appended to
171 * them, because glibc defines a global macro by the same name.
172 */
173
174/* include/linux/dirent.h */
175struct kernel_dirent64 {
176 unsigned long long d_ino;
177 long long d_off;
178 unsigned short d_reclen;
179 unsigned char d_type;
180 char d_name[256];
181};
182
183/* include/linux/dirent.h */
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000184#if defined(__aarch64__)
185// aarch64 only defines dirent64, just uses that for dirent too.
186#define kernel_dirent kernel_dirent64
187#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000188struct kernel_dirent {
189 long d_ino;
190 long d_off;
191 unsigned short d_reclen;
192 char d_name[256];
193};
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000194#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000195
196/* include/linux/uio.h */
197struct kernel_iovec {
198 void *iov_base;
199 unsigned long iov_len;
200};
201
202/* include/linux/socket.h */
203struct kernel_msghdr {
204 void *msg_name;
205 int msg_namelen;
206 struct kernel_iovec*msg_iov;
207 unsigned long msg_iovlen;
208 void *msg_control;
209 unsigned long msg_controllen;
210 unsigned msg_flags;
211};
212
213/* include/asm-generic/poll.h */
214struct kernel_pollfd {
215 int fd;
216 short events;
217 short revents;
218};
219
220/* include/linux/resource.h */
221struct kernel_rlimit {
222 unsigned long rlim_cur;
223 unsigned long rlim_max;
224};
225
226/* include/linux/time.h */
227struct kernel_timespec {
228 long tv_sec;
229 long tv_nsec;
230};
231
232/* include/linux/time.h */
233struct kernel_timeval {
234 long tv_sec;
235 long tv_usec;
236};
237
238/* include/linux/resource.h */
239struct kernel_rusage {
240 struct kernel_timeval ru_utime;
241 struct kernel_timeval ru_stime;
242 long ru_maxrss;
243 long ru_ixrss;
244 long ru_idrss;
245 long ru_isrss;
246 long ru_minflt;
247 long ru_majflt;
248 long ru_nswap;
249 long ru_inblock;
250 long ru_oublock;
251 long ru_msgsnd;
252 long ru_msgrcv;
253 long ru_nsignals;
254 long ru_nvcsw;
255 long ru_nivcsw;
256};
257
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000258#if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \
259 || defined(__PPC__)
260
261/* include/asm-{arm,i386,mips,ppc}/signal.h */
262struct kernel_old_sigaction {
263 union {
264 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000265 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000266 };
267 unsigned long sa_mask;
268 unsigned long sa_flags;
269 void (*sa_restorer)(void);
270} __attribute__((packed,aligned(4)));
271#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
272 #define kernel_old_sigaction kernel_sigaction
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000273#elif defined(__aarch64__)
274 // No kernel_old_sigaction defined for arm64.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000275#endif
276
277/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
278 * exactly match the size of the signal set, even though the API was
279 * intended to be extensible. We define our own KERNEL_NSIG to deal with
280 * this.
281 * Please note that glibc provides signals [1.._NSIG-1], whereas the
282 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
283 * actual number of signals is obviously the same, but the constants
284 * differ by one.
285 */
286#ifdef __mips__
287#define KERNEL_NSIG 128
288#else
289#define KERNEL_NSIG 64
290#endif
291
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000292/* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000293struct kernel_sigset_t {
294 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
295 (8*sizeof(unsigned long))];
296};
297
298/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */
299struct kernel_sigaction {
300#ifdef __mips__
301 unsigned long sa_flags;
302 union {
303 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000304 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000305 };
306 struct kernel_sigset_t sa_mask;
307#else
308 union {
309 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000310 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000311 };
312 unsigned long sa_flags;
313 void (*sa_restorer)(void);
314 struct kernel_sigset_t sa_mask;
315#endif
316};
317
318/* include/linux/socket.h */
319struct kernel_sockaddr {
320 unsigned short sa_family;
321 char sa_data[14];
322};
323
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000324/* include/asm-{arm,aarch64,i386,mips,ppc}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000325#ifdef __mips__
326#if _MIPS_SIM == _MIPS_SIM_ABI64
327struct kernel_stat {
328#else
329struct kernel_stat64 {
330#endif
331 unsigned st_dev;
332 unsigned __pad0[3];
333 unsigned long long st_ino;
334 unsigned st_mode;
335 unsigned st_nlink;
336 unsigned st_uid;
337 unsigned st_gid;
338 unsigned st_rdev;
339 unsigned __pad1[3];
340 long long st_size;
341 unsigned st_atime_;
342 unsigned st_atime_nsec_;
343 unsigned st_mtime_;
344 unsigned st_mtime_nsec_;
345 unsigned st_ctime_;
346 unsigned st_ctime_nsec_;
347 unsigned st_blksize;
348 unsigned __pad2;
349 unsigned long long st_blocks;
350};
351#elif defined __PPC__
352struct kernel_stat64 {
353 unsigned long long st_dev;
354 unsigned long long st_ino;
355 unsigned st_mode;
356 unsigned st_nlink;
357 unsigned st_uid;
358 unsigned st_gid;
359 unsigned long long st_rdev;
360 unsigned short int __pad2;
361 long long st_size;
362 long st_blksize;
363 long long st_blocks;
364 long st_atime_;
365 unsigned long st_atime_nsec_;
366 long st_mtime_;
367 unsigned long st_mtime_nsec_;
368 long st_ctime_;
369 unsigned long st_ctime_nsec_;
370 unsigned long __unused4;
371 unsigned long __unused5;
372};
373#else
374struct kernel_stat64 {
375 unsigned long long st_dev;
376 unsigned char __pad0[4];
377 unsigned __st_ino;
378 unsigned st_mode;
379 unsigned st_nlink;
380 unsigned st_uid;
381 unsigned st_gid;
382 unsigned long long st_rdev;
383 unsigned char __pad3[4];
384 long long st_size;
385 unsigned st_blksize;
386 unsigned long long st_blocks;
387 unsigned st_atime_;
388 unsigned st_atime_nsec_;
389 unsigned st_mtime_;
390 unsigned st_mtime_nsec_;
391 unsigned st_ctime_;
392 unsigned st_ctime_nsec_;
393 unsigned long long st_ino;
394};
395#endif
396
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000397/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000398#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
399struct kernel_stat {
400 /* The kernel headers suggest that st_dev and st_rdev should be 32bit
401 * quantities encoding 12bit major and 20bit minor numbers in an interleaved
402 * format. In reality, we do not see useful data in the top bits. So,
403 * we'll leave the padding in here, until we find a better solution.
404 */
405 unsigned short st_dev;
406 short pad1;
407 unsigned st_ino;
408 unsigned short st_mode;
409 unsigned short st_nlink;
410 unsigned short st_uid;
411 unsigned short st_gid;
412 unsigned short st_rdev;
413 short pad2;
414 unsigned st_size;
415 unsigned st_blksize;
416 unsigned st_blocks;
417 unsigned st_atime_;
418 unsigned st_atime_nsec_;
419 unsigned st_mtime_;
420 unsigned st_mtime_nsec_;
421 unsigned st_ctime_;
422 unsigned st_ctime_nsec_;
423 unsigned __unused4;
424 unsigned __unused5;
425};
426#elif defined(__x86_64__)
427struct kernel_stat {
vapier@chromium.org2273e812013-04-01 17:52:44 +0000428 uint64_t st_dev;
429 uint64_t st_ino;
430 uint64_t st_nlink;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000431 unsigned st_mode;
432 unsigned st_uid;
433 unsigned st_gid;
434 unsigned __pad0;
vapier@chromium.org2273e812013-04-01 17:52:44 +0000435 uint64_t st_rdev;
436 int64_t st_size;
437 int64_t st_blksize;
438 int64_t st_blocks;
439 uint64_t st_atime_;
440 uint64_t st_atime_nsec_;
441 uint64_t st_mtime_;
442 uint64_t st_mtime_nsec_;
443 uint64_t st_ctime_;
444 uint64_t st_ctime_nsec_;
anton@chromium.org43de0522014-04-04 11:20:46 +0000445 int64_t __unused4[3];
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000446};
447#elif defined(__PPC__)
448struct kernel_stat {
449 unsigned st_dev;
450 unsigned long st_ino; // ino_t
451 unsigned long st_mode; // mode_t
452 unsigned short st_nlink; // nlink_t
453 unsigned st_uid; // uid_t
454 unsigned st_gid; // gid_t
455 unsigned st_rdev;
456 long st_size; // off_t
457 unsigned long st_blksize;
458 unsigned long st_blocks;
459 unsigned long st_atime_;
460 unsigned long st_atime_nsec_;
461 unsigned long st_mtime_;
462 unsigned long st_mtime_nsec_;
463 unsigned long st_ctime_;
464 unsigned long st_ctime_nsec_;
465 unsigned long __unused4;
466 unsigned long __unused5;
467};
468#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
469struct kernel_stat {
470 unsigned st_dev;
471 int st_pad1[3];
472 unsigned st_ino;
473 unsigned st_mode;
474 unsigned st_nlink;
475 unsigned st_uid;
476 unsigned st_gid;
477 unsigned st_rdev;
478 int st_pad2[2];
479 long st_size;
480 int st_pad3;
481 long st_atime_;
482 long st_atime_nsec_;
483 long st_mtime_;
484 long st_mtime_nsec_;
485 long st_ctime_;
486 long st_ctime_nsec_;
487 int st_blksize;
488 int st_blocks;
489 int st_pad4[14];
490};
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000491#elif defined(__aarch64__)
492struct kernel_stat {
493 unsigned long st_dev;
494 unsigned long st_ino;
495 unsigned int st_mode;
496 unsigned int st_nlink;
497 unsigned int st_uid;
498 unsigned int st_gid;
499 unsigned long st_rdev;
500 unsigned long __pad1;
501 long st_size;
502 int st_blksize;
503 int __pad2;
504 long st_blocks;
505 long st_atime_;
506 unsigned long st_atime_nsec_;
507 long st_mtime_;
508 unsigned long st_mtime_nsec_;
509 long st_ctime_;
510 unsigned long st_ctime_nsec_;
511 unsigned int __unused4;
512 unsigned int __unused5;
513};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000514#endif
515
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000516/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000517#ifdef __mips__
518#if _MIPS_SIM != _MIPS_SIM_ABI64
519struct kernel_statfs64 {
520 unsigned long f_type;
521 unsigned long f_bsize;
522 unsigned long f_frsize;
523 unsigned long __pad;
524 unsigned long long f_blocks;
525 unsigned long long f_bfree;
526 unsigned long long f_files;
527 unsigned long long f_ffree;
528 unsigned long long f_bavail;
529 struct { int val[2]; } f_fsid;
530 unsigned long f_namelen;
531 unsigned long f_spare[6];
532};
533#endif
534#elif !defined(__x86_64__)
535struct kernel_statfs64 {
536 unsigned long f_type;
537 unsigned long f_bsize;
538 unsigned long long f_blocks;
539 unsigned long long f_bfree;
540 unsigned long long f_bavail;
541 unsigned long long f_files;
542 unsigned long long f_ffree;
543 struct { int val[2]; } f_fsid;
544 unsigned long f_namelen;
545 unsigned long f_frsize;
546 unsigned long f_spare[5];
547};
548#endif
549
550/* include/asm-{arm,i386,mips,x86_64,ppc,generic}/statfs.h */
551#ifdef __mips__
552struct kernel_statfs {
553 long f_type;
554 long f_bsize;
555 long f_frsize;
556 long f_blocks;
557 long f_bfree;
558 long f_files;
559 long f_ffree;
560 long f_bavail;
561 struct { int val[2]; } f_fsid;
562 long f_namelen;
563 long f_spare[6];
564};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000565#elif defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000566struct kernel_statfs {
567 /* x86_64 actually defines all these fields as signed, whereas all other */
568 /* platforms define them as unsigned. Leaving them at unsigned should not */
vapier@chromium.org2273e812013-04-01 17:52:44 +0000569 /* cause any problems. Make sure these are 64-bit even on x32. */
570 uint64_t f_type;
571 uint64_t f_bsize;
572 uint64_t f_blocks;
573 uint64_t f_bfree;
574 uint64_t f_bavail;
575 uint64_t f_files;
576 uint64_t f_ffree;
577 struct { int val[2]; } f_fsid;
578 uint64_t f_namelen;
579 uint64_t f_frsize;
580 uint64_t f_spare[5];
581};
582#else
583struct kernel_statfs {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000584 unsigned long f_type;
585 unsigned long f_bsize;
586 unsigned long f_blocks;
587 unsigned long f_bfree;
588 unsigned long f_bavail;
589 unsigned long f_files;
590 unsigned long f_ffree;
591 struct { int val[2]; } f_fsid;
592 unsigned long f_namelen;
593 unsigned long f_frsize;
594 unsigned long f_spare[5];
595};
596#endif
597
598
599/* Definitions missing from the standard header files */
600#ifndef O_DIRECTORY
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000601#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000602#define O_DIRECTORY 0040000
603#else
604#define O_DIRECTORY 0200000
605#endif
606#endif
607#ifndef NT_PRXFPREG
608#define NT_PRXFPREG 0x46e62b7f
609#endif
610#ifndef PTRACE_GETFPXREGS
611#define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
612#endif
613#ifndef PR_GET_DUMPABLE
614#define PR_GET_DUMPABLE 3
615#endif
616#ifndef PR_SET_DUMPABLE
617#define PR_SET_DUMPABLE 4
618#endif
619#ifndef PR_GET_SECCOMP
620#define PR_GET_SECCOMP 21
621#endif
622#ifndef PR_SET_SECCOMP
623#define PR_SET_SECCOMP 22
624#endif
625#ifndef AT_FDCWD
626#define AT_FDCWD (-100)
627#endif
628#ifndef AT_SYMLINK_NOFOLLOW
629#define AT_SYMLINK_NOFOLLOW 0x100
630#endif
631#ifndef AT_REMOVEDIR
632#define AT_REMOVEDIR 0x200
633#endif
634#ifndef MREMAP_FIXED
635#define MREMAP_FIXED 2
636#endif
637#ifndef SA_RESTORER
638#define SA_RESTORER 0x04000000
639#endif
640#ifndef CPUCLOCK_PROF
641#define CPUCLOCK_PROF 0
642#endif
643#ifndef CPUCLOCK_VIRT
644#define CPUCLOCK_VIRT 1
645#endif
646#ifndef CPUCLOCK_SCHED
647#define CPUCLOCK_SCHED 2
648#endif
649#ifndef CPUCLOCK_PERTHREAD_MASK
650#define CPUCLOCK_PERTHREAD_MASK 4
651#endif
652#ifndef MAKE_PROCESS_CPUCLOCK
653#define MAKE_PROCESS_CPUCLOCK(pid, clock) \
654 ((~(int)(pid) << 3) | (int)(clock))
655#endif
656#ifndef MAKE_THREAD_CPUCLOCK
657#define MAKE_THREAD_CPUCLOCK(tid, clock) \
658 ((~(int)(tid) << 3) | (int)((clock) | CPUCLOCK_PERTHREAD_MASK))
659#endif
660
661#ifndef FUTEX_WAIT
662#define FUTEX_WAIT 0
663#endif
664#ifndef FUTEX_WAKE
665#define FUTEX_WAKE 1
666#endif
667#ifndef FUTEX_FD
668#define FUTEX_FD 2
669#endif
670#ifndef FUTEX_REQUEUE
671#define FUTEX_REQUEUE 3
672#endif
673#ifndef FUTEX_CMP_REQUEUE
674#define FUTEX_CMP_REQUEUE 4
675#endif
676#ifndef FUTEX_WAKE_OP
677#define FUTEX_WAKE_OP 5
678#endif
679#ifndef FUTEX_LOCK_PI
680#define FUTEX_LOCK_PI 6
681#endif
682#ifndef FUTEX_UNLOCK_PI
683#define FUTEX_UNLOCK_PI 7
684#endif
685#ifndef FUTEX_TRYLOCK_PI
686#define FUTEX_TRYLOCK_PI 8
687#endif
688#ifndef FUTEX_PRIVATE_FLAG
689#define FUTEX_PRIVATE_FLAG 128
690#endif
691#ifndef FUTEX_CMD_MASK
692#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG
693#endif
694#ifndef FUTEX_WAIT_PRIVATE
695#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
696#endif
697#ifndef FUTEX_WAKE_PRIVATE
698#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
699#endif
700#ifndef FUTEX_REQUEUE_PRIVATE
701#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
702#endif
703#ifndef FUTEX_CMP_REQUEUE_PRIVATE
704#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
705#endif
706#ifndef FUTEX_WAKE_OP_PRIVATE
707#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
708#endif
709#ifndef FUTEX_LOCK_PI_PRIVATE
710#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
711#endif
712#ifndef FUTEX_UNLOCK_PI_PRIVATE
713#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
714#endif
715#ifndef FUTEX_TRYLOCK_PI_PRIVATE
716#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
717#endif
718
719
720#if defined(__x86_64__)
721#ifndef ARCH_SET_GS
722#define ARCH_SET_GS 0x1001
723#endif
724#ifndef ARCH_GET_GS
725#define ARCH_GET_GS 0x1004
726#endif
727#endif
728
729#if defined(__i386__)
730#ifndef __NR_quotactl
731#define __NR_quotactl 131
732#endif
733#ifndef __NR_setresuid
734#define __NR_setresuid 164
735#define __NR_getresuid 165
736#define __NR_setresgid 170
737#define __NR_getresgid 171
738#endif
739#ifndef __NR_rt_sigaction
740#define __NR_rt_sigreturn 173
741#define __NR_rt_sigaction 174
742#define __NR_rt_sigprocmask 175
743#define __NR_rt_sigpending 176
744#define __NR_rt_sigsuspend 179
745#endif
746#ifndef __NR_pread64
747#define __NR_pread64 180
748#endif
749#ifndef __NR_pwrite64
750#define __NR_pwrite64 181
751#endif
752#ifndef __NR_ugetrlimit
753#define __NR_ugetrlimit 191
754#endif
755#ifndef __NR_stat64
756#define __NR_stat64 195
757#endif
758#ifndef __NR_fstat64
759#define __NR_fstat64 197
760#endif
761#ifndef __NR_setresuid32
762#define __NR_setresuid32 208
763#define __NR_getresuid32 209
764#define __NR_setresgid32 210
765#define __NR_getresgid32 211
766#endif
767#ifndef __NR_setfsuid32
768#define __NR_setfsuid32 215
769#define __NR_setfsgid32 216
770#endif
771#ifndef __NR_getdents64
772#define __NR_getdents64 220
773#endif
774#ifndef __NR_gettid
775#define __NR_gettid 224
776#endif
777#ifndef __NR_readahead
778#define __NR_readahead 225
779#endif
780#ifndef __NR_setxattr
781#define __NR_setxattr 226
782#endif
783#ifndef __NR_lsetxattr
784#define __NR_lsetxattr 227
785#endif
786#ifndef __NR_getxattr
787#define __NR_getxattr 229
788#endif
789#ifndef __NR_lgetxattr
790#define __NR_lgetxattr 230
791#endif
792#ifndef __NR_listxattr
793#define __NR_listxattr 232
794#endif
795#ifndef __NR_llistxattr
796#define __NR_llistxattr 233
797#endif
798#ifndef __NR_tkill
799#define __NR_tkill 238
800#endif
801#ifndef __NR_futex
802#define __NR_futex 240
803#endif
804#ifndef __NR_sched_setaffinity
805#define __NR_sched_setaffinity 241
806#define __NR_sched_getaffinity 242
807#endif
808#ifndef __NR_set_tid_address
809#define __NR_set_tid_address 258
810#endif
811#ifndef __NR_clock_gettime
812#define __NR_clock_gettime 265
813#endif
814#ifndef __NR_clock_getres
815#define __NR_clock_getres 266
816#endif
817#ifndef __NR_statfs64
818#define __NR_statfs64 268
819#endif
820#ifndef __NR_fstatfs64
821#define __NR_fstatfs64 269
822#endif
823#ifndef __NR_fadvise64_64
824#define __NR_fadvise64_64 272
825#endif
826#ifndef __NR_ioprio_set
827#define __NR_ioprio_set 289
828#endif
829#ifndef __NR_ioprio_get
830#define __NR_ioprio_get 290
831#endif
832#ifndef __NR_openat
833#define __NR_openat 295
834#endif
835#ifndef __NR_fstatat64
836#define __NR_fstatat64 300
837#endif
838#ifndef __NR_unlinkat
839#define __NR_unlinkat 301
840#endif
841#ifndef __NR_move_pages
842#define __NR_move_pages 317
843#endif
844#ifndef __NR_getcpu
845#define __NR_getcpu 318
846#endif
847#ifndef __NR_fallocate
848#define __NR_fallocate 324
849#endif
850/* End of i386 definitions */
851#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
852#ifndef __NR_setresuid
853#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
854#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
855#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
856#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
857#endif
858#ifndef __NR_rt_sigaction
859#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
860#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
861#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
862#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
863#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
864#endif
865#ifndef __NR_pread64
866#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
867#endif
868#ifndef __NR_pwrite64
869#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
870#endif
871#ifndef __NR_ugetrlimit
872#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
873#endif
874#ifndef __NR_stat64
875#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
876#endif
877#ifndef __NR_fstat64
878#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
879#endif
880#ifndef __NR_setresuid32
881#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
882#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
883#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
884#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
885#endif
886#ifndef __NR_setfsuid32
887#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
888#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
889#endif
890#ifndef __NR_getdents64
891#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
892#endif
893#ifndef __NR_gettid
894#define __NR_gettid (__NR_SYSCALL_BASE + 224)
895#endif
896#ifndef __NR_readahead
897#define __NR_readahead (__NR_SYSCALL_BASE + 225)
898#endif
899#ifndef __NR_setxattr
900#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
901#endif
902#ifndef __NR_lsetxattr
903#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
904#endif
905#ifndef __NR_getxattr
906#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
907#endif
908#ifndef __NR_lgetxattr
909#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
910#endif
911#ifndef __NR_listxattr
912#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
913#endif
914#ifndef __NR_llistxattr
915#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
916#endif
917#ifndef __NR_tkill
918#define __NR_tkill (__NR_SYSCALL_BASE + 238)
919#endif
920#ifndef __NR_futex
921#define __NR_futex (__NR_SYSCALL_BASE + 240)
922#endif
923#ifndef __NR_sched_setaffinity
924#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
925#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
926#endif
927#ifndef __NR_set_tid_address
928#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
929#endif
930#ifndef __NR_clock_gettime
931#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
932#endif
933#ifndef __NR_clock_getres
934#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
935#endif
936#ifndef __NR_statfs64
937#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
938#endif
939#ifndef __NR_fstatfs64
940#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
941#endif
942#ifndef __NR_ioprio_set
943#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
944#endif
945#ifndef __NR_ioprio_get
946#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
947#endif
948#ifndef __NR_move_pages
949#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
950#endif
951#ifndef __NR_getcpu
952#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
953#endif
954/* End of ARM 3/EABI definitions */
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000955#elif defined(__aarch64__)
956#ifndef __NR_setxattr
957#define __NR_setxattr 5
958#endif
959#ifndef __NR_lsetxattr
960#define __NR_lsetxattr 6
961#endif
962#ifndef __NR_getxattr
963#define __NR_getxattr 8
964#endif
965#ifndef __NR_lgetxattr
966#define __NR_lgetxattr 9
967#endif
968#ifndef __NR_listxattr
969#define __NR_listxattr 11
970#endif
971#ifndef __NR_llistxattr
972#define __NR_llistxattr 12
973#endif
974#ifndef __NR_ioprio_set
975#define __NR_ioprio_set 30
976#endif
977#ifndef __NR_ioprio_get
978#define __NR_ioprio_get 31
979#endif
980#ifndef __NR_unlinkat
981#define __NR_unlinkat 35
982#endif
983#ifndef __NR_fallocate
984#define __NR_fallocate 47
985#endif
986#ifndef __NR_openat
987#define __NR_openat 56
988#endif
989#ifndef __NR_quotactl
990#define __NR_quotactl 60
991#endif
992#ifndef __NR_getdents64
993#define __NR_getdents64 61
994#endif
995#ifndef __NR_getdents
996#define __NR_getdents __NR_getdents64
997#endif
998#ifndef __NR_pread64
999#define __NR_pread64 67
1000#endif
1001#ifndef __NR_pwrite64
1002#define __NR_pwrite64 68
1003#endif
1004#ifndef __NR_ppoll
1005#define __NR_ppoll 73
1006#endif
1007#ifndef __NR_readlinkat
1008#define __NR_readlinkat 78
1009#endif
1010#ifndef __NR_newfstatat
1011#define __NR_newfstatat 79
1012#endif
1013#ifndef __NR_set_tid_address
1014#define __NR_set_tid_address 96
1015#endif
1016#ifndef __NR_futex
1017#define __NR_futex 98
1018#endif
1019#ifndef __NR_clock_gettime
1020#define __NR_clock_gettime 113
1021#endif
1022#ifndef __NR_clock_getres
1023#define __NR_clock_getres 114
1024#endif
1025#ifndef __NR_sched_setaffinity
1026#define __NR_sched_setaffinity 122
1027#define __NR_sched_getaffinity 123
1028#endif
1029#ifndef __NR_tkill
1030#define __NR_tkill 130
1031#endif
1032#ifndef __NR_setresuid
1033#define __NR_setresuid 147
1034#define __NR_getresuid 148
1035#define __NR_setresgid 149
1036#define __NR_getresgid 150
1037#endif
1038#ifndef __NR_gettid
1039#define __NR_gettid 178
1040#endif
1041#ifndef __NR_readahead
1042#define __NR_readahead 213
1043#endif
1044#ifndef __NR_fadvise64
1045#define __NR_fadvise64 223
1046#endif
1047#ifndef __NR_move_pages
1048#define __NR_move_pages 239
1049#endif
1050/* End of aarch64 definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001051#elif defined(__x86_64__)
1052#ifndef __NR_pread64
1053#define __NR_pread64 17
1054#endif
1055#ifndef __NR_pwrite64
1056#define __NR_pwrite64 18
1057#endif
1058#ifndef __NR_setresuid
1059#define __NR_setresuid 117
1060#define __NR_getresuid 118
1061#define __NR_setresgid 119
1062#define __NR_getresgid 120
1063#endif
1064#ifndef __NR_quotactl
1065#define __NR_quotactl 179
1066#endif
1067#ifndef __NR_gettid
1068#define __NR_gettid 186
1069#endif
1070#ifndef __NR_readahead
1071#define __NR_readahead 187
1072#endif
1073#ifndef __NR_setxattr
1074#define __NR_setxattr 188
1075#endif
1076#ifndef __NR_lsetxattr
1077#define __NR_lsetxattr 189
1078#endif
1079#ifndef __NR_getxattr
1080#define __NR_getxattr 191
1081#endif
1082#ifndef __NR_lgetxattr
1083#define __NR_lgetxattr 192
1084#endif
1085#ifndef __NR_listxattr
1086#define __NR_listxattr 194
1087#endif
1088#ifndef __NR_llistxattr
1089#define __NR_llistxattr 195
1090#endif
1091#ifndef __NR_tkill
1092#define __NR_tkill 200
1093#endif
1094#ifndef __NR_futex
1095#define __NR_futex 202
1096#endif
1097#ifndef __NR_sched_setaffinity
1098#define __NR_sched_setaffinity 203
1099#define __NR_sched_getaffinity 204
1100#endif
1101#ifndef __NR_getdents64
1102#define __NR_getdents64 217
1103#endif
1104#ifndef __NR_set_tid_address
1105#define __NR_set_tid_address 218
1106#endif
1107#ifndef __NR_fadvise64
1108#define __NR_fadvise64 221
1109#endif
1110#ifndef __NR_clock_gettime
1111#define __NR_clock_gettime 228
1112#endif
1113#ifndef __NR_clock_getres
1114#define __NR_clock_getres 229
1115#endif
1116#ifndef __NR_ioprio_set
1117#define __NR_ioprio_set 251
1118#endif
1119#ifndef __NR_ioprio_get
1120#define __NR_ioprio_get 252
1121#endif
1122#ifndef __NR_openat
1123#define __NR_openat 257
1124#endif
1125#ifndef __NR_newfstatat
1126#define __NR_newfstatat 262
1127#endif
1128#ifndef __NR_unlinkat
1129#define __NR_unlinkat 263
1130#endif
1131#ifndef __NR_move_pages
1132#define __NR_move_pages 279
1133#endif
1134#ifndef __NR_fallocate
1135#define __NR_fallocate 285
1136#endif
1137/* End of x86-64 definitions */
1138#elif defined(__mips__)
1139#if _MIPS_SIM == _MIPS_SIM_ABI32
1140#ifndef __NR_setresuid
1141#define __NR_setresuid (__NR_Linux + 185)
1142#define __NR_getresuid (__NR_Linux + 186)
1143#define __NR_setresgid (__NR_Linux + 190)
1144#define __NR_getresgid (__NR_Linux + 191)
1145#endif
1146#ifndef __NR_rt_sigaction
1147#define __NR_rt_sigreturn (__NR_Linux + 193)
1148#define __NR_rt_sigaction (__NR_Linux + 194)
1149#define __NR_rt_sigprocmask (__NR_Linux + 195)
1150#define __NR_rt_sigpending (__NR_Linux + 196)
1151#define __NR_rt_sigsuspend (__NR_Linux + 199)
1152#endif
1153#ifndef __NR_pread64
1154#define __NR_pread64 (__NR_Linux + 200)
1155#endif
1156#ifndef __NR_pwrite64
1157#define __NR_pwrite64 (__NR_Linux + 201)
1158#endif
1159#ifndef __NR_stat64
1160#define __NR_stat64 (__NR_Linux + 213)
1161#endif
1162#ifndef __NR_fstat64
1163#define __NR_fstat64 (__NR_Linux + 215)
1164#endif
1165#ifndef __NR_getdents64
1166#define __NR_getdents64 (__NR_Linux + 219)
1167#endif
1168#ifndef __NR_gettid
1169#define __NR_gettid (__NR_Linux + 222)
1170#endif
1171#ifndef __NR_readahead
1172#define __NR_readahead (__NR_Linux + 223)
1173#endif
1174#ifndef __NR_setxattr
1175#define __NR_setxattr (__NR_Linux + 224)
1176#endif
1177#ifndef __NR_lsetxattr
1178#define __NR_lsetxattr (__NR_Linux + 225)
1179#endif
1180#ifndef __NR_getxattr
1181#define __NR_getxattr (__NR_Linux + 227)
1182#endif
1183#ifndef __NR_lgetxattr
1184#define __NR_lgetxattr (__NR_Linux + 228)
1185#endif
1186#ifndef __NR_listxattr
1187#define __NR_listxattr (__NR_Linux + 230)
1188#endif
1189#ifndef __NR_llistxattr
1190#define __NR_llistxattr (__NR_Linux + 231)
1191#endif
1192#ifndef __NR_tkill
1193#define __NR_tkill (__NR_Linux + 236)
1194#endif
1195#ifndef __NR_futex
1196#define __NR_futex (__NR_Linux + 238)
1197#endif
1198#ifndef __NR_sched_setaffinity
1199#define __NR_sched_setaffinity (__NR_Linux + 239)
1200#define __NR_sched_getaffinity (__NR_Linux + 240)
1201#endif
1202#ifndef __NR_set_tid_address
1203#define __NR_set_tid_address (__NR_Linux + 252)
1204#endif
1205#ifndef __NR_statfs64
1206#define __NR_statfs64 (__NR_Linux + 255)
1207#endif
1208#ifndef __NR_fstatfs64
1209#define __NR_fstatfs64 (__NR_Linux + 256)
1210#endif
1211#ifndef __NR_clock_gettime
1212#define __NR_clock_gettime (__NR_Linux + 263)
1213#endif
1214#ifndef __NR_clock_getres
1215#define __NR_clock_getres (__NR_Linux + 264)
1216#endif
1217#ifndef __NR_openat
1218#define __NR_openat (__NR_Linux + 288)
1219#endif
1220#ifndef __NR_fstatat
1221#define __NR_fstatat (__NR_Linux + 293)
1222#endif
1223#ifndef __NR_unlinkat
1224#define __NR_unlinkat (__NR_Linux + 294)
1225#endif
1226#ifndef __NR_move_pages
1227#define __NR_move_pages (__NR_Linux + 308)
1228#endif
1229#ifndef __NR_getcpu
1230#define __NR_getcpu (__NR_Linux + 312)
1231#endif
1232#ifndef __NR_ioprio_set
1233#define __NR_ioprio_set (__NR_Linux + 314)
1234#endif
1235#ifndef __NR_ioprio_get
1236#define __NR_ioprio_get (__NR_Linux + 315)
1237#endif
1238/* End of MIPS (old 32bit API) definitions */
1239#elif _MIPS_SIM == _MIPS_SIM_ABI64
1240#ifndef __NR_pread64
1241#define __NR_pread64 (__NR_Linux + 16)
1242#endif
1243#ifndef __NR_pwrite64
1244#define __NR_pwrite64 (__NR_Linux + 17)
1245#endif
1246#ifndef __NR_setresuid
1247#define __NR_setresuid (__NR_Linux + 115)
1248#define __NR_getresuid (__NR_Linux + 116)
1249#define __NR_setresgid (__NR_Linux + 117)
1250#define __NR_getresgid (__NR_Linux + 118)
1251#endif
1252#ifndef __NR_gettid
1253#define __NR_gettid (__NR_Linux + 178)
1254#endif
1255#ifndef __NR_readahead
1256#define __NR_readahead (__NR_Linux + 179)
1257#endif
1258#ifndef __NR_setxattr
1259#define __NR_setxattr (__NR_Linux + 180)
1260#endif
1261#ifndef __NR_lsetxattr
1262#define __NR_lsetxattr (__NR_Linux + 181)
1263#endif
1264#ifndef __NR_getxattr
1265#define __NR_getxattr (__NR_Linux + 183)
1266#endif
1267#ifndef __NR_lgetxattr
1268#define __NR_lgetxattr (__NR_Linux + 184)
1269#endif
1270#ifndef __NR_listxattr
1271#define __NR_listxattr (__NR_Linux + 186)
1272#endif
1273#ifndef __NR_llistxattr
1274#define __NR_llistxattr (__NR_Linux + 187)
1275#endif
1276#ifndef __NR_tkill
1277#define __NR_tkill (__NR_Linux + 192)
1278#endif
1279#ifndef __NR_futex
1280#define __NR_futex (__NR_Linux + 194)
1281#endif
1282#ifndef __NR_sched_setaffinity
1283#define __NR_sched_setaffinity (__NR_Linux + 195)
1284#define __NR_sched_getaffinity (__NR_Linux + 196)
1285#endif
1286#ifndef __NR_set_tid_address
1287#define __NR_set_tid_address (__NR_Linux + 212)
1288#endif
1289#ifndef __NR_clock_gettime
1290#define __NR_clock_gettime (__NR_Linux + 222)
1291#endif
1292#ifndef __NR_clock_getres
1293#define __NR_clock_getres (__NR_Linux + 223)
1294#endif
1295#ifndef __NR_openat
1296#define __NR_openat (__NR_Linux + 247)
1297#endif
1298#ifndef __NR_fstatat
1299#define __NR_fstatat (__NR_Linux + 252)
1300#endif
1301#ifndef __NR_unlinkat
1302#define __NR_unlinkat (__NR_Linux + 253)
1303#endif
1304#ifndef __NR_move_pages
1305#define __NR_move_pages (__NR_Linux + 267)
1306#endif
1307#ifndef __NR_getcpu
1308#define __NR_getcpu (__NR_Linux + 271)
1309#endif
1310#ifndef __NR_ioprio_set
1311#define __NR_ioprio_set (__NR_Linux + 273)
1312#endif
1313#ifndef __NR_ioprio_get
1314#define __NR_ioprio_get (__NR_Linux + 274)
1315#endif
1316/* End of MIPS (64bit API) definitions */
1317#else
1318#ifndef __NR_setresuid
1319#define __NR_setresuid (__NR_Linux + 115)
1320#define __NR_getresuid (__NR_Linux + 116)
1321#define __NR_setresgid (__NR_Linux + 117)
1322#define __NR_getresgid (__NR_Linux + 118)
1323#endif
1324#ifndef __NR_gettid
1325#define __NR_gettid (__NR_Linux + 178)
1326#endif
1327#ifndef __NR_readahead
1328#define __NR_readahead (__NR_Linux + 179)
1329#endif
1330#ifndef __NR_setxattr
1331#define __NR_setxattr (__NR_Linux + 180)
1332#endif
1333#ifndef __NR_lsetxattr
1334#define __NR_lsetxattr (__NR_Linux + 181)
1335#endif
1336#ifndef __NR_getxattr
1337#define __NR_getxattr (__NR_Linux + 183)
1338#endif
1339#ifndef __NR_lgetxattr
1340#define __NR_lgetxattr (__NR_Linux + 184)
1341#endif
1342#ifndef __NR_listxattr
1343#define __NR_listxattr (__NR_Linux + 186)
1344#endif
1345#ifndef __NR_llistxattr
1346#define __NR_llistxattr (__NR_Linux + 187)
1347#endif
1348#ifndef __NR_tkill
1349#define __NR_tkill (__NR_Linux + 192)
1350#endif
1351#ifndef __NR_futex
1352#define __NR_futex (__NR_Linux + 194)
1353#endif
1354#ifndef __NR_sched_setaffinity
1355#define __NR_sched_setaffinity (__NR_Linux + 195)
1356#define __NR_sched_getaffinity (__NR_Linux + 196)
1357#endif
1358#ifndef __NR_set_tid_address
1359#define __NR_set_tid_address (__NR_Linux + 213)
1360#endif
1361#ifndef __NR_statfs64
1362#define __NR_statfs64 (__NR_Linux + 217)
1363#endif
1364#ifndef __NR_fstatfs64
1365#define __NR_fstatfs64 (__NR_Linux + 218)
1366#endif
1367#ifndef __NR_clock_gettime
1368#define __NR_clock_gettime (__NR_Linux + 226)
1369#endif
1370#ifndef __NR_clock_getres
1371#define __NR_clock_getres (__NR_Linux + 227)
1372#endif
1373#ifndef __NR_openat
1374#define __NR_openat (__NR_Linux + 251)
1375#endif
1376#ifndef __NR_fstatat
1377#define __NR_fstatat (__NR_Linux + 256)
1378#endif
1379#ifndef __NR_unlinkat
1380#define __NR_unlinkat (__NR_Linux + 257)
1381#endif
1382#ifndef __NR_move_pages
1383#define __NR_move_pages (__NR_Linux + 271)
1384#endif
1385#ifndef __NR_getcpu
1386#define __NR_getcpu (__NR_Linux + 275)
1387#endif
1388#ifndef __NR_ioprio_set
1389#define __NR_ioprio_set (__NR_Linux + 277)
1390#endif
1391#ifndef __NR_ioprio_get
1392#define __NR_ioprio_get (__NR_Linux + 278)
1393#endif
1394/* End of MIPS (new 32bit API) definitions */
1395#endif
1396/* End of MIPS definitions */
1397#elif defined(__PPC__)
1398#ifndef __NR_setfsuid
1399#define __NR_setfsuid 138
1400#define __NR_setfsgid 139
1401#endif
1402#ifndef __NR_setresuid
1403#define __NR_setresuid 164
1404#define __NR_getresuid 165
1405#define __NR_setresgid 169
1406#define __NR_getresgid 170
1407#endif
1408#ifndef __NR_rt_sigaction
1409#define __NR_rt_sigreturn 172
1410#define __NR_rt_sigaction 173
1411#define __NR_rt_sigprocmask 174
1412#define __NR_rt_sigpending 175
1413#define __NR_rt_sigsuspend 178
1414#endif
1415#ifndef __NR_pread64
1416#define __NR_pread64 179
1417#endif
1418#ifndef __NR_pwrite64
1419#define __NR_pwrite64 180
1420#endif
1421#ifndef __NR_ugetrlimit
1422#define __NR_ugetrlimit 190
1423#endif
1424#ifndef __NR_readahead
1425#define __NR_readahead 191
1426#endif
1427#ifndef __NR_stat64
1428#define __NR_stat64 195
1429#endif
1430#ifndef __NR_fstat64
1431#define __NR_fstat64 197
1432#endif
1433#ifndef __NR_getdents64
1434#define __NR_getdents64 202
1435#endif
1436#ifndef __NR_gettid
1437#define __NR_gettid 207
1438#endif
1439#ifndef __NR_tkill
1440#define __NR_tkill 208
1441#endif
1442#ifndef __NR_setxattr
1443#define __NR_setxattr 209
1444#endif
1445#ifndef __NR_lsetxattr
1446#define __NR_lsetxattr 210
1447#endif
1448#ifndef __NR_getxattr
1449#define __NR_getxattr 212
1450#endif
1451#ifndef __NR_lgetxattr
1452#define __NR_lgetxattr 213
1453#endif
1454#ifndef __NR_listxattr
1455#define __NR_listxattr 215
1456#endif
1457#ifndef __NR_llistxattr
1458#define __NR_llistxattr 216
1459#endif
1460#ifndef __NR_futex
1461#define __NR_futex 221
1462#endif
1463#ifndef __NR_sched_setaffinity
1464#define __NR_sched_setaffinity 222
1465#define __NR_sched_getaffinity 223
1466#endif
1467#ifndef __NR_set_tid_address
1468#define __NR_set_tid_address 232
1469#endif
1470#ifndef __NR_clock_gettime
1471#define __NR_clock_gettime 246
1472#endif
1473#ifndef __NR_clock_getres
1474#define __NR_clock_getres 247
1475#endif
1476#ifndef __NR_statfs64
1477#define __NR_statfs64 252
1478#endif
1479#ifndef __NR_fstatfs64
1480#define __NR_fstatfs64 253
1481#endif
1482#ifndef __NR_fadvise64_64
1483#define __NR_fadvise64_64 254
1484#endif
1485#ifndef __NR_ioprio_set
1486#define __NR_ioprio_set 273
1487#endif
1488#ifndef __NR_ioprio_get
1489#define __NR_ioprio_get 274
1490#endif
1491#ifndef __NR_openat
1492#define __NR_openat 286
1493#endif
1494#ifndef __NR_fstatat64
1495#define __NR_fstatat64 291
1496#endif
1497#ifndef __NR_unlinkat
1498#define __NR_unlinkat 292
1499#endif
1500#ifndef __NR_move_pages
1501#define __NR_move_pages 301
1502#endif
1503#ifndef __NR_getcpu
1504#define __NR_getcpu 302
1505#endif
1506/* End of powerpc defininitions */
1507#endif
1508
1509
1510/* After forking, we must make sure to only call system calls. */
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001511#if defined(__BOUNDED_POINTERS__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001512 #error "Need to port invocations of syscalls for bounded ptrs"
1513#else
1514 /* The core dumper and the thread lister get executed after threads
1515 * have been suspended. As a consequence, we cannot call any functions
1516 * that acquire locks. Unfortunately, libc wraps most system calls
1517 * (e.g. in order to implement pthread_atfork, and to make calls
1518 * cancellable), which means we cannot call these functions. Instead,
1519 * we have to call syscall() directly.
1520 */
1521 #undef LSS_ERRNO
1522 #ifdef SYS_ERRNO
1523 /* Allow the including file to override the location of errno. This can
1524 * be useful when using clone() with the CLONE_VM option.
1525 */
1526 #define LSS_ERRNO SYS_ERRNO
1527 #else
1528 #define LSS_ERRNO errno
1529 #endif
1530
1531 #undef LSS_INLINE
1532 #ifdef SYS_INLINE
1533 #define LSS_INLINE SYS_INLINE
1534 #else
1535 #define LSS_INLINE static inline
1536 #endif
1537
1538 /* Allow the including file to override the prefix used for all new
1539 * system calls. By default, it will be set to "sys_".
1540 */
1541 #undef LSS_NAME
1542 #ifndef SYS_PREFIX
1543 #define LSS_NAME(name) sys_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001544 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001545 #define LSS_NAME(name) name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001546 #elif defined(SYS_PREFIX) && SYS_PREFIX == 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001547 #define LSS_NAME(name) sys0_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001548 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001549 #define LSS_NAME(name) sys1_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001550 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001551 #define LSS_NAME(name) sys2_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001552 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001553 #define LSS_NAME(name) sys3_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001554 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001555 #define LSS_NAME(name) sys4_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001556 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001557 #define LSS_NAME(name) sys5_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001558 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001559 #define LSS_NAME(name) sys6_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001560 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001561 #define LSS_NAME(name) sys7_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001562 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001563 #define LSS_NAME(name) sys8_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001564 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001565 #define LSS_NAME(name) sys9_##name
1566 #endif
1567
1568 #undef LSS_RETURN
1569 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001570 || defined(__ARM_EABI__) || defined(__aarch64__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001571 /* Failing system calls return a negative result in the range of
1572 * -1..-4095. These are "errno" values with the sign inverted.
1573 */
1574 #define LSS_RETURN(type, res) \
1575 do { \
1576 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
1577 LSS_ERRNO = -(res); \
1578 res = -1; \
1579 } \
1580 return (type) (res); \
1581 } while (0)
1582 #elif defined(__mips__)
1583 /* On MIPS, failing system calls return -1, and set errno in a
1584 * separate CPU register.
1585 */
1586 #define LSS_RETURN(type, res, err) \
1587 do { \
1588 if (err) { \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00001589 unsigned long __errnovalue = (res); \
1590 LSS_ERRNO = __errnovalue; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001591 res = -1; \
1592 } \
1593 return (type) (res); \
1594 } while (0)
1595 #elif defined(__PPC__)
1596 /* On PPC, failing system calls return -1, and set errno in a
1597 * separate CPU register. See linux/unistd.h.
1598 */
1599 #define LSS_RETURN(type, res, err) \
1600 do { \
1601 if (err & 0x10000000 ) { \
1602 LSS_ERRNO = (res); \
1603 res = -1; \
1604 } \
1605 return (type) (res); \
1606 } while (0)
1607 #endif
1608 #if defined(__i386__)
1609 /* In PIC mode (e.g. when building shared libraries), gcc for i386
1610 * reserves ebx. Unfortunately, most distribution ship with implementations
1611 * of _syscallX() which clobber ebx.
1612 * Also, most definitions of _syscallX() neglect to mark "memory" as being
1613 * clobbered. This causes problems with compilers, that do a better job
1614 * at optimizing across __asm__ calls.
1615 * So, we just have to redefine all of the _syscallX() macros.
1616 */
1617 #undef LSS_ENTRYPOINT
1618 #ifdef SYS_SYSCALL_ENTRYPOINT
1619 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
1620 void (**entrypoint)(void);
1621 asm volatile(".bss\n"
1622 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001623 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
1624 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001625 ".previous\n"
1626 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */
1627 "call 0f\n"
1628 "0:pop %0\n"
1629 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001630 "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001631 : "=r"(entrypoint));
1632 return entrypoint;
1633 }
1634
1635 #define LSS_ENTRYPOINT ".bss\n" \
1636 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001637 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
1638 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001639 ".previous\n" \
1640 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \
1641 "push %%eax\n" \
1642 "call 10000f\n" \
1643 "10000:pop %%eax\n" \
1644 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001645 "mov " SYS_SYSCALL_ENTRYPOINT \
1646 "@GOT(%%eax), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001647 "mov 0(%%eax), %%eax\n" \
1648 "test %%eax, %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001649 "jz 10002f\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001650 "push %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001651 "call 10001f\n" \
1652 "10001:pop %%eax\n" \
1653 "add $(10003f-10001b), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001654 "xchg 4(%%esp), %%eax\n" \
1655 "ret\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001656 "10002:pop %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001657 "int $0x80\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001658 "10003:\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001659 #else
1660 #define LSS_ENTRYPOINT "int $0x80\n"
1661 #endif
1662 #undef LSS_BODY
1663 #define LSS_BODY(type,args...) \
1664 long __res; \
1665 __asm__ __volatile__("push %%ebx\n" \
1666 "movl %2,%%ebx\n" \
1667 LSS_ENTRYPOINT \
1668 "pop %%ebx" \
1669 args \
1670 : "esp", "memory"); \
1671 LSS_RETURN(type,__res)
1672 #undef _syscall0
1673 #define _syscall0(type,name) \
1674 type LSS_NAME(name)(void) { \
1675 long __res; \
1676 __asm__ volatile(LSS_ENTRYPOINT \
1677 : "=a" (__res) \
1678 : "0" (__NR_##name) \
1679 : "esp", "memory"); \
1680 LSS_RETURN(type,__res); \
1681 }
1682 #undef _syscall1
1683 #define _syscall1(type,name,type1,arg1) \
1684 type LSS_NAME(name)(type1 arg1) { \
1685 LSS_BODY(type, \
1686 : "=a" (__res) \
1687 : "0" (__NR_##name), "ri" ((long)(arg1))); \
1688 }
1689 #undef _syscall2
1690 #define _syscall2(type,name,type1,arg1,type2,arg2) \
1691 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
1692 LSS_BODY(type, \
1693 : "=a" (__res) \
1694 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
1695 }
1696 #undef _syscall3
1697 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
1698 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
1699 LSS_BODY(type, \
1700 : "=a" (__res) \
1701 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
1702 "d" ((long)(arg3))); \
1703 }
1704 #undef _syscall4
1705 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
1706 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1707 LSS_BODY(type, \
1708 : "=a" (__res) \
1709 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
1710 "d" ((long)(arg3)),"S" ((long)(arg4))); \
1711 }
1712 #undef _syscall5
1713 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1714 type5,arg5) \
1715 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1716 type5 arg5) { \
1717 long __res; \
1718 __asm__ __volatile__("push %%ebx\n" \
1719 "movl %2,%%ebx\n" \
1720 "movl %1,%%eax\n" \
1721 LSS_ENTRYPOINT \
1722 "pop %%ebx" \
1723 : "=a" (__res) \
1724 : "i" (__NR_##name), "ri" ((long)(arg1)), \
1725 "c" ((long)(arg2)), "d" ((long)(arg3)), \
1726 "S" ((long)(arg4)), "D" ((long)(arg5)) \
1727 : "esp", "memory"); \
1728 LSS_RETURN(type,__res); \
1729 }
1730 #undef _syscall6
1731 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1732 type5,arg5,type6,arg6) \
1733 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1734 type5 arg5, type6 arg6) { \
1735 long __res; \
1736 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
1737 __asm__ __volatile__("push %%ebp\n" \
1738 "push %%ebx\n" \
mseaborn@chromium.orge96ade32012-10-27 17:47:38 +00001739 "movl 4(%2),%%ebp\n" \
1740 "movl 0(%2), %%ebx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001741 "movl %1,%%eax\n" \
1742 LSS_ENTRYPOINT \
1743 "pop %%ebx\n" \
1744 "pop %%ebp" \
1745 : "=a" (__res) \
1746 : "i" (__NR_##name), "0" ((long)(&__s)), \
1747 "c" ((long)(arg2)), "d" ((long)(arg3)), \
1748 "S" ((long)(arg4)), "D" ((long)(arg5)) \
1749 : "esp", "memory"); \
1750 LSS_RETURN(type,__res); \
1751 }
1752 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1753 int flags, void *arg, int *parent_tidptr,
1754 void *newtls, int *child_tidptr) {
1755 long __res;
1756 __asm__ __volatile__(/* if (fn == NULL)
1757 * return -EINVAL;
1758 */
1759 "movl %3,%%ecx\n"
1760 "jecxz 1f\n"
1761
1762 /* if (child_stack == NULL)
1763 * return -EINVAL;
1764 */
1765 "movl %4,%%ecx\n"
1766 "jecxz 1f\n"
1767
1768 /* Set up alignment of the child stack:
1769 * child_stack = (child_stack & ~0xF) - 20;
1770 */
1771 "andl $-16,%%ecx\n"
1772 "subl $20,%%ecx\n"
1773
1774 /* Push "arg" and "fn" onto the stack that will be
1775 * used by the child.
1776 */
1777 "movl %6,%%eax\n"
1778 "movl %%eax,4(%%ecx)\n"
1779 "movl %3,%%eax\n"
1780 "movl %%eax,(%%ecx)\n"
1781
1782 /* %eax = syscall(%eax = __NR_clone,
1783 * %ebx = flags,
1784 * %ecx = child_stack,
1785 * %edx = parent_tidptr,
1786 * %esi = newtls,
1787 * %edi = child_tidptr)
1788 * Also, make sure that %ebx gets preserved as it is
1789 * used in PIC mode.
1790 */
1791 "movl %8,%%esi\n"
1792 "movl %7,%%edx\n"
1793 "movl %5,%%eax\n"
1794 "movl %9,%%edi\n"
1795 "pushl %%ebx\n"
1796 "movl %%eax,%%ebx\n"
1797 "movl %2,%%eax\n"
1798 LSS_ENTRYPOINT
1799
1800 /* In the parent: restore %ebx
1801 * In the child: move "fn" into %ebx
1802 */
1803 "popl %%ebx\n"
1804
1805 /* if (%eax != 0)
1806 * return %eax;
1807 */
1808 "test %%eax,%%eax\n"
1809 "jnz 1f\n"
1810
1811 /* In the child, now. Terminate frame pointer chain.
1812 */
1813 "movl $0,%%ebp\n"
1814
1815 /* Call "fn". "arg" is already on the stack.
1816 */
1817 "call *%%ebx\n"
1818
1819 /* Call _exit(%ebx). Unfortunately older versions
1820 * of gcc restrict the number of arguments that can
1821 * be passed to asm(). So, we need to hard-code the
1822 * system call number.
1823 */
1824 "movl %%eax,%%ebx\n"
1825 "movl $1,%%eax\n"
1826 LSS_ENTRYPOINT
1827
1828 /* Return to parent.
1829 */
1830 "1:\n"
1831 : "=a" (__res)
1832 : "0"(-EINVAL), "i"(__NR_clone),
1833 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
1834 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
1835 : "esp", "memory", "ecx", "edx", "esi", "edi");
1836 LSS_RETURN(int, __res);
1837 }
1838
1839 #define __NR__fadvise64_64 __NR_fadvise64_64
1840 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
1841 unsigned, offset_lo, unsigned, offset_hi,
1842 unsigned, len_lo, unsigned, len_hi,
1843 int, advice)
1844
1845 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
1846 loff_t len, int advice) {
1847 return LSS_NAME(_fadvise64_64)(fd,
1848 (unsigned)offset, (unsigned)(offset >>32),
1849 (unsigned)len, (unsigned)(len >> 32),
1850 advice);
1851 }
1852
1853 #define __NR__fallocate __NR_fallocate
1854 LSS_INLINE _syscall6(int, _fallocate, int, fd,
1855 int, mode,
1856 unsigned, offset_lo, unsigned, offset_hi,
1857 unsigned, len_lo, unsigned, len_hi)
1858
1859 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,
1860 loff_t offset, loff_t len) {
1861 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };
1862 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);
1863 }
1864
1865 LSS_INLINE _syscall1(int, set_thread_area, void *, u)
1866 LSS_INLINE _syscall1(int, get_thread_area, void *, u)
1867
1868 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
1869 /* On i386, the kernel does not know how to return from a signal
1870 * handler. Instead, it relies on user space to provide a
1871 * restorer function that calls the {rt_,}sigreturn() system call.
1872 * Unfortunately, we cannot just reference the glibc version of this
1873 * function, as glibc goes out of its way to make it inaccessible.
1874 */
1875 void (*res)(void);
1876 __asm__ __volatile__("call 2f\n"
1877 "0:.align 16\n"
1878 "1:movl %1,%%eax\n"
1879 LSS_ENTRYPOINT
1880 "2:popl %0\n"
1881 "addl $(1b-0b),%0\n"
1882 : "=a" (res)
1883 : "i" (__NR_rt_sigreturn));
1884 return res;
1885 }
1886 LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
1887 /* On i386, the kernel does not know how to return from a signal
1888 * handler. Instead, it relies on user space to provide a
1889 * restorer function that calls the {rt_,}sigreturn() system call.
1890 * Unfortunately, we cannot just reference the glibc version of this
1891 * function, as glibc goes out of its way to make it inaccessible.
1892 */
1893 void (*res)(void);
1894 __asm__ __volatile__("call 2f\n"
1895 "0:.align 16\n"
1896 "1:pop %%eax\n"
1897 "movl %1,%%eax\n"
1898 LSS_ENTRYPOINT
1899 "2:popl %0\n"
1900 "addl $(1b-0b),%0\n"
1901 : "=a" (res)
1902 : "i" (__NR_sigreturn));
1903 return res;
1904 }
1905 #elif defined(__x86_64__)
1906 /* There are no known problems with any of the _syscallX() macros
1907 * currently shipping for x86_64, but we still need to be able to define
1908 * our own version so that we can override the location of the errno
1909 * location (e.g. when using the clone() system call with the CLONE_VM
1910 * option).
1911 */
1912 #undef LSS_ENTRYPOINT
1913 #ifdef SYS_SYSCALL_ENTRYPOINT
1914 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
1915 void (**entrypoint)(void);
1916 asm volatile(".bss\n"
1917 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001918 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
1919 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001920 ".previous\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001921 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001922 : "=r"(entrypoint));
1923 return entrypoint;
1924 }
1925
1926 #define LSS_ENTRYPOINT \
1927 ".bss\n" \
1928 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001929 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
1930 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001931 ".previous\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001932 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001933 "mov 0(%%rcx), %%rcx\n" \
1934 "test %%rcx, %%rcx\n" \
1935 "jz 10001f\n" \
1936 "call *%%rcx\n" \
1937 "jmp 10002f\n" \
1938 "10001:syscall\n" \
1939 "10002:\n"
1940
1941 #else
1942 #define LSS_ENTRYPOINT "syscall\n"
1943 #endif
vapier@chromium.org2273e812013-04-01 17:52:44 +00001944
1945 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
1946 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
1947 * sign extension. We can't cast pointers directly because those are
1948 * 32 bits, and gcc will dump ugly warnings about casting from a pointer
1949 * to an integer of a different size.
1950 */
1951 #undef LSS_SYSCALL_ARG
1952 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
1953 #undef _LSS_RETURN
1954 #define _LSS_RETURN(type, res, cast) \
1955 do { \
1956 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \
1957 LSS_ERRNO = -(res); \
1958 res = -1; \
1959 } \
1960 return (type)(cast)(res); \
1961 } while (0)
1962 #undef LSS_RETURN
1963 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
1964
1965 #undef _LSS_BODY
1966 #define _LSS_BODY(nr, type, name, cast, ...) \
1967 long long __res; \
1968 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \
1969 : "=a" (__res) \
1970 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \
1971 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \
1972 _LSS_RETURN(type, __res, cast)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001973 #undef LSS_BODY
vapier@chromium.org2273e812013-04-01 17:52:44 +00001974 #define LSS_BODY(nr, type, name, args...) \
1975 _LSS_BODY(nr, type, name, uintptr_t, ## args)
1976
1977 #undef LSS_BODY_ASM0
1978 #undef LSS_BODY_ASM1
1979 #undef LSS_BODY_ASM2
1980 #undef LSS_BODY_ASM3
1981 #undef LSS_BODY_ASM4
1982 #undef LSS_BODY_ASM5
1983 #undef LSS_BODY_ASM6
1984 #define LSS_BODY_ASM0
1985 #define LSS_BODY_ASM1 LSS_BODY_ASM0
1986 #define LSS_BODY_ASM2 LSS_BODY_ASM1
1987 #define LSS_BODY_ASM3 LSS_BODY_ASM2
1988 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
1989 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
1990 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
1991
1992 #undef LSS_BODY_CLOBBER0
1993 #undef LSS_BODY_CLOBBER1
1994 #undef LSS_BODY_CLOBBER2
1995 #undef LSS_BODY_CLOBBER3
1996 #undef LSS_BODY_CLOBBER4
1997 #undef LSS_BODY_CLOBBER5
1998 #undef LSS_BODY_CLOBBER6
1999 #define LSS_BODY_CLOBBER0
2000 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
2001 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
2002 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
2003 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
2004 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
2005 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
2006
2007 #undef LSS_BODY_ARG0
2008 #undef LSS_BODY_ARG1
2009 #undef LSS_BODY_ARG2
2010 #undef LSS_BODY_ARG3
2011 #undef LSS_BODY_ARG4
2012 #undef LSS_BODY_ARG5
2013 #undef LSS_BODY_ARG6
2014 #define LSS_BODY_ARG0()
2015 #define LSS_BODY_ARG1(arg1) \
2016 LSS_BODY_ARG0(), "D" (arg1)
2017 #define LSS_BODY_ARG2(arg1, arg2) \
2018 LSS_BODY_ARG1(arg1), "S" (arg2)
2019 #define LSS_BODY_ARG3(arg1, arg2, arg3) \
2020 LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
2021 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
2022 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
2023 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
2024 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
2025 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
2026 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
2027
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002028 #undef _syscall0
2029 #define _syscall0(type,name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002030 type LSS_NAME(name)(void) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002031 LSS_BODY(0, type, name); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002032 }
2033 #undef _syscall1
2034 #define _syscall1(type,name,type1,arg1) \
2035 type LSS_NAME(name)(type1 arg1) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002036 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002037 }
2038 #undef _syscall2
2039 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2040 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002041 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002042 }
2043 #undef _syscall3
2044 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2045 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002046 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2047 LSS_SYSCALL_ARG(arg3)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002048 }
2049 #undef _syscall4
2050 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2051 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002052 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2053 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002054 }
2055 #undef _syscall5
2056 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2057 type5,arg5) \
2058 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2059 type5 arg5) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002060 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2061 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2062 LSS_SYSCALL_ARG(arg5)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002063 }
2064 #undef _syscall6
2065 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2066 type5,arg5,type6,arg6) \
2067 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2068 type5 arg5, type6 arg6) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002069 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2070 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2071 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002072 }
2073 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2074 int flags, void *arg, int *parent_tidptr,
2075 void *newtls, int *child_tidptr) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00002076 long long __res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002077 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002078 __asm__ __volatile__(/* if (fn == NULL)
2079 * return -EINVAL;
2080 */
2081 "testq %4,%4\n"
2082 "jz 1f\n"
2083
2084 /* if (child_stack == NULL)
2085 * return -EINVAL;
2086 */
2087 "testq %5,%5\n"
2088 "jz 1f\n"
2089
2090 /* childstack -= 2*sizeof(void *);
2091 */
2092 "subq $16,%5\n"
2093
2094 /* Push "arg" and "fn" onto the stack that will be
2095 * used by the child.
2096 */
2097 "movq %7,8(%5)\n"
2098 "movq %4,0(%5)\n"
2099
2100 /* %rax = syscall(%rax = __NR_clone,
2101 * %rdi = flags,
2102 * %rsi = child_stack,
2103 * %rdx = parent_tidptr,
2104 * %r8 = new_tls,
2105 * %r10 = child_tidptr)
2106 */
2107 "movq %2,%%rax\n"
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00002108 "movq %9,%%r8\n"
2109 "movq %10,%%r10\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002110 LSS_ENTRYPOINT
2111
2112 /* if (%rax != 0)
2113 * return;
2114 */
2115 "testq %%rax,%%rax\n"
2116 "jnz 1f\n"
2117
2118 /* In the child. Terminate frame pointer chain.
2119 */
2120 "xorq %%rbp,%%rbp\n"
2121
2122 /* Call "fn(arg)".
2123 */
2124 "popq %%rax\n"
2125 "popq %%rdi\n"
2126 "call *%%rax\n"
2127
2128 /* Call _exit(%ebx).
2129 */
2130 "movq %%rax,%%rdi\n"
2131 "movq %3,%%rax\n"
2132 LSS_ENTRYPOINT
2133
2134 /* Return to parent.
2135 */
2136 "1:\n"
2137 : "=a" (__res)
2138 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
vapier@chromium.org2273e812013-04-01 17:52:44 +00002139 "r"(LSS_SYSCALL_ARG(fn)),
2140 "S"(LSS_SYSCALL_ARG(child_stack)),
2141 "D"(LSS_SYSCALL_ARG(flags)),
2142 "r"(LSS_SYSCALL_ARG(arg)),
2143 "d"(LSS_SYSCALL_ARG(parent_tidptr)),
2144 "r"(LSS_SYSCALL_ARG(newtls)),
2145 "r"(LSS_SYSCALL_ARG(child_tidptr))
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00002146 : "rsp", "memory", "r8", "r10", "r11", "rcx");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002147 }
2148 LSS_RETURN(int, __res);
2149 }
2150 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a)
vapier@chromium.org2273e812013-04-01 17:52:44 +00002151
2152 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
2153 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len,
2154 int advice) {
2155 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset),
2156 (uint64_t)(len), LSS_SYSCALL_ARG(advice));
2157 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002158
2159 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2160 /* On x86-64, the kernel does not know how to return from
2161 * a signal handler. Instead, it relies on user space to provide a
2162 * restorer function that calls the rt_sigreturn() system call.
2163 * Unfortunately, we cannot just reference the glibc version of this
2164 * function, as glibc goes out of its way to make it inaccessible.
2165 */
vapier@chromium.org2273e812013-04-01 17:52:44 +00002166 long long res;
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002167 __asm__ __volatile__("jmp 2f\n"
2168 ".align 16\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002169 "1:movq %1,%%rax\n"
2170 LSS_ENTRYPOINT
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002171 "2:leaq 1b(%%rip),%0\n"
2172 : "=r" (res)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002173 : "i" (__NR_rt_sigreturn));
vapier@chromium.org833a10e2013-04-02 19:34:26 +00002174 return (void (*)(void))(uintptr_t)res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002175 }
2176 #elif defined(__ARM_ARCH_3__)
2177 /* Most definitions of _syscallX() neglect to mark "memory" as being
2178 * clobbered. This causes problems with compilers, that do a better job
2179 * at optimizing across __asm__ calls.
2180 * So, we just have to redefine all of the _syscallX() macros.
2181 */
2182 #undef LSS_REG
2183 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2184 #undef LSS_BODY
2185 #define LSS_BODY(type,name,args...) \
2186 register long __res_r0 __asm__("r0"); \
2187 long __res; \
2188 __asm__ __volatile__ (__syscall(name) \
2189 : "=r"(__res_r0) : args : "lr", "memory"); \
2190 __res = __res_r0; \
2191 LSS_RETURN(type, __res)
2192 #undef _syscall0
2193 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002194 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002195 LSS_BODY(type, name); \
2196 }
2197 #undef _syscall1
2198 #define _syscall1(type, name, type1, arg1) \
2199 type LSS_NAME(name)(type1 arg1) { \
2200 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2201 }
2202 #undef _syscall2
2203 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2204 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2205 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2206 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2207 }
2208 #undef _syscall3
2209 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2210 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2211 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2212 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2213 }
2214 #undef _syscall4
2215 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2216 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2217 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2218 LSS_REG(3, arg4); \
2219 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2220 }
2221 #undef _syscall5
2222 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2223 type5,arg5) \
2224 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2225 type5 arg5) { \
2226 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2227 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2228 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2229 "r"(__r4)); \
2230 }
2231 #undef _syscall6
2232 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2233 type5,arg5,type6,arg6) \
2234 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2235 type5 arg5, type6 arg6) { \
2236 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2237 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2238 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2239 "r"(__r4), "r"(__r5)); \
2240 }
2241 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2242 int flags, void *arg, int *parent_tidptr,
2243 void *newtls, int *child_tidptr) {
2244 long __res;
2245 {
2246 register int __flags __asm__("r0") = flags;
2247 register void *__stack __asm__("r1") = child_stack;
2248 register void *__ptid __asm__("r2") = parent_tidptr;
2249 register void *__tls __asm__("r3") = newtls;
2250 register int *__ctid __asm__("r4") = child_tidptr;
2251 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2252 * return -EINVAL;
2253 */
2254 "cmp %2,#0\n"
2255 "cmpne %3,#0\n"
2256 "moveq %0,%1\n"
2257 "beq 1f\n"
2258
2259 /* Push "arg" and "fn" onto the stack that will be
2260 * used by the child.
2261 */
2262 "str %5,[%3,#-4]!\n"
2263 "str %2,[%3,#-4]!\n"
2264
2265 /* %r0 = syscall(%r0 = flags,
2266 * %r1 = child_stack,
2267 * %r2 = parent_tidptr,
2268 * %r3 = newtls,
2269 * %r4 = child_tidptr)
2270 */
2271 __syscall(clone)"\n"
2272
2273 /* if (%r0 != 0)
2274 * return %r0;
2275 */
2276 "movs %0,r0\n"
2277 "bne 1f\n"
2278
2279 /* In the child, now. Call "fn(arg)".
2280 */
2281 "ldr r0,[sp, #4]\n"
2282 "mov lr,pc\n"
2283 "ldr pc,[sp]\n"
2284
2285 /* Call _exit(%r0).
2286 */
2287 __syscall(exit)"\n"
2288 "1:\n"
2289 : "=r" (__res)
2290 : "i"(-EINVAL),
2291 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2292 "r"(__ptid), "r"(__tls), "r"(__ctid)
2293 : "cc", "lr", "memory");
2294 }
2295 LSS_RETURN(int, __res);
2296 }
2297 #elif defined(__ARM_EABI__)
2298 /* Most definitions of _syscallX() neglect to mark "memory" as being
2299 * clobbered. This causes problems with compilers, that do a better job
2300 * at optimizing across __asm__ calls.
2301 * So, we just have to redefine all fo the _syscallX() macros.
2302 */
2303 #undef LSS_REG
2304 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2305 #undef LSS_BODY
2306 #define LSS_BODY(type,name,args...) \
2307 register long __res_r0 __asm__("r0"); \
2308 long __res; \
2309 __asm__ __volatile__ ("push {r7}\n" \
2310 "mov r7, %1\n" \
2311 "swi 0x0\n" \
2312 "pop {r7}\n" \
2313 : "=r"(__res_r0) \
2314 : "i"(__NR_##name) , ## args \
2315 : "lr", "memory"); \
2316 __res = __res_r0; \
2317 LSS_RETURN(type, __res)
2318 #undef _syscall0
2319 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002320 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002321 LSS_BODY(type, name); \
2322 }
2323 #undef _syscall1
2324 #define _syscall1(type, name, type1, arg1) \
2325 type LSS_NAME(name)(type1 arg1) { \
2326 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2327 }
2328 #undef _syscall2
2329 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2330 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2331 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2332 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2333 }
2334 #undef _syscall3
2335 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2336 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2337 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2338 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2339 }
2340 #undef _syscall4
2341 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2342 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2343 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2344 LSS_REG(3, arg4); \
2345 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2346 }
2347 #undef _syscall5
2348 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2349 type5,arg5) \
2350 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2351 type5 arg5) { \
2352 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2353 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2354 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2355 "r"(__r4)); \
2356 }
2357 #undef _syscall6
2358 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2359 type5,arg5,type6,arg6) \
2360 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2361 type5 arg5, type6 arg6) { \
2362 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2363 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2364 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2365 "r"(__r4), "r"(__r5)); \
2366 }
2367 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2368 int flags, void *arg, int *parent_tidptr,
2369 void *newtls, int *child_tidptr) {
2370 long __res;
2371 {
2372 register int __flags __asm__("r0") = flags;
2373 register void *__stack __asm__("r1") = child_stack;
2374 register void *__ptid __asm__("r2") = parent_tidptr;
2375 register void *__tls __asm__("r3") = newtls;
2376 register int *__ctid __asm__("r4") = child_tidptr;
2377 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2378 * return -EINVAL;
2379 */
anton@chromium.org43de0522014-04-04 11:20:46 +00002380#ifdef __thumb2__
thestig@chromium.org952107f2014-08-01 02:22:56 +00002381 "push {r7}\n"
anton@chromium.org43de0522014-04-04 11:20:46 +00002382#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002383 "cmp %2,#0\n"
zodiac@gmail.com4f470182010-10-13 03:47:54 +00002384 "it ne\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002385 "cmpne %3,#0\n"
zodiac@gmail.com4f470182010-10-13 03:47:54 +00002386 "it eq\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002387 "moveq %0,%1\n"
2388 "beq 1f\n"
2389
2390 /* Push "arg" and "fn" onto the stack that will be
2391 * used by the child.
2392 */
2393 "str %5,[%3,#-4]!\n"
2394 "str %2,[%3,#-4]!\n"
2395
2396 /* %r0 = syscall(%r0 = flags,
2397 * %r1 = child_stack,
2398 * %r2 = parent_tidptr,
2399 * %r3 = newtls,
2400 * %r4 = child_tidptr)
2401 */
2402 "mov r7, %9\n"
2403 "swi 0x0\n"
2404
2405 /* if (%r0 != 0)
2406 * return %r0;
2407 */
2408 "movs %0,r0\n"
2409 "bne 1f\n"
2410
2411 /* In the child, now. Call "fn(arg)".
2412 */
2413 "ldr r0,[sp, #4]\n"
zodiac@gmail.com68c659b2011-10-06 05:34:19 +00002414
2415 /* When compiling for Thumb-2 the "MOV LR,PC" here
2416 * won't work because it loads PC+4 into LR,
2417 * whereas the LDR is a 4-byte instruction.
2418 * This results in the child thread always
2419 * crashing with an "Illegal Instruction" when it
2420 * returned into the middle of the LDR instruction
2421 * The instruction sequence used instead was
2422 * recommended by
2423 * "https://wiki.edubuntu.org/ARM/Thumb2PortingHowto#Quick_Reference".
2424 */
2425 #ifdef __thumb2__
2426 "ldr r7,[sp]\n"
2427 "blx r7\n"
2428 #else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002429 "mov lr,pc\n"
2430 "ldr pc,[sp]\n"
zodiac@gmail.com68c659b2011-10-06 05:34:19 +00002431 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002432
2433 /* Call _exit(%r0).
2434 */
2435 "mov r7, %10\n"
2436 "swi 0x0\n"
2437 "1:\n"
zodiac@gmail.com77ebebe2012-10-22 23:52:58 +00002438#ifdef __thumb2__
thestig@chromium.org952107f2014-08-01 02:22:56 +00002439 "pop {r7}"
anton@chromium.org43de0522014-04-04 11:20:46 +00002440#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002441 : "=r" (__res)
2442 : "i"(-EINVAL),
2443 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2444 "r"(__ptid), "r"(__tls), "r"(__ctid),
2445 "i"(__NR_clone), "i"(__NR_exit)
zodiac@gmail.com77ebebe2012-10-22 23:52:58 +00002446#ifdef __thumb2__
thestig@chromium.org952107f2014-08-01 02:22:56 +00002447 : "cc", "lr", "memory");
zodiac@gmail.com77ebebe2012-10-22 23:52:58 +00002448#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002449 : "cc", "r7", "lr", "memory");
zodiac@gmail.com77ebebe2012-10-22 23:52:58 +00002450#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002451 }
2452 LSS_RETURN(int, __res);
2453 }
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002454 #elif defined(__aarch64__)
2455 /* Most definitions of _syscallX() neglect to mark "memory" as being
2456 * clobbered. This causes problems with compilers, that do a better job
2457 * at optimizing across __asm__ calls.
2458 * So, we just have to redefine all of the _syscallX() macros.
2459 */
2460 #undef LSS_REG
2461 #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a
2462 #undef LSS_BODY
2463 #define LSS_BODY(type,name,args...) \
2464 register int64_t __res_x0 __asm__("x0"); \
2465 int64_t __res; \
2466 __asm__ __volatile__ ("mov x8, %1\n" \
2467 "svc 0x0\n" \
2468 : "=r"(__res_x0) \
2469 : "i"(__NR_##name) , ## args \
2470 : "x8", "memory"); \
2471 __res = __res_x0; \
2472 LSS_RETURN(type, __res)
2473 #undef _syscall0
2474 #define _syscall0(type, name) \
2475 type LSS_NAME(name)(void) { \
2476 LSS_BODY(type, name); \
2477 }
2478 #undef _syscall1
2479 #define _syscall1(type, name, type1, arg1) \
2480 type LSS_NAME(name)(type1 arg1) { \
2481 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2482 }
2483 #undef _syscall2
2484 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2485 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2486 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2487 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2488 }
2489 #undef _syscall3
2490 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2491 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2492 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2493 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2494 }
2495 #undef _syscall4
2496 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2497 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2498 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2499 LSS_REG(3, arg4); \
2500 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2501 }
2502 #undef _syscall5
2503 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2504 type5,arg5) \
2505 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2506 type5 arg5) { \
2507 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2508 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2509 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2510 "r"(__r4)); \
2511 }
2512 #undef _syscall6
2513 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2514 type5,arg5,type6,arg6) \
2515 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2516 type5 arg5, type6 arg6) { \
2517 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2518 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2519 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2520 "r"(__r4), "r"(__r5)); \
2521 }
2522
2523 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2524 int flags, void *arg, int *parent_tidptr,
2525 void *newtls, int *child_tidptr) {
2526 int64_t __res;
2527 {
2528 register uint64_t __flags __asm__("x0") = flags;
2529 register void *__stack __asm__("x1") = child_stack;
2530 register void *__ptid __asm__("x2") = parent_tidptr;
2531 register void *__tls __asm__("x3") = newtls;
2532 register int *__ctid __asm__("x4") = child_tidptr;
2533 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
2534 * used by the child.
2535 */
2536 "stp %1, %4, [%2, #-16]!\n"
2537
2538 /* %x0 = syscall(%x0 = flags,
2539 * %x1 = child_stack,
2540 * %x2 = parent_tidptr,
2541 * %x3 = newtls,
2542 * %x4 = child_tidptr)
2543 */
2544 "mov x8, %8\n"
2545 "svc 0x0\n"
2546
2547 /* if (%r0 != 0)
2548 * return %r0;
2549 */
2550 "mov %0, x0\n"
2551 "cbnz x0, 1f\n"
2552
2553 /* In the child, now. Call "fn(arg)".
2554 */
2555 "ldp x1, x0, [sp], #16\n"
2556 "blr x1\n"
2557
2558 /* Call _exit(%r0).
2559 */
2560 "mov x8, %9\n"
2561 "svc 0x0\n"
2562 "1:\n"
2563 : "=r" (__res)
2564 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2565 "r"(__ptid), "r"(__tls), "r"(__ctid),
2566 "i"(__NR_clone), "i"(__NR_exit)
2567 : "cc", "x8", "memory");
2568 }
2569 LSS_RETURN(int, __res);
2570 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002571 #elif defined(__mips__)
2572 #undef LSS_REG
2573 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
2574 (unsigned long)(a)
2575 #undef LSS_BODY
thestig@chromium.org952107f2014-08-01 02:22:56 +00002576 #undef LSS_SYSCALL_CLOBBERS
2577 #if _MIPS_SIM == _MIPS_SIM_ABI32
2578 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \
2579 "$11", "$12", "$13", "$14", "$15", \
2580 "$24", "$25", "hi", "lo", "memory"
2581 #else
2582 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \
2583 "$13", "$14", "$15", "$24", "$25", \
2584 "hi", "lo", "memory"
2585 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002586 #define LSS_BODY(type,name,r7,...) \
2587 register unsigned long __v0 __asm__("$2") = __NR_##name; \
2588 __asm__ __volatile__ ("syscall\n" \
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00002589 : "=r"(__v0), r7 (__r7) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002590 : "0"(__v0), ##__VA_ARGS__ \
thestig@chromium.org952107f2014-08-01 02:22:56 +00002591 : LSS_SYSCALL_CLOBBERS); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002592 LSS_RETURN(type, __v0, __r7)
2593 #undef _syscall0
2594 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002595 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002596 register unsigned long __r7 __asm__("$7"); \
2597 LSS_BODY(type, name, "=r"); \
2598 }
2599 #undef _syscall1
2600 #define _syscall1(type, name, type1, arg1) \
2601 type LSS_NAME(name)(type1 arg1) { \
2602 register unsigned long __r7 __asm__("$7"); \
2603 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
2604 }
2605 #undef _syscall2
2606 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2607 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2608 register unsigned long __r7 __asm__("$7"); \
2609 LSS_REG(4, arg1); LSS_REG(5, arg2); \
2610 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
2611 }
2612 #undef _syscall3
2613 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2614 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2615 register unsigned long __r7 __asm__("$7"); \
2616 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2617 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2618 }
2619 #undef _syscall4
2620 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2621 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2622 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2623 LSS_REG(7, arg4); \
2624 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2625 }
2626 #undef _syscall5
2627 #if _MIPS_SIM == _MIPS_SIM_ABI32
2628 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2629 * on the stack, whereas the new APIs use registers "r8" and "r9".
2630 */
2631 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2632 type5,arg5) \
2633 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2634 type5 arg5) { \
2635 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2636 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002637 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002638 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002639 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002640 "sw %5, 16($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002641 "syscall\n" \
2642 "addiu $29, 32\n" \
2643 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002644 : "+r"(__v0), "+r" (__r7) \
2645 : "r"(__r4), "r"(__r5), \
2646 "r"(__r6), "r" ((unsigned long)arg5) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002647 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002648 "$13", "$14", "$15", "$24", "$25", \
2649 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002650 LSS_RETURN(type, __v0, __r7); \
2651 }
2652 #else
2653 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2654 type5,arg5) \
2655 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2656 type5 arg5) { \
2657 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2658 LSS_REG(7, arg4); LSS_REG(8, arg5); \
2659 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2660 "r"(__r8)); \
2661 }
2662 #endif
2663 #undef _syscall6
2664 #if _MIPS_SIM == _MIPS_SIM_ABI32
2665 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2666 * on the stack, whereas the new APIs use registers "r8" and "r9".
2667 */
2668 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2669 type5,arg5,type6,arg6) \
2670 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2671 type5 arg5, type6 arg6) { \
2672 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2673 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002674 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002675 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002676 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002677 "sw %5, 16($29)\n" \
2678 "sw %6, 20($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002679 "syscall\n" \
2680 "addiu $29, 32\n" \
2681 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002682 : "+r"(__v0), "+r" (__r7) \
2683 : "r"(__r4), "r"(__r5), \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002684 "r"(__r6), "r" ((unsigned long)arg5), \
2685 "r" ((unsigned long)arg6) \
2686 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002687 "$13", "$14", "$15", "$24", "$25", \
2688 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002689 LSS_RETURN(type, __v0, __r7); \
2690 }
2691 #else
2692 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2693 type5,arg5,type6,arg6) \
2694 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2695 type5 arg5,type6 arg6) { \
2696 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2697 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
2698 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2699 "r"(__r8), "r"(__r9)); \
2700 }
2701 #endif
2702 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2703 int flags, void *arg, int *parent_tidptr,
2704 void *newtls, int *child_tidptr) {
vapier@chromium.orge0797682015-02-20 20:45:56 +00002705 register unsigned long __v0 __asm__("$2") = -EINVAL;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002706 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
2707 {
2708 register int __flags __asm__("$4") = flags;
2709 register void *__stack __asm__("$5") = child_stack;
2710 register void *__ptid __asm__("$6") = parent_tidptr;
2711 register int *__ctid __asm__("$8") = child_tidptr;
2712 __asm__ __volatile__(
2713 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
2714 "subu $29,24\n"
2715 #elif _MIPS_SIM == _MIPS_SIM_NABI32
2716 "sub $29,16\n"
2717 #else
2718 "dsubu $29,16\n"
2719 #endif
2720
2721 /* if (fn == NULL || child_stack == NULL)
2722 * return -EINVAL;
2723 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00002724 "beqz %4,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002725 "beqz %5,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002726
2727 /* Push "arg" and "fn" onto the stack that will be
2728 * used by the child.
2729 */
2730 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
vapier@chromium.orge0797682015-02-20 20:45:56 +00002731 "subu %5,32\n"
2732 "sw %4,0(%5)\n"
2733 "sw %7,4(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002734 #elif _MIPS_SIM == _MIPS_SIM_NABI32
vapier@chromium.orge0797682015-02-20 20:45:56 +00002735 "sub %5,32\n"
2736 "sw %4,0(%5)\n"
2737 "sw %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002738 #else
vapier@chromium.orge0797682015-02-20 20:45:56 +00002739 "dsubu %5,32\n"
2740 "sd %4,0(%5)\n"
2741 "sd %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002742 #endif
2743
2744 /* $7 = syscall($4 = flags,
2745 * $5 = child_stack,
2746 * $6 = parent_tidptr,
2747 * $7 = newtls,
2748 * $8 = child_tidptr)
2749 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00002750 "li $2,%2\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002751 "syscall\n"
2752
2753 /* if ($7 != 0)
2754 * return $2;
2755 */
2756 "bnez $7,1f\n"
2757 "bnez $2,1f\n"
2758
2759 /* In the child, now. Call "fn(arg)".
2760 */
2761 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
2762 "lw $25,0($29)\n"
2763 "lw $4,4($29)\n"
2764 #elif _MIPS_SIM == _MIPS_SIM_NABI32
2765 "lw $25,0($29)\n"
2766 "lw $4,8($29)\n"
2767 #else
2768 "ld $25,0($29)\n"
2769 "ld $4,8($29)\n"
2770 #endif
2771 "jalr $25\n"
2772
2773 /* Call _exit($2)
2774 */
2775 "move $4,$2\n"
vapier@chromium.orge0797682015-02-20 20:45:56 +00002776 "li $2,%3\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002777 "syscall\n"
2778
2779 "1:\n"
2780 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
2781 "addu $29, 24\n"
2782 #elif _MIPS_SIM == _MIPS_SIM_NABI32
2783 "add $29, 16\n"
2784 #else
2785 "daddu $29,16\n"
2786 #endif
petarj@mips.com0ece1c62013-04-10 00:28:04 +00002787 : "+r" (__v0), "+r" (__r7)
vapier@chromium.orge0797682015-02-20 20:45:56 +00002788 : "i"(__NR_clone), "i"(__NR_exit), "r"(fn),
2789 "r"(__stack), "r"(__flags), "r"(arg),
2790 "r"(__ptid), "r"(__ctid)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002791 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002792 "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002793 }
2794 LSS_RETURN(int, __v0, __r7);
2795 }
2796 #elif defined (__PPC__)
2797 #undef LSS_LOADARGS_0
2798 #define LSS_LOADARGS_0(name, dummy...) \
2799 __sc_0 = __NR_##name
2800 #undef LSS_LOADARGS_1
2801 #define LSS_LOADARGS_1(name, arg1) \
2802 LSS_LOADARGS_0(name); \
2803 __sc_3 = (unsigned long) (arg1)
2804 #undef LSS_LOADARGS_2
2805 #define LSS_LOADARGS_2(name, arg1, arg2) \
2806 LSS_LOADARGS_1(name, arg1); \
2807 __sc_4 = (unsigned long) (arg2)
2808 #undef LSS_LOADARGS_3
2809 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
2810 LSS_LOADARGS_2(name, arg1, arg2); \
2811 __sc_5 = (unsigned long) (arg3)
2812 #undef LSS_LOADARGS_4
2813 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
2814 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
2815 __sc_6 = (unsigned long) (arg4)
2816 #undef LSS_LOADARGS_5
2817 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
2818 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
2819 __sc_7 = (unsigned long) (arg5)
2820 #undef LSS_LOADARGS_6
2821 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
2822 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
2823 __sc_8 = (unsigned long) (arg6)
2824 #undef LSS_ASMINPUT_0
2825 #define LSS_ASMINPUT_0 "0" (__sc_0)
2826 #undef LSS_ASMINPUT_1
2827 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
2828 #undef LSS_ASMINPUT_2
2829 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
2830 #undef LSS_ASMINPUT_3
2831 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
2832 #undef LSS_ASMINPUT_4
2833 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
2834 #undef LSS_ASMINPUT_5
2835 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
2836 #undef LSS_ASMINPUT_6
2837 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
2838 #undef LSS_BODY
2839 #define LSS_BODY(nr, type, name, args...) \
2840 long __sc_ret, __sc_err; \
2841 { \
2842 register unsigned long __sc_0 __asm__ ("r0"); \
2843 register unsigned long __sc_3 __asm__ ("r3"); \
2844 register unsigned long __sc_4 __asm__ ("r4"); \
2845 register unsigned long __sc_5 __asm__ ("r5"); \
2846 register unsigned long __sc_6 __asm__ ("r6"); \
2847 register unsigned long __sc_7 __asm__ ("r7"); \
2848 register unsigned long __sc_8 __asm__ ("r8"); \
2849 \
2850 LSS_LOADARGS_##nr(name, args); \
2851 __asm__ __volatile__ \
2852 ("sc\n\t" \
2853 "mfcr %0" \
2854 : "=&r" (__sc_0), \
2855 "=&r" (__sc_3), "=&r" (__sc_4), \
2856 "=&r" (__sc_5), "=&r" (__sc_6), \
2857 "=&r" (__sc_7), "=&r" (__sc_8) \
2858 : LSS_ASMINPUT_##nr \
2859 : "cr0", "ctr", "memory", \
2860 "r9", "r10", "r11", "r12"); \
2861 __sc_ret = __sc_3; \
2862 __sc_err = __sc_0; \
2863 } \
2864 LSS_RETURN(type, __sc_ret, __sc_err)
2865 #undef _syscall0
2866 #define _syscall0(type, name) \
2867 type LSS_NAME(name)(void) { \
2868 LSS_BODY(0, type, name); \
2869 }
2870 #undef _syscall1
2871 #define _syscall1(type, name, type1, arg1) \
2872 type LSS_NAME(name)(type1 arg1) { \
2873 LSS_BODY(1, type, name, arg1); \
2874 }
2875 #undef _syscall2
2876 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2877 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2878 LSS_BODY(2, type, name, arg1, arg2); \
2879 }
2880 #undef _syscall3
2881 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2882 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2883 LSS_BODY(3, type, name, arg1, arg2, arg3); \
2884 }
2885 #undef _syscall4
2886 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
2887 type4, arg4) \
2888 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2889 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
2890 }
2891 #undef _syscall5
2892 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
2893 type4, arg4, type5, arg5) \
2894 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2895 type5 arg5) { \
2896 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
2897 }
2898 #undef _syscall6
2899 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
2900 type4, arg4, type5, arg5, type6, arg6) \
2901 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2902 type5 arg5, type6 arg6) { \
2903 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
2904 }
2905 /* clone function adapted from glibc 2.3.6 clone.S */
2906 /* TODO(csilvers): consider wrapping some args up in a struct, like we
2907 * do for i386's _syscall6, so we can compile successfully on gcc 2.95
2908 */
2909 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2910 int flags, void *arg, int *parent_tidptr,
2911 void *newtls, int *child_tidptr) {
2912 long __ret, __err;
2913 {
2914 register int (*__fn)(void *) __asm__ ("r8") = fn;
2915 register void *__cstack __asm__ ("r4") = child_stack;
2916 register int __flags __asm__ ("r3") = flags;
2917 register void * __arg __asm__ ("r9") = arg;
2918 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
2919 register void * __newtls __asm__ ("r6") = newtls;
2920 register int * __ctidptr __asm__ ("r7") = child_tidptr;
2921 __asm__ __volatile__(
2922 /* check for fn == NULL
2923 * and child_stack == NULL
2924 */
2925 "cmpwi cr0, %6, 0\n\t"
2926 "cmpwi cr1, %7, 0\n\t"
2927 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
2928 "beq- cr0, 1f\n\t"
2929
2930 /* set up stack frame for child */
2931 "clrrwi %7, %7, 4\n\t"
2932 "li 0, 0\n\t"
2933 "stwu 0, -16(%7)\n\t"
2934
2935 /* fn, arg, child_stack are saved across the syscall: r28-30 */
2936 "mr 28, %6\n\t"
2937 "mr 29, %7\n\t"
2938 "mr 27, %9\n\t"
2939
2940 /* syscall */
2941 "li 0, %4\n\t"
2942 /* flags already in r3
2943 * child_stack already in r4
2944 * ptidptr already in r5
2945 * newtls already in r6
2946 * ctidptr already in r7
2947 */
2948 "sc\n\t"
2949
2950 /* Test if syscall was successful */
2951 "cmpwi cr1, 3, 0\n\t"
2952 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
2953 "bne- cr1, 1f\n\t"
2954
2955 /* Do the function call */
2956 "mtctr 28\n\t"
2957 "mr 3, 27\n\t"
2958 "bctrl\n\t"
2959
2960 /* Call _exit(r3) */
2961 "li 0, %5\n\t"
2962 "sc\n\t"
2963
2964 /* Return to parent */
2965 "1:\n"
2966 "mfcr %1\n\t"
2967 "mr %0, 3\n\t"
2968 : "=r" (__ret), "=r" (__err)
2969 : "0" (-1), "1" (EINVAL),
2970 "i" (__NR_clone), "i" (__NR_exit),
2971 "r" (__fn), "r" (__cstack), "r" (__flags),
2972 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
2973 "r" (__ctidptr)
2974 : "cr0", "cr1", "memory", "ctr",
2975 "r0", "r29", "r27", "r28");
2976 }
2977 LSS_RETURN(int, __ret, __err);
2978 }
2979 #endif
2980 #define __NR__exit __NR_exit
2981 #define __NR__gettid __NR_gettid
2982 #define __NR__mremap __NR_mremap
phosek@chromium.orga9c02722013-08-16 17:31:42 +00002983 LSS_INLINE _syscall1(void *, brk, void *, e)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002984 LSS_INLINE _syscall1(int, chdir, const char *,p)
2985 LSS_INLINE _syscall1(int, close, int, f)
2986 LSS_INLINE _syscall2(int, clock_getres, int, c,
2987 struct kernel_timespec*, t)
2988 LSS_INLINE _syscall2(int, clock_gettime, int, c,
2989 struct kernel_timespec*, t)
2990 LSS_INLINE _syscall1(int, dup, int, f)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002991 #if !defined(__aarch64__)
2992 // The dup2 syscall has been deprecated on aarch64. We polyfill it below.
2993 LSS_INLINE _syscall2(int, dup2, int, s,
2994 int, d)
2995 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002996 LSS_INLINE _syscall3(int, execve, const char*, f,
2997 const char*const*,a,const char*const*, e)
2998 LSS_INLINE _syscall1(int, _exit, int, e)
2999 LSS_INLINE _syscall1(int, exit_group, int, e)
3000 LSS_INLINE _syscall3(int, fcntl, int, f,
3001 int, c, long, a)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003002 #if !defined(__aarch64__)
3003 // The fork syscall has been deprecated on aarch64. We polyfill it below.
3004 LSS_INLINE _syscall0(pid_t, fork)
3005 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003006 LSS_INLINE _syscall2(int, fstat, int, f,
3007 struct kernel_stat*, b)
3008 LSS_INLINE _syscall2(int, fstatfs, int, f,
3009 struct kernel_statfs*, b)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003010 #if defined(__x86_64__)
3011 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3012 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) {
3013 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l));
3014 }
3015 #else
3016 LSS_INLINE _syscall2(int, ftruncate, int, f,
3017 off_t, l)
3018 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003019 LSS_INLINE _syscall4(int, futex, int*, a,
3020 int, o, int, v,
3021 struct kernel_timespec*, t)
3022 LSS_INLINE _syscall3(int, getdents, int, f,
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003023 struct kernel_dirent*, d, int, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003024 LSS_INLINE _syscall3(int, getdents64, int, f,
3025 struct kernel_dirent64*, d, int, c)
3026 LSS_INLINE _syscall0(gid_t, getegid)
3027 LSS_INLINE _syscall0(uid_t, geteuid)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003028 #if !defined(__aarch64__)
3029 // The getgprp syscall has been deprecated on aarch64.
3030 LSS_INLINE _syscall0(pid_t, getpgrp)
3031 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003032 LSS_INLINE _syscall0(pid_t, getpid)
3033 LSS_INLINE _syscall0(pid_t, getppid)
3034 LSS_INLINE _syscall2(int, getpriority, int, a,
3035 int, b)
3036 LSS_INLINE _syscall3(int, getresgid, gid_t *, r,
3037 gid_t *, e, gid_t *, s)
3038 LSS_INLINE _syscall3(int, getresuid, uid_t *, r,
3039 uid_t *, e, uid_t *, s)
3040#if !defined(__ARM_EABI__)
3041 LSS_INLINE _syscall2(int, getrlimit, int, r,
3042 struct kernel_rlimit*, l)
3043#endif
3044 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
3045 LSS_INLINE _syscall0(pid_t, _gettid)
3046 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t,
3047 void*, tz)
3048 LSS_INLINE _syscall5(int, setxattr, const char *,p,
3049 const char *, n, const void *,v,
3050 size_t, s, int, f)
3051 LSS_INLINE _syscall5(int, lsetxattr, const char *,p,
3052 const char *, n, const void *,v,
3053 size_t, s, int, f)
3054 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p,
3055 const char *, n, void *, v, size_t, s)
3056 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p,
3057 const char *, n, void *, v, size_t, s)
3058 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p,
3059 char *, l, size_t, s)
3060 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p,
3061 char *, l, size_t, s)
3062 LSS_INLINE _syscall3(int, ioctl, int, d,
3063 int, r, void *, a)
3064 LSS_INLINE _syscall2(int, ioprio_get, int, which,
3065 int, who)
3066 LSS_INLINE _syscall3(int, ioprio_set, int, which,
3067 int, who, int, ioprio)
3068 LSS_INLINE _syscall2(int, kill, pid_t, p,
3069 int, s)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003070 #if defined(__x86_64__)
3071 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3072 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
3073 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
3074 LSS_SYSCALL_ARG(w));
3075 }
3076 #else
3077 LSS_INLINE _syscall3(off_t, lseek, int, f,
3078 off_t, o, int, w)
3079 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003080 LSS_INLINE _syscall2(int, munmap, void*, s,
3081 size_t, l)
3082 LSS_INLINE _syscall6(long, move_pages, pid_t, p,
3083 unsigned long, n, void **,g, int *, d,
3084 int *, s, int, f)
3085 LSS_INLINE _syscall3(int, mprotect, const void *,a,
3086 size_t, l, int, p)
3087 LSS_INLINE _syscall5(void*, _mremap, void*, o,
3088 size_t, os, size_t, ns,
3089 unsigned long, f, void *, a)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003090 #if !defined(__aarch64__)
3091 // The open and poll syscalls have been deprecated on aarch64. We polyfill
3092 // them below.
3093 LSS_INLINE _syscall3(int, open, const char*, p,
3094 int, f, int, m)
3095 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
3096 unsigned int, n, int, t)
3097 #endif
mseaborn@chromium.orge6c76822013-08-31 00:08:44 +00003098 LSS_INLINE _syscall5(int, prctl, int, option,
3099 unsigned long, arg2,
3100 unsigned long, arg3,
3101 unsigned long, arg4,
3102 unsigned long, arg5)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003103 LSS_INLINE _syscall4(long, ptrace, int, r,
3104 pid_t, p, void *, a, void *, d)
3105 #if defined(__NR_quotactl)
3106 // Defined on x86_64 / i386 only
3107 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special,
3108 int, id, caddr_t, addr)
3109 #endif
3110 LSS_INLINE _syscall3(ssize_t, read, int, f,
3111 void *, b, size_t, c)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003112 #if !defined(__aarch64__)
3113 // The readlink syscall has been deprecated on aarch64. We polyfill below.
3114 LSS_INLINE _syscall3(int, readlink, const char*, p,
3115 char*, b, size_t, s)
3116 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003117 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
3118 const struct kernel_sigaction*, a,
3119 struct kernel_sigaction*, o, size_t, c)
3120 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,
3121 size_t, c)
3122 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
3123 const struct kernel_sigset_t*, s,
3124 struct kernel_sigset_t*, o, size_t, c)
3125 LSS_INLINE _syscall2(int, rt_sigsuspend,
3126 const struct kernel_sigset_t*, s, size_t, c)
3127 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
3128 unsigned int, l, unsigned long *, m)
3129 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
3130 unsigned int, l, unsigned long *, m)
3131 LSS_INLINE _syscall0(int, sched_yield)
3132 LSS_INLINE _syscall1(long, set_tid_address, int *, t)
3133 LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
3134 LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
3135 LSS_INLINE _syscall1(int, setuid, uid_t, u)
3136 LSS_INLINE _syscall1(int, setgid, gid_t, g)
3137 LSS_INLINE _syscall2(int, setpgid, pid_t, p,
3138 pid_t, g)
3139 LSS_INLINE _syscall3(int, setpriority, int, a,
3140 int, b, int, p)
3141 LSS_INLINE _syscall3(int, setresgid, gid_t, r,
3142 gid_t, e, gid_t, s)
3143 LSS_INLINE _syscall3(int, setresuid, uid_t, r,
3144 uid_t, e, uid_t, s)
3145 LSS_INLINE _syscall2(int, setrlimit, int, r,
3146 const struct kernel_rlimit*, l)
3147 LSS_INLINE _syscall0(pid_t, setsid)
3148 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
3149 const stack_t*, o)
3150 #if defined(__NR_sigreturn)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003151 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003152 #endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003153 #if !defined(__aarch64__)
3154 // The stat syscall has been deprecated on aarch64. We polyfill it below.
3155 LSS_INLINE _syscall2(int, stat, const char*, f,
3156 struct kernel_stat*, b)
3157 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003158 LSS_INLINE _syscall2(int, statfs, const char*, f,
3159 struct kernel_statfs*, b)
3160 LSS_INLINE _syscall3(int, tgkill, pid_t, p,
3161 pid_t, t, int, s)
3162 LSS_INLINE _syscall2(int, tkill, pid_t, p,
3163 int, s)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003164 #if !defined(__aarch64__)
3165 // The unlink syscall has been deprecated on aarch64. We polyfill it below.
3166 LSS_INLINE _syscall1(int, unlink, const char*, f)
3167 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003168 LSS_INLINE _syscall3(ssize_t, write, int, f,
3169 const void *, b, size_t, c)
3170 LSS_INLINE _syscall3(ssize_t, writev, int, f,
3171 const struct kernel_iovec*, v, size_t, c)
3172 #if defined(__NR_getcpu)
3173 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00003174 unsigned *, node, void *, unused)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003175 #endif
3176 #if defined(__x86_64__) || \
3177 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
3178 LSS_INLINE _syscall3(int, recvmsg, int, s,
3179 struct kernel_msghdr*, m, int, f)
3180 LSS_INLINE _syscall3(int, sendmsg, int, s,
3181 const struct kernel_msghdr*, m, int, f)
3182 LSS_INLINE _syscall6(int, sendto, int, s,
3183 const void*, m, size_t, l,
3184 int, f,
3185 const struct kernel_sockaddr*, a, int, t)
3186 LSS_INLINE _syscall2(int, shutdown, int, s,
3187 int, h)
3188 LSS_INLINE _syscall3(int, socket, int, d,
3189 int, t, int, p)
3190 LSS_INLINE _syscall4(int, socketpair, int, d,
3191 int, t, int, p, int*, s)
3192 #endif
3193 #if defined(__x86_64__)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003194 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
3195 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset,
3196 loff_t len) {
3197 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode),
3198 (uint64_t)(offset), (uint64_t)(len));
3199 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003200
3201 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
3202 gid_t *egid,
3203 gid_t *sgid) {
3204 return LSS_NAME(getresgid)(rgid, egid, sgid);
3205 }
3206
3207 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
3208 uid_t *euid,
3209 uid_t *suid) {
3210 return LSS_NAME(getresuid)(ruid, euid, suid);
3211 }
3212
vapier@chromium.org2273e812013-04-01 17:52:44 +00003213 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */
3214 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
anton@chromium.org43de0522014-04-04 11:20:46 +00003215 int64_t o) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00003216 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
3217 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
3218 LSS_SYSCALL_ARG(d), (uint64_t)(o));
3219 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003220
3221 LSS_INLINE _syscall4(int, newfstatat, int, d,
3222 const char *, p,
3223 struct kernel_stat*, b, int, f)
3224
3225 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
3226 return LSS_NAME(setfsgid)(gid);
3227 }
3228
3229 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
3230 return LSS_NAME(setfsuid)(uid);
3231 }
3232
3233 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
3234 return LSS_NAME(setresgid)(rgid, egid, sgid);
3235 }
3236
3237 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
3238 return LSS_NAME(setresuid)(ruid, euid, suid);
3239 }
3240
3241 LSS_INLINE int LSS_NAME(sigaction)(int signum,
3242 const struct kernel_sigaction *act,
3243 struct kernel_sigaction *oldact) {
3244 /* On x86_64, the kernel requires us to always set our own
3245 * SA_RESTORER in order to be able to return from a signal handler.
3246 * This function must have a "magic" signature that the "gdb"
3247 * (and maybe the kernel?) can recognize.
3248 */
3249 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
3250 struct kernel_sigaction a = *act;
3251 a.sa_flags |= SA_RESTORER;
3252 a.sa_restorer = LSS_NAME(restore_rt)();
3253 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
3254 (KERNEL_NSIG+7)/8);
3255 } else {
3256 return LSS_NAME(rt_sigaction)(signum, act, oldact,
3257 (KERNEL_NSIG+7)/8);
3258 }
3259 }
3260
3261 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
3262 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
3263 }
3264
3265 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
3266 const struct kernel_sigset_t *set,
3267 struct kernel_sigset_t *oldset) {
3268 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
3269 }
3270
3271 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
3272 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
3273 }
3274 #endif
3275 #if defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003276 defined(__ARM_EABI__) || defined(__aarch64__) || \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003277 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
3278 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
3279 int*, s, int, o,
3280 struct kernel_rusage*, r)
3281
3282 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){
3283 return LSS_NAME(wait4)(pid, status, options, 0);
3284 }
3285 #endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003286 #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003287 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
3288 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
3289 #endif
3290 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
3291 #define __NR__getresgid32 __NR_getresgid32
3292 #define __NR__getresuid32 __NR_getresuid32
3293 #define __NR__setfsgid32 __NR_setfsgid32
3294 #define __NR__setfsuid32 __NR_setfsuid32
3295 #define __NR__setresgid32 __NR_setresgid32
3296 #define __NR__setresuid32 __NR_setresuid32
3297#if defined(__ARM_EABI__)
3298 LSS_INLINE _syscall2(int, ugetrlimit, int, r,
3299 struct kernel_rlimit*, l)
3300#endif
3301 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r,
3302 gid_t *, e, gid_t *, s)
3303 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r,
3304 uid_t *, e, uid_t *, s)
3305 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
3306 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
3307 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
3308 gid_t, e, gid_t, s)
3309 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
3310 uid_t, e, uid_t, s)
3311
3312 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
3313 gid_t *egid,
3314 gid_t *sgid) {
3315 int rc;
3316 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 &&
3317 LSS_ERRNO == ENOSYS) {
3318 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) {
3319 return EFAULT;
3320 }
3321 // Clear the high bits first, since getresgid only sets 16 bits
3322 *rgid = *egid = *sgid = 0;
3323 rc = LSS_NAME(getresgid)(rgid, egid, sgid);
3324 }
3325 return rc;
3326 }
3327
3328 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
3329 uid_t *euid,
3330 uid_t *suid) {
3331 int rc;
3332 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 &&
3333 LSS_ERRNO == ENOSYS) {
3334 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) {
3335 return EFAULT;
3336 }
3337 // Clear the high bits first, since getresuid only sets 16 bits
3338 *ruid = *euid = *suid = 0;
3339 rc = LSS_NAME(getresuid)(ruid, euid, suid);
3340 }
3341 return rc;
3342 }
3343
3344 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
3345 int rc;
3346 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
3347 LSS_ERRNO == ENOSYS) {
3348 if ((unsigned int)gid & ~0xFFFFu) {
3349 rc = EINVAL;
3350 } else {
3351 rc = LSS_NAME(setfsgid)(gid);
3352 }
3353 }
3354 return rc;
3355 }
3356
3357 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
3358 int rc;
3359 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
3360 LSS_ERRNO == ENOSYS) {
3361 if ((unsigned int)uid & ~0xFFFFu) {
3362 rc = EINVAL;
3363 } else {
3364 rc = LSS_NAME(setfsuid)(uid);
3365 }
3366 }
3367 return rc;
3368 }
3369
3370 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
3371 int rc;
3372 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
3373 LSS_ERRNO == ENOSYS) {
3374 if ((unsigned int)rgid & ~0xFFFFu ||
3375 (unsigned int)egid & ~0xFFFFu ||
3376 (unsigned int)sgid & ~0xFFFFu) {
3377 rc = EINVAL;
3378 } else {
3379 rc = LSS_NAME(setresgid)(rgid, egid, sgid);
3380 }
3381 }
3382 return rc;
3383 }
3384
3385 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
3386 int rc;
3387 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
3388 LSS_ERRNO == ENOSYS) {
3389 if ((unsigned int)ruid & ~0xFFFFu ||
3390 (unsigned int)euid & ~0xFFFFu ||
3391 (unsigned int)suid & ~0xFFFFu) {
3392 rc = EINVAL;
3393 } else {
3394 rc = LSS_NAME(setresuid)(ruid, euid, suid);
3395 }
3396 }
3397 return rc;
3398 }
3399 #endif
3400 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
3401 memset(&set->sig, 0, sizeof(set->sig));
3402 return 0;
3403 }
3404
3405 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
3406 memset(&set->sig, -1, sizeof(set->sig));
3407 return 0;
3408 }
3409
3410 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
3411 int signum) {
3412 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3413 LSS_ERRNO = EINVAL;
3414 return -1;
3415 } else {
3416 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
3417 |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0])));
3418 return 0;
3419 }
3420 }
3421
3422 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
3423 int signum) {
3424 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3425 LSS_ERRNO = EINVAL;
3426 return -1;
3427 } else {
3428 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
3429 &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0]))));
3430 return 0;
3431 }
3432 }
mcgrathr@google.coma7999932011-11-21 22:26:20 +00003433
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003434 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,
3435 int signum) {
3436 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3437 LSS_ERRNO = EINVAL;
3438 return -1;
3439 } else {
3440 return !!(set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] &
3441 (1UL << ((signum - 1) % (8*sizeof(set->sig[0])))));
3442 }
3443 }
3444 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
3445 defined(__ARM_EABI__) || \
3446 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || defined(__PPC__)
3447 #define __NR__sigaction __NR_sigaction
3448 #define __NR__sigpending __NR_sigpending
3449 #define __NR__sigprocmask __NR_sigprocmask
3450 #define __NR__sigsuspend __NR_sigsuspend
3451 #define __NR__socketcall __NR_socketcall
3452 LSS_INLINE _syscall2(int, fstat64, int, f,
3453 struct kernel_stat64 *, b)
zodiac@gmail.com4f470182010-10-13 03:47:54 +00003454 LSS_INLINE _syscall5(int, _llseek, uint, fd,
3455 unsigned long, hi, unsigned long, lo,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003456 loff_t *, res, uint, wh)
3457#if !defined(__ARM_EABI__)
3458 LSS_INLINE _syscall1(void*, mmap, void*, a)
3459#endif
3460 LSS_INLINE _syscall6(void*, mmap2, void*, s,
3461 size_t, l, int, p,
3462 int, f, int, d,
zodiac@gmail.com4f470182010-10-13 03:47:54 +00003463 off_t, o)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003464 LSS_INLINE _syscall3(int, _sigaction, int, s,
3465 const struct kernel_old_sigaction*, a,
3466 struct kernel_old_sigaction*, o)
3467 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s)
3468 LSS_INLINE _syscall3(int, _sigprocmask, int, h,
3469 const unsigned long*, s,
3470 unsigned long*, o)
3471 #ifdef __PPC__
3472 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s)
3473 #else
3474 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a,
3475 int, b,
3476 unsigned long, s)
3477 #endif
3478 LSS_INLINE _syscall2(int, stat64, const char *, p,
3479 struct kernel_stat64 *, b)
3480
3481 LSS_INLINE int LSS_NAME(sigaction)(int signum,
3482 const struct kernel_sigaction *act,
3483 struct kernel_sigaction *oldact) {
3484 int old_errno = LSS_ERRNO;
3485 int rc;
3486 struct kernel_sigaction a;
3487 if (act != NULL) {
3488 a = *act;
3489 #ifdef __i386__
3490 /* On i386, the kernel requires us to always set our own
3491 * SA_RESTORER when using realtime signals. Otherwise, it does not
3492 * know how to return from a signal handler. This function must have
3493 * a "magic" signature that the "gdb" (and maybe the kernel?) can
3494 * recognize.
3495 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
3496 * using non-realtime signals.
3497 *
3498 * TODO: Test whether ARM needs a restorer
3499 */
3500 if (!(a.sa_flags & SA_RESTORER)) {
3501 a.sa_flags |= SA_RESTORER;
3502 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
3503 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
3504 }
3505 #endif
3506 }
3507 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
3508 (KERNEL_NSIG+7)/8);
3509 if (rc < 0 && LSS_ERRNO == ENOSYS) {
3510 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
3511 if (!act) {
3512 ptr_a = NULL;
3513 } else {
3514 oa.sa_handler_ = act->sa_handler_;
3515 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
3516 #ifndef __mips__
3517 oa.sa_restorer = act->sa_restorer;
3518 #endif
3519 oa.sa_flags = act->sa_flags;
3520 }
3521 if (!oldact) {
3522 ptr_oa = NULL;
3523 }
3524 LSS_ERRNO = old_errno;
3525 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
3526 if (rc == 0 && oldact) {
3527 if (act) {
3528 memcpy(oldact, act, sizeof(*act));
3529 } else {
3530 memset(oldact, 0, sizeof(*oldact));
3531 }
3532 oldact->sa_handler_ = ptr_oa->sa_handler_;
3533 oldact->sa_flags = ptr_oa->sa_flags;
3534 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
3535 #ifndef __mips__
3536 oldact->sa_restorer = ptr_oa->sa_restorer;
3537 #endif
3538 }
3539 }
3540 return rc;
3541 }
3542
3543 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
3544 int old_errno = LSS_ERRNO;
3545 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
3546 if (rc < 0 && LSS_ERRNO == ENOSYS) {
3547 LSS_ERRNO = old_errno;
3548 LSS_NAME(sigemptyset)(set);
3549 rc = LSS_NAME(_sigpending)(&set->sig[0]);
3550 }
3551 return rc;
3552 }
3553
3554 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
3555 const struct kernel_sigset_t *set,
3556 struct kernel_sigset_t *oldset) {
3557 int olderrno = LSS_ERRNO;
3558 int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
3559 if (rc < 0 && LSS_ERRNO == ENOSYS) {
3560 LSS_ERRNO = olderrno;
3561 if (oldset) {
3562 LSS_NAME(sigemptyset)(oldset);
3563 }
3564 rc = LSS_NAME(_sigprocmask)(how,
3565 set ? &set->sig[0] : NULL,
3566 oldset ? &oldset->sig[0] : NULL);
3567 }
3568 return rc;
3569 }
3570
3571 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
3572 int olderrno = LSS_ERRNO;
3573 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
3574 if (rc < 0 && LSS_ERRNO == ENOSYS) {
3575 LSS_ERRNO = olderrno;
3576 rc = LSS_NAME(_sigsuspend)(
3577 #ifndef __PPC__
3578 set, 0,
3579 #endif
3580 set->sig[0]);
3581 }
3582 return rc;
3583 }
3584 #endif
3585 #if defined(__PPC__)
3586 #undef LSS_SC_LOADARGS_0
3587 #define LSS_SC_LOADARGS_0(dummy...)
3588 #undef LSS_SC_LOADARGS_1
3589 #define LSS_SC_LOADARGS_1(arg1) \
3590 __sc_4 = (unsigned long) (arg1)
3591 #undef LSS_SC_LOADARGS_2
3592 #define LSS_SC_LOADARGS_2(arg1, arg2) \
3593 LSS_SC_LOADARGS_1(arg1); \
3594 __sc_5 = (unsigned long) (arg2)
3595 #undef LSS_SC_LOADARGS_3
3596 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \
3597 LSS_SC_LOADARGS_2(arg1, arg2); \
3598 __sc_6 = (unsigned long) (arg3)
3599 #undef LSS_SC_LOADARGS_4
3600 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \
3601 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \
3602 __sc_7 = (unsigned long) (arg4)
3603 #undef LSS_SC_LOADARGS_5
3604 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \
3605 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \
3606 __sc_8 = (unsigned long) (arg5)
3607 #undef LSS_SC_BODY
3608 #define LSS_SC_BODY(nr, type, opt, args...) \
3609 long __sc_ret, __sc_err; \
3610 { \
3611 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \
3612 register unsigned long __sc_3 __asm__ ("r3") = opt; \
3613 register unsigned long __sc_4 __asm__ ("r4"); \
3614 register unsigned long __sc_5 __asm__ ("r5"); \
3615 register unsigned long __sc_6 __asm__ ("r6"); \
3616 register unsigned long __sc_7 __asm__ ("r7"); \
3617 register unsigned long __sc_8 __asm__ ("r8"); \
3618 LSS_SC_LOADARGS_##nr(args); \
3619 __asm__ __volatile__ \
3620 ("stwu 1, -48(1)\n\t" \
3621 "stw 4, 20(1)\n\t" \
3622 "stw 5, 24(1)\n\t" \
3623 "stw 6, 28(1)\n\t" \
3624 "stw 7, 32(1)\n\t" \
3625 "stw 8, 36(1)\n\t" \
3626 "addi 4, 1, 20\n\t" \
3627 "sc\n\t" \
3628 "mfcr %0" \
3629 : "=&r" (__sc_0), \
3630 "=&r" (__sc_3), "=&r" (__sc_4), \
3631 "=&r" (__sc_5), "=&r" (__sc_6), \
3632 "=&r" (__sc_7), "=&r" (__sc_8) \
3633 : LSS_ASMINPUT_##nr \
3634 : "cr0", "ctr", "memory"); \
3635 __sc_ret = __sc_3; \
3636 __sc_err = __sc_0; \
3637 } \
3638 LSS_RETURN(type, __sc_ret, __sc_err)
3639
3640 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
3641 int flags){
3642 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);
3643 }
3644
3645 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
3646 const struct kernel_msghdr *msg,
3647 int flags) {
3648 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);
3649 }
3650
3651 // TODO(csilvers): why is this ifdef'ed out?
3652#if 0
3653 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
3654 int flags,
3655 const struct kernel_sockaddr *to,
3656 unsigned int tolen) {
3657 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);
3658 }
3659#endif
3660
3661 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
3662 LSS_SC_BODY(2, int, 13, s, how);
3663 }
3664
3665 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
3666 LSS_SC_BODY(3, int, 1, domain, type, protocol);
3667 }
3668
3669 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
3670 int sv[2]) {
3671 LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
3672 }
3673 #endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003674 #if defined(__ARM_EABI__) || defined (__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003675 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
3676 int, flags)
3677 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
3678 msg, int, flags)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003679 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len,
3680 int, flags, const struct kernel_sockaddr*, to,
3681 unsigned int, tolen)
3682 LSS_INLINE _syscall2(int, shutdown, int, s, int, how)
3683 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol)
3684 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol,
3685 int*, sv)
3686 #endif
3687 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
3688 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
3689 #define __NR__socketcall __NR_socketcall
3690 LSS_INLINE _syscall2(int, _socketcall, int, c,
3691 va_list, a)
3692 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
3693 int rc;
3694 va_list ap;
3695 va_start(ap, op);
3696 rc = LSS_NAME(_socketcall)(op, ap);
3697 va_end(ap);
3698 return rc;
3699 }
3700
3701 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
3702 int flags){
3703 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
3704 }
3705
3706 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
3707 const struct kernel_msghdr *msg,
3708 int flags) {
3709 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
3710 }
3711
3712 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
3713 int flags,
3714 const struct kernel_sockaddr *to,
3715 unsigned int tolen) {
3716 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
3717 }
3718
3719 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
3720 return LSS_NAME(socketcall)(13, s, how);
3721 }
3722
3723 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
3724 return LSS_NAME(socketcall)(1, domain, type, protocol);
3725 }
3726
3727 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
3728 int sv[2]) {
3729 return LSS_NAME(socketcall)(8, d, type, protocol, sv);
3730 }
3731 #endif
3732 #if defined(__i386__) || defined(__PPC__)
3733 LSS_INLINE _syscall4(int, fstatat64, int, d,
3734 const char *, p,
3735 struct kernel_stat64 *, b, int, f)
3736 #endif
3737 #if defined(__i386__) || defined(__PPC__) || \
3738 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
3739 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
3740 int*, s, int, o)
3741 #endif
3742 #if defined(__mips__)
3743 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
3744 * both file handles through CPU registers.
3745 */
3746 LSS_INLINE int LSS_NAME(pipe)(int *p) {
3747 register unsigned long __v0 __asm__("$2") = __NR_pipe;
3748 register unsigned long __v1 __asm__("$3");
3749 register unsigned long __r7 __asm__("$7");
3750 __asm__ __volatile__ ("syscall\n"
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00003751 : "=r"(__v0), "=r"(__v1), "=r" (__r7)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003752 : "0"(__v0)
3753 : "$8", "$9", "$10", "$11", "$12",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003754 "$13", "$14", "$15", "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003755 if (__r7) {
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003756 unsigned long __errnovalue = __v0;
3757 LSS_ERRNO = __errnovalue;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003758 return -1;
3759 } else {
3760 p[0] = __v0;
3761 p[1] = __v1;
3762 return 0;
3763 }
3764 }
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003765 #elif !defined(__aarch64__)
3766 // The unlink syscall has been deprecated on aarch64. We polyfill it below.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003767 LSS_INLINE _syscall1(int, pipe, int *, p)
3768 #endif
3769 /* TODO(csilvers): see if ppc can/should support this as well */
3770 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
3771 defined(__ARM_EABI__) || \
3772 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
3773 #define __NR__statfs64 __NR_statfs64
3774 #define __NR__fstatfs64 __NR_fstatfs64
3775 LSS_INLINE _syscall3(int, _statfs64, const char*, p,
3776 size_t, s,struct kernel_statfs64*, b)
3777 LSS_INLINE _syscall3(int, _fstatfs64, int, f,
3778 size_t, s,struct kernel_statfs64*, b)
3779 LSS_INLINE int LSS_NAME(statfs64)(const char *p,
3780 struct kernel_statfs64 *b) {
3781 return LSS_NAME(_statfs64)(p, sizeof(*b), b);
3782 }
3783 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {
3784 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);
3785 }
3786 #endif
3787
3788 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {
3789 extern char **environ;
3790 return LSS_NAME(execve)(path, argv, (const char *const *)environ);
3791 }
3792
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00003793 LSS_INLINE pid_t LSS_NAME(gettid)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003794 pid_t tid = LSS_NAME(_gettid)();
3795 if (tid != -1) {
3796 return tid;
3797 }
3798 return LSS_NAME(getpid)();
3799 }
3800
3801 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
3802 size_t new_size, int flags, ...) {
3803 va_list ap;
3804 void *new_address, *rc;
3805 va_start(ap, flags);
3806 new_address = va_arg(ap, void *);
3807 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
3808 flags, new_address);
3809 va_end(ap);
3810 return rc;
3811 }
3812
3813 LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {
3814 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
3815 * then sends job control signals to the real parent, rather than to
3816 * the tracer. We reduce the risk of this happening by starting a
3817 * whole new time slice, and then quickly sending a SIGCONT signal
3818 * right after detaching from the tracee.
3819 *
3820 * We use tkill to ensure that we only issue a wakeup for the thread being
3821 * detached. Large multi threaded apps can take a long time in the kernel
3822 * processing SIGCONT.
3823 */
3824 int rc, err;
3825 LSS_NAME(sched_yield)();
3826 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
3827 err = LSS_ERRNO;
3828 LSS_NAME(tkill)(pid, SIGCONT);
3829 /* Old systems don't have tkill */
3830 if (LSS_ERRNO == ENOSYS)
3831 LSS_NAME(kill)(pid, SIGCONT);
3832 LSS_ERRNO = err;
3833 return rc;
3834 }
3835
3836 LSS_INLINE int LSS_NAME(raise)(int sig) {
3837 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
3838 }
3839
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00003840 LSS_INLINE int LSS_NAME(setpgrp)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003841 return LSS_NAME(setpgid)(0, 0);
3842 }
3843
3844 LSS_INLINE int LSS_NAME(sysconf)(int name) {
3845 extern int __getpagesize(void);
3846 switch (name) {
3847 case _SC_OPEN_MAX: {
3848 struct kernel_rlimit limit;
3849#if defined(__ARM_EABI__)
3850 return LSS_NAME(ugetrlimit)(RLIMIT_NOFILE, &limit) < 0
3851 ? 8192 : limit.rlim_cur;
3852#else
3853 return LSS_NAME(getrlimit)(RLIMIT_NOFILE, &limit) < 0
3854 ? 8192 : limit.rlim_cur;
3855#endif
3856 }
3857 case _SC_PAGESIZE:
3858 return __getpagesize();
3859 default:
3860 LSS_ERRNO = ENOSYS;
3861 return -1;
3862 }
3863 }
vapier@chromium.org2273e812013-04-01 17:52:44 +00003864 #if defined(__x86_64__)
3865 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
3866 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) {
3867 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
3868 LSS_SYSCALL_ARG(c), (uint64_t)(o));
3869 }
3870
3871 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c,
3872 loff_t o) {
3873 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
3874 LSS_SYSCALL_ARG(c), (uint64_t)(o));
3875 }
3876
3877 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, unsigned c) {
3878 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o),
3879 LSS_SYSCALL_ARG(c));
3880 }
3881 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003882 LSS_INLINE _syscall4(ssize_t, pread64, int, f,
3883 void *, b, size_t, c,
3884 loff_t, o)
3885 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f,
3886 const void *, b, size_t, c,
3887 loff_t, o)
3888 LSS_INLINE _syscall3(int, readahead, int, f,
3889 loff_t, o, unsigned, c)
petarj@mips.com6f972982015-04-22 00:29:49 +00003890 LSS_INLINE _syscall6(void *, mmap, void *, addr, size_t, length, int, prot,
3891 int, flags, int, fd, int64_t, offset)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003892 #else
3893 #define __NR__pread64 __NR_pread64
3894 #define __NR__pwrite64 __NR_pwrite64
3895 #define __NR__readahead __NR_readahead
mseaborn@chromium.org2c73abf2012-09-15 03:46:48 +00003896 #if defined(__ARM_EABI__) || defined(__mips__)
3897 /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register
3898 * pair. Hence these calls ignore their fourth argument (r3) so that their
mcgrathr@google.coma7999932011-11-21 22:26:20 +00003899 * fifth and sixth make such a pair (r4,r5).
3900 */
3901 #define LSS_LLARG_PAD 0,
3902 LSS_INLINE _syscall6(ssize_t, _pread64, int, f,
3903 void *, b, size_t, c,
3904 unsigned, skip, unsigned, o1, unsigned, o2)
3905 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f,
3906 const void *, b, size_t, c,
3907 unsigned, skip, unsigned, o1, unsigned, o2)
3908 LSS_INLINE _syscall5(int, _readahead, int, f,
3909 unsigned, skip,
3910 unsigned, o1, unsigned, o2, size_t, c)
3911 #else
3912 #define LSS_LLARG_PAD
3913 LSS_INLINE _syscall5(ssize_t, _pread64, int, f,
3914 void *, b, size_t, c, unsigned, o1,
3915 unsigned, o2)
3916 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f,
3917 const void *, b, size_t, c, unsigned, o1,
3918 long, o2)
3919 LSS_INLINE _syscall4(int, _readahead, int, f,
3920 unsigned, o1, unsigned, o2, size_t, c)
3921 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003922 /* We force 64bit-wide parameters onto the stack, then access each
3923 * 32-bit component individually. This guarantees that we build the
3924 * correct parameters independent of the native byte-order of the
3925 * underlying architecture.
3926 */
3927 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,
3928 loff_t off) {
3929 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00003930 return LSS_NAME(_pread64)(fd, buf, count,
3931 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003932 }
3933 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,
3934 size_t count, loff_t off) {
3935 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00003936 return LSS_NAME(_pwrite64)(fd, buf, count,
3937 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003938 }
3939 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) {
3940 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00003941 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], len);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003942 }
3943 #endif
3944#endif
3945
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003946#if defined(__aarch64__)
3947 LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f)
3948 LSS_INLINE _syscall6(void *, mmap, void *, addr, size_t, length, int, prot,
3949 int, flags, int, fd, int64_t, offset)
3950 LSS_INLINE _syscall4(int, newfstatat, int, dirfd, const char *, pathname,
3951 struct kernel_stat *, buf, int, flags)
3952 LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags)
3953 LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u,
3954 unsigned int, n, const struct kernel_timespec *, t,
vapier@chromium.orgdb1e07d2015-01-16 14:14:42 +00003955 const struct kernel_sigset_t *, sigmask, size_t, s)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003956 LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b,
3957 size_t, s)
3958#endif
3959
3960/*
3961 * Polyfills for deprecated syscalls.
3962 */
3963
3964#if defined(__aarch64__)
3965 LSS_INLINE int LSS_NAME(dup2)(int s, int d) {
3966 return LSS_NAME(dup3)(s, d, 0);
3967 }
3968
3969 LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) {
3970 return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode);
3971 }
3972
3973 LSS_INLINE int LSS_NAME(unlink)(const char *pathname) {
3974 return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0);
3975 }
3976
3977 LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer,
3978 size_t size) {
3979 return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size);
3980 }
3981
3982 LSS_INLINE pid_t LSS_NAME(pipe)(int *pipefd) {
3983 return LSS_NAME(pipe2)(pipefd, 0);
3984 }
3985
3986 LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds,
3987 int timeout) {
3988 struct kernel_timespec timeout_ts;
3989 struct kernel_timespec *timeout_ts_p = NULL;
3990
3991 if (timeout >= 0) {
3992 timeout_ts.tv_sec = timeout / 1000;
3993 timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
3994 timeout_ts_p = &timeout_ts;
3995 }
3996 return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0);
3997 }
3998
3999 LSS_INLINE int LSS_NAME(stat)(const char *pathname,
4000 struct kernel_stat *buf) {
4001 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0);
4002 }
4003
4004 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4005 // No fork syscall on aarch64 - implement by means of the clone syscall.
4006 // Note that this does not reset glibc's cached view of the PID/TID, so
4007 // some glibc interfaces might go wrong in the forked subprocess.
4008 int flags = SIGCHLD;
4009 void *child_stack = NULL;
4010 void *parent_tidptr = NULL;
4011 void *newtls = NULL;
4012 void *child_tidptr = NULL;
4013
4014 LSS_REG(0, flags);
4015 LSS_REG(1, child_stack);
4016 LSS_REG(2, parent_tidptr);
4017 LSS_REG(3, newtls);
4018 LSS_REG(4, child_tidptr);
4019 LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),
4020 "r"(__r4));
4021 }
4022#endif
4023
mseaborn@chromium.orgca749372012-09-05 18:26:20 +00004024#ifdef __ANDROID__
4025 /* These restore the original values of these macros saved by the
4026 * corresponding #pragma push_macro near the top of this file. */
4027# pragma pop_macro("stat64")
4028# pragma pop_macro("fstat64")
4029# pragma pop_macro("lstat64")
4030#endif
4031
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004032#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
4033}
4034#endif
4035
4036#endif
4037#endif