Planeshift
|
00001 /* Copyright (c) 2005-2011, Google Inc. 00002 * All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are 00006 * met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above 00011 * copyright notice, this list of conditions and the following disclaimer 00012 * in the documentation and/or other materials provided with the 00013 * distribution. 00014 * * Neither the name of Google Inc. nor the names of its 00015 * contributors may be used to endorse or promote products derived from 00016 * this software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00022 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00023 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00024 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * --- 00031 * Author: Markus Gutschke 00032 */ 00033 00034 /* This file includes Linux-specific support functions common to the 00035 * coredumper and the thread lister; primarily, this is a collection 00036 * of direct system calls, and a couple of symbols missing from 00037 * standard header files. 00038 * There are a few options that the including file can set to control 00039 * the behavior of this file: 00040 * 00041 * SYS_CPLUSPLUS: 00042 * The entire header file will normally be wrapped in 'extern "C" { }", 00043 * making it suitable for compilation as both C and C++ source. If you 00044 * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit 00045 * the wrapping. N.B. doing so will suppress inclusion of all prerequisite 00046 * system header files, too. It is the caller's responsibility to provide 00047 * the necessary definitions. 00048 * 00049 * SYS_ERRNO: 00050 * All system calls will update "errno" unless overriden by setting the 00051 * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be 00052 * an l-value. 00053 * 00054 * SYS_INLINE: 00055 * New symbols will be defined "static inline", unless overridden by 00056 * the SYS_INLINE macro. 00057 * 00058 * SYS_LINUX_SYSCALL_SUPPORT_H 00059 * This macro is used to avoid multiple inclusions of this header file. 00060 * If you need to include this file more than once, make sure to 00061 * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion. 00062 * 00063 * SYS_PREFIX: 00064 * New system calls will have a prefix of "sys_" unless overridden by 00065 * the SYS_PREFIX macro. Valid values for this macro are [0..9] which 00066 * results in prefixes "sys[0..9]_". It is also possible to set this 00067 * macro to -1, which avoids all prefixes. 00068 * 00069 * SYS_SYSCALL_ENTRYPOINT: 00070 * Some applications (such as sandboxes that filter system calls), need 00071 * to be able to run custom-code each time a system call is made. If this 00072 * macro is defined, it expands to the name of a "common" symbol. If 00073 * this symbol is assigned a non-NULL pointer value, it is used as the 00074 * address of the system call entrypoint. 00075 * A pointer to this symbol can be obtained by calling 00076 * get_syscall_entrypoint() 00077 * 00078 * This file defines a few internal symbols that all start with "LSS_". 00079 * Do not access these symbols from outside this file. They are not part 00080 * of the supported API. 00081 */ 00082 #ifndef SYS_LINUX_SYSCALL_SUPPORT_H 00083 #define SYS_LINUX_SYSCALL_SUPPORT_H 00084 00085 /* We currently only support x86-32, x86-64, ARM, MIPS, and PPC on Linux. 00086 * Porting to other related platforms should not be difficult. 00087 */ 00088 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \ 00089 defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__)) \ 00090 && (defined(__linux) || defined(__ANDROID__)) 00091 00092 #ifndef SYS_CPLUSPLUS 00093 #ifdef __cplusplus 00094 /* Some system header files in older versions of gcc neglect to properly 00095 * handle being included from C++. As it appears to be harmless to have 00096 * multiple nested 'extern "C"' blocks, just add another one here. 00097 */ 00098 extern "C" { 00099 #endif 00100 00101 #include <errno.h> 00102 #include <fcntl.h> 00103 #include <signal.h> 00104 #include <stdarg.h> 00105 #include <stddef.h> 00106 #include <string.h> 00107 #include <sys/ptrace.h> 00108 #include <sys/resource.h> 00109 #include <sys/time.h> 00110 #include <sys/types.h> 00111 #include <sys/syscall.h> 00112 #include <unistd.h> 00113 #include <linux/unistd.h> 00114 #include <endian.h> 00115 00116 #ifdef __mips__ 00117 /* Include definitions of the ABI currently in use. */ 00118 #include <sgidefs.h> 00119 #endif 00120 #endif 00121 00122 /* The Android NDK's <sys/stat.h> #defines these macros as aliases 00123 * to their non-64 counterparts. To avoid naming conflict, remove them. */ 00124 #ifdef __ANDROID__ 00125 /* These are restored by the corresponding #pragma pop_macro near 00126 * the end of this file. */ 00127 # pragma push_macro("stat64") 00128 # pragma push_macro("fstat64") 00129 # pragma push_macro("lstat64") 00130 # undef stat64 00131 # undef fstat64 00132 # undef lstat64 00133 #endif 00134 00135 /* As glibc often provides subtly incompatible data structures (and implicit 00136 * wrapper functions that convert them), we provide our own kernel data 00137 * structures for use by the system calls. 00138 * These structures have been developed by using Linux 2.6.23 headers for 00139 * reference. Note though, we do not care about exact API compatibility 00140 * with the kernel, and in fact the kernel often does not have a single 00141 * API that works across architectures. Instead, we try to mimic the glibc 00142 * API where reasonable, and only guarantee ABI compatibility with the 00143 * kernel headers. 00144 * Most notably, here are a few changes that were made to the structures 00145 * defined by kernel headers: 00146 * 00147 * - we only define structures, but not symbolic names for kernel data 00148 * types. For the latter, we directly use the native C datatype 00149 * (i.e. "unsigned" instead of "mode_t"). 00150 * - in a few cases, it is possible to define identical structures for 00151 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by 00152 * standardizing on the 64bit version of the data types. In particular, 00153 * this means that we use "unsigned" where the 32bit headers say 00154 * "unsigned long". 00155 * - overall, we try to minimize the number of cases where we need to 00156 * conditionally define different structures. 00157 * - the "struct kernel_sigaction" class of structures have been 00158 * modified to more closely mimic glibc's API by introducing an 00159 * anonymous union for the function pointer. 00160 * - a small number of field names had to have an underscore appended to 00161 * them, because glibc defines a global macro by the same name. 00162 */ 00163 00164 /* include/linux/dirent.h */ 00165 struct kernel_dirent64 { 00166 unsigned long long d_ino; 00167 long long d_off; 00168 unsigned short d_reclen; 00169 unsigned char d_type; 00170 char d_name[256]; 00171 }; 00172 00173 /* include/linux/dirent.h */ 00174 struct kernel_dirent { 00175 long d_ino; 00176 long d_off; 00177 unsigned short d_reclen; 00178 char d_name[256]; 00179 }; 00180 00181 /* include/linux/uio.h */ 00182 struct kernel_iovec { 00183 void *iov_base; 00184 unsigned long iov_len; 00185 }; 00186 00187 /* include/linux/socket.h */ 00188 struct kernel_msghdr { 00189 void *msg_name; 00190 int msg_namelen; 00191 struct kernel_iovec*msg_iov; 00192 unsigned long msg_iovlen; 00193 void *msg_control; 00194 unsigned long msg_controllen; 00195 unsigned msg_flags; 00196 }; 00197 00198 /* include/asm-generic/poll.h */ 00199 struct kernel_pollfd { 00200 int fd; 00201 short events; 00202 short revents; 00203 }; 00204 00205 /* include/linux/resource.h */ 00206 struct kernel_rlimit { 00207 unsigned long rlim_cur; 00208 unsigned long rlim_max; 00209 }; 00210 00211 /* include/linux/time.h */ 00212 struct kernel_timespec { 00213 long tv_sec; 00214 long tv_nsec; 00215 }; 00216 00217 /* include/linux/time.h */ 00218 struct kernel_timeval { 00219 long tv_sec; 00220 long tv_usec; 00221 }; 00222 00223 /* include/linux/resource.h */ 00224 struct kernel_rusage { 00225 struct kernel_timeval ru_utime; 00226 struct kernel_timeval ru_stime; 00227 long ru_maxrss; 00228 long ru_ixrss; 00229 long ru_idrss; 00230 long ru_isrss; 00231 long ru_minflt; 00232 long ru_majflt; 00233 long ru_nswap; 00234 long ru_inblock; 00235 long ru_oublock; 00236 long ru_msgsnd; 00237 long ru_msgrcv; 00238 long ru_nsignals; 00239 long ru_nvcsw; 00240 long ru_nivcsw; 00241 }; 00242 00243 struct siginfo; 00244 #if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \ 00245 || defined(__PPC__) 00246 00247 /* include/asm-{arm,i386,mips,ppc}/signal.h */ 00248 struct kernel_old_sigaction { 00249 union { 00250 void (*sa_handler_)(int); 00251 void (*sa_sigaction_)(int, struct siginfo *, void *); 00252 }; 00253 unsigned long sa_mask; 00254 unsigned long sa_flags; 00255 void (*sa_restorer)(void); 00256 } __attribute__((packed,aligned(4))); 00257 #elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 00258 #define kernel_old_sigaction kernel_sigaction 00259 #endif 00260 00261 /* Some kernel functions (e.g. sigaction() in 2.6.23) require that the 00262 * exactly match the size of the signal set, even though the API was 00263 * intended to be extensible. We define our own KERNEL_NSIG to deal with 00264 * this. 00265 * Please note that glibc provides signals [1.._NSIG-1], whereas the 00266 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The 00267 * actual number of signals is obviously the same, but the constants 00268 * differ by one. 00269 */ 00270 #ifdef __mips__ 00271 #define KERNEL_NSIG 128 00272 #else 00273 #define KERNEL_NSIG 64 00274 #endif 00275 00276 /* include/asm-{arm,i386,mips,x86_64}/signal.h */ 00277 struct kernel_sigset_t { 00278 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/ 00279 (8*sizeof(unsigned long))]; 00280 }; 00281 00282 /* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */ 00283 struct kernel_sigaction { 00284 #ifdef __mips__ 00285 unsigned long sa_flags; 00286 union { 00287 void (*sa_handler_)(int); 00288 void (*sa_sigaction_)(int, struct siginfo *, void *); 00289 }; 00290 struct kernel_sigset_t sa_mask; 00291 #else 00292 union { 00293 void (*sa_handler_)(int); 00294 void (*sa_sigaction_)(int, struct siginfo *, void *); 00295 }; 00296 unsigned long sa_flags; 00297 void (*sa_restorer)(void); 00298 struct kernel_sigset_t sa_mask; 00299 #endif 00300 }; 00301 00302 /* include/linux/socket.h */ 00303 struct kernel_sockaddr { 00304 unsigned short sa_family; 00305 char sa_data[14]; 00306 }; 00307 00308 /* include/asm-{arm,i386,mips,ppc}/stat.h */ 00309 #ifdef __mips__ 00310 #if _MIPS_SIM == _MIPS_SIM_ABI64 00311 struct kernel_stat { 00312 #else 00313 struct kernel_stat64 { 00314 #endif 00315 unsigned st_dev; 00316 unsigned __pad0[3]; 00317 unsigned long long st_ino; 00318 unsigned st_mode; 00319 unsigned st_nlink; 00320 unsigned st_uid; 00321 unsigned st_gid; 00322 unsigned st_rdev; 00323 unsigned __pad1[3]; 00324 long long st_size; 00325 unsigned st_atime_; 00326 unsigned st_atime_nsec_; 00327 unsigned st_mtime_; 00328 unsigned st_mtime_nsec_; 00329 unsigned st_ctime_; 00330 unsigned st_ctime_nsec_; 00331 unsigned st_blksize; 00332 unsigned __pad2; 00333 unsigned long long st_blocks; 00334 }; 00335 #elif defined __PPC__ 00336 struct kernel_stat64 { 00337 unsigned long long st_dev; 00338 unsigned long long st_ino; 00339 unsigned st_mode; 00340 unsigned st_nlink; 00341 unsigned st_uid; 00342 unsigned st_gid; 00343 unsigned long long st_rdev; 00344 unsigned short int __pad2; 00345 long long st_size; 00346 long st_blksize; 00347 long long st_blocks; 00348 long st_atime_; 00349 unsigned long st_atime_nsec_; 00350 long st_mtime_; 00351 unsigned long st_mtime_nsec_; 00352 long st_ctime_; 00353 unsigned long st_ctime_nsec_; 00354 unsigned long __unused4; 00355 unsigned long __unused5; 00356 }; 00357 #else 00358 struct kernel_stat64 { 00359 unsigned long long st_dev; 00360 unsigned char __pad0[4]; 00361 unsigned __st_ino; 00362 unsigned st_mode; 00363 unsigned st_nlink; 00364 unsigned st_uid; 00365 unsigned st_gid; 00366 unsigned long long st_rdev; 00367 unsigned char __pad3[4]; 00368 long long st_size; 00369 unsigned st_blksize; 00370 unsigned long long st_blocks; 00371 unsigned st_atime_; 00372 unsigned st_atime_nsec_; 00373 unsigned st_mtime_; 00374 unsigned st_mtime_nsec_; 00375 unsigned st_ctime_; 00376 unsigned st_ctime_nsec_; 00377 unsigned long long st_ino; 00378 }; 00379 #endif 00380 00381 /* include/asm-{arm,i386,mips,x86_64,ppc}/stat.h */ 00382 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) 00383 struct kernel_stat { 00384 /* The kernel headers suggest that st_dev and st_rdev should be 32bit 00385 * quantities encoding 12bit major and 20bit minor numbers in an interleaved 00386 * format. In reality, we do not see useful data in the top bits. So, 00387 * we'll leave the padding in here, until we find a better solution. 00388 */ 00389 unsigned short st_dev; 00390 short pad1; 00391 unsigned st_ino; 00392 unsigned short st_mode; 00393 unsigned short st_nlink; 00394 unsigned short st_uid; 00395 unsigned short st_gid; 00396 unsigned short st_rdev; 00397 short pad2; 00398 unsigned st_size; 00399 unsigned st_blksize; 00400 unsigned st_blocks; 00401 unsigned st_atime_; 00402 unsigned st_atime_nsec_; 00403 unsigned st_mtime_; 00404 unsigned st_mtime_nsec_; 00405 unsigned st_ctime_; 00406 unsigned st_ctime_nsec_; 00407 unsigned __unused4; 00408 unsigned __unused5; 00409 }; 00410 #elif defined(__x86_64__) 00411 struct kernel_stat { 00412 unsigned long st_dev; 00413 unsigned long st_ino; 00414 unsigned long st_nlink; 00415 unsigned st_mode; 00416 unsigned st_uid; 00417 unsigned st_gid; 00418 unsigned __pad0; 00419 unsigned long st_rdev; 00420 long st_size; 00421 long st_blksize; 00422 long st_blocks; 00423 unsigned long st_atime_; 00424 unsigned long st_atime_nsec_; 00425 unsigned long st_mtime_; 00426 unsigned long st_mtime_nsec_; 00427 unsigned long st_ctime_; 00428 unsigned long st_ctime_nsec_; 00429 long __unused[3]; 00430 }; 00431 #elif defined(__PPC__) 00432 struct kernel_stat { 00433 unsigned st_dev; 00434 unsigned long st_ino; // ino_t 00435 unsigned long st_mode; // mode_t 00436 unsigned short st_nlink; // nlink_t 00437 unsigned st_uid; // uid_t 00438 unsigned st_gid; // gid_t 00439 unsigned st_rdev; 00440 long st_size; // off_t 00441 unsigned long st_blksize; 00442 unsigned long st_blocks; 00443 unsigned long st_atime_; 00444 unsigned long st_atime_nsec_; 00445 unsigned long st_mtime_; 00446 unsigned long st_mtime_nsec_; 00447 unsigned long st_ctime_; 00448 unsigned long st_ctime_nsec_; 00449 unsigned long __unused4; 00450 unsigned long __unused5; 00451 }; 00452 #elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) 00453 struct kernel_stat { 00454 unsigned st_dev; 00455 int st_pad1[3]; 00456 unsigned st_ino; 00457 unsigned st_mode; 00458 unsigned st_nlink; 00459 unsigned st_uid; 00460 unsigned st_gid; 00461 unsigned st_rdev; 00462 int st_pad2[2]; 00463 long st_size; 00464 int st_pad3; 00465 long st_atime_; 00466 long st_atime_nsec_; 00467 long st_mtime_; 00468 long st_mtime_nsec_; 00469 long st_ctime_; 00470 long st_ctime_nsec_; 00471 int st_blksize; 00472 int st_blocks; 00473 int st_pad4[14]; 00474 }; 00475 #endif 00476 00477 /* include/asm-{arm,i386,mips,x86_64,ppc}/statfs.h */ 00478 #ifdef __mips__ 00479 #if _MIPS_SIM != _MIPS_SIM_ABI64 00480 struct kernel_statfs64 { 00481 unsigned long f_type; 00482 unsigned long f_bsize; 00483 unsigned long f_frsize; 00484 unsigned long __pad; 00485 unsigned long long f_blocks; 00486 unsigned long long f_bfree; 00487 unsigned long long f_files; 00488 unsigned long long f_ffree; 00489 unsigned long long f_bavail; 00490 struct { int val[2]; } f_fsid; 00491 unsigned long f_namelen; 00492 unsigned long f_spare[6]; 00493 }; 00494 #endif 00495 #elif !defined(__x86_64__) 00496 struct kernel_statfs64 { 00497 unsigned long f_type; 00498 unsigned long f_bsize; 00499 unsigned long long f_blocks; 00500 unsigned long long f_bfree; 00501 unsigned long long f_bavail; 00502 unsigned long long f_files; 00503 unsigned long long f_ffree; 00504 struct { int val[2]; } f_fsid; 00505 unsigned long f_namelen; 00506 unsigned long f_frsize; 00507 unsigned long f_spare[5]; 00508 }; 00509 #endif 00510 00511 /* include/asm-{arm,i386,mips,x86_64,ppc,generic}/statfs.h */ 00512 #ifdef __mips__ 00513 struct kernel_statfs { 00514 long f_type; 00515 long f_bsize; 00516 long f_frsize; 00517 long f_blocks; 00518 long f_bfree; 00519 long f_files; 00520 long f_ffree; 00521 long f_bavail; 00522 struct { int val[2]; } f_fsid; 00523 long f_namelen; 00524 long f_spare[6]; 00525 }; 00526 #else 00527 struct kernel_statfs { 00528 /* x86_64 actually defines all these fields as signed, whereas all other */ 00529 /* platforms define them as unsigned. Leaving them at unsigned should not */ 00530 /* cause any problems. */ 00531 unsigned long f_type; 00532 unsigned long f_bsize; 00533 unsigned long f_blocks; 00534 unsigned long f_bfree; 00535 unsigned long f_bavail; 00536 unsigned long f_files; 00537 unsigned long f_ffree; 00538 struct { int val[2]; } f_fsid; 00539 unsigned long f_namelen; 00540 unsigned long f_frsize; 00541 unsigned long f_spare[5]; 00542 }; 00543 #endif 00544 00545 00546 /* Definitions missing from the standard header files */ 00547 #ifndef O_DIRECTORY 00548 #if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) 00549 #define O_DIRECTORY 0040000 00550 #else 00551 #define O_DIRECTORY 0200000 00552 #endif 00553 #endif 00554 #ifndef NT_PRXFPREG 00555 #define NT_PRXFPREG 0x46e62b7f 00556 #endif 00557 #ifndef PTRACE_GETFPXREGS 00558 #define PTRACE_GETFPXREGS ((enum __ptrace_request)18) 00559 #endif 00560 #ifndef PR_GET_DUMPABLE 00561 #define PR_GET_DUMPABLE 3 00562 #endif 00563 #ifndef PR_SET_DUMPABLE 00564 #define PR_SET_DUMPABLE 4 00565 #endif 00566 #ifndef PR_GET_SECCOMP 00567 #define PR_GET_SECCOMP 21 00568 #endif 00569 #ifndef PR_SET_SECCOMP 00570 #define PR_SET_SECCOMP 22 00571 #endif 00572 #ifndef AT_FDCWD 00573 #define AT_FDCWD (-100) 00574 #endif 00575 #ifndef AT_SYMLINK_NOFOLLOW 00576 #define AT_SYMLINK_NOFOLLOW 0x100 00577 #endif 00578 #ifndef AT_REMOVEDIR 00579 #define AT_REMOVEDIR 0x200 00580 #endif 00581 #ifndef MREMAP_FIXED 00582 #define MREMAP_FIXED 2 00583 #endif 00584 #ifndef SA_RESTORER 00585 #define SA_RESTORER 0x04000000 00586 #endif 00587 #ifndef CPUCLOCK_PROF 00588 #define CPUCLOCK_PROF 0 00589 #endif 00590 #ifndef CPUCLOCK_VIRT 00591 #define CPUCLOCK_VIRT 1 00592 #endif 00593 #ifndef CPUCLOCK_SCHED 00594 #define CPUCLOCK_SCHED 2 00595 #endif 00596 #ifndef CPUCLOCK_PERTHREAD_MASK 00597 #define CPUCLOCK_PERTHREAD_MASK 4 00598 #endif 00599 #ifndef MAKE_PROCESS_CPUCLOCK 00600 #define MAKE_PROCESS_CPUCLOCK(pid, clock) \ 00601 ((~(int)(pid) << 3) | (int)(clock)) 00602 #endif 00603 #ifndef MAKE_THREAD_CPUCLOCK 00604 #define MAKE_THREAD_CPUCLOCK(tid, clock) \ 00605 ((~(int)(tid) << 3) | (int)((clock) | CPUCLOCK_PERTHREAD_MASK)) 00606 #endif 00607 00608 #ifndef FUTEX_WAIT 00609 #define FUTEX_WAIT 0 00610 #endif 00611 #ifndef FUTEX_WAKE 00612 #define FUTEX_WAKE 1 00613 #endif 00614 #ifndef FUTEX_FD 00615 #define FUTEX_FD 2 00616 #endif 00617 #ifndef FUTEX_REQUEUE 00618 #define FUTEX_REQUEUE 3 00619 #endif 00620 #ifndef FUTEX_CMP_REQUEUE 00621 #define FUTEX_CMP_REQUEUE 4 00622 #endif 00623 #ifndef FUTEX_WAKE_OP 00624 #define FUTEX_WAKE_OP 5 00625 #endif 00626 #ifndef FUTEX_LOCK_PI 00627 #define FUTEX_LOCK_PI 6 00628 #endif 00629 #ifndef FUTEX_UNLOCK_PI 00630 #define FUTEX_UNLOCK_PI 7 00631 #endif 00632 #ifndef FUTEX_TRYLOCK_PI 00633 #define FUTEX_TRYLOCK_PI 8 00634 #endif 00635 #ifndef FUTEX_PRIVATE_FLAG 00636 #define FUTEX_PRIVATE_FLAG 128 00637 #endif 00638 #ifndef FUTEX_CMD_MASK 00639 #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG 00640 #endif 00641 #ifndef FUTEX_WAIT_PRIVATE 00642 #define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) 00643 #endif 00644 #ifndef FUTEX_WAKE_PRIVATE 00645 #define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) 00646 #endif 00647 #ifndef FUTEX_REQUEUE_PRIVATE 00648 #define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG) 00649 #endif 00650 #ifndef FUTEX_CMP_REQUEUE_PRIVATE 00651 #define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG) 00652 #endif 00653 #ifndef FUTEX_WAKE_OP_PRIVATE 00654 #define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG) 00655 #endif 00656 #ifndef FUTEX_LOCK_PI_PRIVATE 00657 #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) 00658 #endif 00659 #ifndef FUTEX_UNLOCK_PI_PRIVATE 00660 #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) 00661 #endif 00662 #ifndef FUTEX_TRYLOCK_PI_PRIVATE 00663 #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) 00664 #endif 00665 00666 00667 #if defined(__x86_64__) 00668 #ifndef ARCH_SET_GS 00669 #define ARCH_SET_GS 0x1001 00670 #endif 00671 #ifndef ARCH_GET_GS 00672 #define ARCH_GET_GS 0x1004 00673 #endif 00674 #endif 00675 00676 #if defined(__i386__) 00677 #ifndef __NR_quotactl 00678 #define __NR_quotactl 131 00679 #endif 00680 #ifndef __NR_setresuid 00681 #define __NR_setresuid 164 00682 #define __NR_getresuid 165 00683 #define __NR_setresgid 170 00684 #define __NR_getresgid 171 00685 #endif 00686 #ifndef __NR_rt_sigaction 00687 #define __NR_rt_sigreturn 173 00688 #define __NR_rt_sigaction 174 00689 #define __NR_rt_sigprocmask 175 00690 #define __NR_rt_sigpending 176 00691 #define __NR_rt_sigsuspend 179 00692 #endif 00693 #ifndef __NR_pread64 00694 #define __NR_pread64 180 00695 #endif 00696 #ifndef __NR_pwrite64 00697 #define __NR_pwrite64 181 00698 #endif 00699 #ifndef __NR_ugetrlimit 00700 #define __NR_ugetrlimit 191 00701 #endif 00702 #ifndef __NR_stat64 00703 #define __NR_stat64 195 00704 #endif 00705 #ifndef __NR_fstat64 00706 #define __NR_fstat64 197 00707 #endif 00708 #ifndef __NR_setresuid32 00709 #define __NR_setresuid32 208 00710 #define __NR_getresuid32 209 00711 #define __NR_setresgid32 210 00712 #define __NR_getresgid32 211 00713 #endif 00714 #ifndef __NR_setfsuid32 00715 #define __NR_setfsuid32 215 00716 #define __NR_setfsgid32 216 00717 #endif 00718 #ifndef __NR_getdents64 00719 #define __NR_getdents64 220 00720 #endif 00721 #ifndef __NR_gettid 00722 #define __NR_gettid 224 00723 #endif 00724 #ifndef __NR_readahead 00725 #define __NR_readahead 225 00726 #endif 00727 #ifndef __NR_setxattr 00728 #define __NR_setxattr 226 00729 #endif 00730 #ifndef __NR_lsetxattr 00731 #define __NR_lsetxattr 227 00732 #endif 00733 #ifndef __NR_getxattr 00734 #define __NR_getxattr 229 00735 #endif 00736 #ifndef __NR_lgetxattr 00737 #define __NR_lgetxattr 230 00738 #endif 00739 #ifndef __NR_listxattr 00740 #define __NR_listxattr 232 00741 #endif 00742 #ifndef __NR_llistxattr 00743 #define __NR_llistxattr 233 00744 #endif 00745 #ifndef __NR_tkill 00746 #define __NR_tkill 238 00747 #endif 00748 #ifndef __NR_futex 00749 #define __NR_futex 240 00750 #endif 00751 #ifndef __NR_sched_setaffinity 00752 #define __NR_sched_setaffinity 241 00753 #define __NR_sched_getaffinity 242 00754 #endif 00755 #ifndef __NR_set_tid_address 00756 #define __NR_set_tid_address 258 00757 #endif 00758 #ifndef __NR_clock_gettime 00759 #define __NR_clock_gettime 265 00760 #endif 00761 #ifndef __NR_clock_getres 00762 #define __NR_clock_getres 266 00763 #endif 00764 #ifndef __NR_statfs64 00765 #define __NR_statfs64 268 00766 #endif 00767 #ifndef __NR_fstatfs64 00768 #define __NR_fstatfs64 269 00769 #endif 00770 #ifndef __NR_fadvise64_64 00771 #define __NR_fadvise64_64 272 00772 #endif 00773 #ifndef __NR_ioprio_set 00774 #define __NR_ioprio_set 289 00775 #endif 00776 #ifndef __NR_ioprio_get 00777 #define __NR_ioprio_get 290 00778 #endif 00779 #ifndef __NR_openat 00780 #define __NR_openat 295 00781 #endif 00782 #ifndef __NR_fstatat64 00783 #define __NR_fstatat64 300 00784 #endif 00785 #ifndef __NR_unlinkat 00786 #define __NR_unlinkat 301 00787 #endif 00788 #ifndef __NR_move_pages 00789 #define __NR_move_pages 317 00790 #endif 00791 #ifndef __NR_getcpu 00792 #define __NR_getcpu 318 00793 #endif 00794 #ifndef __NR_fallocate 00795 #define __NR_fallocate 324 00796 #endif 00797 /* End of i386 definitions */ 00798 #elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) 00799 #ifndef __NR_setresuid 00800 #define __NR_setresuid (__NR_SYSCALL_BASE + 164) 00801 #define __NR_getresuid (__NR_SYSCALL_BASE + 165) 00802 #define __NR_setresgid (__NR_SYSCALL_BASE + 170) 00803 #define __NR_getresgid (__NR_SYSCALL_BASE + 171) 00804 #endif 00805 #ifndef __NR_rt_sigaction 00806 #define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173) 00807 #define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174) 00808 #define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175) 00809 #define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176) 00810 #define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179) 00811 #endif 00812 #ifndef __NR_pread64 00813 #define __NR_pread64 (__NR_SYSCALL_BASE + 180) 00814 #endif 00815 #ifndef __NR_pwrite64 00816 #define __NR_pwrite64 (__NR_SYSCALL_BASE + 181) 00817 #endif 00818 #ifndef __NR_ugetrlimit 00819 #define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191) 00820 #endif 00821 #ifndef __NR_stat64 00822 #define __NR_stat64 (__NR_SYSCALL_BASE + 195) 00823 #endif 00824 #ifndef __NR_fstat64 00825 #define __NR_fstat64 (__NR_SYSCALL_BASE + 197) 00826 #endif 00827 #ifndef __NR_setresuid32 00828 #define __NR_setresuid32 (__NR_SYSCALL_BASE + 208) 00829 #define __NR_getresuid32 (__NR_SYSCALL_BASE + 209) 00830 #define __NR_setresgid32 (__NR_SYSCALL_BASE + 210) 00831 #define __NR_getresgid32 (__NR_SYSCALL_BASE + 211) 00832 #endif 00833 #ifndef __NR_setfsuid32 00834 #define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215) 00835 #define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216) 00836 #endif 00837 #ifndef __NR_getdents64 00838 #define __NR_getdents64 (__NR_SYSCALL_BASE + 217) 00839 #endif 00840 #ifndef __NR_gettid 00841 #define __NR_gettid (__NR_SYSCALL_BASE + 224) 00842 #endif 00843 #ifndef __NR_readahead 00844 #define __NR_readahead (__NR_SYSCALL_BASE + 225) 00845 #endif 00846 #ifndef __NR_setxattr 00847 #define __NR_setxattr (__NR_SYSCALL_BASE + 226) 00848 #endif 00849 #ifndef __NR_lsetxattr 00850 #define __NR_lsetxattr (__NR_SYSCALL_BASE + 227) 00851 #endif 00852 #ifndef __NR_getxattr 00853 #define __NR_getxattr (__NR_SYSCALL_BASE + 229) 00854 #endif 00855 #ifndef __NR_lgetxattr 00856 #define __NR_lgetxattr (__NR_SYSCALL_BASE + 230) 00857 #endif 00858 #ifndef __NR_listxattr 00859 #define __NR_listxattr (__NR_SYSCALL_BASE + 232) 00860 #endif 00861 #ifndef __NR_llistxattr 00862 #define __NR_llistxattr (__NR_SYSCALL_BASE + 233) 00863 #endif 00864 #ifndef __NR_tkill 00865 #define __NR_tkill (__NR_SYSCALL_BASE + 238) 00866 #endif 00867 #ifndef __NR_futex 00868 #define __NR_futex (__NR_SYSCALL_BASE + 240) 00869 #endif 00870 #ifndef __NR_sched_setaffinity 00871 #define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241) 00872 #define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242) 00873 #endif 00874 #ifndef __NR_set_tid_address 00875 #define __NR_set_tid_address (__NR_SYSCALL_BASE + 256) 00876 #endif 00877 #ifndef __NR_clock_gettime 00878 #define __NR_clock_gettime (__NR_SYSCALL_BASE + 263) 00879 #endif 00880 #ifndef __NR_clock_getres 00881 #define __NR_clock_getres (__NR_SYSCALL_BASE + 264) 00882 #endif 00883 #ifndef __NR_statfs64 00884 #define __NR_statfs64 (__NR_SYSCALL_BASE + 266) 00885 #endif 00886 #ifndef __NR_fstatfs64 00887 #define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267) 00888 #endif 00889 #ifndef __NR_ioprio_set 00890 #define __NR_ioprio_set (__NR_SYSCALL_BASE + 314) 00891 #endif 00892 #ifndef __NR_ioprio_get 00893 #define __NR_ioprio_get (__NR_SYSCALL_BASE + 315) 00894 #endif 00895 #ifndef __NR_move_pages 00896 #define __NR_move_pages (__NR_SYSCALL_BASE + 344) 00897 #endif 00898 #ifndef __NR_getcpu 00899 #define __NR_getcpu (__NR_SYSCALL_BASE + 345) 00900 #endif 00901 /* End of ARM 3/EABI definitions */ 00902 #elif defined(__x86_64__) 00903 #ifndef __NR_pread64 00904 #define __NR_pread64 17 00905 #endif 00906 #ifndef __NR_pwrite64 00907 #define __NR_pwrite64 18 00908 #endif 00909 #ifndef __NR_setresuid 00910 #define __NR_setresuid 117 00911 #define __NR_getresuid 118 00912 #define __NR_setresgid 119 00913 #define __NR_getresgid 120 00914 #endif 00915 #ifndef __NR_quotactl 00916 #define __NR_quotactl 179 00917 #endif 00918 #ifndef __NR_gettid 00919 #define __NR_gettid 186 00920 #endif 00921 #ifndef __NR_readahead 00922 #define __NR_readahead 187 00923 #endif 00924 #ifndef __NR_setxattr 00925 #define __NR_setxattr 188 00926 #endif 00927 #ifndef __NR_lsetxattr 00928 #define __NR_lsetxattr 189 00929 #endif 00930 #ifndef __NR_getxattr 00931 #define __NR_getxattr 191 00932 #endif 00933 #ifndef __NR_lgetxattr 00934 #define __NR_lgetxattr 192 00935 #endif 00936 #ifndef __NR_listxattr 00937 #define __NR_listxattr 194 00938 #endif 00939 #ifndef __NR_llistxattr 00940 #define __NR_llistxattr 195 00941 #endif 00942 #ifndef __NR_tkill 00943 #define __NR_tkill 200 00944 #endif 00945 #ifndef __NR_futex 00946 #define __NR_futex 202 00947 #endif 00948 #ifndef __NR_sched_setaffinity 00949 #define __NR_sched_setaffinity 203 00950 #define __NR_sched_getaffinity 204 00951 #endif 00952 #ifndef __NR_getdents64 00953 #define __NR_getdents64 217 00954 #endif 00955 #ifndef __NR_set_tid_address 00956 #define __NR_set_tid_address 218 00957 #endif 00958 #ifndef __NR_fadvise64 00959 #define __NR_fadvise64 221 00960 #endif 00961 #ifndef __NR_clock_gettime 00962 #define __NR_clock_gettime 228 00963 #endif 00964 #ifndef __NR_clock_getres 00965 #define __NR_clock_getres 229 00966 #endif 00967 #ifndef __NR_ioprio_set 00968 #define __NR_ioprio_set 251 00969 #endif 00970 #ifndef __NR_ioprio_get 00971 #define __NR_ioprio_get 252 00972 #endif 00973 #ifndef __NR_openat 00974 #define __NR_openat 257 00975 #endif 00976 #ifndef __NR_newfstatat 00977 #define __NR_newfstatat 262 00978 #endif 00979 #ifndef __NR_unlinkat 00980 #define __NR_unlinkat 263 00981 #endif 00982 #ifndef __NR_move_pages 00983 #define __NR_move_pages 279 00984 #endif 00985 #ifndef __NR_fallocate 00986 #define __NR_fallocate 285 00987 #endif 00988 /* End of x86-64 definitions */ 00989 #elif defined(__mips__) 00990 #if _MIPS_SIM == _MIPS_SIM_ABI32 00991 #ifndef __NR_setresuid 00992 #define __NR_setresuid (__NR_Linux + 185) 00993 #define __NR_getresuid (__NR_Linux + 186) 00994 #define __NR_setresgid (__NR_Linux + 190) 00995 #define __NR_getresgid (__NR_Linux + 191) 00996 #endif 00997 #ifndef __NR_rt_sigaction 00998 #define __NR_rt_sigreturn (__NR_Linux + 193) 00999 #define __NR_rt_sigaction (__NR_Linux + 194) 01000 #define __NR_rt_sigprocmask (__NR_Linux + 195) 01001 #define __NR_rt_sigpending (__NR_Linux + 196) 01002 #define __NR_rt_sigsuspend (__NR_Linux + 199) 01003 #endif 01004 #ifndef __NR_pread64 01005 #define __NR_pread64 (__NR_Linux + 200) 01006 #endif 01007 #ifndef __NR_pwrite64 01008 #define __NR_pwrite64 (__NR_Linux + 201) 01009 #endif 01010 #ifndef __NR_stat64 01011 #define __NR_stat64 (__NR_Linux + 213) 01012 #endif 01013 #ifndef __NR_fstat64 01014 #define __NR_fstat64 (__NR_Linux + 215) 01015 #endif 01016 #ifndef __NR_getdents64 01017 #define __NR_getdents64 (__NR_Linux + 219) 01018 #endif 01019 #ifndef __NR_gettid 01020 #define __NR_gettid (__NR_Linux + 222) 01021 #endif 01022 #ifndef __NR_readahead 01023 #define __NR_readahead (__NR_Linux + 223) 01024 #endif 01025 #ifndef __NR_setxattr 01026 #define __NR_setxattr (__NR_Linux + 224) 01027 #endif 01028 #ifndef __NR_lsetxattr 01029 #define __NR_lsetxattr (__NR_Linux + 225) 01030 #endif 01031 #ifndef __NR_getxattr 01032 #define __NR_getxattr (__NR_Linux + 227) 01033 #endif 01034 #ifndef __NR_lgetxattr 01035 #define __NR_lgetxattr (__NR_Linux + 228) 01036 #endif 01037 #ifndef __NR_listxattr 01038 #define __NR_listxattr (__NR_Linux + 230) 01039 #endif 01040 #ifndef __NR_llistxattr 01041 #define __NR_llistxattr (__NR_Linux + 231) 01042 #endif 01043 #ifndef __NR_tkill 01044 #define __NR_tkill (__NR_Linux + 236) 01045 #endif 01046 #ifndef __NR_futex 01047 #define __NR_futex (__NR_Linux + 238) 01048 #endif 01049 #ifndef __NR_sched_setaffinity 01050 #define __NR_sched_setaffinity (__NR_Linux + 239) 01051 #define __NR_sched_getaffinity (__NR_Linux + 240) 01052 #endif 01053 #ifndef __NR_set_tid_address 01054 #define __NR_set_tid_address (__NR_Linux + 252) 01055 #endif 01056 #ifndef __NR_statfs64 01057 #define __NR_statfs64 (__NR_Linux + 255) 01058 #endif 01059 #ifndef __NR_fstatfs64 01060 #define __NR_fstatfs64 (__NR_Linux + 256) 01061 #endif 01062 #ifndef __NR_clock_gettime 01063 #define __NR_clock_gettime (__NR_Linux + 263) 01064 #endif 01065 #ifndef __NR_clock_getres 01066 #define __NR_clock_getres (__NR_Linux + 264) 01067 #endif 01068 #ifndef __NR_openat 01069 #define __NR_openat (__NR_Linux + 288) 01070 #endif 01071 #ifndef __NR_fstatat 01072 #define __NR_fstatat (__NR_Linux + 293) 01073 #endif 01074 #ifndef __NR_unlinkat 01075 #define __NR_unlinkat (__NR_Linux + 294) 01076 #endif 01077 #ifndef __NR_move_pages 01078 #define __NR_move_pages (__NR_Linux + 308) 01079 #endif 01080 #ifndef __NR_getcpu 01081 #define __NR_getcpu (__NR_Linux + 312) 01082 #endif 01083 #ifndef __NR_ioprio_set 01084 #define __NR_ioprio_set (__NR_Linux + 314) 01085 #endif 01086 #ifndef __NR_ioprio_get 01087 #define __NR_ioprio_get (__NR_Linux + 315) 01088 #endif 01089 /* End of MIPS (old 32bit API) definitions */ 01090 #elif _MIPS_SIM == _MIPS_SIM_ABI64 01091 #ifndef __NR_pread64 01092 #define __NR_pread64 (__NR_Linux + 16) 01093 #endif 01094 #ifndef __NR_pwrite64 01095 #define __NR_pwrite64 (__NR_Linux + 17) 01096 #endif 01097 #ifndef __NR_setresuid 01098 #define __NR_setresuid (__NR_Linux + 115) 01099 #define __NR_getresuid (__NR_Linux + 116) 01100 #define __NR_setresgid (__NR_Linux + 117) 01101 #define __NR_getresgid (__NR_Linux + 118) 01102 #endif 01103 #ifndef __NR_gettid 01104 #define __NR_gettid (__NR_Linux + 178) 01105 #endif 01106 #ifndef __NR_readahead 01107 #define __NR_readahead (__NR_Linux + 179) 01108 #endif 01109 #ifndef __NR_setxattr 01110 #define __NR_setxattr (__NR_Linux + 180) 01111 #endif 01112 #ifndef __NR_lsetxattr 01113 #define __NR_lsetxattr (__NR_Linux + 181) 01114 #endif 01115 #ifndef __NR_getxattr 01116 #define __NR_getxattr (__NR_Linux + 183) 01117 #endif 01118 #ifndef __NR_lgetxattr 01119 #define __NR_lgetxattr (__NR_Linux + 184) 01120 #endif 01121 #ifndef __NR_listxattr 01122 #define __NR_listxattr (__NR_Linux + 186) 01123 #endif 01124 #ifndef __NR_llistxattr 01125 #define __NR_llistxattr (__NR_Linux + 187) 01126 #endif 01127 #ifndef __NR_tkill 01128 #define __NR_tkill (__NR_Linux + 192) 01129 #endif 01130 #ifndef __NR_futex 01131 #define __NR_futex (__NR_Linux + 194) 01132 #endif 01133 #ifndef __NR_sched_setaffinity 01134 #define __NR_sched_setaffinity (__NR_Linux + 195) 01135 #define __NR_sched_getaffinity (__NR_Linux + 196) 01136 #endif 01137 #ifndef __NR_set_tid_address 01138 #define __NR_set_tid_address (__NR_Linux + 212) 01139 #endif 01140 #ifndef __NR_clock_gettime 01141 #define __NR_clock_gettime (__NR_Linux + 222) 01142 #endif 01143 #ifndef __NR_clock_getres 01144 #define __NR_clock_getres (__NR_Linux + 223) 01145 #endif 01146 #ifndef __NR_openat 01147 #define __NR_openat (__NR_Linux + 247) 01148 #endif 01149 #ifndef __NR_fstatat 01150 #define __NR_fstatat (__NR_Linux + 252) 01151 #endif 01152 #ifndef __NR_unlinkat 01153 #define __NR_unlinkat (__NR_Linux + 253) 01154 #endif 01155 #ifndef __NR_move_pages 01156 #define __NR_move_pages (__NR_Linux + 267) 01157 #endif 01158 #ifndef __NR_getcpu 01159 #define __NR_getcpu (__NR_Linux + 271) 01160 #endif 01161 #ifndef __NR_ioprio_set 01162 #define __NR_ioprio_set (__NR_Linux + 273) 01163 #endif 01164 #ifndef __NR_ioprio_get 01165 #define __NR_ioprio_get (__NR_Linux + 274) 01166 #endif 01167 /* End of MIPS (64bit API) definitions */ 01168 #else 01169 #ifndef __NR_setresuid 01170 #define __NR_setresuid (__NR_Linux + 115) 01171 #define __NR_getresuid (__NR_Linux + 116) 01172 #define __NR_setresgid (__NR_Linux + 117) 01173 #define __NR_getresgid (__NR_Linux + 118) 01174 #endif 01175 #ifndef __NR_gettid 01176 #define __NR_gettid (__NR_Linux + 178) 01177 #endif 01178 #ifndef __NR_readahead 01179 #define __NR_readahead (__NR_Linux + 179) 01180 #endif 01181 #ifndef __NR_setxattr 01182 #define __NR_setxattr (__NR_Linux + 180) 01183 #endif 01184 #ifndef __NR_lsetxattr 01185 #define __NR_lsetxattr (__NR_Linux + 181) 01186 #endif 01187 #ifndef __NR_getxattr 01188 #define __NR_getxattr (__NR_Linux + 183) 01189 #endif 01190 #ifndef __NR_lgetxattr 01191 #define __NR_lgetxattr (__NR_Linux + 184) 01192 #endif 01193 #ifndef __NR_listxattr 01194 #define __NR_listxattr (__NR_Linux + 186) 01195 #endif 01196 #ifndef __NR_llistxattr 01197 #define __NR_llistxattr (__NR_Linux + 187) 01198 #endif 01199 #ifndef __NR_tkill 01200 #define __NR_tkill (__NR_Linux + 192) 01201 #endif 01202 #ifndef __NR_futex 01203 #define __NR_futex (__NR_Linux + 194) 01204 #endif 01205 #ifndef __NR_sched_setaffinity 01206 #define __NR_sched_setaffinity (__NR_Linux + 195) 01207 #define __NR_sched_getaffinity (__NR_Linux + 196) 01208 #endif 01209 #ifndef __NR_set_tid_address 01210 #define __NR_set_tid_address (__NR_Linux + 213) 01211 #endif 01212 #ifndef __NR_statfs64 01213 #define __NR_statfs64 (__NR_Linux + 217) 01214 #endif 01215 #ifndef __NR_fstatfs64 01216 #define __NR_fstatfs64 (__NR_Linux + 218) 01217 #endif 01218 #ifndef __NR_clock_gettime 01219 #define __NR_clock_gettime (__NR_Linux + 226) 01220 #endif 01221 #ifndef __NR_clock_getres 01222 #define __NR_clock_getres (__NR_Linux + 227) 01223 #endif 01224 #ifndef __NR_openat 01225 #define __NR_openat (__NR_Linux + 251) 01226 #endif 01227 #ifndef __NR_fstatat 01228 #define __NR_fstatat (__NR_Linux + 256) 01229 #endif 01230 #ifndef __NR_unlinkat 01231 #define __NR_unlinkat (__NR_Linux + 257) 01232 #endif 01233 #ifndef __NR_move_pages 01234 #define __NR_move_pages (__NR_Linux + 271) 01235 #endif 01236 #ifndef __NR_getcpu 01237 #define __NR_getcpu (__NR_Linux + 275) 01238 #endif 01239 #ifndef __NR_ioprio_set 01240 #define __NR_ioprio_set (__NR_Linux + 277) 01241 #endif 01242 #ifndef __NR_ioprio_get 01243 #define __NR_ioprio_get (__NR_Linux + 278) 01244 #endif 01245 /* End of MIPS (new 32bit API) definitions */ 01246 #endif 01247 /* End of MIPS definitions */ 01248 #elif defined(__PPC__) 01249 #ifndef __NR_setfsuid 01250 #define __NR_setfsuid 138 01251 #define __NR_setfsgid 139 01252 #endif 01253 #ifndef __NR_setresuid 01254 #define __NR_setresuid 164 01255 #define __NR_getresuid 165 01256 #define __NR_setresgid 169 01257 #define __NR_getresgid 170 01258 #endif 01259 #ifndef __NR_rt_sigaction 01260 #define __NR_rt_sigreturn 172 01261 #define __NR_rt_sigaction 173 01262 #define __NR_rt_sigprocmask 174 01263 #define __NR_rt_sigpending 175 01264 #define __NR_rt_sigsuspend 178 01265 #endif 01266 #ifndef __NR_pread64 01267 #define __NR_pread64 179 01268 #endif 01269 #ifndef __NR_pwrite64 01270 #define __NR_pwrite64 180 01271 #endif 01272 #ifndef __NR_ugetrlimit 01273 #define __NR_ugetrlimit 190 01274 #endif 01275 #ifndef __NR_readahead 01276 #define __NR_readahead 191 01277 #endif 01278 #ifndef __NR_stat64 01279 #define __NR_stat64 195 01280 #endif 01281 #ifndef __NR_fstat64 01282 #define __NR_fstat64 197 01283 #endif 01284 #ifndef __NR_getdents64 01285 #define __NR_getdents64 202 01286 #endif 01287 #ifndef __NR_gettid 01288 #define __NR_gettid 207 01289 #endif 01290 #ifndef __NR_tkill 01291 #define __NR_tkill 208 01292 #endif 01293 #ifndef __NR_setxattr 01294 #define __NR_setxattr 209 01295 #endif 01296 #ifndef __NR_lsetxattr 01297 #define __NR_lsetxattr 210 01298 #endif 01299 #ifndef __NR_getxattr 01300 #define __NR_getxattr 212 01301 #endif 01302 #ifndef __NR_lgetxattr 01303 #define __NR_lgetxattr 213 01304 #endif 01305 #ifndef __NR_listxattr 01306 #define __NR_listxattr 215 01307 #endif 01308 #ifndef __NR_llistxattr 01309 #define __NR_llistxattr 216 01310 #endif 01311 #ifndef __NR_futex 01312 #define __NR_futex 221 01313 #endif 01314 #ifndef __NR_sched_setaffinity 01315 #define __NR_sched_setaffinity 222 01316 #define __NR_sched_getaffinity 223 01317 #endif 01318 #ifndef __NR_set_tid_address 01319 #define __NR_set_tid_address 232 01320 #endif 01321 #ifndef __NR_clock_gettime 01322 #define __NR_clock_gettime 246 01323 #endif 01324 #ifndef __NR_clock_getres 01325 #define __NR_clock_getres 247 01326 #endif 01327 #ifndef __NR_statfs64 01328 #define __NR_statfs64 252 01329 #endif 01330 #ifndef __NR_fstatfs64 01331 #define __NR_fstatfs64 253 01332 #endif 01333 #ifndef __NR_fadvise64_64 01334 #define __NR_fadvise64_64 254 01335 #endif 01336 #ifndef __NR_ioprio_set 01337 #define __NR_ioprio_set 273 01338 #endif 01339 #ifndef __NR_ioprio_get 01340 #define __NR_ioprio_get 274 01341 #endif 01342 #ifndef __NR_openat 01343 #define __NR_openat 286 01344 #endif 01345 #ifndef __NR_fstatat64 01346 #define __NR_fstatat64 291 01347 #endif 01348 #ifndef __NR_unlinkat 01349 #define __NR_unlinkat 292 01350 #endif 01351 #ifndef __NR_move_pages 01352 #define __NR_move_pages 301 01353 #endif 01354 #ifndef __NR_getcpu 01355 #define __NR_getcpu 302 01356 #endif 01357 /* End of powerpc defininitions */ 01358 #endif 01359 01360 01361 /* After forking, we must make sure to only call system calls. */ 01362 #if defined(__BOUNDED_POINTERS__) 01363 #error "Need to port invocations of syscalls for bounded ptrs" 01364 #else 01365 /* The core dumper and the thread lister get executed after threads 01366 * have been suspended. As a consequence, we cannot call any functions 01367 * that acquire locks. Unfortunately, libc wraps most system calls 01368 * (e.g. in order to implement pthread_atfork, and to make calls 01369 * cancellable), which means we cannot call these functions. Instead, 01370 * we have to call syscall() directly. 01371 */ 01372 #undef LSS_ERRNO 01373 #ifdef SYS_ERRNO 01374 /* Allow the including file to override the location of errno. This can 01375 * be useful when using clone() with the CLONE_VM option. 01376 */ 01377 #define LSS_ERRNO SYS_ERRNO 01378 #else 01379 #define LSS_ERRNO errno 01380 #endif 01381 01382 #undef LSS_INLINE 01383 #ifdef SYS_INLINE 01384 #define LSS_INLINE SYS_INLINE 01385 #else 01386 #define LSS_INLINE static inline 01387 #endif 01388 01389 /* Allow the including file to override the prefix used for all new 01390 * system calls. By default, it will be set to "sys_". 01391 */ 01392 #undef LSS_NAME 01393 #ifndef SYS_PREFIX 01394 #define LSS_NAME(name) sys_##name 01395 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0 01396 #define LSS_NAME(name) name 01397 #elif defined(SYS_PREFIX) && SYS_PREFIX == 0 01398 #define LSS_NAME(name) sys0_##name 01399 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1 01400 #define LSS_NAME(name) sys1_##name 01401 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2 01402 #define LSS_NAME(name) sys2_##name 01403 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3 01404 #define LSS_NAME(name) sys3_##name 01405 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4 01406 #define LSS_NAME(name) sys4_##name 01407 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5 01408 #define LSS_NAME(name) sys5_##name 01409 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6 01410 #define LSS_NAME(name) sys6_##name 01411 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7 01412 #define LSS_NAME(name) sys7_##name 01413 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8 01414 #define LSS_NAME(name) sys8_##name 01415 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9 01416 #define LSS_NAME(name) sys9_##name 01417 #endif 01418 01419 #undef LSS_RETURN 01420 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \ 01421 || defined(__ARM_EABI__)) 01422 /* Failing system calls return a negative result in the range of 01423 * -1..-4095. These are "errno" values with the sign inverted. 01424 */ 01425 #define LSS_RETURN(type, res) \ 01426 do { \ 01427 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \ 01428 LSS_ERRNO = -(res); \ 01429 res = -1; \ 01430 } \ 01431 return (type) (res); \ 01432 } while (0) 01433 #elif defined(__mips__) 01434 /* On MIPS, failing system calls return -1, and set errno in a 01435 * separate CPU register. 01436 */ 01437 #define LSS_RETURN(type, res, err) \ 01438 do { \ 01439 if (err) { \ 01440 unsigned long __errnovalue = (res); \ 01441 LSS_ERRNO = __errnovalue; \ 01442 res = -1; \ 01443 } \ 01444 return (type) (res); \ 01445 } while (0) 01446 #elif defined(__PPC__) 01447 /* On PPC, failing system calls return -1, and set errno in a 01448 * separate CPU register. See linux/unistd.h. 01449 */ 01450 #define LSS_RETURN(type, res, err) \ 01451 do { \ 01452 if (err & 0x10000000 ) { \ 01453 LSS_ERRNO = (res); \ 01454 res = -1; \ 01455 } \ 01456 return (type) (res); \ 01457 } while (0) 01458 #endif 01459 #if defined(__i386__) 01460 /* In PIC mode (e.g. when building shared libraries), gcc for i386 01461 * reserves ebx. Unfortunately, most distribution ship with implementations 01462 * of _syscallX() which clobber ebx. 01463 * Also, most definitions of _syscallX() neglect to mark "memory" as being 01464 * clobbered. This causes problems with compilers, that do a better job 01465 * at optimizing across __asm__ calls. 01466 * So, we just have to redefine all of the _syscallX() macros. 01467 */ 01468 #undef LSS_ENTRYPOINT 01469 #ifdef SYS_SYSCALL_ENTRYPOINT 01470 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { 01471 void (**entrypoint)(void); 01472 asm volatile(".bss\n" 01473 ".align 8\n" 01474 ".globl "SYS_SYSCALL_ENTRYPOINT"\n" 01475 ".common "SYS_SYSCALL_ENTRYPOINT",8,8\n" 01476 ".previous\n" 01477 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */ 01478 "call 0f\n" 01479 "0:pop %0\n" 01480 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n" 01481 "mov "SYS_SYSCALL_ENTRYPOINT"@GOT(%0), %0\n" 01482 : "=r"(entrypoint)); 01483 return entrypoint; 01484 } 01485 01486 #define LSS_ENTRYPOINT ".bss\n" \ 01487 ".align 8\n" \ 01488 ".globl "SYS_SYSCALL_ENTRYPOINT"\n" \ 01489 ".common "SYS_SYSCALL_ENTRYPOINT",8,8\n" \ 01490 ".previous\n" \ 01491 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \ 01492 "push %%eax\n" \ 01493 "call 10000f\n" \ 01494 "10000:pop %%eax\n" \ 01495 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \ 01496 "mov "SYS_SYSCALL_ENTRYPOINT"@GOT(%%eax), %%eax\n"\ 01497 "mov 0(%%eax), %%eax\n" \ 01498 "test %%eax, %%eax\n" \ 01499 "jz 10002f\n" \ 01500 "push %%eax\n" \ 01501 "call 10001f\n" \ 01502 "10001:pop %%eax\n" \ 01503 "add $(10003f-10001b), %%eax\n" \ 01504 "xchg 4(%%esp), %%eax\n" \ 01505 "ret\n" \ 01506 "10002:pop %%eax\n" \ 01507 "int $0x80\n" \ 01508 "10003:\n" 01509 #else 01510 #define LSS_ENTRYPOINT "int $0x80\n" 01511 #endif 01512 #undef LSS_BODY 01513 #define LSS_BODY(type,args...) \ 01514 long __res; \ 01515 __asm__ __volatile__("push %%ebx\n" \ 01516 "movl %2,%%ebx\n" \ 01517 LSS_ENTRYPOINT \ 01518 "pop %%ebx" \ 01519 args \ 01520 : "esp", "memory"); \ 01521 LSS_RETURN(type,__res) 01522 #undef _syscall0 01523 #define _syscall0(type,name) \ 01524 type LSS_NAME(name)(void) { \ 01525 long __res; \ 01526 __asm__ volatile(LSS_ENTRYPOINT \ 01527 : "=a" (__res) \ 01528 : "0" (__NR_##name) \ 01529 : "esp", "memory"); \ 01530 LSS_RETURN(type,__res); \ 01531 } 01532 #undef _syscall1 01533 #define _syscall1(type,name,type1,arg1) \ 01534 type LSS_NAME(name)(type1 arg1) { \ 01535 LSS_BODY(type, \ 01536 : "=a" (__res) \ 01537 : "0" (__NR_##name), "ri" ((long)(arg1))); \ 01538 } 01539 #undef _syscall2 01540 #define _syscall2(type,name,type1,arg1,type2,arg2) \ 01541 type LSS_NAME(name)(type1 arg1,type2 arg2) { \ 01542 LSS_BODY(type, \ 01543 : "=a" (__res) \ 01544 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \ 01545 } 01546 #undef _syscall3 01547 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 01548 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \ 01549 LSS_BODY(type, \ 01550 : "=a" (__res) \ 01551 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ 01552 "d" ((long)(arg3))); \ 01553 } 01554 #undef _syscall4 01555 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 01556 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 01557 LSS_BODY(type, \ 01558 : "=a" (__res) \ 01559 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ 01560 "d" ((long)(arg3)),"S" ((long)(arg4))); \ 01561 } 01562 #undef _syscall5 01563 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 01564 type5,arg5) \ 01565 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 01566 type5 arg5) { \ 01567 long __res; \ 01568 __asm__ __volatile__("push %%ebx\n" \ 01569 "movl %2,%%ebx\n" \ 01570 "movl %1,%%eax\n" \ 01571 LSS_ENTRYPOINT \ 01572 "pop %%ebx" \ 01573 : "=a" (__res) \ 01574 : "i" (__NR_##name), "ri" ((long)(arg1)), \ 01575 "c" ((long)(arg2)), "d" ((long)(arg3)), \ 01576 "S" ((long)(arg4)), "D" ((long)(arg5)) \ 01577 : "esp", "memory"); \ 01578 LSS_RETURN(type,__res); \ 01579 } 01580 #undef _syscall6 01581 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 01582 type5,arg5,type6,arg6) \ 01583 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 01584 type5 arg5, type6 arg6) { \ 01585 long __res; \ 01586 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \ 01587 __asm__ __volatile__("push %%ebp\n" \ 01588 "push %%ebx\n" \ 01589 "movl 4(%2),%%ebp\n" \ 01590 "movl 0(%2), %%ebx\n" \ 01591 "movl %1,%%eax\n" \ 01592 LSS_ENTRYPOINT \ 01593 "pop %%ebx\n" \ 01594 "pop %%ebp" \ 01595 : "=a" (__res) \ 01596 : "i" (__NR_##name), "0" ((long)(&__s)), \ 01597 "c" ((long)(arg2)), "d" ((long)(arg3)), \ 01598 "S" ((long)(arg4)), "D" ((long)(arg5)) \ 01599 : "esp", "memory"); \ 01600 LSS_RETURN(type,__res); \ 01601 } 01602 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 01603 int flags, void *arg, int *parent_tidptr, 01604 void *newtls, int *child_tidptr) { 01605 long __res; 01606 __asm__ __volatile__(/* if (fn == NULL) 01607 * return -EINVAL; 01608 */ 01609 "movl %3,%%ecx\n" 01610 "jecxz 1f\n" 01611 01612 /* if (child_stack == NULL) 01613 * return -EINVAL; 01614 */ 01615 "movl %4,%%ecx\n" 01616 "jecxz 1f\n" 01617 01618 /* Set up alignment of the child stack: 01619 * child_stack = (child_stack & ~0xF) - 20; 01620 */ 01621 "andl $-16,%%ecx\n" 01622 "subl $20,%%ecx\n" 01623 01624 /* Push "arg" and "fn" onto the stack that will be 01625 * used by the child. 01626 */ 01627 "movl %6,%%eax\n" 01628 "movl %%eax,4(%%ecx)\n" 01629 "movl %3,%%eax\n" 01630 "movl %%eax,(%%ecx)\n" 01631 01632 /* %eax = syscall(%eax = __NR_clone, 01633 * %ebx = flags, 01634 * %ecx = child_stack, 01635 * %edx = parent_tidptr, 01636 * %esi = newtls, 01637 * %edi = child_tidptr) 01638 * Also, make sure that %ebx gets preserved as it is 01639 * used in PIC mode. 01640 */ 01641 "movl %8,%%esi\n" 01642 "movl %7,%%edx\n" 01643 "movl %5,%%eax\n" 01644 "movl %9,%%edi\n" 01645 "pushl %%ebx\n" 01646 "movl %%eax,%%ebx\n" 01647 "movl %2,%%eax\n" 01648 LSS_ENTRYPOINT 01649 01650 /* In the parent: restore %ebx 01651 * In the child: move "fn" into %ebx 01652 */ 01653 "popl %%ebx\n" 01654 01655 /* if (%eax != 0) 01656 * return %eax; 01657 */ 01658 "test %%eax,%%eax\n" 01659 "jnz 1f\n" 01660 01661 /* In the child, now. Terminate frame pointer chain. 01662 */ 01663 "movl $0,%%ebp\n" 01664 01665 /* Call "fn". "arg" is already on the stack. 01666 */ 01667 "call *%%ebx\n" 01668 01669 /* Call _exit(%ebx). Unfortunately older versions 01670 * of gcc restrict the number of arguments that can 01671 * be passed to asm(). So, we need to hard-code the 01672 * system call number. 01673 */ 01674 "movl %%eax,%%ebx\n" 01675 "movl $1,%%eax\n" 01676 LSS_ENTRYPOINT 01677 01678 /* Return to parent. 01679 */ 01680 "1:\n" 01681 : "=a" (__res) 01682 : "0"(-EINVAL), "i"(__NR_clone), 01683 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg), 01684 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr) 01685 : "esp", "memory", "ecx", "edx", "esi", "edi"); 01686 LSS_RETURN(int, __res); 01687 } 01688 01689 #define __NR__fadvise64_64 __NR_fadvise64_64 01690 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd, 01691 unsigned, offset_lo, unsigned, offset_hi, 01692 unsigned, len_lo, unsigned, len_hi, 01693 int, advice) 01694 01695 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, 01696 loff_t len, int advice) { 01697 return LSS_NAME(_fadvise64_64)(fd, 01698 (unsigned)offset, (unsigned)(offset >>32), 01699 (unsigned)len, (unsigned)(len >> 32), 01700 advice); 01701 } 01702 01703 #define __NR__fallocate __NR_fallocate 01704 LSS_INLINE _syscall6(int, _fallocate, int, fd, 01705 int, mode, 01706 unsigned, offset_lo, unsigned, offset_hi, 01707 unsigned, len_lo, unsigned, len_hi) 01708 01709 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode, 01710 loff_t offset, loff_t len) { 01711 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len }; 01712 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]); 01713 } 01714 01715 LSS_INLINE _syscall1(int, set_thread_area, void *, u) 01716 LSS_INLINE _syscall1(int, get_thread_area, void *, u) 01717 01718 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { 01719 /* On i386, the kernel does not know how to return from a signal 01720 * handler. Instead, it relies on user space to provide a 01721 * restorer function that calls the {rt_,}sigreturn() system call. 01722 * Unfortunately, we cannot just reference the glibc version of this 01723 * function, as glibc goes out of its way to make it inaccessible. 01724 */ 01725 void (*res)(void); 01726 __asm__ __volatile__("call 2f\n" 01727 "0:.align 16\n" 01728 "1:movl %1,%%eax\n" 01729 LSS_ENTRYPOINT 01730 "2:popl %0\n" 01731 "addl $(1b-0b),%0\n" 01732 : "=a" (res) 01733 : "i" (__NR_rt_sigreturn)); 01734 return res; 01735 } 01736 LSS_INLINE void (*LSS_NAME(restore)(void))(void) { 01737 /* On i386, the kernel does not know how to return from a signal 01738 * handler. Instead, it relies on user space to provide a 01739 * restorer function that calls the {rt_,}sigreturn() system call. 01740 * Unfortunately, we cannot just reference the glibc version of this 01741 * function, as glibc goes out of its way to make it inaccessible. 01742 */ 01743 void (*res)(void); 01744 __asm__ __volatile__("call 2f\n" 01745 "0:.align 16\n" 01746 "1:pop %%eax\n" 01747 "movl %1,%%eax\n" 01748 LSS_ENTRYPOINT 01749 "2:popl %0\n" 01750 "addl $(1b-0b),%0\n" 01751 : "=a" (res) 01752 : "i" (__NR_sigreturn)); 01753 return res; 01754 } 01755 #elif defined(__x86_64__) 01756 /* There are no known problems with any of the _syscallX() macros 01757 * currently shipping for x86_64, but we still need to be able to define 01758 * our own version so that we can override the location of the errno 01759 * location (e.g. when using the clone() system call with the CLONE_VM 01760 * option). 01761 */ 01762 #undef LSS_ENTRYPOINT 01763 #ifdef SYS_SYSCALL_ENTRYPOINT 01764 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { 01765 void (**entrypoint)(void); 01766 asm volatile(".bss\n" 01767 ".align 8\n" 01768 ".globl "SYS_SYSCALL_ENTRYPOINT"\n" 01769 ".common "SYS_SYSCALL_ENTRYPOINT",8,8\n" 01770 ".previous\n" 01771 "mov "SYS_SYSCALL_ENTRYPOINT"@GOTPCREL(%%rip), %0\n" 01772 : "=r"(entrypoint)); 01773 return entrypoint; 01774 } 01775 01776 #define LSS_ENTRYPOINT \ 01777 ".bss\n" \ 01778 ".align 8\n" \ 01779 ".globl "SYS_SYSCALL_ENTRYPOINT"\n" \ 01780 ".common "SYS_SYSCALL_ENTRYPOINT",8,8\n" \ 01781 ".previous\n" \ 01782 "mov "SYS_SYSCALL_ENTRYPOINT"@GOTPCREL(%%rip), %%rcx\n" \ 01783 "mov 0(%%rcx), %%rcx\n" \ 01784 "test %%rcx, %%rcx\n" \ 01785 "jz 10001f\n" \ 01786 "call *%%rcx\n" \ 01787 "jmp 10002f\n" \ 01788 "10001:syscall\n" \ 01789 "10002:\n" 01790 01791 #else 01792 #define LSS_ENTRYPOINT "syscall\n" 01793 #endif 01794 #undef LSS_BODY 01795 #define LSS_BODY(type,name, ...) \ 01796 long __res; \ 01797 __asm__ __volatile__(LSS_ENTRYPOINT \ 01798 : "=a" (__res) : "0" (__NR_##name), \ 01799 ##__VA_ARGS__ : "r11", "rcx", "memory"); \ 01800 LSS_RETURN(type, __res) 01801 #undef _syscall0 01802 #define _syscall0(type,name) \ 01803 type LSS_NAME(name)() { \ 01804 LSS_BODY(type, name); \ 01805 } 01806 #undef _syscall1 01807 #define _syscall1(type,name,type1,arg1) \ 01808 type LSS_NAME(name)(type1 arg1) { \ 01809 LSS_BODY(type, name, "D" ((long)(arg1))); \ 01810 } 01811 #undef _syscall2 01812 #define _syscall2(type,name,type1,arg1,type2,arg2) \ 01813 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 01814 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \ 01815 } 01816 #undef _syscall3 01817 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 01818 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 01819 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \ 01820 "d" ((long)(arg3))); \ 01821 } 01822 #undef _syscall4 01823 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 01824 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 01825 long __res; \ 01826 __asm__ __volatile__("movq %5,%%r10;" LSS_ENTRYPOINT : \ 01827 "=a" (__res) : "0" (__NR_##name), \ 01828 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ 01829 "r" ((long)(arg4)) : "r10", "r11", "rcx", "memory"); \ 01830 LSS_RETURN(type, __res); \ 01831 } 01832 #undef _syscall5 01833 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 01834 type5,arg5) \ 01835 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 01836 type5 arg5) { \ 01837 long __res; \ 01838 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8;" LSS_ENTRYPOINT :\ 01839 "=a" (__res) : "0" (__NR_##name), \ 01840 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ 01841 "r" ((long)(arg4)), "r" ((long)(arg5)) : \ 01842 "r8", "r10", "r11", "rcx", "memory"); \ 01843 LSS_RETURN(type, __res); \ 01844 } 01845 #undef _syscall6 01846 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 01847 type5,arg5,type6,arg6) \ 01848 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 01849 type5 arg5, type6 arg6) { \ 01850 long __res; \ 01851 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \ 01852 LSS_ENTRYPOINT : \ 01853 "=a" (__res) : "0" (__NR_##name), \ 01854 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ 01855 "r" ((long)(arg4)), "r" ((long)(arg5)), "r" ((long)(arg6)) : \ 01856 "r8", "r9", "r10", "r11", "rcx", "memory"); \ 01857 LSS_RETURN(type, __res); \ 01858 } 01859 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 01860 int flags, void *arg, int *parent_tidptr, 01861 void *newtls, int *child_tidptr) { 01862 long __res; 01863 { 01864 __asm__ __volatile__(/* if (fn == NULL) 01865 * return -EINVAL; 01866 */ 01867 "testq %4,%4\n" 01868 "jz 1f\n" 01869 01870 /* if (child_stack == NULL) 01871 * return -EINVAL; 01872 */ 01873 "testq %5,%5\n" 01874 "jz 1f\n" 01875 01876 /* childstack -= 2*sizeof(void *); 01877 */ 01878 "subq $16,%5\n" 01879 01880 /* Push "arg" and "fn" onto the stack that will be 01881 * used by the child. 01882 */ 01883 "movq %7,8(%5)\n" 01884 "movq %4,0(%5)\n" 01885 01886 /* %rax = syscall(%rax = __NR_clone, 01887 * %rdi = flags, 01888 * %rsi = child_stack, 01889 * %rdx = parent_tidptr, 01890 * %r8 = new_tls, 01891 * %r10 = child_tidptr) 01892 */ 01893 "movq %2,%%rax\n" 01894 "movq %9,%%r8\n" 01895 "movq %10,%%r10\n" 01896 LSS_ENTRYPOINT 01897 01898 /* if (%rax != 0) 01899 * return; 01900 */ 01901 "testq %%rax,%%rax\n" 01902 "jnz 1f\n" 01903 01904 /* In the child. Terminate frame pointer chain. 01905 */ 01906 "xorq %%rbp,%%rbp\n" 01907 01908 /* Call "fn(arg)". 01909 */ 01910 "popq %%rax\n" 01911 "popq %%rdi\n" 01912 "call *%%rax\n" 01913 01914 /* Call _exit(%ebx). 01915 */ 01916 "movq %%rax,%%rdi\n" 01917 "movq %3,%%rax\n" 01918 LSS_ENTRYPOINT 01919 01920 /* Return to parent. 01921 */ 01922 "1:\n" 01923 : "=a" (__res) 01924 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), 01925 "r"(fn), "S"(child_stack), "D"(flags), "r"(arg), 01926 "d"(parent_tidptr), "r"(newtls), 01927 "r"(child_tidptr) 01928 : "rsp", "memory", "r8", "r10", "r11", "rcx"); 01929 } 01930 LSS_RETURN(int, __res); 01931 } 01932 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) 01933 LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len, 01934 int, advice) 01935 01936 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { 01937 /* On x86-64, the kernel does not know how to return from 01938 * a signal handler. Instead, it relies on user space to provide a 01939 * restorer function that calls the rt_sigreturn() system call. 01940 * Unfortunately, we cannot just reference the glibc version of this 01941 * function, as glibc goes out of its way to make it inaccessible. 01942 */ 01943 void (*res)(void); 01944 __asm__ __volatile__("call 2f\n" 01945 "0:.align 16\n" 01946 "1:movq %1,%%rax\n" 01947 LSS_ENTRYPOINT 01948 "2:popq %0\n" 01949 "addq $(1b-0b),%0\n" 01950 : "=a" (res) 01951 : "i" (__NR_rt_sigreturn)); 01952 return res; 01953 } 01954 #elif defined(__ARM_ARCH_3__) 01955 /* Most definitions of _syscallX() neglect to mark "memory" as being 01956 * clobbered. This causes problems with compilers, that do a better job 01957 * at optimizing across __asm__ calls. 01958 * So, we just have to redefine all of the _syscallX() macros. 01959 */ 01960 #undef LSS_REG 01961 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a 01962 #undef LSS_BODY 01963 #define LSS_BODY(type,name,args...) \ 01964 register long __res_r0 __asm__("r0"); \ 01965 long __res; \ 01966 __asm__ __volatile__ (__syscall(name) \ 01967 : "=r"(__res_r0) : args : "lr", "memory"); \ 01968 __res = __res_r0; \ 01969 LSS_RETURN(type, __res) 01970 #undef _syscall0 01971 #define _syscall0(type, name) \ 01972 type LSS_NAME(name)() { \ 01973 LSS_BODY(type, name); \ 01974 } 01975 #undef _syscall1 01976 #define _syscall1(type, name, type1, arg1) \ 01977 type LSS_NAME(name)(type1 arg1) { \ 01978 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ 01979 } 01980 #undef _syscall2 01981 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 01982 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 01983 LSS_REG(0, arg1); LSS_REG(1, arg2); \ 01984 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ 01985 } 01986 #undef _syscall3 01987 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 01988 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 01989 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 01990 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ 01991 } 01992 #undef _syscall4 01993 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 01994 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 01995 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 01996 LSS_REG(3, arg4); \ 01997 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ 01998 } 01999 #undef _syscall5 02000 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 02001 type5,arg5) \ 02002 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02003 type5 arg5) { \ 02004 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 02005 LSS_REG(3, arg4); LSS_REG(4, arg5); \ 02006 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 02007 "r"(__r4)); \ 02008 } 02009 #undef _syscall6 02010 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 02011 type5,arg5,type6,arg6) \ 02012 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02013 type5 arg5, type6 arg6) { \ 02014 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 02015 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ 02016 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 02017 "r"(__r4), "r"(__r5)); \ 02018 } 02019 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 02020 int flags, void *arg, int *parent_tidptr, 02021 void *newtls, int *child_tidptr) { 02022 long __res; 02023 { 02024 register int __flags __asm__("r0") = flags; 02025 register void *__stack __asm__("r1") = child_stack; 02026 register void *__ptid __asm__("r2") = parent_tidptr; 02027 register void *__tls __asm__("r3") = newtls; 02028 register int *__ctid __asm__("r4") = child_tidptr; 02029 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL) 02030 * return -EINVAL; 02031 */ 02032 "cmp %2,#0\n" 02033 "cmpne %3,#0\n" 02034 "moveq %0,%1\n" 02035 "beq 1f\n" 02036 02037 /* Push "arg" and "fn" onto the stack that will be 02038 * used by the child. 02039 */ 02040 "str %5,[%3,#-4]!\n" 02041 "str %2,[%3,#-4]!\n" 02042 02043 /* %r0 = syscall(%r0 = flags, 02044 * %r1 = child_stack, 02045 * %r2 = parent_tidptr, 02046 * %r3 = newtls, 02047 * %r4 = child_tidptr) 02048 */ 02049 __syscall(clone)"\n" 02050 02051 /* if (%r0 != 0) 02052 * return %r0; 02053 */ 02054 "movs %0,r0\n" 02055 "bne 1f\n" 02056 02057 /* In the child, now. Call "fn(arg)". 02058 */ 02059 "ldr r0,[sp, #4]\n" 02060 "mov lr,pc\n" 02061 "ldr pc,[sp]\n" 02062 02063 /* Call _exit(%r0). 02064 */ 02065 __syscall(exit)"\n" 02066 "1:\n" 02067 : "=r" (__res) 02068 : "i"(-EINVAL), 02069 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), 02070 "r"(__ptid), "r"(__tls), "r"(__ctid) 02071 : "cc", "lr", "memory"); 02072 } 02073 LSS_RETURN(int, __res); 02074 } 02075 #elif defined(__ARM_EABI__) 02076 /* Most definitions of _syscallX() neglect to mark "memory" as being 02077 * clobbered. This causes problems with compilers, that do a better job 02078 * at optimizing across __asm__ calls. 02079 * So, we just have to redefine all fo the _syscallX() macros. 02080 */ 02081 #undef LSS_REG 02082 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a 02083 #undef LSS_BODY 02084 #define LSS_BODY(type,name,args...) \ 02085 register long __res_r0 __asm__("r0"); \ 02086 long __res; \ 02087 __asm__ __volatile__ ("push {r7}\n" \ 02088 "mov r7, %1\n" \ 02089 "swi 0x0\n" \ 02090 "pop {r7}\n" \ 02091 : "=r"(__res_r0) \ 02092 : "i"(__NR_##name) , ## args \ 02093 : "lr", "memory"); \ 02094 __res = __res_r0; \ 02095 LSS_RETURN(type, __res) 02096 #undef _syscall0 02097 #define _syscall0(type, name) \ 02098 type LSS_NAME(name)() { \ 02099 LSS_BODY(type, name); \ 02100 } 02101 #undef _syscall1 02102 #define _syscall1(type, name, type1, arg1) \ 02103 type LSS_NAME(name)(type1 arg1) { \ 02104 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ 02105 } 02106 #undef _syscall2 02107 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 02108 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 02109 LSS_REG(0, arg1); LSS_REG(1, arg2); \ 02110 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ 02111 } 02112 #undef _syscall3 02113 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 02114 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 02115 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 02116 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ 02117 } 02118 #undef _syscall4 02119 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 02120 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 02121 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 02122 LSS_REG(3, arg4); \ 02123 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ 02124 } 02125 #undef _syscall5 02126 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 02127 type5,arg5) \ 02128 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02129 type5 arg5) { \ 02130 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 02131 LSS_REG(3, arg4); LSS_REG(4, arg5); \ 02132 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 02133 "r"(__r4)); \ 02134 } 02135 #undef _syscall6 02136 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 02137 type5,arg5,type6,arg6) \ 02138 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02139 type5 arg5, type6 arg6) { \ 02140 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 02141 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ 02142 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 02143 "r"(__r4), "r"(__r5)); \ 02144 } 02145 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 02146 int flags, void *arg, int *parent_tidptr, 02147 void *newtls, int *child_tidptr) { 02148 long __res; 02149 { 02150 register int __flags __asm__("r0") = flags; 02151 register void *__stack __asm__("r1") = child_stack; 02152 register void *__ptid __asm__("r2") = parent_tidptr; 02153 register void *__tls __asm__("r3") = newtls; 02154 register int *__ctid __asm__("r4") = child_tidptr; 02155 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL) 02156 * return -EINVAL; 02157 */ 02158 "cmp %2,#0\n" 02159 "it ne\n" 02160 "cmpne %3,#0\n" 02161 "it eq\n" 02162 "moveq %0,%1\n" 02163 "beq 1f\n" 02164 02165 /* Push "arg" and "fn" onto the stack that will be 02166 * used by the child. 02167 */ 02168 "str %5,[%3,#-4]!\n" 02169 "str %2,[%3,#-4]!\n" 02170 02171 /* %r0 = syscall(%r0 = flags, 02172 * %r1 = child_stack, 02173 * %r2 = parent_tidptr, 02174 * %r3 = newtls, 02175 * %r4 = child_tidptr) 02176 */ 02177 "mov r7, %9\n" 02178 "swi 0x0\n" 02179 02180 /* if (%r0 != 0) 02181 * return %r0; 02182 */ 02183 "movs %0,r0\n" 02184 "bne 1f\n" 02185 02186 /* In the child, now. Call "fn(arg)". 02187 */ 02188 "ldr r0,[sp, #4]\n" 02189 02190 /* When compiling for Thumb-2 the "MOV LR,PC" here 02191 * won't work because it loads PC+4 into LR, 02192 * whereas the LDR is a 4-byte instruction. 02193 * This results in the child thread always 02194 * crashing with an "Illegal Instruction" when it 02195 * returned into the middle of the LDR instruction 02196 * The instruction sequence used instead was 02197 * recommended by 02198 * "https://wiki.edubuntu.org/ARM/Thumb2PortingHowto#Quick_Reference". 02199 */ 02200 #ifdef __thumb2__ 02201 "ldr r7,[sp]\n" 02202 "blx r7\n" 02203 #else 02204 "mov lr,pc\n" 02205 "ldr pc,[sp]\n" 02206 #endif 02207 02208 /* Call _exit(%r0). 02209 */ 02210 "mov r7, %10\n" 02211 "swi 0x0\n" 02212 "1:\n" 02213 : "=r" (__res) 02214 : "i"(-EINVAL), 02215 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), 02216 "r"(__ptid), "r"(__tls), "r"(__ctid), 02217 "i"(__NR_clone), "i"(__NR_exit) 02218 : "cc", "r7", "lr", "memory"); 02219 } 02220 LSS_RETURN(int, __res); 02221 } 02222 #elif defined(__mips__) 02223 #undef LSS_REG 02224 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \ 02225 (unsigned long)(a) 02226 #undef LSS_BODY 02227 #define LSS_BODY(type,name,r7,...) \ 02228 register unsigned long __v0 __asm__("$2") = __NR_##name; \ 02229 __asm__ __volatile__ ("syscall\n" \ 02230 : "+r"(__v0), r7 (__r7) \ 02231 : "0"(__v0), ##__VA_ARGS__ \ 02232 : "$8", "$9", "$10", "$11", "$12", \ 02233 "$13", "$14", "$15", "$24", "$25", \ 02234 "memory"); \ 02235 LSS_RETURN(type, __v0, __r7) 02236 #undef _syscall0 02237 #define _syscall0(type, name) \ 02238 type LSS_NAME(name)() { \ 02239 register unsigned long __r7 __asm__("$7"); \ 02240 LSS_BODY(type, name, "=r"); \ 02241 } 02242 #undef _syscall1 02243 #define _syscall1(type, name, type1, arg1) \ 02244 type LSS_NAME(name)(type1 arg1) { \ 02245 register unsigned long __r7 __asm__("$7"); \ 02246 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \ 02247 } 02248 #undef _syscall2 02249 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 02250 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 02251 register unsigned long __r7 __asm__("$7"); \ 02252 LSS_REG(4, arg1); LSS_REG(5, arg2); \ 02253 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \ 02254 } 02255 #undef _syscall3 02256 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 02257 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 02258 register unsigned long __r7 __asm__("$7"); \ 02259 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 02260 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \ 02261 } 02262 #undef _syscall4 02263 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 02264 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 02265 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 02266 LSS_REG(7, arg4); \ 02267 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \ 02268 } 02269 #undef _syscall5 02270 #if _MIPS_SIM == _MIPS_SIM_ABI32 02271 /* The old 32bit MIPS system call API passes the fifth and sixth argument 02272 * on the stack, whereas the new APIs use registers "r8" and "r9". 02273 */ 02274 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 02275 type5,arg5) \ 02276 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02277 type5 arg5) { \ 02278 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 02279 LSS_REG(7, arg4); \ 02280 register unsigned long __v0 __asm__("$2") = __NR_##name; \ 02281 __asm__ __volatile__ (".set noreorder\n" \ 02282 "subu $29, 32\n" \ 02283 "sw %5, 16($29)\n" \ 02284 "syscall\n" \ 02285 "addiu $29, 32\n" \ 02286 ".set reorder\n" \ 02287 : "+r"(__v0), "+r" (__r7) \ 02288 : "r"(__r4), "r"(__r5), \ 02289 "r"(__r6), "r" ((unsigned long)arg5) \ 02290 : "$8", "$9", "$10", "$11", "$12", \ 02291 "$13", "$14", "$15", "$24", "$25", \ 02292 "memory"); \ 02293 LSS_RETURN(type, __v0, __r7); \ 02294 } 02295 #else 02296 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 02297 type5,arg5) \ 02298 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02299 type5 arg5) { \ 02300 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 02301 LSS_REG(7, arg4); LSS_REG(8, arg5); \ 02302 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ 02303 "r"(__r8)); \ 02304 } 02305 #endif 02306 #undef _syscall6 02307 #if _MIPS_SIM == _MIPS_SIM_ABI32 02308 /* The old 32bit MIPS system call API passes the fifth and sixth argument 02309 * on the stack, whereas the new APIs use registers "r8" and "r9". 02310 */ 02311 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 02312 type5,arg5,type6,arg6) \ 02313 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02314 type5 arg5, type6 arg6) { \ 02315 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 02316 LSS_REG(7, arg4); \ 02317 register unsigned long __v0 __asm__("$2") = __NR_##name; \ 02318 __asm__ __volatile__ (".set noreorder\n" \ 02319 "subu $29, 32\n" \ 02320 "sw %5, 16($29)\n" \ 02321 "sw %6, 20($29)\n" \ 02322 "syscall\n" \ 02323 "addiu $29, 32\n" \ 02324 ".set reorder\n" \ 02325 : "+r"(__v0), "+r" (__r7) \ 02326 : "r"(__r4), "r"(__r5), \ 02327 "r"(__r6), "r" ((unsigned long)arg5), \ 02328 "r" ((unsigned long)arg6) \ 02329 : "$8", "$9", "$10", "$11", "$12", \ 02330 "$13", "$14", "$15", "$24", "$25", \ 02331 "memory"); \ 02332 LSS_RETURN(type, __v0, __r7); \ 02333 } 02334 #else 02335 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 02336 type5,arg5,type6,arg6) \ 02337 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02338 type5 arg5,type6 arg6) { \ 02339 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 02340 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \ 02341 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ 02342 "r"(__r8), "r"(__r9)); \ 02343 } 02344 #endif 02345 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 02346 int flags, void *arg, int *parent_tidptr, 02347 void *newtls, int *child_tidptr) { 02348 register unsigned long __v0 __asm__("$2"); 02349 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls; 02350 { 02351 register int __flags __asm__("$4") = flags; 02352 register void *__stack __asm__("$5") = child_stack; 02353 register void *__ptid __asm__("$6") = parent_tidptr; 02354 register int *__ctid __asm__("$8") = child_tidptr; 02355 __asm__ __volatile__( 02356 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 02357 "subu $29,24\n" 02358 #elif _MIPS_SIM == _MIPS_SIM_NABI32 02359 "sub $29,16\n" 02360 #else 02361 "dsubu $29,16\n" 02362 #endif 02363 02364 /* if (fn == NULL || child_stack == NULL) 02365 * return -EINVAL; 02366 */ 02367 "li %0,%2\n" 02368 "beqz %5,1f\n" 02369 "beqz %6,1f\n" 02370 02371 /* Push "arg" and "fn" onto the stack that will be 02372 * used by the child. 02373 */ 02374 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 02375 "subu %6,32\n" 02376 "sw %5,0(%6)\n" 02377 "sw %8,4(%6)\n" 02378 #elif _MIPS_SIM == _MIPS_SIM_NABI32 02379 "sub %6,32\n" 02380 "sw %5,0(%6)\n" 02381 "sw %8,8(%6)\n" 02382 #else 02383 "dsubu %6,32\n" 02384 "sd %5,0(%6)\n" 02385 "sd %8,8(%6)\n" 02386 #endif 02387 02388 /* $7 = syscall($4 = flags, 02389 * $5 = child_stack, 02390 * $6 = parent_tidptr, 02391 * $7 = newtls, 02392 * $8 = child_tidptr) 02393 */ 02394 "li $2,%3\n" 02395 "syscall\n" 02396 02397 /* if ($7 != 0) 02398 * return $2; 02399 */ 02400 "bnez $7,1f\n" 02401 "bnez $2,1f\n" 02402 02403 /* In the child, now. Call "fn(arg)". 02404 */ 02405 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 02406 "lw $25,0($29)\n" 02407 "lw $4,4($29)\n" 02408 #elif _MIPS_SIM == _MIPS_SIM_NABI32 02409 "lw $25,0($29)\n" 02410 "lw $4,8($29)\n" 02411 #else 02412 "ld $25,0($29)\n" 02413 "ld $4,8($29)\n" 02414 #endif 02415 "jalr $25\n" 02416 02417 /* Call _exit($2) 02418 */ 02419 "move $4,$2\n" 02420 "li $2,%4\n" 02421 "syscall\n" 02422 02423 "1:\n" 02424 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 02425 "addu $29, 24\n" 02426 #elif _MIPS_SIM == _MIPS_SIM_NABI32 02427 "add $29, 16\n" 02428 #else 02429 "daddu $29,16\n" 02430 #endif 02431 : "=&r" (__v0), "+r" (__r7) 02432 : "i"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), 02433 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), 02434 "r"(__ptid), "r"(__r7), "r"(__ctid) 02435 : "$9", "$10", "$11", "$12", "$13", "$14", "$15", 02436 "$24", "$25", "memory"); 02437 } 02438 LSS_RETURN(int, __v0, __r7); 02439 } 02440 #elif defined (__PPC__) 02441 #undef LSS_LOADARGS_0 02442 #define LSS_LOADARGS_0(name, dummy...) \ 02443 __sc_0 = __NR_##name 02444 #undef LSS_LOADARGS_1 02445 #define LSS_LOADARGS_1(name, arg1) \ 02446 LSS_LOADARGS_0(name); \ 02447 __sc_3 = (unsigned long) (arg1) 02448 #undef LSS_LOADARGS_2 02449 #define LSS_LOADARGS_2(name, arg1, arg2) \ 02450 LSS_LOADARGS_1(name, arg1); \ 02451 __sc_4 = (unsigned long) (arg2) 02452 #undef LSS_LOADARGS_3 02453 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \ 02454 LSS_LOADARGS_2(name, arg1, arg2); \ 02455 __sc_5 = (unsigned long) (arg3) 02456 #undef LSS_LOADARGS_4 02457 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \ 02458 LSS_LOADARGS_3(name, arg1, arg2, arg3); \ 02459 __sc_6 = (unsigned long) (arg4) 02460 #undef LSS_LOADARGS_5 02461 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \ 02462 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \ 02463 __sc_7 = (unsigned long) (arg5) 02464 #undef LSS_LOADARGS_6 02465 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ 02466 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \ 02467 __sc_8 = (unsigned long) (arg6) 02468 #undef LSS_ASMINPUT_0 02469 #define LSS_ASMINPUT_0 "0" (__sc_0) 02470 #undef LSS_ASMINPUT_1 02471 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3) 02472 #undef LSS_ASMINPUT_2 02473 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4) 02474 #undef LSS_ASMINPUT_3 02475 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5) 02476 #undef LSS_ASMINPUT_4 02477 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6) 02478 #undef LSS_ASMINPUT_5 02479 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7) 02480 #undef LSS_ASMINPUT_6 02481 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8) 02482 #undef LSS_BODY 02483 #define LSS_BODY(nr, type, name, args...) \ 02484 long __sc_ret, __sc_err; \ 02485 { \ 02486 register unsigned long __sc_0 __asm__ ("r0"); \ 02487 register unsigned long __sc_3 __asm__ ("r3"); \ 02488 register unsigned long __sc_4 __asm__ ("r4"); \ 02489 register unsigned long __sc_5 __asm__ ("r5"); \ 02490 register unsigned long __sc_6 __asm__ ("r6"); \ 02491 register unsigned long __sc_7 __asm__ ("r7"); \ 02492 register unsigned long __sc_8 __asm__ ("r8"); \ 02493 \ 02494 LSS_LOADARGS_##nr(name, args); \ 02495 __asm__ __volatile__ \ 02496 ("sc\n\t" \ 02497 "mfcr %0" \ 02498 : "=&r" (__sc_0), \ 02499 "=&r" (__sc_3), "=&r" (__sc_4), \ 02500 "=&r" (__sc_5), "=&r" (__sc_6), \ 02501 "=&r" (__sc_7), "=&r" (__sc_8) \ 02502 : LSS_ASMINPUT_##nr \ 02503 : "cr0", "ctr", "memory", \ 02504 "r9", "r10", "r11", "r12"); \ 02505 __sc_ret = __sc_3; \ 02506 __sc_err = __sc_0; \ 02507 } \ 02508 LSS_RETURN(type, __sc_ret, __sc_err) 02509 #undef _syscall0 02510 #define _syscall0(type, name) \ 02511 type LSS_NAME(name)(void) { \ 02512 LSS_BODY(0, type, name); \ 02513 } 02514 #undef _syscall1 02515 #define _syscall1(type, name, type1, arg1) \ 02516 type LSS_NAME(name)(type1 arg1) { \ 02517 LSS_BODY(1, type, name, arg1); \ 02518 } 02519 #undef _syscall2 02520 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 02521 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 02522 LSS_BODY(2, type, name, arg1, arg2); \ 02523 } 02524 #undef _syscall3 02525 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 02526 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 02527 LSS_BODY(3, type, name, arg1, arg2, arg3); \ 02528 } 02529 #undef _syscall4 02530 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ 02531 type4, arg4) \ 02532 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 02533 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \ 02534 } 02535 #undef _syscall5 02536 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ 02537 type4, arg4, type5, arg5) \ 02538 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02539 type5 arg5) { \ 02540 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \ 02541 } 02542 #undef _syscall6 02543 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ 02544 type4, arg4, type5, arg5, type6, arg6) \ 02545 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 02546 type5 arg5, type6 arg6) { \ 02547 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ 02548 } 02549 /* clone function adapted from glibc 2.3.6 clone.S */ 02550 /* TODO(csilvers): consider wrapping some args up in a struct, like we 02551 * do for i386's _syscall6, so we can compile successfully on gcc 2.95 02552 */ 02553 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 02554 int flags, void *arg, int *parent_tidptr, 02555 void *newtls, int *child_tidptr) { 02556 long __ret, __err; 02557 { 02558 register int (*__fn)(void *) __asm__ ("r8") = fn; 02559 register void *__cstack __asm__ ("r4") = child_stack; 02560 register int __flags __asm__ ("r3") = flags; 02561 register void * __arg __asm__ ("r9") = arg; 02562 register int * __ptidptr __asm__ ("r5") = parent_tidptr; 02563 register void * __newtls __asm__ ("r6") = newtls; 02564 register int * __ctidptr __asm__ ("r7") = child_tidptr; 02565 __asm__ __volatile__( 02566 /* check for fn == NULL 02567 * and child_stack == NULL 02568 */ 02569 "cmpwi cr0, %6, 0\n\t" 02570 "cmpwi cr1, %7, 0\n\t" 02571 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t" 02572 "beq- cr0, 1f\n\t" 02573 02574 /* set up stack frame for child */ 02575 "clrrwi %7, %7, 4\n\t" 02576 "li 0, 0\n\t" 02577 "stwu 0, -16(%7)\n\t" 02578 02579 /* fn, arg, child_stack are saved across the syscall: r28-30 */ 02580 "mr 28, %6\n\t" 02581 "mr 29, %7\n\t" 02582 "mr 27, %9\n\t" 02583 02584 /* syscall */ 02585 "li 0, %4\n\t" 02586 /* flags already in r3 02587 * child_stack already in r4 02588 * ptidptr already in r5 02589 * newtls already in r6 02590 * ctidptr already in r7 02591 */ 02592 "sc\n\t" 02593 02594 /* Test if syscall was successful */ 02595 "cmpwi cr1, 3, 0\n\t" 02596 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" 02597 "bne- cr1, 1f\n\t" 02598 02599 /* Do the function call */ 02600 "mtctr 28\n\t" 02601 "mr 3, 27\n\t" 02602 "bctrl\n\t" 02603 02604 /* Call _exit(r3) */ 02605 "li 0, %5\n\t" 02606 "sc\n\t" 02607 02608 /* Return to parent */ 02609 "1:\n" 02610 "mfcr %1\n\t" 02611 "mr %0, 3\n\t" 02612 : "=r" (__ret), "=r" (__err) 02613 : "0" (-1), "1" (EINVAL), 02614 "i" (__NR_clone), "i" (__NR_exit), 02615 "r" (__fn), "r" (__cstack), "r" (__flags), 02616 "r" (__arg), "r" (__ptidptr), "r" (__newtls), 02617 "r" (__ctidptr) 02618 : "cr0", "cr1", "memory", "ctr", 02619 "r0", "r29", "r27", "r28"); 02620 } 02621 LSS_RETURN(int, __ret, __err); 02622 } 02623 #endif 02624 #define __NR__exit __NR_exit 02625 #define __NR__gettid __NR_gettid 02626 #define __NR__mremap __NR_mremap 02627 LSS_INLINE _syscall1(int, brk, void *, e) 02628 LSS_INLINE _syscall1(int, chdir, const char *,p) 02629 LSS_INLINE _syscall1(int, close, int, f) 02630 LSS_INLINE _syscall2(int, clock_getres, int, c, 02631 struct kernel_timespec*, t) 02632 LSS_INLINE _syscall2(int, clock_gettime, int, c, 02633 struct kernel_timespec*, t) 02634 LSS_INLINE _syscall1(int, dup, int, f) 02635 LSS_INLINE _syscall2(int, dup2, int, s, 02636 int, d) 02637 LSS_INLINE _syscall3(int, execve, const char*, f, 02638 const char*const*,a,const char*const*, e) 02639 LSS_INLINE _syscall1(int, _exit, int, e) 02640 LSS_INLINE _syscall1(int, exit_group, int, e) 02641 LSS_INLINE _syscall3(int, fcntl, int, f, 02642 int, c, long, a) 02643 LSS_INLINE _syscall0(pid_t, fork) 02644 LSS_INLINE _syscall2(int, fstat, int, f, 02645 struct kernel_stat*, b) 02646 LSS_INLINE _syscall2(int, fstatfs, int, f, 02647 struct kernel_statfs*, b) 02648 LSS_INLINE _syscall2(int, ftruncate, int, f, 02649 off_t, l) 02650 LSS_INLINE _syscall4(int, futex, int*, a, 02651 int, o, int, v, 02652 struct kernel_timespec*, t) 02653 LSS_INLINE _syscall3(int, getdents, int, f, 02654 struct kernel_dirent*, d, int, c) 02655 LSS_INLINE _syscall3(int, getdents64, int, f, 02656 struct kernel_dirent64*, d, int, c) 02657 LSS_INLINE _syscall0(gid_t, getegid) 02658 LSS_INLINE _syscall0(uid_t, geteuid) 02659 LSS_INLINE _syscall0(pid_t, getpgrp) 02660 LSS_INLINE _syscall0(pid_t, getpid) 02661 LSS_INLINE _syscall0(pid_t, getppid) 02662 LSS_INLINE _syscall2(int, getpriority, int, a, 02663 int, b) 02664 LSS_INLINE _syscall3(int, getresgid, gid_t *, r, 02665 gid_t *, e, gid_t *, s) 02666 LSS_INLINE _syscall3(int, getresuid, uid_t *, r, 02667 uid_t *, e, uid_t *, s) 02668 #if !defined(__ARM_EABI__) 02669 LSS_INLINE _syscall2(int, getrlimit, int, r, 02670 struct kernel_rlimit*, l) 02671 #endif 02672 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p) 02673 LSS_INLINE _syscall0(pid_t, _gettid) 02674 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t, 02675 void*, tz) 02676 LSS_INLINE _syscall5(int, setxattr, const char *,p, 02677 const char *, n, const void *,v, 02678 size_t, s, int, f) 02679 LSS_INLINE _syscall5(int, lsetxattr, const char *,p, 02680 const char *, n, const void *,v, 02681 size_t, s, int, f) 02682 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p, 02683 const char *, n, void *, v, size_t, s) 02684 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p, 02685 const char *, n, void *, v, size_t, s) 02686 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p, 02687 char *, l, size_t, s) 02688 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p, 02689 char *, l, size_t, s) 02690 LSS_INLINE _syscall3(int, ioctl, int, d, 02691 int, r, void *, a) 02692 LSS_INLINE _syscall2(int, ioprio_get, int, which, 02693 int, who) 02694 LSS_INLINE _syscall3(int, ioprio_set, int, which, 02695 int, who, int, ioprio) 02696 LSS_INLINE _syscall2(int, kill, pid_t, p, 02697 int, s) 02698 LSS_INLINE _syscall3(off_t, lseek, int, f, 02699 off_t, o, int, w) 02700 LSS_INLINE _syscall2(int, munmap, void*, s, 02701 size_t, l) 02702 LSS_INLINE _syscall6(long, move_pages, pid_t, p, 02703 unsigned long, n, void **,g, int *, d, 02704 int *, s, int, f) 02705 LSS_INLINE _syscall3(int, mprotect, const void *,a, 02706 size_t, l, int, p) 02707 LSS_INLINE _syscall5(void*, _mremap, void*, o, 02708 size_t, os, size_t, ns, 02709 unsigned long, f, void *, a) 02710 LSS_INLINE _syscall3(int, open, const char*, p, 02711 int, f, int, m) 02712 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u, 02713 unsigned int, n, int, t) 02714 LSS_INLINE _syscall2(int, prctl, int, o, 02715 long, a) 02716 LSS_INLINE _syscall4(long, ptrace, int, r, 02717 pid_t, p, void *, a, void *, d) 02718 #if defined(__NR_quotactl) 02719 // Defined on x86_64 / i386 only 02720 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special, 02721 int, id, caddr_t, addr) 02722 #endif 02723 LSS_INLINE _syscall3(ssize_t, read, int, f, 02724 void *, b, size_t, c) 02725 LSS_INLINE _syscall3(int, readlink, const char*, p, 02726 char*, b, size_t, s) 02727 LSS_INLINE _syscall4(int, rt_sigaction, int, s, 02728 const struct kernel_sigaction*, a, 02729 struct kernel_sigaction*, o, size_t, c) 02730 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s, 02731 size_t, c) 02732 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h, 02733 const struct kernel_sigset_t*, s, 02734 struct kernel_sigset_t*, o, size_t, c) 02735 LSS_INLINE _syscall2(int, rt_sigsuspend, 02736 const struct kernel_sigset_t*, s, size_t, c) 02737 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p, 02738 unsigned int, l, unsigned long *, m) 02739 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p, 02740 unsigned int, l, unsigned long *, m) 02741 LSS_INLINE _syscall0(int, sched_yield) 02742 LSS_INLINE _syscall1(long, set_tid_address, int *, t) 02743 LSS_INLINE _syscall1(int, setfsgid, gid_t, g) 02744 LSS_INLINE _syscall1(int, setfsuid, uid_t, u) 02745 LSS_INLINE _syscall1(int, setuid, uid_t, u) 02746 LSS_INLINE _syscall1(int, setgid, gid_t, g) 02747 LSS_INLINE _syscall2(int, setpgid, pid_t, p, 02748 pid_t, g) 02749 LSS_INLINE _syscall3(int, setpriority, int, a, 02750 int, b, int, p) 02751 LSS_INLINE _syscall3(int, setresgid, gid_t, r, 02752 gid_t, e, gid_t, s) 02753 LSS_INLINE _syscall3(int, setresuid, uid_t, r, 02754 uid_t, e, uid_t, s) 02755 LSS_INLINE _syscall2(int, setrlimit, int, r, 02756 const struct kernel_rlimit*, l) 02757 LSS_INLINE _syscall0(pid_t, setsid) 02758 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s, 02759 const stack_t*, o) 02760 #if defined(__NR_sigreturn) 02761 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u) 02762 #endif 02763 LSS_INLINE _syscall2(int, stat, const char*, f, 02764 struct kernel_stat*, b) 02765 LSS_INLINE _syscall2(int, statfs, const char*, f, 02766 struct kernel_statfs*, b) 02767 LSS_INLINE _syscall3(int, tgkill, pid_t, p, 02768 pid_t, t, int, s) 02769 LSS_INLINE _syscall2(int, tkill, pid_t, p, 02770 int, s) 02771 LSS_INLINE _syscall1(int, unlink, const char*, f) 02772 LSS_INLINE _syscall3(ssize_t, write, int, f, 02773 const void *, b, size_t, c) 02774 LSS_INLINE _syscall3(ssize_t, writev, int, f, 02775 const struct kernel_iovec*, v, size_t, c) 02776 #if defined(__NR_getcpu) 02777 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu, 02778 unsigned *, node, void *, unused) 02779 #endif 02780 #if defined(__x86_64__) || \ 02781 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) 02782 LSS_INLINE _syscall3(int, recvmsg, int, s, 02783 struct kernel_msghdr*, m, int, f) 02784 LSS_INLINE _syscall3(int, sendmsg, int, s, 02785 const struct kernel_msghdr*, m, int, f) 02786 LSS_INLINE _syscall6(int, sendto, int, s, 02787 const void*, m, size_t, l, 02788 int, f, 02789 const struct kernel_sockaddr*, a, int, t) 02790 LSS_INLINE _syscall2(int, shutdown, int, s, 02791 int, h) 02792 LSS_INLINE _syscall3(int, socket, int, d, 02793 int, t, int, p) 02794 LSS_INLINE _syscall4(int, socketpair, int, d, 02795 int, t, int, p, int*, s) 02796 #endif 02797 #if defined(__x86_64__) 02798 LSS_INLINE _syscall4(int, fallocate, int, fd, int, mode, 02799 loff_t, offset, loff_t, len) 02800 02801 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, 02802 gid_t *egid, 02803 gid_t *sgid) { 02804 return LSS_NAME(getresgid)(rgid, egid, sgid); 02805 } 02806 02807 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, 02808 uid_t *euid, 02809 uid_t *suid) { 02810 return LSS_NAME(getresuid)(ruid, euid, suid); 02811 } 02812 02813 LSS_INLINE _syscall6(void*, mmap, void*, s, 02814 size_t, l, int, p, 02815 int, f, int, d, 02816 __off64_t, o) 02817 02818 LSS_INLINE _syscall4(int, newfstatat, int, d, 02819 const char *, p, 02820 struct kernel_stat*, b, int, f) 02821 02822 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { 02823 return LSS_NAME(setfsgid)(gid); 02824 } 02825 02826 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { 02827 return LSS_NAME(setfsuid)(uid); 02828 } 02829 02830 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { 02831 return LSS_NAME(setresgid)(rgid, egid, sgid); 02832 } 02833 02834 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { 02835 return LSS_NAME(setresuid)(ruid, euid, suid); 02836 } 02837 02838 LSS_INLINE int LSS_NAME(sigaction)(int signum, 02839 const struct kernel_sigaction *act, 02840 struct kernel_sigaction *oldact) { 02841 /* On x86_64, the kernel requires us to always set our own 02842 * SA_RESTORER in order to be able to return from a signal handler. 02843 * This function must have a "magic" signature that the "gdb" 02844 * (and maybe the kernel?) can recognize. 02845 */ 02846 if (act != NULL && !(act->sa_flags & SA_RESTORER)) { 02847 struct kernel_sigaction a = *act; 02848 a.sa_flags |= SA_RESTORER; 02849 a.sa_restorer = LSS_NAME(restore_rt)(); 02850 return LSS_NAME(rt_sigaction)(signum, &a, oldact, 02851 (KERNEL_NSIG+7)/8); 02852 } else { 02853 return LSS_NAME(rt_sigaction)(signum, act, oldact, 02854 (KERNEL_NSIG+7)/8); 02855 } 02856 } 02857 02858 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { 02859 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); 02860 } 02861 02862 LSS_INLINE int LSS_NAME(sigprocmask)(int how, 02863 const struct kernel_sigset_t *set, 02864 struct kernel_sigset_t *oldset) { 02865 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); 02866 } 02867 02868 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { 02869 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); 02870 } 02871 #endif 02872 #if defined(__x86_64__) || defined(__ARM_ARCH_3__) || \ 02873 defined(__ARM_EABI__) || \ 02874 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) 02875 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p, 02876 int*, s, int, o, 02877 struct kernel_rusage*, r) 02878 02879 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){ 02880 return LSS_NAME(wait4)(pid, status, options, 0); 02881 } 02882 #endif 02883 #if defined(__i386__) || defined(__x86_64__) 02884 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m) 02885 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f) 02886 #endif 02887 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) 02888 #define __NR__getresgid32 __NR_getresgid32 02889 #define __NR__getresuid32 __NR_getresuid32 02890 #define __NR__setfsgid32 __NR_setfsgid32 02891 #define __NR__setfsuid32 __NR_setfsuid32 02892 #define __NR__setresgid32 __NR_setresgid32 02893 #define __NR__setresuid32 __NR_setresuid32 02894 #if defined(__ARM_EABI__) 02895 LSS_INLINE _syscall2(int, ugetrlimit, int, r, 02896 struct kernel_rlimit*, l) 02897 #endif 02898 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r, 02899 gid_t *, e, gid_t *, s) 02900 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r, 02901 uid_t *, e, uid_t *, s) 02902 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f) 02903 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f) 02904 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r, 02905 gid_t, e, gid_t, s) 02906 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r, 02907 uid_t, e, uid_t, s) 02908 02909 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, 02910 gid_t *egid, 02911 gid_t *sgid) { 02912 int rc; 02913 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 && 02914 LSS_ERRNO == ENOSYS) { 02915 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) { 02916 return EFAULT; 02917 } 02918 // Clear the high bits first, since getresgid only sets 16 bits 02919 *rgid = *egid = *sgid = 0; 02920 rc = LSS_NAME(getresgid)(rgid, egid, sgid); 02921 } 02922 return rc; 02923 } 02924 02925 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, 02926 uid_t *euid, 02927 uid_t *suid) { 02928 int rc; 02929 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 && 02930 LSS_ERRNO == ENOSYS) { 02931 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) { 02932 return EFAULT; 02933 } 02934 // Clear the high bits first, since getresuid only sets 16 bits 02935 *ruid = *euid = *suid = 0; 02936 rc = LSS_NAME(getresuid)(ruid, euid, suid); 02937 } 02938 return rc; 02939 } 02940 02941 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { 02942 int rc; 02943 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 && 02944 LSS_ERRNO == ENOSYS) { 02945 if ((unsigned int)gid & ~0xFFFFu) { 02946 rc = EINVAL; 02947 } else { 02948 rc = LSS_NAME(setfsgid)(gid); 02949 } 02950 } 02951 return rc; 02952 } 02953 02954 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { 02955 int rc; 02956 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 && 02957 LSS_ERRNO == ENOSYS) { 02958 if ((unsigned int)uid & ~0xFFFFu) { 02959 rc = EINVAL; 02960 } else { 02961 rc = LSS_NAME(setfsuid)(uid); 02962 } 02963 } 02964 return rc; 02965 } 02966 02967 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { 02968 int rc; 02969 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 && 02970 LSS_ERRNO == ENOSYS) { 02971 if ((unsigned int)rgid & ~0xFFFFu || 02972 (unsigned int)egid & ~0xFFFFu || 02973 (unsigned int)sgid & ~0xFFFFu) { 02974 rc = EINVAL; 02975 } else { 02976 rc = LSS_NAME(setresgid)(rgid, egid, sgid); 02977 } 02978 } 02979 return rc; 02980 } 02981 02982 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { 02983 int rc; 02984 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 && 02985 LSS_ERRNO == ENOSYS) { 02986 if ((unsigned int)ruid & ~0xFFFFu || 02987 (unsigned int)euid & ~0xFFFFu || 02988 (unsigned int)suid & ~0xFFFFu) { 02989 rc = EINVAL; 02990 } else { 02991 rc = LSS_NAME(setresuid)(ruid, euid, suid); 02992 } 02993 } 02994 return rc; 02995 } 02996 #endif 02997 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) { 02998 memset(&set->sig, 0, sizeof(set->sig)); 02999 return 0; 03000 } 03001 03002 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) { 03003 memset(&set->sig, -1, sizeof(set->sig)); 03004 return 0; 03005 } 03006 03007 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set, 03008 int signum) { 03009 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { 03010 LSS_ERRNO = EINVAL; 03011 return -1; 03012 } else { 03013 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] 03014 |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0]))); 03015 return 0; 03016 } 03017 } 03018 03019 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set, 03020 int signum) { 03021 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { 03022 LSS_ERRNO = EINVAL; 03023 return -1; 03024 } else { 03025 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] 03026 &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0])))); 03027 return 0; 03028 } 03029 } 03030 03031 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set, 03032 int signum) { 03033 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { 03034 LSS_ERRNO = EINVAL; 03035 return -1; 03036 } else { 03037 return !!(set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] & 03038 (1UL << ((signum - 1) % (8*sizeof(set->sig[0]))))); 03039 } 03040 } 03041 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ 03042 defined(__ARM_EABI__) || \ 03043 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || defined(__PPC__) 03044 #define __NR__sigaction __NR_sigaction 03045 #define __NR__sigpending __NR_sigpending 03046 #define __NR__sigprocmask __NR_sigprocmask 03047 #define __NR__sigsuspend __NR_sigsuspend 03048 #define __NR__socketcall __NR_socketcall 03049 LSS_INLINE _syscall2(int, fstat64, int, f, 03050 struct kernel_stat64 *, b) 03051 LSS_INLINE _syscall5(int, _llseek, uint, fd, 03052 unsigned long, hi, unsigned long, lo, 03053 loff_t *, res, uint, wh) 03054 #if !defined(__ARM_EABI__) 03055 LSS_INLINE _syscall1(void*, mmap, void*, a) 03056 #endif 03057 LSS_INLINE _syscall6(void*, mmap2, void*, s, 03058 size_t, l, int, p, 03059 int, f, int, d, 03060 off_t, o) 03061 LSS_INLINE _syscall3(int, _sigaction, int, s, 03062 const struct kernel_old_sigaction*, a, 03063 struct kernel_old_sigaction*, o) 03064 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s) 03065 LSS_INLINE _syscall3(int, _sigprocmask, int, h, 03066 const unsigned long*, s, 03067 unsigned long*, o) 03068 #ifdef __PPC__ 03069 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s) 03070 #else 03071 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a, 03072 int, b, 03073 unsigned long, s) 03074 #endif 03075 LSS_INLINE _syscall2(int, stat64, const char *, p, 03076 struct kernel_stat64 *, b) 03077 03078 LSS_INLINE int LSS_NAME(sigaction)(int signum, 03079 const struct kernel_sigaction *act, 03080 struct kernel_sigaction *oldact) { 03081 int old_errno = LSS_ERRNO; 03082 int rc; 03083 struct kernel_sigaction a; 03084 if (act != NULL) { 03085 a = *act; 03086 #ifdef __i386__ 03087 /* On i386, the kernel requires us to always set our own 03088 * SA_RESTORER when using realtime signals. Otherwise, it does not 03089 * know how to return from a signal handler. This function must have 03090 * a "magic" signature that the "gdb" (and maybe the kernel?) can 03091 * recognize. 03092 * Apparently, a SA_RESTORER is implicitly set by the kernel, when 03093 * using non-realtime signals. 03094 * 03095 * TODO: Test whether ARM needs a restorer 03096 */ 03097 if (!(a.sa_flags & SA_RESTORER)) { 03098 a.sa_flags |= SA_RESTORER; 03099 a.sa_restorer = (a.sa_flags & SA_SIGINFO) 03100 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)(); 03101 } 03102 #endif 03103 } 03104 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact, 03105 (KERNEL_NSIG+7)/8); 03106 if (rc < 0 && LSS_ERRNO == ENOSYS) { 03107 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa; 03108 if (!act) { 03109 ptr_a = NULL; 03110 } else { 03111 oa.sa_handler_ = act->sa_handler_; 03112 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask)); 03113 #ifndef __mips__ 03114 oa.sa_restorer = act->sa_restorer; 03115 #endif 03116 oa.sa_flags = act->sa_flags; 03117 } 03118 if (!oldact) { 03119 ptr_oa = NULL; 03120 } 03121 LSS_ERRNO = old_errno; 03122 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa); 03123 if (rc == 0 && oldact) { 03124 if (act) { 03125 memcpy(oldact, act, sizeof(*act)); 03126 } else { 03127 memset(oldact, 0, sizeof(*oldact)); 03128 } 03129 oldact->sa_handler_ = ptr_oa->sa_handler_; 03130 oldact->sa_flags = ptr_oa->sa_flags; 03131 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask)); 03132 #ifndef __mips__ 03133 oldact->sa_restorer = ptr_oa->sa_restorer; 03134 #endif 03135 } 03136 } 03137 return rc; 03138 } 03139 03140 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { 03141 int old_errno = LSS_ERRNO; 03142 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); 03143 if (rc < 0 && LSS_ERRNO == ENOSYS) { 03144 LSS_ERRNO = old_errno; 03145 LSS_NAME(sigemptyset)(set); 03146 rc = LSS_NAME(_sigpending)(&set->sig[0]); 03147 } 03148 return rc; 03149 } 03150 03151 LSS_INLINE int LSS_NAME(sigprocmask)(int how, 03152 const struct kernel_sigset_t *set, 03153 struct kernel_sigset_t *oldset) { 03154 int olderrno = LSS_ERRNO; 03155 int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); 03156 if (rc < 0 && LSS_ERRNO == ENOSYS) { 03157 LSS_ERRNO = olderrno; 03158 if (oldset) { 03159 LSS_NAME(sigemptyset)(oldset); 03160 } 03161 rc = LSS_NAME(_sigprocmask)(how, 03162 set ? &set->sig[0] : NULL, 03163 oldset ? &oldset->sig[0] : NULL); 03164 } 03165 return rc; 03166 } 03167 03168 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { 03169 int olderrno = LSS_ERRNO; 03170 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); 03171 if (rc < 0 && LSS_ERRNO == ENOSYS) { 03172 LSS_ERRNO = olderrno; 03173 rc = LSS_NAME(_sigsuspend)( 03174 #ifndef __PPC__ 03175 set, 0, 03176 #endif 03177 set->sig[0]); 03178 } 03179 return rc; 03180 } 03181 #endif 03182 #if defined(__PPC__) 03183 #undef LSS_SC_LOADARGS_0 03184 #define LSS_SC_LOADARGS_0(dummy...) 03185 #undef LSS_SC_LOADARGS_1 03186 #define LSS_SC_LOADARGS_1(arg1) \ 03187 __sc_4 = (unsigned long) (arg1) 03188 #undef LSS_SC_LOADARGS_2 03189 #define LSS_SC_LOADARGS_2(arg1, arg2) \ 03190 LSS_SC_LOADARGS_1(arg1); \ 03191 __sc_5 = (unsigned long) (arg2) 03192 #undef LSS_SC_LOADARGS_3 03193 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \ 03194 LSS_SC_LOADARGS_2(arg1, arg2); \ 03195 __sc_6 = (unsigned long) (arg3) 03196 #undef LSS_SC_LOADARGS_4 03197 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \ 03198 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \ 03199 __sc_7 = (unsigned long) (arg4) 03200 #undef LSS_SC_LOADARGS_5 03201 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \ 03202 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \ 03203 __sc_8 = (unsigned long) (arg5) 03204 #undef LSS_SC_BODY 03205 #define LSS_SC_BODY(nr, type, opt, args...) \ 03206 long __sc_ret, __sc_err; \ 03207 { \ 03208 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \ 03209 register unsigned long __sc_3 __asm__ ("r3") = opt; \ 03210 register unsigned long __sc_4 __asm__ ("r4"); \ 03211 register unsigned long __sc_5 __asm__ ("r5"); \ 03212 register unsigned long __sc_6 __asm__ ("r6"); \ 03213 register unsigned long __sc_7 __asm__ ("r7"); \ 03214 register unsigned long __sc_8 __asm__ ("r8"); \ 03215 LSS_SC_LOADARGS_##nr(args); \ 03216 __asm__ __volatile__ \ 03217 ("stwu 1, -48(1)\n\t" \ 03218 "stw 4, 20(1)\n\t" \ 03219 "stw 5, 24(1)\n\t" \ 03220 "stw 6, 28(1)\n\t" \ 03221 "stw 7, 32(1)\n\t" \ 03222 "stw 8, 36(1)\n\t" \ 03223 "addi 4, 1, 20\n\t" \ 03224 "sc\n\t" \ 03225 "mfcr %0" \ 03226 : "=&r" (__sc_0), \ 03227 "=&r" (__sc_3), "=&r" (__sc_4), \ 03228 "=&r" (__sc_5), "=&r" (__sc_6), \ 03229 "=&r" (__sc_7), "=&r" (__sc_8) \ 03230 : LSS_ASMINPUT_##nr \ 03231 : "cr0", "ctr", "memory"); \ 03232 __sc_ret = __sc_3; \ 03233 __sc_err = __sc_0; \ 03234 } \ 03235 LSS_RETURN(type, __sc_ret, __sc_err) 03236 03237 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, 03238 int flags){ 03239 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags); 03240 } 03241 03242 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, 03243 const struct kernel_msghdr *msg, 03244 int flags) { 03245 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags); 03246 } 03247 03248 // TODO(csilvers): why is this ifdef'ed out? 03249 #if 0 03250 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, 03251 int flags, 03252 const struct kernel_sockaddr *to, 03253 unsigned int tolen) { 03254 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen); 03255 } 03256 #endif 03257 03258 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { 03259 LSS_SC_BODY(2, int, 13, s, how); 03260 } 03261 03262 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { 03263 LSS_SC_BODY(3, int, 1, domain, type, protocol); 03264 } 03265 03266 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, 03267 int sv[2]) { 03268 LSS_SC_BODY(4, int, 8, d, type, protocol, sv); 03269 } 03270 #endif 03271 #if defined(__ARM_EABI__) 03272 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg, 03273 int, flags) 03274 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*, 03275 msg, int, flags) 03276 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len, 03277 int, flags, const struct kernel_sockaddr*, to, 03278 unsigned int, tolen) 03279 LSS_INLINE _syscall2(int, shutdown, int, s, int, how) 03280 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol) 03281 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol, 03282 int*, sv) 03283 #endif 03284 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ 03285 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 03286 #define __NR__socketcall __NR_socketcall 03287 LSS_INLINE _syscall2(int, _socketcall, int, c, 03288 va_list, a) 03289 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) { 03290 int rc; 03291 va_list ap; 03292 va_start(ap, op); 03293 rc = LSS_NAME(_socketcall)(op, ap); 03294 va_end(ap); 03295 return rc; 03296 } 03297 03298 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, 03299 int flags){ 03300 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags); 03301 } 03302 03303 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, 03304 const struct kernel_msghdr *msg, 03305 int flags) { 03306 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags); 03307 } 03308 03309 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, 03310 int flags, 03311 const struct kernel_sockaddr *to, 03312 unsigned int tolen) { 03313 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen); 03314 } 03315 03316 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { 03317 return LSS_NAME(socketcall)(13, s, how); 03318 } 03319 03320 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { 03321 return LSS_NAME(socketcall)(1, domain, type, protocol); 03322 } 03323 03324 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, 03325 int sv[2]) { 03326 return LSS_NAME(socketcall)(8, d, type, protocol, sv); 03327 } 03328 #endif 03329 #if defined(__i386__) || defined(__PPC__) 03330 LSS_INLINE _syscall4(int, fstatat64, int, d, 03331 const char *, p, 03332 struct kernel_stat64 *, b, int, f) 03333 #endif 03334 #if defined(__i386__) || defined(__PPC__) || \ 03335 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 03336 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p, 03337 int*, s, int, o) 03338 #endif 03339 #if defined(__mips__) 03340 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns 03341 * both file handles through CPU registers. 03342 */ 03343 LSS_INLINE int LSS_NAME(pipe)(int *p) { 03344 register unsigned long __v0 __asm__("$2") = __NR_pipe; 03345 register unsigned long __v1 __asm__("$3"); 03346 register unsigned long __r7 __asm__("$7"); 03347 __asm__ __volatile__ ("syscall\n" 03348 : "+r"(__v0), "=r"(__v1), "=r" (__r7) 03349 : "0"(__v0) 03350 : "$8", "$9", "$10", "$11", "$12", 03351 "$13", "$14", "$15", "$24", "$25", "memory"); 03352 if (__r7) { 03353 unsigned long __errnovalue = __v0; 03354 LSS_ERRNO = __errnovalue; 03355 return -1; 03356 } else { 03357 p[0] = __v0; 03358 p[1] = __v1; 03359 return 0; 03360 } 03361 } 03362 #else 03363 LSS_INLINE _syscall1(int, pipe, int *, p) 03364 #endif 03365 /* TODO(csilvers): see if ppc can/should support this as well */ 03366 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ 03367 defined(__ARM_EABI__) || \ 03368 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) 03369 #define __NR__statfs64 __NR_statfs64 03370 #define __NR__fstatfs64 __NR_fstatfs64 03371 LSS_INLINE _syscall3(int, _statfs64, const char*, p, 03372 size_t, s,struct kernel_statfs64*, b) 03373 LSS_INLINE _syscall3(int, _fstatfs64, int, f, 03374 size_t, s,struct kernel_statfs64*, b) 03375 LSS_INLINE int LSS_NAME(statfs64)(const char *p, 03376 struct kernel_statfs64 *b) { 03377 return LSS_NAME(_statfs64)(p, sizeof(*b), b); 03378 } 03379 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) { 03380 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b); 03381 } 03382 #endif 03383 03384 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) { 03385 extern char **environ; 03386 return LSS_NAME(execve)(path, argv, (const char *const *)environ); 03387 } 03388 03389 LSS_INLINE pid_t LSS_NAME(gettid)() { 03390 pid_t tid = LSS_NAME(_gettid)(); 03391 if (tid != -1) { 03392 return tid; 03393 } 03394 return LSS_NAME(getpid)(); 03395 } 03396 03397 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size, 03398 size_t new_size, int flags, ...) { 03399 va_list ap; 03400 void *new_address, *rc; 03401 va_start(ap, flags); 03402 new_address = va_arg(ap, void *); 03403 rc = LSS_NAME(_mremap)(old_address, old_size, new_size, 03404 flags, new_address); 03405 va_end(ap); 03406 return rc; 03407 } 03408 03409 LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) { 03410 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it 03411 * then sends job control signals to the real parent, rather than to 03412 * the tracer. We reduce the risk of this happening by starting a 03413 * whole new time slice, and then quickly sending a SIGCONT signal 03414 * right after detaching from the tracee. 03415 * 03416 * We use tkill to ensure that we only issue a wakeup for the thread being 03417 * detached. Large multi threaded apps can take a long time in the kernel 03418 * processing SIGCONT. 03419 */ 03420 int rc, err; 03421 LSS_NAME(sched_yield)(); 03422 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0); 03423 err = LSS_ERRNO; 03424 LSS_NAME(tkill)(pid, SIGCONT); 03425 /* Old systems don't have tkill */ 03426 if (LSS_ERRNO == ENOSYS) 03427 LSS_NAME(kill)(pid, SIGCONT); 03428 LSS_ERRNO = err; 03429 return rc; 03430 } 03431 03432 LSS_INLINE int LSS_NAME(raise)(int sig) { 03433 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig); 03434 } 03435 03436 LSS_INLINE int LSS_NAME(setpgrp)() { 03437 return LSS_NAME(setpgid)(0, 0); 03438 } 03439 03440 LSS_INLINE int LSS_NAME(sysconf)(int name) { 03441 extern int __getpagesize(void); 03442 switch (name) { 03443 case _SC_OPEN_MAX: { 03444 struct kernel_rlimit limit; 03445 #if defined(__ARM_EABI__) 03446 return LSS_NAME(ugetrlimit)(RLIMIT_NOFILE, &limit) < 0 03447 ? 8192 : limit.rlim_cur; 03448 #else 03449 return LSS_NAME(getrlimit)(RLIMIT_NOFILE, &limit) < 0 03450 ? 8192 : limit.rlim_cur; 03451 #endif 03452 } 03453 case _SC_PAGESIZE: 03454 return __getpagesize(); 03455 default: 03456 LSS_ERRNO = ENOSYS; 03457 return -1; 03458 } 03459 } 03460 #if defined(__x86_64__) || \ 03461 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64) 03462 LSS_INLINE _syscall4(ssize_t, pread64, int, f, 03463 void *, b, size_t, c, 03464 loff_t, o) 03465 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f, 03466 const void *, b, size_t, c, 03467 loff_t, o) 03468 LSS_INLINE _syscall3(int, readahead, int, f, 03469 loff_t, o, unsigned, c) 03470 #else 03471 #define __NR__pread64 __NR_pread64 03472 #define __NR__pwrite64 __NR_pwrite64 03473 #define __NR__readahead __NR_readahead 03474 #if defined(__ARM_EABI__) 03475 /* On ARM, a 64-bit parameter has to be in an even-odd register pair. 03476 * Hence these calls ignore their fourth argument (r3) so that their 03477 * fifth and sixth make such a pair (r4,r5). 03478 */ 03479 #define LSS_LLARG_PAD 0, 03480 LSS_INLINE _syscall6(ssize_t, _pread64, int, f, 03481 void *, b, size_t, c, 03482 unsigned, skip, unsigned, o1, unsigned, o2) 03483 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f, 03484 const void *, b, size_t, c, 03485 unsigned, skip, unsigned, o1, unsigned, o2) 03486 LSS_INLINE _syscall5(int, _readahead, int, f, 03487 unsigned, skip, 03488 unsigned, o1, unsigned, o2, size_t, c) 03489 #else 03490 #define LSS_LLARG_PAD 03491 LSS_INLINE _syscall5(ssize_t, _pread64, int, f, 03492 void *, b, size_t, c, unsigned, o1, 03493 unsigned, o2) 03494 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f, 03495 const void *, b, size_t, c, unsigned, o1, 03496 long, o2) 03497 LSS_INLINE _syscall4(int, _readahead, int, f, 03498 unsigned, o1, unsigned, o2, size_t, c) 03499 #endif 03500 /* We force 64bit-wide parameters onto the stack, then access each 03501 * 32-bit component individually. This guarantees that we build the 03502 * correct parameters independent of the native byte-order of the 03503 * underlying architecture. 03504 */ 03505 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count, 03506 loff_t off) { 03507 union { loff_t off; unsigned arg[2]; } o = { off }; 03508 return LSS_NAME(_pread64)(fd, buf, count, 03509 LSS_LLARG_PAD o.arg[0], o.arg[1]); 03510 } 03511 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf, 03512 size_t count, loff_t off) { 03513 union { loff_t off; unsigned arg[2]; } o = { off }; 03514 return LSS_NAME(_pwrite64)(fd, buf, count, 03515 LSS_LLARG_PAD o.arg[0], o.arg[1]); 03516 } 03517 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) { 03518 union { loff_t off; unsigned arg[2]; } o = { off }; 03519 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], len); 03520 } 03521 #endif 03522 #endif 03523 03524 #ifdef __ANDROID__ 03525 /* These restore the original values of these macros saved by the 03526 * corresponding #pragma push_macro near the top of this file. */ 03527 # pragma pop_macro("stat64") 03528 # pragma pop_macro("fstat64") 03529 # pragma pop_macro("lstat64") 03530 #endif 03531 03532 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) 03533 } 03534 #endif 03535 03536 #endif 03537 #endif