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