1 /* Copyright (c) 2005-2011, Google Inc. 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * --- 31 * Author: Markus Gutschke 32 */ 33 34 /* This file includes Linux-specific support functions common to the 35 * coredumper and the thread lister; primarily, this is a collection 36 * of direct system calls, and a couple of symbols missing from 37 * standard header files. 38 * There are a few options that the including file can set to control 39 * the behavior of this file: 40 * 41 * SYS_CPLUSPLUS: 42 * The entire header file will normally be wrapped in 'extern "C" { }", 43 * making it suitable for compilation as both C and C++ source. If you 44 * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit 45 * the wrapping. N.B. doing so will suppress inclusion of all prerequisite 46 * system header files, too. It is the caller's responsibility to provide 47 * the necessary definitions. 48 * 49 * SYS_ERRNO: 50 * All system calls will update "errno" unless overriden by setting the 51 * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be 52 * an l-value. 53 * 54 * SYS_INLINE: 55 * New symbols will be defined "static inline", unless overridden by 56 * the SYS_INLINE macro. 57 * 58 * SYS_LINUX_SYSCALL_SUPPORT_H 59 * This macro is used to avoid multiple inclusions of this header file. 60 * If you need to include this file more than once, make sure to 61 * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion. 62 * 63 * SYS_PREFIX: 64 * New system calls will have a prefix of "sys_" unless overridden by 65 * the SYS_PREFIX macro. Valid values for this macro are [0..9] which 66 * results in prefixes "sys[0..9]_". It is also possible to set this 67 * macro to -1, which avoids all prefixes. 68 * 69 * SYS_SYSCALL_ENTRYPOINT: 70 * Some applications (such as sandboxes that filter system calls), need 71 * to be able to run custom-code each time a system call is made. If this 72 * macro is defined, it expands to the name of a "common" symbol. If 73 * this symbol is assigned a non-NULL pointer value, it is used as the 74 * address of the system call entrypoint. 75 * A pointer to this symbol can be obtained by calling 76 * get_syscall_entrypoint() 77 * 78 * This file defines a few internal symbols that all start with "LSS_". 79 * Do not access these symbols from outside this file. They are not part 80 * of the supported API. 81 */ 82 #ifndef SYS_LINUX_SYSCALL_SUPPORT_H 83 #define SYS_LINUX_SYSCALL_SUPPORT_H 84 85 /* We currently only support x86-32, x86-64, ARM, MIPS, PPC, s390 and s390x 86 * on Linux. 87 * Porting to other related platforms should not be difficult. 88 */ 89 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \ 90 defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__) || \ 91 defined(__aarch64__) || defined(__s390__) || defined(__e2k__) || \ 92 (defined(__riscv) && __riscv_xlen == 64) || defined(__loongarch_lp64)) \ 93 && (defined(__linux) || defined(__ANDROID__)) 94 95 #ifndef SYS_CPLUSPLUS 96 #ifdef __cplusplus 97 /* Some system header files in older versions of gcc neglect to properly 98 * handle being included from C++. As it appears to be harmless to have 99 * multiple nested 'extern "C"' blocks, just add another one here. 100 */ 101 extern "C" { 102 #endif 103 104 #include <errno.h> 105 #include <fcntl.h> 106 #include <sched.h> 107 #include <signal.h> 108 #include <stdarg.h> 109 #include <stddef.h> 110 #include <stdint.h> 111 #include <string.h> 112 #include <sys/ptrace.h> 113 #include <sys/resource.h> 114 #include <sys/time.h> 115 #include <sys/types.h> 116 #include <sys/syscall.h> 117 #include <unistd.h> 118 #include <linux/unistd.h> 119 #include <endian.h> 120 121 #ifdef __mips__ 122 /* Include definitions of the ABI currently in use. */ 123 #ifdef __ANDROID__ 124 /* Android doesn't have sgidefs.h, but does have asm/sgidefs.h, 125 * which has the definitions we need. 126 */ 127 #include <asm/sgidefs.h> 128 #else 129 #include <sgidefs.h> 130 #endif 131 #endif 132 #endif 133 134 /* Some libcs, for example Android NDK and musl, #define these 135 * macros as aliases to their non-64 counterparts. To avoid naming 136 * conflict, remove them. 137 * 138 * These are restored by the corresponding #pragma pop_macro near 139 * the end of this file. 140 */ 141 #pragma push_macro("stat64") 142 #pragma push_macro("fstat64") 143 #pragma push_macro("lstat64") 144 #pragma push_macro("pread64") 145 #pragma push_macro("pwrite64") 146 #pragma push_macro("getdents64") 147 #undef stat64 148 #undef fstat64 149 #undef lstat64 150 #undef pread64 151 #undef pwrite64 152 #undef getdents64 153 154 #if defined(__ANDROID__) && defined(__x86_64__) 155 // A number of x86_64 syscalls are blocked by seccomp on recent Android; 156 // undefine them so that modern alternatives will be used instead where 157 // possible. 158 // The alternative syscalls have been sanity checked against linux-3.4+; 159 // older versions might not work. 160 # undef __NR_getdents 161 # undef __NR_dup2 162 # undef __NR_fork 163 # undef __NR_getpgrp 164 # undef __NR_open 165 # undef __NR_poll 166 # undef __NR_readlink 167 # undef __NR_stat 168 # undef __NR_unlink 169 # undef __NR_pipe 170 #endif 171 172 #if defined(__ANDROID__) 173 // waitpid is blocked by seccomp on all architectures on recent Android. 174 # undef __NR_waitpid 175 #endif 176 177 /* As glibc often provides subtly incompatible data structures (and implicit 178 * wrapper functions that convert them), we provide our own kernel data 179 * structures for use by the system calls. 180 * These structures have been developed by using Linux 2.6.23 headers for 181 * reference. Note though, we do not care about exact API compatibility 182 * with the kernel, and in fact the kernel often does not have a single 183 * API that works across architectures. Instead, we try to mimic the glibc 184 * API where reasonable, and only guarantee ABI compatibility with the 185 * kernel headers. 186 * Most notably, here are a few changes that were made to the structures 187 * defined by kernel headers: 188 * 189 * - we only define structures, but not symbolic names for kernel data 190 * types. For the latter, we directly use the native C datatype 191 * (i.e. "unsigned" instead of "mode_t"). 192 * - in a few cases, it is possible to define identical structures for 193 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by 194 * standardizing on the 64bit version of the data types. In particular, 195 * this means that we use "unsigned" where the 32bit headers say 196 * "unsigned long". 197 * - overall, we try to minimize the number of cases where we need to 198 * conditionally define different structures. 199 * - the "struct kernel_sigaction" class of structures have been 200 * modified to more closely mimic glibc's API by introducing an 201 * anonymous union for the function pointer. 202 * - a small number of field names had to have an underscore appended to 203 * them, because glibc defines a global macro by the same name. 204 */ 205 206 /* include/linux/dirent.h */ 207 struct kernel_dirent64 { 208 unsigned long long d_ino; 209 long long d_off; 210 unsigned short d_reclen; 211 unsigned char d_type; 212 char d_name[256]; 213 }; 214 215 /* include/linux/dirent.h */ 216 #if !defined(__NR_getdents) 217 // when getdents is not available, getdents64 is used for both. 218 #define kernel_dirent kernel_dirent64 219 #else 220 struct kernel_dirent { 221 long d_ino; 222 long d_off; 223 unsigned short d_reclen; 224 char d_name[256]; 225 }; 226 #endif 227 228 /* include/linux/uio.h */ 229 struct kernel_iovec { 230 void *iov_base; 231 unsigned long iov_len; 232 }; 233 234 /* include/linux/socket.h */ 235 struct kernel_msghdr { 236 void *msg_name; 237 int msg_namelen; 238 struct kernel_iovec*msg_iov; 239 unsigned long msg_iovlen; 240 void *msg_control; 241 unsigned long msg_controllen; 242 unsigned msg_flags; 243 }; 244 245 /* include/asm-generic/poll.h */ 246 struct kernel_pollfd { 247 int fd; 248 short events; 249 short revents; 250 }; 251 252 /* include/linux/resource.h */ 253 struct kernel_rlimit { 254 unsigned long rlim_cur; 255 unsigned long rlim_max; 256 }; 257 258 /* include/linux/time.h */ 259 struct kernel_timespec { 260 long tv_sec; 261 long tv_nsec; 262 }; 263 264 /* include/linux/time.h */ 265 struct kernel_timeval { 266 long tv_sec; 267 long tv_usec; 268 }; 269 270 /* include/linux/time.h */ 271 struct kernel_itimerval { 272 struct kernel_timeval it_interval; 273 struct kernel_timeval it_value; 274 }; 275 276 /* include/linux/resource.h */ 277 struct kernel_rusage { 278 struct kernel_timeval ru_utime; 279 struct kernel_timeval ru_stime; 280 long ru_maxrss; 281 long ru_ixrss; 282 long ru_idrss; 283 long ru_isrss; 284 long ru_minflt; 285 long ru_majflt; 286 long ru_nswap; 287 long ru_inblock; 288 long ru_oublock; 289 long ru_msgsnd; 290 long ru_msgrcv; 291 long ru_nsignals; 292 long ru_nvcsw; 293 long ru_nivcsw; 294 }; 295 296 #if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \ 297 || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__)) \ 298 || defined(__e2k__) 299 300 /* include/asm-{arm,i386,mips,ppc}/signal.h */ 301 struct kernel_old_sigaction { 302 union { 303 void (*sa_handler_)(int); 304 void (*sa_sigaction_)(int, siginfo_t *, void *); 305 }; 306 unsigned long sa_mask; 307 unsigned long sa_flags; 308 void (*sa_restorer)(void); 309 } __attribute__((packed,aligned(4))); 310 #elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 311 #define kernel_old_sigaction kernel_sigaction 312 #elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64) 313 // No kernel_old_sigaction defined for arm64 riscv and loongarch64. 314 #endif 315 316 /* Some kernel functions (e.g. sigaction() in 2.6.23) require that the 317 * exactly match the size of the signal set, even though the API was 318 * intended to be extensible. We define our own KERNEL_NSIG to deal with 319 * this. 320 * Please note that glibc provides signals [1.._NSIG-1], whereas the 321 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The 322 * actual number of signals is obviously the same, but the constants 323 * differ by one. 324 */ 325 #ifdef __mips__ 326 #define KERNEL_NSIG 128 327 #else 328 #define KERNEL_NSIG 64 329 #endif 330 331 /* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */ 332 struct kernel_sigset_t { 333 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/ 334 (8*sizeof(unsigned long))]; 335 }; 336 337 /* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */ 338 struct kernel_sigaction { 339 #ifdef __mips__ 340 unsigned long sa_flags; 341 union { 342 void (*sa_handler_)(int); 343 void (*sa_sigaction_)(int, siginfo_t *, void *); 344 }; 345 struct kernel_sigset_t sa_mask; 346 #else 347 union { 348 void (*sa_handler_)(int); 349 void (*sa_sigaction_)(int, siginfo_t *, void *); 350 }; 351 unsigned long sa_flags; 352 #if !defined(__riscv) && !defined(__loongarch_lp64) 353 void (*sa_restorer)(void); 354 #endif 355 struct kernel_sigset_t sa_mask; 356 #endif 357 }; 358 359 /* include/linux/socket.h */ 360 struct kernel_sockaddr { 361 unsigned short sa_family; 362 char sa_data[14]; 363 }; 364 365 /* include/asm-{arm,aarch64,i386,mips,ppc,s390}/stat.h */ 366 #ifdef __mips__ 367 #if _MIPS_SIM == _MIPS_SIM_ABI64 368 typedef unsigned long long kernel_blkcnt_t; 369 typedef unsigned kernel_blksize_t; 370 typedef unsigned kernel_dev_t; 371 typedef unsigned kernel_gid_t; 372 typedef unsigned long long kernel_ino_t; 373 typedef unsigned kernel_mode_t; 374 typedef unsigned kernel_nlink_t; 375 typedef long long kernel_off_t; 376 typedef unsigned kernel_time_t; 377 typedef unsigned kernel_uid_t; 378 struct kernel_stat { 379 #else 380 struct kernel_stat64 { 381 #endif 382 unsigned st_dev; 383 unsigned __pad0[3]; 384 unsigned long long st_ino; 385 unsigned st_mode; 386 unsigned st_nlink; 387 unsigned st_uid; 388 unsigned st_gid; 389 unsigned st_rdev; 390 unsigned __pad1[3]; 391 long long st_size; 392 unsigned st_atime_; 393 unsigned st_atime_nsec_; 394 unsigned st_mtime_; 395 unsigned st_mtime_nsec_; 396 unsigned st_ctime_; 397 unsigned st_ctime_nsec_; 398 unsigned st_blksize; 399 unsigned __pad2; 400 unsigned long long st_blocks; 401 }; 402 #elif defined __PPC__ 403 struct kernel_stat64 { 404 unsigned long long st_dev; 405 unsigned long long st_ino; 406 unsigned st_mode; 407 unsigned st_nlink; 408 unsigned st_uid; 409 unsigned st_gid; 410 unsigned long long st_rdev; 411 unsigned short int __pad2; 412 long long st_size; 413 long st_blksize; 414 long long st_blocks; 415 long st_atime_; 416 unsigned long st_atime_nsec_; 417 long st_mtime_; 418 unsigned long st_mtime_nsec_; 419 long st_ctime_; 420 unsigned long st_ctime_nsec_; 421 unsigned long __unused4; 422 unsigned long __unused5; 423 }; 424 #elif defined(__e2k__) 425 struct kernel_stat64 { 426 unsigned long long st_dev; 427 unsigned long long st_ino; 428 unsigned int st_mode; 429 unsigned int st_nlink; 430 unsigned int st_uid; 431 unsigned int st_gid; 432 unsigned long long st_rdev; 433 long long st_size; 434 int st_blksize; 435 int __pad2; 436 unsigned long long st_blocks; 437 int st_atime_; 438 unsigned int st_atime_nsec_; 439 int st_mtime_; 440 unsigned int st_mtime_nsec_; 441 int st_ctime_; 442 unsigned int st_ctime_nsec_; 443 unsigned int __unused4; 444 unsigned int __unused5; 445 }; 446 #else 447 struct kernel_stat64 { 448 unsigned long long st_dev; 449 unsigned char __pad0[4]; 450 unsigned __st_ino; 451 unsigned st_mode; 452 unsigned st_nlink; 453 unsigned st_uid; 454 unsigned st_gid; 455 unsigned long long st_rdev; 456 unsigned char __pad3[4]; 457 long long st_size; 458 unsigned st_blksize; 459 unsigned long long st_blocks; 460 unsigned st_atime_; 461 unsigned st_atime_nsec_; 462 unsigned st_mtime_; 463 unsigned st_mtime_nsec_; 464 unsigned st_ctime_; 465 unsigned st_ctime_nsec_; 466 unsigned long long st_ino; 467 }; 468 #endif 469 470 /* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/stat.h */ 471 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) 472 typedef unsigned kernel_blkcnt_t; 473 typedef unsigned kernel_blksize_t; 474 typedef unsigned short kernel_dev_t; 475 typedef unsigned short kernel_gid_t; 476 typedef unsigned kernel_ino_t; 477 typedef unsigned short kernel_mode_t; 478 typedef unsigned short kernel_nlink_t; 479 typedef unsigned kernel_off_t; 480 typedef unsigned kernel_time_t; 481 typedef unsigned short kernel_uid_t; 482 struct kernel_stat { 483 /* The kernel headers suggest that st_dev and st_rdev should be 32bit 484 * quantities encoding 12bit major and 20bit minor numbers in an interleaved 485 * format. In reality, we do not see useful data in the top bits. So, 486 * we'll leave the padding in here, until we find a better solution. 487 */ 488 kernel_dev_t st_dev; 489 short pad1; 490 kernel_ino_t st_ino; 491 kernel_mode_t st_mode; 492 kernel_nlink_t st_nlink; 493 kernel_uid_t st_uid; 494 kernel_gid_t st_gid; 495 kernel_dev_t st_rdev; 496 short pad2; 497 kernel_off_t st_size; 498 kernel_blksize_t st_blksize; 499 kernel_blkcnt_t st_blocks; 500 kernel_time_t st_atime_; 501 unsigned st_atime_nsec_; 502 kernel_time_t st_mtime_; 503 unsigned st_mtime_nsec_; 504 kernel_time_t st_ctime_; 505 unsigned st_ctime_nsec_; 506 unsigned __unused4; 507 unsigned __unused5; 508 }; 509 #elif defined(__x86_64__) 510 typedef int64_t kernel_blkcnt_t; 511 typedef int64_t kernel_blksize_t; 512 typedef uint64_t kernel_dev_t; 513 typedef unsigned kernel_gid_t; 514 typedef uint64_t kernel_ino_t; 515 typedef unsigned kernel_mode_t; 516 typedef uint64_t kernel_nlink_t; 517 typedef int64_t kernel_off_t; 518 typedef uint64_t kernel_time_t; 519 typedef unsigned kernel_uid_t; 520 struct kernel_stat { 521 kernel_dev_t st_dev; 522 kernel_ino_t st_ino; 523 kernel_nlink_t st_nlink; 524 kernel_mode_t st_mode; 525 kernel_uid_t st_uid; 526 kernel_gid_t st_gid; 527 unsigned __pad0; 528 kernel_dev_t st_rdev; 529 kernel_off_t st_size; 530 kernel_blksize_t st_blksize; 531 kernel_blkcnt_t st_blocks; 532 kernel_time_t st_atime_; 533 uint64_t st_atime_nsec_; 534 kernel_time_t st_mtime_; 535 uint64_t st_mtime_nsec_; 536 kernel_time_t st_ctime_; 537 uint64_t st_ctime_nsec_; 538 int64_t __unused4[3]; 539 }; 540 #elif defined(__PPC__) 541 typedef unsigned long kernel_blkcnt_t; 542 typedef unsigned long kernel_blksize_t; 543 typedef unsigned kernel_dev_t; 544 typedef unsigned kernel_gid_t; 545 typedef unsigned long kernel_ino_t; 546 typedef unsigned long kernel_mode_t; 547 typedef unsigned short kernel_nlink_t; 548 typedef long kernel_off_t; 549 typedef unsigned long kernel_time_t; 550 typedef unsigned kernel_uid_t; 551 struct kernel_stat { 552 kernel_dev_t st_dev; 553 kernel_ino_t st_ino; 554 kernel_mode_t st_mode; 555 kernel_nlink_t st_nlink; 556 kernel_gid_t st_uid; 557 kernel_uid_t st_gid; 558 kernel_dev_t st_rdev; 559 kernel_off_t st_size; 560 kernel_blksize_t st_blksize; 561 kernel_blkcnt_t st_blocks; 562 kernel_time_t st_atime_; 563 unsigned long st_atime_nsec_; 564 kernel_time_t st_mtime_; 565 unsigned long st_mtime_nsec_; 566 kernel_time_t st_ctime_; 567 unsigned long st_ctime_nsec_; 568 unsigned long __unused4; 569 unsigned long __unused5; 570 }; 571 #elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) 572 typedef int kernel_blkcnt_t; 573 typedef int kernel_blksize_t; 574 typedef unsigned kernel_dev_t; 575 typedef unsigned kernel_gid_t; 576 typedef unsigned kernel_ino_t; 577 typedef unsigned kernel_mode_t; 578 typedef unsigned kernel_nlink_t; 579 typedef long kernel_off_t; 580 typedef long kernel_time_t; 581 typedef unsigned kernel_uid_t; 582 struct kernel_stat { 583 kernel_dev_t st_dev; 584 int st_pad1[3]; 585 kernel_ino_t st_ino; 586 kernel_mode_t st_mode; 587 kernel_nlink_t st_nlink; 588 kernel_uid_t st_uid; 589 kernel_gid_t st_gid; 590 kernel_dev_t st_rdev; 591 int st_pad2[2]; 592 kernel_off_t st_size; 593 int st_pad3; 594 kernel_time_t st_atime_; 595 long st_atime_nsec_; 596 kernel_time_t st_mtime_; 597 long st_mtime_nsec_; 598 kernel_time_t st_ctime_; 599 long st_ctime_nsec_; 600 kernel_blksize_t st_blksize; 601 kernel_blkcnt_t st_blocks; 602 int st_pad4[14]; 603 }; 604 #elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64) 605 typedef long kernel_blkcnt_t; 606 typedef int kernel_blksize_t; 607 typedef unsigned long kernel_dev_t; 608 typedef unsigned int kernel_gid_t; 609 typedef unsigned long kernel_ino_t; 610 typedef unsigned int kernel_mode_t; 611 typedef unsigned int kernel_nlink_t; 612 typedef long kernel_off_t; 613 typedef long kernel_time_t; 614 typedef unsigned int kernel_uid_t; 615 struct kernel_stat { 616 kernel_dev_t st_dev; 617 kernel_ino_t st_ino; 618 kernel_mode_t st_mode; 619 kernel_nlink_t st_nlink; 620 kernel_uid_t st_uid; 621 kernel_gid_t st_gid; 622 kernel_dev_t st_rdev; 623 unsigned long __pad1; 624 kernel_off_t st_size; 625 kernel_blksize_t st_blksize; 626 int __pad2; 627 kernel_blkcnt_t st_blocks; 628 kernel_time_t st_atime_; 629 unsigned long st_atime_nsec_; 630 kernel_time_t st_mtime_; 631 unsigned long st_mtime_nsec_; 632 kernel_time_t st_ctime_; 633 unsigned long st_ctime_nsec_; 634 unsigned int __unused4; 635 unsigned int __unused5; 636 }; 637 #elif defined(__s390x__) 638 typedef long kernel_blkcnt_t; 639 typedef unsigned long kernel_blksize_t; 640 typedef unsigned long kernel_dev_t; 641 typedef unsigned int kernel_gid_t; 642 typedef unsigned long kernel_ino_t; 643 typedef unsigned int kernel_mode_t; 644 typedef unsigned long kernel_nlink_t; 645 typedef unsigned long kernel_off_t; 646 typedef unsigned long kernel_time_t; 647 typedef unsigned int kernel_uid_t; 648 struct kernel_stat { 649 kernel_dev_t st_dev; 650 kernel_ino_t st_ino; 651 kernel_nlink_t st_nlink; 652 kernel_mode_t st_mode; 653 kernel_uid_t st_uid; 654 kernel_gid_t st_gid; 655 unsigned int __pad1; 656 kernel_dev_t st_rdev; 657 kernel_off_t st_size; 658 kernel_time_t st_atime_; 659 unsigned long st_atime_nsec_; 660 kernel_time_t st_mtime_; 661 unsigned long st_mtime_nsec_; 662 kernel_time_t st_ctime_; 663 unsigned long st_ctime_nsec_; 664 kernel_blksize_t st_blksize; 665 kernel_blkcnt_t st_blocks; 666 unsigned long __unused[3]; 667 }; 668 #elif defined(__s390__) 669 typedef unsigned long kernel_blkcnt_t; 670 typedef unsigned long kernel_blksize_t; 671 typedef unsigned short kernel_dev_t; 672 typedef unsigned short kernel_gid_t; 673 typedef unsigned long kernel_ino_t; 674 typedef unsigned short kernel_mode_t; 675 typedef unsigned short kernel_nlink_t; 676 typedef unsigned long kernel_off_t; 677 typedef unsigned long kernel_time_t; 678 typedef unsigned short kernel_uid_t; 679 struct kernel_stat { 680 kernel_dev_t st_dev; 681 unsigned short __pad1; 682 kernel_ino_t st_ino; 683 kernel_mode_t st_mode; 684 kernel_nlink_t st_nlink; 685 kernel_uid_t st_uid; 686 kernel_gid_t st_gid; 687 kernel_dev_t st_rdev; 688 unsigned short __pad2; 689 kernel_off_t st_size; 690 kernel_blksize_t st_blksize; 691 kernel_blkcnt_t st_blocks; 692 kernel_time_t st_atime_; 693 unsigned long st_atime_nsec_; 694 kernel_time_t st_mtime_; 695 unsigned long st_mtime_nsec_; 696 kernel_time_t st_ctime_; 697 unsigned long st_ctime_nsec_; 698 unsigned long __unused4; 699 unsigned long __unused5; 700 }; 701 #elif defined(__e2k__) 702 typedef unsigned long kernel_blkcnt_t; 703 typedef unsigned long kernel_blksize_t; 704 typedef unsigned long kernel_dev_t; 705 typedef unsigned int kernel_gid_t; 706 typedef unsigned long kernel_ino_t; 707 typedef unsigned int kernel_mode_t; 708 typedef unsigned long kernel_nlink_t; 709 typedef unsigned long kernel_off_t; 710 typedef unsigned long kernel_time_t; 711 typedef unsigned int kernel_uid_t; 712 struct kernel_stat { 713 kernel_dev_t st_dev; 714 kernel_ino_t st_ino; 715 kernel_mode_t st_mode; 716 kernel_nlink_t st_nlink; 717 kernel_uid_t st_uid; 718 kernel_gid_t st_gid; 719 kernel_dev_t st_rdev; 720 kernel_off_t st_size; 721 kernel_blksize_t st_blksize; 722 kernel_blkcnt_t st_blocks; 723 kernel_time_t st_atime_; 724 unsigned long st_atime_nsec_; 725 kernel_time_t st_mtime_; 726 unsigned long st_mtime_nsec_; 727 kernel_time_t st_ctime_; 728 unsigned long st_ctime_nsec_; 729 }; 730 #endif 731 732 /* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/statfs.h */ 733 #ifdef __mips__ 734 #if _MIPS_SIM != _MIPS_SIM_ABI64 735 struct kernel_statfs64 { 736 unsigned long f_type; 737 unsigned long f_bsize; 738 unsigned long f_frsize; 739 unsigned long __pad; 740 unsigned long long f_blocks; 741 unsigned long long f_bfree; 742 unsigned long long f_files; 743 unsigned long long f_ffree; 744 unsigned long long f_bavail; 745 struct { int val[2]; } f_fsid; 746 unsigned long f_namelen; 747 unsigned long f_spare[6]; 748 }; 749 #endif 750 #elif defined(__s390__) 751 /* See also arch/s390/include/asm/compat.h */ 752 struct kernel_statfs64 { 753 unsigned int f_type; 754 unsigned int f_bsize; 755 unsigned long long f_blocks; 756 unsigned long long f_bfree; 757 unsigned long long f_bavail; 758 unsigned long long f_files; 759 unsigned long long f_ffree; 760 struct { int val[2]; } f_fsid; 761 unsigned int f_namelen; 762 unsigned int f_frsize; 763 unsigned int f_flags; 764 unsigned int f_spare[4]; 765 }; 766 #elif !defined(__x86_64__) 767 struct kernel_statfs64 { 768 unsigned long f_type; 769 unsigned long f_bsize; 770 unsigned long long f_blocks; 771 unsigned long long f_bfree; 772 unsigned long long f_bavail; 773 unsigned long long f_files; 774 unsigned long long f_ffree; 775 struct { int val[2]; } f_fsid; 776 unsigned long f_namelen; 777 unsigned long f_frsize; 778 unsigned long f_spare[5]; 779 }; 780 #endif 781 782 /* include/asm-{arm,i386,mips,x86_64,ppc,generic,s390}/statfs.h */ 783 #ifdef __mips__ 784 struct kernel_statfs { 785 long f_type; 786 long f_bsize; 787 long f_frsize; 788 long f_blocks; 789 long f_bfree; 790 long f_files; 791 long f_ffree; 792 long f_bavail; 793 struct { int val[2]; } f_fsid; 794 long f_namelen; 795 long f_spare[6]; 796 }; 797 #elif defined(__x86_64__) 798 struct kernel_statfs { 799 /* x86_64 actually defines all these fields as signed, whereas all other */ 800 /* platforms define them as unsigned. Leaving them at unsigned should not */ 801 /* cause any problems. Make sure these are 64-bit even on x32. */ 802 uint64_t f_type; 803 uint64_t f_bsize; 804 uint64_t f_blocks; 805 uint64_t f_bfree; 806 uint64_t f_bavail; 807 uint64_t f_files; 808 uint64_t f_ffree; 809 struct { int val[2]; } f_fsid; 810 uint64_t f_namelen; 811 uint64_t f_frsize; 812 uint64_t f_spare[5]; 813 }; 814 #elif defined(__s390__) 815 struct kernel_statfs { 816 unsigned int f_type; 817 unsigned int f_bsize; 818 unsigned long f_blocks; 819 unsigned long f_bfree; 820 unsigned long f_bavail; 821 unsigned long f_files; 822 unsigned long f_ffree; 823 struct { int val[2]; } f_fsid; 824 unsigned int f_namelen; 825 unsigned int f_frsize; 826 unsigned int f_flags; 827 unsigned int f_spare[4]; 828 }; 829 #else 830 struct kernel_statfs { 831 unsigned long f_type; 832 unsigned long f_bsize; 833 unsigned long f_blocks; 834 unsigned long f_bfree; 835 unsigned long f_bavail; 836 unsigned long f_files; 837 unsigned long f_ffree; 838 struct { int val[2]; } f_fsid; 839 unsigned long f_namelen; 840 unsigned long f_frsize; 841 unsigned long f_spare[5]; 842 }; 843 #endif 844 845 struct kernel_statx_timestamp { 846 int64_t tv_sec; 847 uint32_t tv_nsec; 848 int32_t __reserved; 849 }; 850 851 struct kernel_statx { 852 uint32_t stx_mask; 853 uint32_t stx_blksize; 854 uint64_t stx_attributes; 855 uint32_t stx_nlink; 856 uint32_t stx_uid; 857 uint32_t stx_gid; 858 uint16_t stx_mode; 859 uint16_t __spare0[1]; 860 uint64_t stx_ino; 861 uint64_t stx_size; 862 uint64_t stx_blocks; 863 uint64_t stx_attributes_mask; 864 struct kernel_statx_timestamp stx_atime; 865 struct kernel_statx_timestamp stx_btime; 866 struct kernel_statx_timestamp stx_ctime; 867 struct kernel_statx_timestamp stx_mtime; 868 uint32_t stx_rdev_major; 869 uint32_t stx_rdev_minor; 870 uint32_t stx_dev_major; 871 uint32_t stx_dev_minor; 872 uint64_t stx_mnt_id; 873 uint64_t __spare2; 874 uint64_t __spare3[12]; 875 }; 876 877 /* Definitions missing from the standard header files */ 878 #ifndef O_DIRECTORY 879 #if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__) 880 #define O_DIRECTORY 0040000 881 #else 882 #define O_DIRECTORY 0200000 883 #endif 884 #endif 885 #ifndef NT_PRXFPREG 886 #define NT_PRXFPREG 0x46e62b7f 887 #endif 888 #ifndef PTRACE_GETFPXREGS 889 #define PTRACE_GETFPXREGS ((enum __ptrace_request)18) 890 #endif 891 #ifndef PR_GET_DUMPABLE 892 #define PR_GET_DUMPABLE 3 893 #endif 894 #ifndef PR_SET_DUMPABLE 895 #define PR_SET_DUMPABLE 4 896 #endif 897 #ifndef PR_GET_SECCOMP 898 #define PR_GET_SECCOMP 21 899 #endif 900 #ifndef PR_SET_SECCOMP 901 #define PR_SET_SECCOMP 22 902 #endif 903 #ifndef AT_FDCWD 904 #define AT_FDCWD (-100) 905 #endif 906 #ifndef AT_SYMLINK_NOFOLLOW 907 #define AT_SYMLINK_NOFOLLOW 0x100 908 #endif 909 #ifndef AT_REMOVEDIR 910 #define AT_REMOVEDIR 0x200 911 #endif 912 #ifndef AT_NO_AUTOMOUNT 913 #define AT_NO_AUTOMOUNT 0x800 914 #endif 915 #ifndef AT_EMPTY_PATH 916 #define AT_EMPTY_PATH 0x1000 917 #endif 918 #ifndef STATX_BASIC_STATS 919 #define STATX_BASIC_STATS 0x000007ffU 920 #endif 921 #ifndef AT_STATX_SYNC_AS_STAT 922 #define AT_STATX_SYNC_AS_STAT 0x0000 923 #endif 924 #ifndef MREMAP_FIXED 925 #define MREMAP_FIXED 2 926 #endif 927 #ifndef SA_RESTORER 928 #define SA_RESTORER 0x04000000 929 #endif 930 #ifndef CPUCLOCK_PROF 931 #define CPUCLOCK_PROF 0 932 #endif 933 #ifndef CPUCLOCK_VIRT 934 #define CPUCLOCK_VIRT 1 935 #endif 936 #ifndef CPUCLOCK_SCHED 937 #define CPUCLOCK_SCHED 2 938 #endif 939 #ifndef CPUCLOCK_PERTHREAD_MASK 940 #define CPUCLOCK_PERTHREAD_MASK 4 941 #endif 942 #ifndef MAKE_PROCESS_CPUCLOCK 943 #define MAKE_PROCESS_CPUCLOCK(pid, clock) \ 944 ((int)(~(unsigned)(pid) << 3) | (int)(clock)) 945 #endif 946 #ifndef MAKE_THREAD_CPUCLOCK 947 #define MAKE_THREAD_CPUCLOCK(tid, clock) \ 948 ((int)(~(unsigned)(tid) << 3) | \ 949 (int)((clock) | CPUCLOCK_PERTHREAD_MASK)) 950 #endif 951 952 #ifndef FUTEX_WAIT 953 #define FUTEX_WAIT 0 954 #endif 955 #ifndef FUTEX_WAKE 956 #define FUTEX_WAKE 1 957 #endif 958 #ifndef FUTEX_FD 959 #define FUTEX_FD 2 960 #endif 961 #ifndef FUTEX_REQUEUE 962 #define FUTEX_REQUEUE 3 963 #endif 964 #ifndef FUTEX_CMP_REQUEUE 965 #define FUTEX_CMP_REQUEUE 4 966 #endif 967 #ifndef FUTEX_WAKE_OP 968 #define FUTEX_WAKE_OP 5 969 #endif 970 #ifndef FUTEX_LOCK_PI 971 #define FUTEX_LOCK_PI 6 972 #endif 973 #ifndef FUTEX_UNLOCK_PI 974 #define FUTEX_UNLOCK_PI 7 975 #endif 976 #ifndef FUTEX_TRYLOCK_PI 977 #define FUTEX_TRYLOCK_PI 8 978 #endif 979 #ifndef FUTEX_PRIVATE_FLAG 980 #define FUTEX_PRIVATE_FLAG 128 981 #endif 982 #ifndef FUTEX_CMD_MASK 983 #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG 984 #endif 985 #ifndef FUTEX_WAIT_PRIVATE 986 #define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) 987 #endif 988 #ifndef FUTEX_WAKE_PRIVATE 989 #define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) 990 #endif 991 #ifndef FUTEX_REQUEUE_PRIVATE 992 #define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG) 993 #endif 994 #ifndef FUTEX_CMP_REQUEUE_PRIVATE 995 #define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG) 996 #endif 997 #ifndef FUTEX_WAKE_OP_PRIVATE 998 #define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG) 999 #endif 1000 #ifndef FUTEX_LOCK_PI_PRIVATE 1001 #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) 1002 #endif 1003 #ifndef FUTEX_UNLOCK_PI_PRIVATE 1004 #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) 1005 #endif 1006 #ifndef FUTEX_TRYLOCK_PI_PRIVATE 1007 #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) 1008 #endif 1009 1010 1011 #if defined(__x86_64__) 1012 #ifndef ARCH_SET_GS 1013 #define ARCH_SET_GS 0x1001 1014 #endif 1015 #ifndef ARCH_GET_GS 1016 #define ARCH_GET_GS 0x1004 1017 #endif 1018 #endif 1019 1020 #if defined(__i386__) 1021 #ifndef __NR_quotactl 1022 #define __NR_quotactl 131 1023 #endif 1024 #ifndef __NR_setresuid 1025 #define __NR_setresuid 164 1026 #define __NR_getresuid 165 1027 #define __NR_setresgid 170 1028 #define __NR_getresgid 171 1029 #endif 1030 #ifndef __NR_rt_sigaction 1031 #define __NR_rt_sigreturn 173 1032 #define __NR_rt_sigaction 174 1033 #define __NR_rt_sigprocmask 175 1034 #define __NR_rt_sigpending 176 1035 #define __NR_rt_sigsuspend 179 1036 #endif 1037 #ifndef __NR_pread64 1038 #define __NR_pread64 180 1039 #endif 1040 #ifndef __NR_pwrite64 1041 #define __NR_pwrite64 181 1042 #endif 1043 #ifndef __NR_ugetrlimit 1044 #define __NR_ugetrlimit 191 1045 #endif 1046 #ifndef __NR_stat64 1047 #define __NR_stat64 195 1048 #endif 1049 #ifndef __NR_fstat64 1050 #define __NR_fstat64 197 1051 #endif 1052 #ifndef __NR_setresuid32 1053 #define __NR_setresuid32 208 1054 #define __NR_getresuid32 209 1055 #define __NR_setresgid32 210 1056 #define __NR_getresgid32 211 1057 #endif 1058 #ifndef __NR_setfsuid32 1059 #define __NR_setfsuid32 215 1060 #define __NR_setfsgid32 216 1061 #endif 1062 #ifndef __NR_getdents64 1063 #define __NR_getdents64 220 1064 #endif 1065 #ifndef __NR_gettid 1066 #define __NR_gettid 224 1067 #endif 1068 #ifndef __NR_readahead 1069 #define __NR_readahead 225 1070 #endif 1071 #ifndef __NR_setxattr 1072 #define __NR_setxattr 226 1073 #endif 1074 #ifndef __NR_lsetxattr 1075 #define __NR_lsetxattr 227 1076 #endif 1077 #ifndef __NR_getxattr 1078 #define __NR_getxattr 229 1079 #endif 1080 #ifndef __NR_lgetxattr 1081 #define __NR_lgetxattr 230 1082 #endif 1083 #ifndef __NR_listxattr 1084 #define __NR_listxattr 232 1085 #endif 1086 #ifndef __NR_llistxattr 1087 #define __NR_llistxattr 233 1088 #endif 1089 #ifndef __NR_tkill 1090 #define __NR_tkill 238 1091 #endif 1092 #ifndef __NR_futex 1093 #define __NR_futex 240 1094 #endif 1095 #ifndef __NR_sched_setaffinity 1096 #define __NR_sched_setaffinity 241 1097 #define __NR_sched_getaffinity 242 1098 #endif 1099 #ifndef __NR_set_tid_address 1100 #define __NR_set_tid_address 258 1101 #endif 1102 #ifndef __NR_clock_gettime 1103 #define __NR_clock_gettime 265 1104 #endif 1105 #ifndef __NR_clock_getres 1106 #define __NR_clock_getres 266 1107 #endif 1108 #ifndef __NR_statfs64 1109 #define __NR_statfs64 268 1110 #endif 1111 #ifndef __NR_fstatfs64 1112 #define __NR_fstatfs64 269 1113 #endif 1114 #ifndef __NR_fadvise64_64 1115 #define __NR_fadvise64_64 272 1116 #endif 1117 #ifndef __NR_ioprio_set 1118 #define __NR_ioprio_set 289 1119 #endif 1120 #ifndef __NR_ioprio_get 1121 #define __NR_ioprio_get 290 1122 #endif 1123 #ifndef __NR_openat 1124 #define __NR_openat 295 1125 #endif 1126 #ifndef __NR_fstatat64 1127 #define __NR_fstatat64 300 1128 #endif 1129 #ifndef __NR_unlinkat 1130 #define __NR_unlinkat 301 1131 #endif 1132 #ifndef __NR_move_pages 1133 #define __NR_move_pages 317 1134 #endif 1135 #ifndef __NR_getcpu 1136 #define __NR_getcpu 318 1137 #endif 1138 #ifndef __NR_fallocate 1139 #define __NR_fallocate 324 1140 #endif 1141 #ifndef __NR_getrandom 1142 #define __NR_getrandom 355 1143 #endif 1144 /* End of i386 definitions */ 1145 #elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) 1146 #ifndef __NR_setresuid 1147 #define __NR_setresuid (__NR_SYSCALL_BASE + 164) 1148 #define __NR_getresuid (__NR_SYSCALL_BASE + 165) 1149 #define __NR_setresgid (__NR_SYSCALL_BASE + 170) 1150 #define __NR_getresgid (__NR_SYSCALL_BASE + 171) 1151 #endif 1152 #ifndef __NR_rt_sigaction 1153 #define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173) 1154 #define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174) 1155 #define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175) 1156 #define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176) 1157 #define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179) 1158 #endif 1159 #ifndef __NR_pread64 1160 #define __NR_pread64 (__NR_SYSCALL_BASE + 180) 1161 #endif 1162 #ifndef __NR_pwrite64 1163 #define __NR_pwrite64 (__NR_SYSCALL_BASE + 181) 1164 #endif 1165 #ifndef __NR_ugetrlimit 1166 #define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191) 1167 #endif 1168 #ifndef __NR_stat64 1169 #define __NR_stat64 (__NR_SYSCALL_BASE + 195) 1170 #endif 1171 #ifndef __NR_fstat64 1172 #define __NR_fstat64 (__NR_SYSCALL_BASE + 197) 1173 #endif 1174 #ifndef __NR_setresuid32 1175 #define __NR_setresuid32 (__NR_SYSCALL_BASE + 208) 1176 #define __NR_getresuid32 (__NR_SYSCALL_BASE + 209) 1177 #define __NR_setresgid32 (__NR_SYSCALL_BASE + 210) 1178 #define __NR_getresgid32 (__NR_SYSCALL_BASE + 211) 1179 #endif 1180 #ifndef __NR_setfsuid32 1181 #define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215) 1182 #define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216) 1183 #endif 1184 #ifndef __NR_getdents64 1185 #define __NR_getdents64 (__NR_SYSCALL_BASE + 217) 1186 #endif 1187 #ifndef __NR_gettid 1188 #define __NR_gettid (__NR_SYSCALL_BASE + 224) 1189 #endif 1190 #ifndef __NR_readahead 1191 #define __NR_readahead (__NR_SYSCALL_BASE + 225) 1192 #endif 1193 #ifndef __NR_setxattr 1194 #define __NR_setxattr (__NR_SYSCALL_BASE + 226) 1195 #endif 1196 #ifndef __NR_lsetxattr 1197 #define __NR_lsetxattr (__NR_SYSCALL_BASE + 227) 1198 #endif 1199 #ifndef __NR_getxattr 1200 #define __NR_getxattr (__NR_SYSCALL_BASE + 229) 1201 #endif 1202 #ifndef __NR_lgetxattr 1203 #define __NR_lgetxattr (__NR_SYSCALL_BASE + 230) 1204 #endif 1205 #ifndef __NR_listxattr 1206 #define __NR_listxattr (__NR_SYSCALL_BASE + 232) 1207 #endif 1208 #ifndef __NR_llistxattr 1209 #define __NR_llistxattr (__NR_SYSCALL_BASE + 233) 1210 #endif 1211 #ifndef __NR_tkill 1212 #define __NR_tkill (__NR_SYSCALL_BASE + 238) 1213 #endif 1214 #ifndef __NR_futex 1215 #define __NR_futex (__NR_SYSCALL_BASE + 240) 1216 #endif 1217 #ifndef __NR_sched_setaffinity 1218 #define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241) 1219 #define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242) 1220 #endif 1221 #ifndef __NR_set_tid_address 1222 #define __NR_set_tid_address (__NR_SYSCALL_BASE + 256) 1223 #endif 1224 #ifndef __NR_clock_gettime 1225 #define __NR_clock_gettime (__NR_SYSCALL_BASE + 263) 1226 #endif 1227 #ifndef __NR_clock_getres 1228 #define __NR_clock_getres (__NR_SYSCALL_BASE + 264) 1229 #endif 1230 #ifndef __NR_statfs64 1231 #define __NR_statfs64 (__NR_SYSCALL_BASE + 266) 1232 #endif 1233 #ifndef __NR_fstatfs64 1234 #define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267) 1235 #endif 1236 #ifndef __NR_ioprio_set 1237 #define __NR_ioprio_set (__NR_SYSCALL_BASE + 314) 1238 #endif 1239 #ifndef __NR_ioprio_get 1240 #define __NR_ioprio_get (__NR_SYSCALL_BASE + 315) 1241 #endif 1242 #ifndef __NR_fstatat64 1243 #define __NR_fstatat64 (__NR_SYSCALL_BASE + 327) 1244 #endif 1245 #ifndef __NR_move_pages 1246 #define __NR_move_pages (__NR_SYSCALL_BASE + 344) 1247 #endif 1248 #ifndef __NR_getcpu 1249 #define __NR_getcpu (__NR_SYSCALL_BASE + 345) 1250 #endif 1251 #ifndef __NR_getrandom 1252 #define __NR_getrandom (__NR_SYSCALL_BASE + 384) 1253 #endif 1254 /* End of ARM 3/EABI definitions */ 1255 #elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64) 1256 #ifndef __NR_setxattr 1257 #define __NR_setxattr 5 1258 #endif 1259 #ifndef __NR_lsetxattr 1260 #define __NR_lsetxattr 6 1261 #endif 1262 #ifndef __NR_getxattr 1263 #define __NR_getxattr 8 1264 #endif 1265 #ifndef __NR_lgetxattr 1266 #define __NR_lgetxattr 9 1267 #endif 1268 #ifndef __NR_listxattr 1269 #define __NR_listxattr 11 1270 #endif 1271 #ifndef __NR_llistxattr 1272 #define __NR_llistxattr 12 1273 #endif 1274 #ifndef __NR_ioprio_set 1275 #define __NR_ioprio_set 30 1276 #endif 1277 #ifndef __NR_ioprio_get 1278 #define __NR_ioprio_get 31 1279 #endif 1280 #ifndef __NR_unlinkat 1281 #define __NR_unlinkat 35 1282 #endif 1283 #ifndef __NR_fallocate 1284 #define __NR_fallocate 47 1285 #endif 1286 #ifndef __NR_openat 1287 #define __NR_openat 56 1288 #endif 1289 #ifndef __NR_quotactl 1290 #define __NR_quotactl 60 1291 #endif 1292 #ifndef __NR_getdents64 1293 #define __NR_getdents64 61 1294 #endif 1295 #ifndef __NR_getdents 1296 // when getdents is not available, getdents64 is used for both. 1297 #define __NR_getdents __NR_getdents64 1298 #endif 1299 #ifndef __NR_pread64 1300 #define __NR_pread64 67 1301 #endif 1302 #ifndef __NR_pwrite64 1303 #define __NR_pwrite64 68 1304 #endif 1305 #ifndef __NR_ppoll 1306 #define __NR_ppoll 73 1307 #endif 1308 #ifndef __NR_readlinkat 1309 #define __NR_readlinkat 78 1310 #endif 1311 #if !defined(__loongarch_lp64) 1312 #ifndef __NR_newfstatat 1313 #define __NR_newfstatat 79 1314 #endif 1315 #endif 1316 #ifndef __NR_set_tid_address 1317 #define __NR_set_tid_address 96 1318 #endif 1319 #ifndef __NR_futex 1320 #define __NR_futex 98 1321 #endif 1322 #ifndef __NR_clock_gettime 1323 #define __NR_clock_gettime 113 1324 #endif 1325 #ifndef __NR_clock_getres 1326 #define __NR_clock_getres 114 1327 #endif 1328 #ifndef __NR_sched_setaffinity 1329 #define __NR_sched_setaffinity 122 1330 #define __NR_sched_getaffinity 123 1331 #endif 1332 #ifndef __NR_tkill 1333 #define __NR_tkill 130 1334 #endif 1335 #ifndef __NR_setresuid 1336 #define __NR_setresuid 147 1337 #define __NR_getresuid 148 1338 #define __NR_setresgid 149 1339 #define __NR_getresgid 150 1340 #endif 1341 #ifndef __NR_gettid 1342 #define __NR_gettid 178 1343 #endif 1344 #ifndef __NR_readahead 1345 #define __NR_readahead 213 1346 #endif 1347 #ifndef __NR_fadvise64 1348 #define __NR_fadvise64 223 1349 #endif 1350 #ifndef __NR_move_pages 1351 #define __NR_move_pages 239 1352 #endif 1353 #ifndef __NR_getrandom 1354 #define __NR_getrandom 278 1355 #endif 1356 #ifndef __NR_statx 1357 #define __NR_statx 291 1358 #endif 1359 #elif defined(__x86_64__) 1360 #ifndef __NR_pread64 1361 #define __NR_pread64 17 1362 #endif 1363 #ifndef __NR_pwrite64 1364 #define __NR_pwrite64 18 1365 #endif 1366 #ifndef __NR_setresuid 1367 #define __NR_setresuid 117 1368 #define __NR_getresuid 118 1369 #define __NR_setresgid 119 1370 #define __NR_getresgid 120 1371 #endif 1372 #ifndef __NR_quotactl 1373 #define __NR_quotactl 179 1374 #endif 1375 #ifndef __NR_gettid 1376 #define __NR_gettid 186 1377 #endif 1378 #ifndef __NR_readahead 1379 #define __NR_readahead 187 1380 #endif 1381 #ifndef __NR_setxattr 1382 #define __NR_setxattr 188 1383 #endif 1384 #ifndef __NR_lsetxattr 1385 #define __NR_lsetxattr 189 1386 #endif 1387 #ifndef __NR_getxattr 1388 #define __NR_getxattr 191 1389 #endif 1390 #ifndef __NR_lgetxattr 1391 #define __NR_lgetxattr 192 1392 #endif 1393 #ifndef __NR_listxattr 1394 #define __NR_listxattr 194 1395 #endif 1396 #ifndef __NR_llistxattr 1397 #define __NR_llistxattr 195 1398 #endif 1399 #ifndef __NR_tkill 1400 #define __NR_tkill 200 1401 #endif 1402 #ifndef __NR_futex 1403 #define __NR_futex 202 1404 #endif 1405 #ifndef __NR_sched_setaffinity 1406 #define __NR_sched_setaffinity 203 1407 #define __NR_sched_getaffinity 204 1408 #endif 1409 #ifndef __NR_getdents64 1410 #define __NR_getdents64 217 1411 #endif 1412 #ifndef __NR_getdents 1413 // when getdents is not available, getdents64 is used for both. 1414 #define __NR_getdents __NR_getdents64 1415 #endif 1416 #ifndef __NR_set_tid_address 1417 #define __NR_set_tid_address 218 1418 #endif 1419 #ifndef __NR_fadvise64 1420 #define __NR_fadvise64 221 1421 #endif 1422 #ifndef __NR_clock_gettime 1423 #define __NR_clock_gettime 228 1424 #endif 1425 #ifndef __NR_clock_getres 1426 #define __NR_clock_getres 229 1427 #endif 1428 #ifndef __NR_ioprio_set 1429 #define __NR_ioprio_set 251 1430 #endif 1431 #ifndef __NR_ioprio_get 1432 #define __NR_ioprio_get 252 1433 #endif 1434 #ifndef __NR_openat 1435 #define __NR_openat 257 1436 #endif 1437 #ifndef __NR_newfstatat 1438 #define __NR_newfstatat 262 1439 #endif 1440 #ifndef __NR_unlinkat 1441 #define __NR_unlinkat 263 1442 #endif 1443 #ifndef __NR_move_pages 1444 #define __NR_move_pages 279 1445 #endif 1446 #ifndef __NR_fallocate 1447 #define __NR_fallocate 285 1448 #endif 1449 #ifndef __NR_getrandom 1450 #define __NR_getrandom 318 1451 #endif 1452 /* End of x86-64 definitions */ 1453 #elif defined(__mips__) 1454 #if _MIPS_SIM == _MIPS_SIM_ABI32 1455 #ifndef __NR_setresuid 1456 #define __NR_setresuid (__NR_Linux + 185) 1457 #define __NR_getresuid (__NR_Linux + 186) 1458 #define __NR_setresgid (__NR_Linux + 190) 1459 #define __NR_getresgid (__NR_Linux + 191) 1460 #endif 1461 #ifndef __NR_rt_sigaction 1462 #define __NR_rt_sigreturn (__NR_Linux + 193) 1463 #define __NR_rt_sigaction (__NR_Linux + 194) 1464 #define __NR_rt_sigprocmask (__NR_Linux + 195) 1465 #define __NR_rt_sigpending (__NR_Linux + 196) 1466 #define __NR_rt_sigsuspend (__NR_Linux + 199) 1467 #endif 1468 #ifndef __NR_pread64 1469 #define __NR_pread64 (__NR_Linux + 200) 1470 #endif 1471 #ifndef __NR_pwrite64 1472 #define __NR_pwrite64 (__NR_Linux + 201) 1473 #endif 1474 #ifndef __NR_stat64 1475 #define __NR_stat64 (__NR_Linux + 213) 1476 #endif 1477 #ifndef __NR_fstat64 1478 #define __NR_fstat64 (__NR_Linux + 215) 1479 #endif 1480 #ifndef __NR_getdents64 1481 #define __NR_getdents64 (__NR_Linux + 219) 1482 #endif 1483 #ifndef __NR_gettid 1484 #define __NR_gettid (__NR_Linux + 222) 1485 #endif 1486 #ifndef __NR_readahead 1487 #define __NR_readahead (__NR_Linux + 223) 1488 #endif 1489 #ifndef __NR_setxattr 1490 #define __NR_setxattr (__NR_Linux + 224) 1491 #endif 1492 #ifndef __NR_lsetxattr 1493 #define __NR_lsetxattr (__NR_Linux + 225) 1494 #endif 1495 #ifndef __NR_getxattr 1496 #define __NR_getxattr (__NR_Linux + 227) 1497 #endif 1498 #ifndef __NR_lgetxattr 1499 #define __NR_lgetxattr (__NR_Linux + 228) 1500 #endif 1501 #ifndef __NR_listxattr 1502 #define __NR_listxattr (__NR_Linux + 230) 1503 #endif 1504 #ifndef __NR_llistxattr 1505 #define __NR_llistxattr (__NR_Linux + 231) 1506 #endif 1507 #ifndef __NR_tkill 1508 #define __NR_tkill (__NR_Linux + 236) 1509 #endif 1510 #ifndef __NR_futex 1511 #define __NR_futex (__NR_Linux + 238) 1512 #endif 1513 #ifndef __NR_sched_setaffinity 1514 #define __NR_sched_setaffinity (__NR_Linux + 239) 1515 #define __NR_sched_getaffinity (__NR_Linux + 240) 1516 #endif 1517 #ifndef __NR_set_tid_address 1518 #define __NR_set_tid_address (__NR_Linux + 252) 1519 #endif 1520 #ifndef __NR_statfs64 1521 #define __NR_statfs64 (__NR_Linux + 255) 1522 #endif 1523 #ifndef __NR_fstatfs64 1524 #define __NR_fstatfs64 (__NR_Linux + 256) 1525 #endif 1526 #ifndef __NR_clock_gettime 1527 #define __NR_clock_gettime (__NR_Linux + 263) 1528 #endif 1529 #ifndef __NR_clock_getres 1530 #define __NR_clock_getres (__NR_Linux + 264) 1531 #endif 1532 #ifndef __NR_openat 1533 #define __NR_openat (__NR_Linux + 288) 1534 #endif 1535 #ifndef __NR_fstatat 1536 #define __NR_fstatat (__NR_Linux + 293) 1537 #endif 1538 #ifndef __NR_unlinkat 1539 #define __NR_unlinkat (__NR_Linux + 294) 1540 #endif 1541 #ifndef __NR_move_pages 1542 #define __NR_move_pages (__NR_Linux + 308) 1543 #endif 1544 #ifndef __NR_getcpu 1545 #define __NR_getcpu (__NR_Linux + 312) 1546 #endif 1547 #ifndef __NR_ioprio_set 1548 #define __NR_ioprio_set (__NR_Linux + 314) 1549 #endif 1550 #ifndef __NR_ioprio_get 1551 #define __NR_ioprio_get (__NR_Linux + 315) 1552 #endif 1553 #ifndef __NR_getrandom 1554 #define __NR_getrandom (__NR_Linux + 353) 1555 #endif 1556 /* End of MIPS (old 32bit API) definitions */ 1557 #elif _MIPS_SIM == _MIPS_SIM_ABI64 1558 #ifndef __NR_pread64 1559 #define __NR_pread64 (__NR_Linux + 16) 1560 #endif 1561 #ifndef __NR_pwrite64 1562 #define __NR_pwrite64 (__NR_Linux + 17) 1563 #endif 1564 #ifndef __NR_setresuid 1565 #define __NR_setresuid (__NR_Linux + 115) 1566 #define __NR_getresuid (__NR_Linux + 116) 1567 #define __NR_setresgid (__NR_Linux + 117) 1568 #define __NR_getresgid (__NR_Linux + 118) 1569 #endif 1570 #ifndef __NR_gettid 1571 #define __NR_gettid (__NR_Linux + 178) 1572 #endif 1573 #ifndef __NR_readahead 1574 #define __NR_readahead (__NR_Linux + 179) 1575 #endif 1576 #ifndef __NR_setxattr 1577 #define __NR_setxattr (__NR_Linux + 180) 1578 #endif 1579 #ifndef __NR_lsetxattr 1580 #define __NR_lsetxattr (__NR_Linux + 181) 1581 #endif 1582 #ifndef __NR_getxattr 1583 #define __NR_getxattr (__NR_Linux + 183) 1584 #endif 1585 #ifndef __NR_lgetxattr 1586 #define __NR_lgetxattr (__NR_Linux + 184) 1587 #endif 1588 #ifndef __NR_listxattr 1589 #define __NR_listxattr (__NR_Linux + 186) 1590 #endif 1591 #ifndef __NR_llistxattr 1592 #define __NR_llistxattr (__NR_Linux + 187) 1593 #endif 1594 #ifndef __NR_tkill 1595 #define __NR_tkill (__NR_Linux + 192) 1596 #endif 1597 #ifndef __NR_futex 1598 #define __NR_futex (__NR_Linux + 194) 1599 #endif 1600 #ifndef __NR_sched_setaffinity 1601 #define __NR_sched_setaffinity (__NR_Linux + 195) 1602 #define __NR_sched_getaffinity (__NR_Linux + 196) 1603 #endif 1604 #ifndef __NR_set_tid_address 1605 #define __NR_set_tid_address (__NR_Linux + 212) 1606 #endif 1607 #ifndef __NR_clock_gettime 1608 #define __NR_clock_gettime (__NR_Linux + 222) 1609 #endif 1610 #ifndef __NR_clock_getres 1611 #define __NR_clock_getres (__NR_Linux + 223) 1612 #endif 1613 #ifndef __NR_openat 1614 #define __NR_openat (__NR_Linux + 247) 1615 #endif 1616 #ifndef __NR_fstatat 1617 #define __NR_fstatat (__NR_Linux + 252) 1618 #endif 1619 #ifndef __NR_unlinkat 1620 #define __NR_unlinkat (__NR_Linux + 253) 1621 #endif 1622 #ifndef __NR_move_pages 1623 #define __NR_move_pages (__NR_Linux + 267) 1624 #endif 1625 #ifndef __NR_getcpu 1626 #define __NR_getcpu (__NR_Linux + 271) 1627 #endif 1628 #ifndef __NR_ioprio_set 1629 #define __NR_ioprio_set (__NR_Linux + 273) 1630 #endif 1631 #ifndef __NR_ioprio_get 1632 #define __NR_ioprio_get (__NR_Linux + 274) 1633 #endif 1634 #ifndef __NR_getrandom 1635 #define __NR_getrandom (__NR_Linux + 313) 1636 #endif 1637 /* End of MIPS (64bit API) definitions */ 1638 #else 1639 #ifndef __NR_setresuid 1640 #define __NR_setresuid (__NR_Linux + 115) 1641 #define __NR_getresuid (__NR_Linux + 116) 1642 #define __NR_setresgid (__NR_Linux + 117) 1643 #define __NR_getresgid (__NR_Linux + 118) 1644 #endif 1645 #ifndef __NR_gettid 1646 #define __NR_gettid (__NR_Linux + 178) 1647 #endif 1648 #ifndef __NR_readahead 1649 #define __NR_readahead (__NR_Linux + 179) 1650 #endif 1651 #ifndef __NR_setxattr 1652 #define __NR_setxattr (__NR_Linux + 180) 1653 #endif 1654 #ifndef __NR_lsetxattr 1655 #define __NR_lsetxattr (__NR_Linux + 181) 1656 #endif 1657 #ifndef __NR_getxattr 1658 #define __NR_getxattr (__NR_Linux + 183) 1659 #endif 1660 #ifndef __NR_lgetxattr 1661 #define __NR_lgetxattr (__NR_Linux + 184) 1662 #endif 1663 #ifndef __NR_listxattr 1664 #define __NR_listxattr (__NR_Linux + 186) 1665 #endif 1666 #ifndef __NR_llistxattr 1667 #define __NR_llistxattr (__NR_Linux + 187) 1668 #endif 1669 #ifndef __NR_tkill 1670 #define __NR_tkill (__NR_Linux + 192) 1671 #endif 1672 #ifndef __NR_futex 1673 #define __NR_futex (__NR_Linux + 194) 1674 #endif 1675 #ifndef __NR_sched_setaffinity 1676 #define __NR_sched_setaffinity (__NR_Linux + 195) 1677 #define __NR_sched_getaffinity (__NR_Linux + 196) 1678 #endif 1679 #ifndef __NR_set_tid_address 1680 #define __NR_set_tid_address (__NR_Linux + 213) 1681 #endif 1682 #ifndef __NR_statfs64 1683 #define __NR_statfs64 (__NR_Linux + 217) 1684 #endif 1685 #ifndef __NR_fstatfs64 1686 #define __NR_fstatfs64 (__NR_Linux + 218) 1687 #endif 1688 #ifndef __NR_clock_gettime 1689 #define __NR_clock_gettime (__NR_Linux + 226) 1690 #endif 1691 #ifndef __NR_clock_getres 1692 #define __NR_clock_getres (__NR_Linux + 227) 1693 #endif 1694 #ifndef __NR_openat 1695 #define __NR_openat (__NR_Linux + 251) 1696 #endif 1697 #ifndef __NR_fstatat 1698 #define __NR_fstatat (__NR_Linux + 256) 1699 #endif 1700 #ifndef __NR_unlinkat 1701 #define __NR_unlinkat (__NR_Linux + 257) 1702 #endif 1703 #ifndef __NR_move_pages 1704 #define __NR_move_pages (__NR_Linux + 271) 1705 #endif 1706 #ifndef __NR_getcpu 1707 #define __NR_getcpu (__NR_Linux + 275) 1708 #endif 1709 #ifndef __NR_ioprio_set 1710 #define __NR_ioprio_set (__NR_Linux + 277) 1711 #endif 1712 #ifndef __NR_ioprio_get 1713 #define __NR_ioprio_get (__NR_Linux + 278) 1714 #endif 1715 /* End of MIPS (new 32bit API) definitions */ 1716 #endif 1717 /* End of MIPS definitions */ 1718 #elif defined(__PPC__) 1719 #ifndef __NR_setfsuid 1720 #define __NR_setfsuid 138 1721 #define __NR_setfsgid 139 1722 #endif 1723 #ifndef __NR_setresuid 1724 #define __NR_setresuid 164 1725 #define __NR_getresuid 165 1726 #define __NR_setresgid 169 1727 #define __NR_getresgid 170 1728 #endif 1729 #ifndef __NR_rt_sigaction 1730 #define __NR_rt_sigreturn 172 1731 #define __NR_rt_sigaction 173 1732 #define __NR_rt_sigprocmask 174 1733 #define __NR_rt_sigpending 175 1734 #define __NR_rt_sigsuspend 178 1735 #endif 1736 #ifndef __NR_pread64 1737 #define __NR_pread64 179 1738 #endif 1739 #ifndef __NR_pwrite64 1740 #define __NR_pwrite64 180 1741 #endif 1742 #ifndef __NR_ugetrlimit 1743 #define __NR_ugetrlimit 190 1744 #endif 1745 #ifndef __NR_readahead 1746 #define __NR_readahead 191 1747 #endif 1748 #ifndef __NR_stat64 1749 #define __NR_stat64 195 1750 #endif 1751 #ifndef __NR_fstat64 1752 #define __NR_fstat64 197 1753 #endif 1754 #ifndef __NR_getdents64 1755 #define __NR_getdents64 202 1756 #endif 1757 #ifndef __NR_gettid 1758 #define __NR_gettid 207 1759 #endif 1760 #ifndef __NR_tkill 1761 #define __NR_tkill 208 1762 #endif 1763 #ifndef __NR_setxattr 1764 #define __NR_setxattr 209 1765 #endif 1766 #ifndef __NR_lsetxattr 1767 #define __NR_lsetxattr 210 1768 #endif 1769 #ifndef __NR_getxattr 1770 #define __NR_getxattr 212 1771 #endif 1772 #ifndef __NR_lgetxattr 1773 #define __NR_lgetxattr 213 1774 #endif 1775 #ifndef __NR_listxattr 1776 #define __NR_listxattr 215 1777 #endif 1778 #ifndef __NR_llistxattr 1779 #define __NR_llistxattr 216 1780 #endif 1781 #ifndef __NR_futex 1782 #define __NR_futex 221 1783 #endif 1784 #ifndef __NR_sched_setaffinity 1785 #define __NR_sched_setaffinity 222 1786 #define __NR_sched_getaffinity 223 1787 #endif 1788 #ifndef __NR_set_tid_address 1789 #define __NR_set_tid_address 232 1790 #endif 1791 #ifndef __NR_clock_gettime 1792 #define __NR_clock_gettime 246 1793 #endif 1794 #ifndef __NR_clock_getres 1795 #define __NR_clock_getres 247 1796 #endif 1797 #ifndef __NR_statfs64 1798 #define __NR_statfs64 252 1799 #endif 1800 #ifndef __NR_fstatfs64 1801 #define __NR_fstatfs64 253 1802 #endif 1803 #ifndef __NR_fadvise64_64 1804 #define __NR_fadvise64_64 254 1805 #endif 1806 #ifndef __NR_ioprio_set 1807 #define __NR_ioprio_set 273 1808 #endif 1809 #ifndef __NR_ioprio_get 1810 #define __NR_ioprio_get 274 1811 #endif 1812 #ifndef __NR_openat 1813 #define __NR_openat 286 1814 #endif 1815 #ifndef __NR_fstatat64 1816 #define __NR_fstatat64 291 1817 #endif 1818 #ifndef __NR_unlinkat 1819 #define __NR_unlinkat 292 1820 #endif 1821 #ifndef __NR_move_pages 1822 #define __NR_move_pages 301 1823 #endif 1824 #ifndef __NR_getcpu 1825 #define __NR_getcpu 302 1826 #endif 1827 /* End of powerpc defininitions */ 1828 #elif defined(__s390__) 1829 #ifndef __NR_quotactl 1830 #define __NR_quotactl 131 1831 #endif 1832 #ifndef __NR_rt_sigreturn 1833 #define __NR_rt_sigreturn 173 1834 #endif 1835 #ifndef __NR_rt_sigaction 1836 #define __NR_rt_sigaction 174 1837 #endif 1838 #ifndef __NR_rt_sigprocmask 1839 #define __NR_rt_sigprocmask 175 1840 #endif 1841 #ifndef __NR_rt_sigpending 1842 #define __NR_rt_sigpending 176 1843 #endif 1844 #ifndef __NR_rt_sigsuspend 1845 #define __NR_rt_sigsuspend 179 1846 #endif 1847 #ifndef __NR_pread64 1848 #define __NR_pread64 180 1849 #endif 1850 #ifndef __NR_pwrite64 1851 #define __NR_pwrite64 181 1852 #endif 1853 #ifndef __NR_getdents64 1854 #define __NR_getdents64 220 1855 #endif 1856 #ifndef __NR_readahead 1857 #define __NR_readahead 222 1858 #endif 1859 #ifndef __NR_setxattr 1860 #define __NR_setxattr 224 1861 #endif 1862 #ifndef __NR_lsetxattr 1863 #define __NR_lsetxattr 225 1864 #endif 1865 #ifndef __NR_getxattr 1866 #define __NR_getxattr 227 1867 #endif 1868 #ifndef __NR_lgetxattr 1869 #define __NR_lgetxattr 228 1870 #endif 1871 #ifndef __NR_listxattr 1872 #define __NR_listxattr 230 1873 #endif 1874 #ifndef __NR_llistxattr 1875 #define __NR_llistxattr 231 1876 #endif 1877 #ifndef __NR_gettid 1878 #define __NR_gettid 236 1879 #endif 1880 #ifndef __NR_tkill 1881 #define __NR_tkill 237 1882 #endif 1883 #ifndef __NR_futex 1884 #define __NR_futex 238 1885 #endif 1886 #ifndef __NR_sched_setaffinity 1887 #define __NR_sched_setaffinity 239 1888 #endif 1889 #ifndef __NR_sched_getaffinity 1890 #define __NR_sched_getaffinity 240 1891 #endif 1892 #ifndef __NR_set_tid_address 1893 #define __NR_set_tid_address 252 1894 #endif 1895 #ifndef __NR_clock_gettime 1896 #define __NR_clock_gettime 260 1897 #endif 1898 #ifndef __NR_clock_getres 1899 #define __NR_clock_getres 261 1900 #endif 1901 #ifndef __NR_statfs64 1902 #define __NR_statfs64 265 1903 #endif 1904 #ifndef __NR_fstatfs64 1905 #define __NR_fstatfs64 266 1906 #endif 1907 #ifndef __NR_ioprio_set 1908 #define __NR_ioprio_set 282 1909 #endif 1910 #ifndef __NR_ioprio_get 1911 #define __NR_ioprio_get 283 1912 #endif 1913 #ifndef __NR_openat 1914 #define __NR_openat 288 1915 #endif 1916 #ifndef __NR_unlinkat 1917 #define __NR_unlinkat 294 1918 #endif 1919 #ifndef __NR_move_pages 1920 #define __NR_move_pages 310 1921 #endif 1922 #ifndef __NR_getcpu 1923 #define __NR_getcpu 311 1924 #endif 1925 #ifndef __NR_fallocate 1926 #define __NR_fallocate 314 1927 #endif 1928 /* Some syscalls are named/numbered differently between s390 and s390x. */ 1929 #ifdef __s390x__ 1930 # ifndef __NR_getrlimit 1931 # define __NR_getrlimit 191 1932 # endif 1933 # ifndef __NR_setresuid 1934 # define __NR_setresuid 208 1935 # endif 1936 # ifndef __NR_getresuid 1937 # define __NR_getresuid 209 1938 # endif 1939 # ifndef __NR_setresgid 1940 # define __NR_setresgid 210 1941 # endif 1942 # ifndef __NR_getresgid 1943 # define __NR_getresgid 211 1944 # endif 1945 # ifndef __NR_setfsuid 1946 # define __NR_setfsuid 215 1947 # endif 1948 # ifndef __NR_setfsgid 1949 # define __NR_setfsgid 216 1950 # endif 1951 # ifndef __NR_fadvise64 1952 # define __NR_fadvise64 253 1953 # endif 1954 # ifndef __NR_newfstatat 1955 # define __NR_newfstatat 293 1956 # endif 1957 #else /* __s390x__ */ 1958 # ifndef __NR_getrlimit 1959 # define __NR_getrlimit 76 1960 # endif 1961 # ifndef __NR_setfsuid 1962 # define __NR_setfsuid 138 1963 # endif 1964 # ifndef __NR_setfsgid 1965 # define __NR_setfsgid 139 1966 # endif 1967 # ifndef __NR_setresuid 1968 # define __NR_setresuid 164 1969 # endif 1970 # ifndef __NR_getresuid 1971 # define __NR_getresuid 165 1972 # endif 1973 # ifndef __NR_setresgid 1974 # define __NR_setresgid 170 1975 # endif 1976 # ifndef __NR_getresgid 1977 # define __NR_getresgid 171 1978 # endif 1979 # ifndef __NR_ugetrlimit 1980 # define __NR_ugetrlimit 191 1981 # endif 1982 # ifndef __NR_mmap2 1983 # define __NR_mmap2 192 1984 # endif 1985 # ifndef __NR_setresuid32 1986 # define __NR_setresuid32 208 1987 # endif 1988 # ifndef __NR_getresuid32 1989 # define __NR_getresuid32 209 1990 # endif 1991 # ifndef __NR_setresgid32 1992 # define __NR_setresgid32 210 1993 # endif 1994 # ifndef __NR_getresgid32 1995 # define __NR_getresgid32 211 1996 # endif 1997 # ifndef __NR_setfsuid32 1998 # define __NR_setfsuid32 215 1999 # endif 2000 # ifndef __NR_setfsgid32 2001 # define __NR_setfsgid32 216 2002 # endif 2003 # ifndef __NR_fadvise64_64 2004 # define __NR_fadvise64_64 264 2005 # endif 2006 # ifndef __NR_fstatat64 2007 # define __NR_fstatat64 293 2008 # endif 2009 #endif /* __s390__ */ 2010 /* End of s390/s390x definitions */ 2011 #endif 2012 2013 2014 /* After forking, we must make sure to only call system calls. */ 2015 #if defined(__BOUNDED_POINTERS__) 2016 #error "Need to port invocations of syscalls for bounded ptrs" 2017 #else 2018 /* The core dumper and the thread lister get executed after threads 2019 * have been suspended. As a consequence, we cannot call any functions 2020 * that acquire locks. Unfortunately, libc wraps most system calls 2021 * (e.g. in order to implement pthread_atfork, and to make calls 2022 * cancellable), which means we cannot call these functions. Instead, 2023 * we have to call syscall() directly. 2024 */ 2025 #undef LSS_ERRNO 2026 #ifdef SYS_ERRNO 2027 /* Allow the including file to override the location of errno. This can 2028 * be useful when using clone() with the CLONE_VM option. 2029 */ 2030 #define LSS_ERRNO SYS_ERRNO 2031 #else 2032 #define LSS_ERRNO errno 2033 #endif 2034 2035 #undef LSS_INLINE 2036 #ifdef SYS_INLINE 2037 #define LSS_INLINE SYS_INLINE 2038 #else 2039 #define LSS_INLINE static inline 2040 #endif 2041 2042 /* Allow the including file to override the prefix used for all new 2043 * system calls. By default, it will be set to "sys_". 2044 */ 2045 #undef LSS_NAME 2046 #ifndef SYS_PREFIX 2047 #define LSS_NAME(name) sys_##name 2048 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0 2049 #define LSS_NAME(name) name 2050 #elif defined(SYS_PREFIX) && SYS_PREFIX == 0 2051 #define LSS_NAME(name) sys0_##name 2052 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1 2053 #define LSS_NAME(name) sys1_##name 2054 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2 2055 #define LSS_NAME(name) sys2_##name 2056 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3 2057 #define LSS_NAME(name) sys3_##name 2058 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4 2059 #define LSS_NAME(name) sys4_##name 2060 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5 2061 #define LSS_NAME(name) sys5_##name 2062 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6 2063 #define LSS_NAME(name) sys6_##name 2064 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7 2065 #define LSS_NAME(name) sys7_##name 2066 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8 2067 #define LSS_NAME(name) sys8_##name 2068 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9 2069 #define LSS_NAME(name) sys9_##name 2070 #endif 2071 2072 #undef LSS_RETURN 2073 #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \ 2074 || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__) \ 2075 || defined(__e2k__) || defined(__riscv) || defined(__loongarch_lp64) 2076 /* Failing system calls return a negative result in the range of 2077 * -1..-4095. These are "errno" values with the sign inverted. 2078 */ 2079 #define LSS_RETURN(type, res) \ 2080 do { \ 2081 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \ 2082 LSS_ERRNO = (int)(-(res)); \ 2083 res = -1; \ 2084 } \ 2085 return (type) (res); \ 2086 } while (0) 2087 #elif defined(__mips__) 2088 /* On MIPS, failing system calls return -1, and set errno in a 2089 * separate CPU register. 2090 */ 2091 #define LSS_RETURN(type, res, err) \ 2092 do { \ 2093 if (err) { \ 2094 unsigned long __errnovalue = (res); \ 2095 LSS_ERRNO = __errnovalue; \ 2096 res = -1; \ 2097 } \ 2098 return (type) (res); \ 2099 } while (0) 2100 #elif defined(__PPC__) 2101 /* On PPC, failing system calls return -1, and set errno in a 2102 * separate CPU register. See linux/unistd.h. 2103 */ 2104 #define LSS_RETURN(type, res, err) \ 2105 do { \ 2106 if (err & 0x10000000 ) { \ 2107 LSS_ERRNO = (res); \ 2108 res = -1; \ 2109 } \ 2110 return (type) (res); \ 2111 } while (0) 2112 #endif 2113 #if defined(__i386__) 2114 /* In PIC mode (e.g. when building shared libraries), gcc for i386 2115 * reserves ebx. Unfortunately, most distribution ship with implementations 2116 * of _syscallX() which clobber ebx. 2117 * Also, most definitions of _syscallX() neglect to mark "memory" as being 2118 * clobbered. This causes problems with compilers, that do a better job 2119 * at optimizing across __asm__ calls. 2120 * So, we just have to redefine all of the _syscallX() macros. 2121 */ 2122 #undef LSS_ENTRYPOINT 2123 #ifdef SYS_SYSCALL_ENTRYPOINT LSS_NAME(get_syscall_entrypoint)2124 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { 2125 void (**entrypoint)(void); 2126 asm volatile(".bss\n" 2127 ".align 8\n" 2128 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" 2129 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" 2130 ".previous\n" 2131 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */ 2132 "call 0f\n" 2133 "0:pop %0\n" 2134 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n" 2135 "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n" 2136 : "=r"(entrypoint)); 2137 return entrypoint; 2138 } 2139 2140 #define LSS_ENTRYPOINT ".bss\n" \ 2141 ".align 8\n" \ 2142 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \ 2143 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \ 2144 ".previous\n" \ 2145 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \ 2146 "push %%eax\n" \ 2147 "call 10000f\n" \ 2148 "10000:pop %%eax\n" \ 2149 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \ 2150 "mov " SYS_SYSCALL_ENTRYPOINT \ 2151 "@GOT(%%eax), %%eax\n" \ 2152 "mov 0(%%eax), %%eax\n" \ 2153 "test %%eax, %%eax\n" \ 2154 "jz 10002f\n" \ 2155 "push %%eax\n" \ 2156 "call 10001f\n" \ 2157 "10001:pop %%eax\n" \ 2158 "add $(10003f-10001b), %%eax\n" \ 2159 "xchg 4(%%esp), %%eax\n" \ 2160 "ret\n" \ 2161 "10002:pop %%eax\n" \ 2162 "int $0x80\n" \ 2163 "10003:\n" 2164 #else 2165 #define LSS_ENTRYPOINT "int $0x80\n" 2166 #endif 2167 #undef LSS_BODY 2168 #define LSS_BODY(type,args...) \ 2169 long __res; \ 2170 __asm__ __volatile__("push %%ebx\n" \ 2171 "movl %2,%%ebx\n" \ 2172 LSS_ENTRYPOINT \ 2173 "pop %%ebx" \ 2174 args \ 2175 : "memory"); \ 2176 LSS_RETURN(type,__res) 2177 #undef _syscall0 2178 #define _syscall0(type,name) \ 2179 type LSS_NAME(name)(void) { \ 2180 long __res; \ 2181 __asm__ volatile(LSS_ENTRYPOINT \ 2182 : "=a" (__res) \ 2183 : "0" (__NR_##name) \ 2184 : "memory"); \ 2185 LSS_RETURN(type,__res); \ 2186 } 2187 #undef _syscall1 2188 #define _syscall1(type,name,type1,arg1) \ 2189 type LSS_NAME(name)(type1 arg1) { \ 2190 LSS_BODY(type, \ 2191 : "=a" (__res) \ 2192 : "0" (__NR_##name), "ri" ((long)(arg1))); \ 2193 } 2194 #undef _syscall2 2195 #define _syscall2(type,name,type1,arg1,type2,arg2) \ 2196 type LSS_NAME(name)(type1 arg1,type2 arg2) { \ 2197 LSS_BODY(type, \ 2198 : "=a" (__res) \ 2199 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \ 2200 } 2201 #undef _syscall3 2202 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 2203 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \ 2204 LSS_BODY(type, \ 2205 : "=a" (__res) \ 2206 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ 2207 "d" ((long)(arg3))); \ 2208 } 2209 #undef _syscall4 2210 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 2211 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 2212 LSS_BODY(type, \ 2213 : "=a" (__res) \ 2214 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ 2215 "d" ((long)(arg3)),"S" ((long)(arg4))); \ 2216 } 2217 #undef _syscall5 2218 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2219 type5,arg5) \ 2220 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2221 type5 arg5) { \ 2222 long __res; \ 2223 __asm__ __volatile__("push %%ebx\n" \ 2224 "movl %2,%%ebx\n" \ 2225 "movl %1,%%eax\n" \ 2226 LSS_ENTRYPOINT \ 2227 "pop %%ebx" \ 2228 : "=a" (__res) \ 2229 : "i" (__NR_##name), "ri" ((long)(arg1)), \ 2230 "c" ((long)(arg2)), "d" ((long)(arg3)), \ 2231 "S" ((long)(arg4)), "D" ((long)(arg5)) \ 2232 : "memory"); \ 2233 LSS_RETURN(type,__res); \ 2234 } 2235 #undef _syscall6 2236 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2237 type5,arg5,type6,arg6) \ 2238 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2239 type5 arg5, type6 arg6) { \ 2240 long __res; \ 2241 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \ 2242 __asm__ __volatile__("push %%ebp\n" \ 2243 "push %%ebx\n" \ 2244 "movl 4(%2),%%ebp\n" \ 2245 "movl 0(%2), %%ebx\n" \ 2246 "movl %1,%%eax\n" \ 2247 LSS_ENTRYPOINT \ 2248 "pop %%ebx\n" \ 2249 "pop %%ebp" \ 2250 : "=a" (__res) \ 2251 : "i" (__NR_##name), "0" ((long)(&__s)), \ 2252 "c" ((long)(arg2)), "d" ((long)(arg3)), \ 2253 "S" ((long)(arg4)), "D" ((long)(arg5)) \ 2254 : "memory"); \ 2255 LSS_RETURN(type,__res); \ 2256 } LSS_NAME(clone)2257 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 2258 int flags, void *arg, int *parent_tidptr, 2259 void *newtls, int *child_tidptr) { 2260 long __res; 2261 __asm__ __volatile__(/* if (fn == NULL) 2262 * return -EINVAL; 2263 */ 2264 "movl %3,%%ecx\n" 2265 "jecxz 1f\n" 2266 2267 /* if (child_stack == NULL) 2268 * return -EINVAL; 2269 */ 2270 "movl %4,%%ecx\n" 2271 "jecxz 1f\n" 2272 2273 /* Set up alignment of the child stack: 2274 * child_stack = (child_stack & ~0xF) - 20; 2275 */ 2276 "andl $-16,%%ecx\n" 2277 "subl $20,%%ecx\n" 2278 2279 /* Push "arg" and "fn" onto the stack that will be 2280 * used by the child. 2281 */ 2282 "movl %6,%%eax\n" 2283 "movl %%eax,4(%%ecx)\n" 2284 "movl %3,%%eax\n" 2285 "movl %%eax,(%%ecx)\n" 2286 2287 /* %eax = syscall(%eax = __NR_clone, 2288 * %ebx = flags, 2289 * %ecx = child_stack, 2290 * %edx = parent_tidptr, 2291 * %esi = newtls, 2292 * %edi = child_tidptr) 2293 * Also, make sure that %ebx gets preserved as it is 2294 * used in PIC mode. 2295 */ 2296 "movl %8,%%esi\n" 2297 "movl %7,%%edx\n" 2298 "movl %5,%%eax\n" 2299 "movl %9,%%edi\n" 2300 "pushl %%ebx\n" 2301 "movl %%eax,%%ebx\n" 2302 "movl %2,%%eax\n" 2303 LSS_ENTRYPOINT 2304 2305 /* In the parent: restore %ebx 2306 * In the child: move "fn" into %ebx 2307 */ 2308 "popl %%ebx\n" 2309 2310 /* if (%eax != 0) 2311 * return %eax; 2312 */ 2313 "test %%eax,%%eax\n" 2314 "jnz 1f\n" 2315 2316 /* In the child, now. Terminate frame pointer chain. 2317 */ 2318 "movl $0,%%ebp\n" 2319 2320 /* Call "fn". "arg" is already on the stack. 2321 */ 2322 "call *%%ebx\n" 2323 2324 /* Call _exit(%ebx). Unfortunately older versions 2325 * of gcc restrict the number of arguments that can 2326 * be passed to asm(). So, we need to hard-code the 2327 * system call number. 2328 */ 2329 "movl %%eax,%%ebx\n" 2330 "movl $1,%%eax\n" 2331 LSS_ENTRYPOINT 2332 2333 /* Return to parent. 2334 */ 2335 "1:\n" 2336 : "=a" (__res) 2337 : "0"(-EINVAL), "i"(__NR_clone), 2338 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg), 2339 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr) 2340 : "memory", "ecx", "edx", "esi", "edi"); 2341 LSS_RETURN(int, __res); 2342 } 2343 _syscall1(int,set_thread_area,void *,u)2344 LSS_INLINE _syscall1(int, set_thread_area, void *, u) 2345 LSS_INLINE _syscall1(int, get_thread_area, void *, u) 2346 2347 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { 2348 /* On i386, the kernel does not know how to return from a signal 2349 * handler. Instead, it relies on user space to provide a 2350 * restorer function that calls the {rt_,}sigreturn() system call. 2351 * Unfortunately, we cannot just reference the glibc version of this 2352 * function, as glibc goes out of its way to make it inaccessible. 2353 */ 2354 void (*res)(void); 2355 __asm__ __volatile__("call 2f\n" 2356 "0:.align 16\n" 2357 "1:movl %1,%%eax\n" 2358 LSS_ENTRYPOINT 2359 "2:popl %0\n" 2360 "addl $(1b-0b),%0\n" 2361 : "=a" (res) 2362 : "i" (__NR_rt_sigreturn)); 2363 return res; 2364 } LSS_NAME(restore)2365 LSS_INLINE void (*LSS_NAME(restore)(void))(void) { 2366 /* On i386, the kernel does not know how to return from a signal 2367 * handler. Instead, it relies on user space to provide a 2368 * restorer function that calls the {rt_,}sigreturn() system call. 2369 * Unfortunately, we cannot just reference the glibc version of this 2370 * function, as glibc goes out of its way to make it inaccessible. 2371 */ 2372 void (*res)(void); 2373 __asm__ __volatile__("call 2f\n" 2374 "0:.align 16\n" 2375 "1:pop %%eax\n" 2376 "movl %1,%%eax\n" 2377 LSS_ENTRYPOINT 2378 "2:popl %0\n" 2379 "addl $(1b-0b),%0\n" 2380 : "=a" (res) 2381 : "i" (__NR_sigreturn)); 2382 return res; 2383 } 2384 #elif defined(__x86_64__) 2385 /* There are no known problems with any of the _syscallX() macros 2386 * currently shipping for x86_64, but we still need to be able to define 2387 * our own version so that we can override the location of the errno 2388 * location (e.g. when using the clone() system call with the CLONE_VM 2389 * option). 2390 */ 2391 #undef LSS_ENTRYPOINT 2392 #ifdef SYS_SYSCALL_ENTRYPOINT LSS_NAME(get_syscall_entrypoint)2393 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { 2394 void (**entrypoint)(void); 2395 asm volatile(".bss\n" 2396 ".align 8\n" 2397 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" 2398 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" 2399 ".previous\n" 2400 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n" 2401 : "=r"(entrypoint)); 2402 return entrypoint; 2403 } 2404 2405 #define LSS_ENTRYPOINT \ 2406 ".bss\n" \ 2407 ".align 8\n" \ 2408 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \ 2409 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \ 2410 ".previous\n" \ 2411 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \ 2412 "mov 0(%%rcx), %%rcx\n" \ 2413 "test %%rcx, %%rcx\n" \ 2414 "jz 10001f\n" \ 2415 "call *%%rcx\n" \ 2416 "jmp 10002f\n" \ 2417 "10001:syscall\n" \ 2418 "10002:\n" 2419 2420 #else 2421 #define LSS_ENTRYPOINT "syscall\n" 2422 #endif 2423 2424 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit. 2425 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit 2426 * sign extension. We can't cast pointers directly because those are 2427 * 32 bits, and gcc will dump ugly warnings about casting from a pointer 2428 * to an integer of a different size. 2429 */ 2430 #undef LSS_SYSCALL_ARG 2431 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a)) 2432 #undef _LSS_RETURN 2433 #define _LSS_RETURN(type, res, cast) \ 2434 do { \ 2435 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \ 2436 LSS_ERRNO = (int)(-(res)); \ 2437 res = -1; \ 2438 } \ 2439 return (type)(cast)(res); \ 2440 } while (0) 2441 #undef LSS_RETURN 2442 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t) 2443 2444 #undef _LSS_BODY 2445 #define _LSS_BODY(nr, type, name, cast, ...) \ 2446 long long __res; \ 2447 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \ 2448 : "=a" (__res) \ 2449 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \ 2450 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \ 2451 _LSS_RETURN(type, __res, cast) 2452 #undef LSS_BODY 2453 #define LSS_BODY(nr, type, name, args...) \ 2454 _LSS_BODY(nr, type, name, uintptr_t, ## args) 2455 2456 #undef LSS_BODY_ASM0 2457 #undef LSS_BODY_ASM1 2458 #undef LSS_BODY_ASM2 2459 #undef LSS_BODY_ASM3 2460 #undef LSS_BODY_ASM4 2461 #undef LSS_BODY_ASM5 2462 #undef LSS_BODY_ASM6 2463 #define LSS_BODY_ASM0 2464 #define LSS_BODY_ASM1 LSS_BODY_ASM0 2465 #define LSS_BODY_ASM2 LSS_BODY_ASM1 2466 #define LSS_BODY_ASM3 LSS_BODY_ASM2 2467 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;" 2468 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;" 2469 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;" 2470 2471 #undef LSS_BODY_CLOBBER0 2472 #undef LSS_BODY_CLOBBER1 2473 #undef LSS_BODY_CLOBBER2 2474 #undef LSS_BODY_CLOBBER3 2475 #undef LSS_BODY_CLOBBER4 2476 #undef LSS_BODY_CLOBBER5 2477 #undef LSS_BODY_CLOBBER6 2478 #define LSS_BODY_CLOBBER0 2479 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0 2480 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1 2481 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2 2482 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10", 2483 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8", 2484 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9", 2485 2486 #undef LSS_BODY_ARG0 2487 #undef LSS_BODY_ARG1 2488 #undef LSS_BODY_ARG2 2489 #undef LSS_BODY_ARG3 2490 #undef LSS_BODY_ARG4 2491 #undef LSS_BODY_ARG5 2492 #undef LSS_BODY_ARG6 2493 #define LSS_BODY_ARG0() 2494 #define LSS_BODY_ARG1(arg1) \ 2495 LSS_BODY_ARG0(), "D" (arg1) 2496 #define LSS_BODY_ARG2(arg1, arg2) \ 2497 LSS_BODY_ARG1(arg1), "S" (arg2) 2498 #define LSS_BODY_ARG3(arg1, arg2, arg3) \ 2499 LSS_BODY_ARG2(arg1, arg2), "d" (arg3) 2500 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \ 2501 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4) 2502 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \ 2503 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5) 2504 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \ 2505 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6) 2506 2507 #undef _syscall0 2508 #define _syscall0(type,name) \ 2509 type LSS_NAME(name)(void) { \ 2510 LSS_BODY(0, type, name); \ 2511 } 2512 #undef _syscall1 2513 #define _syscall1(type,name,type1,arg1) \ 2514 type LSS_NAME(name)(type1 arg1) { \ 2515 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \ 2516 } 2517 #undef _syscall2 2518 #define _syscall2(type,name,type1,arg1,type2,arg2) \ 2519 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 2520 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\ 2521 } 2522 #undef _syscall3 2523 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 2524 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 2525 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ 2526 LSS_SYSCALL_ARG(arg3)); \ 2527 } 2528 #undef _syscall4 2529 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 2530 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 2531 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ 2532 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\ 2533 } 2534 #undef _syscall5 2535 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2536 type5,arg5) \ 2537 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2538 type5 arg5) { \ 2539 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ 2540 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ 2541 LSS_SYSCALL_ARG(arg5)); \ 2542 } 2543 #undef _syscall6 2544 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2545 type5,arg5,type6,arg6) \ 2546 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2547 type5 arg5, type6 arg6) { \ 2548 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ 2549 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ 2550 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\ 2551 } LSS_NAME(clone)2552 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 2553 int flags, void *arg, int *parent_tidptr, 2554 void *newtls, int *child_tidptr) { 2555 long long __res; 2556 { 2557 __asm__ __volatile__(/* if (fn == NULL) 2558 * return -EINVAL; 2559 */ 2560 "testq %4,%4\n" 2561 "jz 1f\n" 2562 2563 /* if (child_stack == NULL) 2564 * return -EINVAL; 2565 */ 2566 "testq %5,%5\n" 2567 "jz 1f\n" 2568 2569 /* childstack -= 2*sizeof(void *); 2570 */ 2571 "subq $16,%5\n" 2572 2573 /* Push "arg" and "fn" onto the stack that will be 2574 * used by the child. 2575 */ 2576 "movq %7,8(%5)\n" 2577 "movq %4,0(%5)\n" 2578 2579 /* %rax = syscall(%rax = __NR_clone, 2580 * %rdi = flags, 2581 * %rsi = child_stack, 2582 * %rdx = parent_tidptr, 2583 * %r8 = new_tls, 2584 * %r10 = child_tidptr) 2585 */ 2586 "movq %2,%%rax\n" 2587 "movq %9,%%r8\n" 2588 "movq %10,%%r10\n" 2589 LSS_ENTRYPOINT 2590 2591 /* if (%rax != 0) 2592 * return; 2593 */ 2594 "testq %%rax,%%rax\n" 2595 "jnz 1f\n" 2596 2597 /* In the child. Terminate frame pointer chain. 2598 */ 2599 "xorq %%rbp,%%rbp\n" 2600 2601 /* Call "fn(arg)". 2602 */ 2603 "popq %%rax\n" 2604 "popq %%rdi\n" 2605 "call *%%rax\n" 2606 2607 /* Call _exit(%ebx). 2608 */ 2609 "movq %%rax,%%rdi\n" 2610 "movq %3,%%rax\n" 2611 LSS_ENTRYPOINT 2612 2613 /* Return to parent. 2614 */ 2615 "1:\n" 2616 : "=a" (__res) 2617 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), 2618 "r"(LSS_SYSCALL_ARG(fn)), 2619 "S"(LSS_SYSCALL_ARG(child_stack)), 2620 "D"(LSS_SYSCALL_ARG(flags)), 2621 "r"(LSS_SYSCALL_ARG(arg)), 2622 "d"(LSS_SYSCALL_ARG(parent_tidptr)), 2623 "r"(LSS_SYSCALL_ARG(newtls)), 2624 "r"(LSS_SYSCALL_ARG(child_tidptr)) 2625 : "memory", "r8", "r10", "r11", "rcx"); 2626 } 2627 LSS_RETURN(int, __res); 2628 } _syscall2(int,arch_prctl,int,c,void *,a)2629 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) 2630 2631 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { 2632 /* On x86-64, the kernel does not know how to return from 2633 * a signal handler. Instead, it relies on user space to provide a 2634 * restorer function that calls the rt_sigreturn() system call. 2635 * Unfortunately, we cannot just reference the glibc version of this 2636 * function, as glibc goes out of its way to make it inaccessible. 2637 */ 2638 long long res; 2639 __asm__ __volatile__("jmp 2f\n" 2640 ".align 16\n" 2641 "1:movq %1,%%rax\n" 2642 LSS_ENTRYPOINT 2643 "2:leaq 1b(%%rip),%0\n" 2644 : "=r" (res) 2645 : "i" (__NR_rt_sigreturn)); 2646 return (void (*)(void))(uintptr_t)res; 2647 } 2648 #elif defined(__ARM_ARCH_3__) 2649 /* Most definitions of _syscallX() neglect to mark "memory" as being 2650 * clobbered. This causes problems with compilers, that do a better job 2651 * at optimizing across __asm__ calls. 2652 * So, we just have to redefine all of the _syscallX() macros. 2653 */ 2654 #undef LSS_REG 2655 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a 2656 #undef LSS_BODY 2657 #define LSS_BODY(type,name,args...) \ 2658 register long __res_r0 __asm__("r0"); \ 2659 long __res; \ 2660 __asm__ __volatile__ (__syscall(name) \ 2661 : "=r"(__res_r0) : args : "lr", "memory"); \ 2662 __res = __res_r0; \ 2663 LSS_RETURN(type, __res) 2664 #undef _syscall0 2665 #define _syscall0(type, name) \ 2666 type LSS_NAME(name)(void) { \ 2667 LSS_BODY(type, name); \ 2668 } 2669 #undef _syscall1 2670 #define _syscall1(type, name, type1, arg1) \ 2671 type LSS_NAME(name)(type1 arg1) { \ 2672 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ 2673 } 2674 #undef _syscall2 2675 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 2676 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 2677 LSS_REG(0, arg1); LSS_REG(1, arg2); \ 2678 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ 2679 } 2680 #undef _syscall3 2681 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 2682 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 2683 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2684 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ 2685 } 2686 #undef _syscall4 2687 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 2688 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 2689 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2690 LSS_REG(3, arg4); \ 2691 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ 2692 } 2693 #undef _syscall5 2694 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2695 type5,arg5) \ 2696 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2697 type5 arg5) { \ 2698 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2699 LSS_REG(3, arg4); LSS_REG(4, arg5); \ 2700 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 2701 "r"(__r4)); \ 2702 } 2703 #undef _syscall6 2704 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2705 type5,arg5,type6,arg6) \ 2706 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2707 type5 arg5, type6 arg6) { \ 2708 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2709 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ 2710 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 2711 "r"(__r4), "r"(__r5)); \ 2712 } LSS_NAME(clone)2713 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 2714 int flags, void *arg, int *parent_tidptr, 2715 void *newtls, int *child_tidptr) { 2716 long __res; 2717 { 2718 register int __flags __asm__("r0") = flags; 2719 register void *__stack __asm__("r1") = child_stack; 2720 register void *__ptid __asm__("r2") = parent_tidptr; 2721 register void *__tls __asm__("r3") = newtls; 2722 register int *__ctid __asm__("r4") = child_tidptr; 2723 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL) 2724 * return -EINVAL; 2725 */ 2726 "cmp %2,#0\n" 2727 "cmpne %3,#0\n" 2728 "moveq %0,%1\n" 2729 "beq 1f\n" 2730 2731 /* Push "arg" and "fn" onto the stack that will be 2732 * used by the child. 2733 */ 2734 "str %5,[%3,#-4]!\n" 2735 "str %2,[%3,#-4]!\n" 2736 2737 /* %r0 = syscall(%r0 = flags, 2738 * %r1 = child_stack, 2739 * %r2 = parent_tidptr, 2740 * %r3 = newtls, 2741 * %r4 = child_tidptr) 2742 */ 2743 __syscall(clone)"\n" 2744 2745 /* if (%r0 != 0) 2746 * return %r0; 2747 */ 2748 "movs %0,r0\n" 2749 "bne 1f\n" 2750 2751 /* In the child, now. Call "fn(arg)". 2752 */ 2753 "ldr r0,[sp, #4]\n" 2754 "mov lr,pc\n" 2755 "ldr pc,[sp]\n" 2756 2757 /* Call _exit(%r0). 2758 */ 2759 __syscall(exit)"\n" 2760 "1:\n" 2761 : "=r" (__res) 2762 : "i"(-EINVAL), 2763 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), 2764 "r"(__ptid), "r"(__tls), "r"(__ctid) 2765 : "cc", "lr", "memory"); 2766 } 2767 LSS_RETURN(int, __res); 2768 } 2769 #elif defined(__ARM_EABI__) 2770 /* Most definitions of _syscallX() neglect to mark "memory" as being 2771 * clobbered. This causes problems with compilers, that do a better job 2772 * at optimizing across __asm__ calls. 2773 * So, we just have to redefine all fo the _syscallX() macros. 2774 */ 2775 #undef LSS_REG 2776 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a 2777 #undef LSS_BODY 2778 #define LSS_BODY(type,name,args...) \ 2779 register long __res_r0 __asm__("r0"); \ 2780 long __res; \ 2781 __asm__ __volatile__ ("push {r7}\n" \ 2782 "mov r7, %1\n" \ 2783 "swi 0x0\n" \ 2784 "pop {r7}\n" \ 2785 : "=r"(__res_r0) \ 2786 : "i"(__NR_##name) , ## args \ 2787 : "lr", "memory"); \ 2788 __res = __res_r0; \ 2789 LSS_RETURN(type, __res) 2790 #undef _syscall0 2791 #define _syscall0(type, name) \ 2792 type LSS_NAME(name)(void) { \ 2793 LSS_BODY(type, name); \ 2794 } 2795 #undef _syscall1 2796 #define _syscall1(type, name, type1, arg1) \ 2797 type LSS_NAME(name)(type1 arg1) { \ 2798 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ 2799 } 2800 #undef _syscall2 2801 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 2802 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 2803 LSS_REG(0, arg1); LSS_REG(1, arg2); \ 2804 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ 2805 } 2806 #undef _syscall3 2807 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 2808 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 2809 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2810 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ 2811 } 2812 #undef _syscall4 2813 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 2814 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 2815 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2816 LSS_REG(3, arg4); \ 2817 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ 2818 } 2819 #undef _syscall5 2820 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2821 type5,arg5) \ 2822 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2823 type5 arg5) { \ 2824 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2825 LSS_REG(3, arg4); LSS_REG(4, arg5); \ 2826 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 2827 "r"(__r4)); \ 2828 } 2829 #undef _syscall6 2830 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2831 type5,arg5,type6,arg6) \ 2832 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2833 type5 arg5, type6 arg6) { \ 2834 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2835 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ 2836 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 2837 "r"(__r4), "r"(__r5)); \ 2838 } LSS_NAME(clone)2839 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 2840 int flags, void *arg, int *parent_tidptr, 2841 void *newtls, int *child_tidptr) { 2842 long __res; 2843 if (fn == NULL || child_stack == NULL) { 2844 __res = -EINVAL; 2845 LSS_RETURN(int, __res); 2846 } 2847 2848 /* Push "arg" and "fn" onto the stack that will be 2849 * used by the child. 2850 */ 2851 { 2852 uintptr_t* cstack = (uintptr_t*)child_stack - 2; 2853 cstack[0] = (uintptr_t)fn; 2854 cstack[1] = (uintptr_t)arg; 2855 child_stack = cstack; 2856 } 2857 { 2858 register int __flags __asm__("r0") = flags; 2859 register void *__stack __asm__("r1") = child_stack; 2860 register void *__ptid __asm__("r2") = parent_tidptr; 2861 register void *__tls __asm__("r3") = newtls; 2862 register int *__ctid __asm__("r4") = child_tidptr; 2863 __asm__ __volatile__( 2864 #ifdef __thumb2__ 2865 "push {r7}\n" 2866 #endif 2867 /* %r0 = syscall(%r0 = flags, 2868 * %r1 = child_stack, 2869 * %r2 = parent_tidptr, 2870 * %r3 = newtls, 2871 * %r4 = child_tidptr) 2872 */ 2873 "mov r7, %6\n" 2874 "swi 0x0\n" 2875 2876 /* if (%r0 != 0) 2877 * return %r0; 2878 */ 2879 "cmp r0, #0\n" 2880 "bne 1f\n" 2881 2882 /* In the child, now. Call "fn(arg)". 2883 */ 2884 "ldr r0,[sp, #4]\n" 2885 2886 "ldr lr,[sp]\n" 2887 "blx lr\n" 2888 2889 /* Call _exit(%r0). 2890 */ 2891 "mov r7, %7\n" 2892 "swi 0x0\n" 2893 /* Unreachable */ 2894 "bkpt #0\n" 2895 "1:\n" 2896 #ifdef __thumb2__ 2897 "pop {r7}\n" 2898 #endif 2899 "movs %0,r0\n" 2900 : "=r"(__res) 2901 : "r"(__stack), "r"(__flags), "r"(__ptid), "r"(__tls), "r"(__ctid), 2902 "i"(__NR_clone), "i"(__NR_exit) 2903 : "cc", "lr", "memory" 2904 #ifndef __thumb2__ 2905 , "r7" 2906 #endif 2907 ); 2908 } 2909 LSS_RETURN(int, __res); 2910 } 2911 #elif defined(__aarch64__) 2912 /* Most definitions of _syscallX() neglect to mark "memory" as being 2913 * clobbered. This causes problems with compilers, that do a better job 2914 * at optimizing across __asm__ calls. 2915 * So, we just have to redefine all of the _syscallX() macros. 2916 */ 2917 #undef LSS_REG 2918 #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a 2919 #undef LSS_BODY 2920 #define LSS_BODY(type,name,args...) \ 2921 register int64_t __res_x0 __asm__("x0"); \ 2922 int64_t __res; \ 2923 __asm__ __volatile__ ("mov x8, %1\n" \ 2924 "svc 0x0\n" \ 2925 : "=r"(__res_x0) \ 2926 : "i"(__NR_##name) , ## args \ 2927 : "x8", "memory"); \ 2928 __res = __res_x0; \ 2929 LSS_RETURN(type, __res) 2930 #undef _syscall0 2931 #define _syscall0(type, name) \ 2932 type LSS_NAME(name)(void) { \ 2933 LSS_BODY(type, name); \ 2934 } 2935 #undef _syscall1 2936 #define _syscall1(type, name, type1, arg1) \ 2937 type LSS_NAME(name)(type1 arg1) { \ 2938 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ 2939 } 2940 #undef _syscall2 2941 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 2942 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 2943 LSS_REG(0, arg1); LSS_REG(1, arg2); \ 2944 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ 2945 } 2946 #undef _syscall3 2947 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 2948 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 2949 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2950 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ 2951 } 2952 #undef _syscall4 2953 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 2954 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 2955 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2956 LSS_REG(3, arg4); \ 2957 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ 2958 } 2959 #undef _syscall5 2960 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2961 type5,arg5) \ 2962 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2963 type5 arg5) { \ 2964 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2965 LSS_REG(3, arg4); LSS_REG(4, arg5); \ 2966 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 2967 "r"(__r4)); \ 2968 } 2969 #undef _syscall6 2970 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 2971 type5,arg5,type6,arg6) \ 2972 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 2973 type5 arg5, type6 arg6) { \ 2974 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 2975 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ 2976 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 2977 "r"(__r4), "r"(__r5)); \ 2978 } 2979 LSS_NAME(clone)2980 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 2981 int flags, void *arg, int *parent_tidptr, 2982 void *newtls, int *child_tidptr) { 2983 int64_t __res; 2984 { 2985 register uint64_t __flags __asm__("x0") = (uint64_t)flags; 2986 register void *__stack __asm__("x1") = child_stack; 2987 register void *__ptid __asm__("x2") = parent_tidptr; 2988 register void *__tls __asm__("x3") = newtls; 2989 register int *__ctid __asm__("x4") = child_tidptr; 2990 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be 2991 * used by the child. 2992 */ 2993 "stp %1, %4, [%2, #-16]!\n" 2994 2995 /* %x0 = syscall(%x0 = flags, 2996 * %x1 = child_stack, 2997 * %x2 = parent_tidptr, 2998 * %x3 = newtls, 2999 * %x4 = child_tidptr) 3000 */ 3001 "mov x8, %8\n" 3002 "svc 0x0\n" 3003 3004 /* if (%r0 != 0) 3005 * return %r0; 3006 */ 3007 "mov %0, x0\n" 3008 "cbnz x0, 1f\n" 3009 3010 /* In the child, now. Call "fn(arg)". 3011 */ 3012 "ldp x1, x0, [sp], #16\n" 3013 "blr x1\n" 3014 3015 /* Call _exit(%r0). 3016 */ 3017 "mov x8, %9\n" 3018 "svc 0x0\n" 3019 "1:\n" 3020 : "=r" (__res) 3021 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), 3022 "r"(__ptid), "r"(__tls), "r"(__ctid), 3023 "i"(__NR_clone), "i"(__NR_exit) 3024 : "cc", "x8", "memory"); 3025 } 3026 LSS_RETURN(int, __res); 3027 } 3028 #elif defined(__mips__) 3029 #undef LSS_REG 3030 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \ 3031 (unsigned long)(a) 3032 #undef LSS_BODY 3033 #undef LSS_SYSCALL_CLOBBERS 3034 #if _MIPS_SIM == _MIPS_SIM_ABI32 3035 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \ 3036 "$11", "$12", "$13", "$14", "$15", \ 3037 "$24", "$25", "hi", "lo", "memory" 3038 #else 3039 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \ 3040 "$13", "$14", "$15", "$24", "$25", \ 3041 "hi", "lo", "memory" 3042 #endif 3043 #define LSS_BODY(type,name,r7,...) \ 3044 register unsigned long __v0 __asm__("$2") = __NR_##name; \ 3045 __asm__ __volatile__ ("syscall\n" \ 3046 : "=r"(__v0), r7 (__r7) \ 3047 : "0"(__v0), ##__VA_ARGS__ \ 3048 : LSS_SYSCALL_CLOBBERS); \ 3049 LSS_RETURN(type, __v0, __r7) 3050 #undef _syscall0 3051 #define _syscall0(type, name) \ 3052 type LSS_NAME(name)(void) { \ 3053 register unsigned long __r7 __asm__("$7"); \ 3054 LSS_BODY(type, name, "=r"); \ 3055 } 3056 #undef _syscall1 3057 #define _syscall1(type, name, type1, arg1) \ 3058 type LSS_NAME(name)(type1 arg1) { \ 3059 register unsigned long __r7 __asm__("$7"); \ 3060 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \ 3061 } 3062 #undef _syscall2 3063 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 3064 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 3065 register unsigned long __r7 __asm__("$7"); \ 3066 LSS_REG(4, arg1); LSS_REG(5, arg2); \ 3067 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \ 3068 } 3069 #undef _syscall3 3070 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 3071 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 3072 register unsigned long __r7 __asm__("$7"); \ 3073 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 3074 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \ 3075 } 3076 #undef _syscall4 3077 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 3078 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 3079 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 3080 LSS_REG(7, arg4); \ 3081 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \ 3082 } 3083 #undef _syscall5 3084 #if _MIPS_SIM == _MIPS_SIM_ABI32 3085 /* The old 32bit MIPS system call API passes the fifth and sixth argument 3086 * on the stack, whereas the new APIs use registers "r8" and "r9". 3087 */ 3088 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 3089 type5,arg5) \ 3090 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3091 type5 arg5) { \ 3092 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 3093 LSS_REG(7, arg4); \ 3094 register unsigned long __v0 __asm__("$2") = __NR_##name; \ 3095 __asm__ __volatile__ (".set noreorder\n" \ 3096 "subu $29, 32\n" \ 3097 "sw %5, 16($29)\n" \ 3098 "syscall\n" \ 3099 "addiu $29, 32\n" \ 3100 ".set reorder\n" \ 3101 : "+r"(__v0), "+r" (__r7) \ 3102 : "r"(__r4), "r"(__r5), \ 3103 "r"(__r6), "r" ((unsigned long)arg5) \ 3104 : "$8", "$9", "$10", "$11", "$12", \ 3105 "$13", "$14", "$15", "$24", "$25", \ 3106 "memory"); \ 3107 LSS_RETURN(type, __v0, __r7); \ 3108 } 3109 #else 3110 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 3111 type5,arg5) \ 3112 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3113 type5 arg5) { \ 3114 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 3115 LSS_REG(7, arg4); LSS_REG(8, arg5); \ 3116 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ 3117 "r"(__r8)); \ 3118 } 3119 #endif 3120 #undef _syscall6 3121 #if _MIPS_SIM == _MIPS_SIM_ABI32 3122 /* The old 32bit MIPS system call API passes the fifth and sixth argument 3123 * on the stack, whereas the new APIs use registers "r8" and "r9". 3124 */ 3125 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 3126 type5,arg5,type6,arg6) \ 3127 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3128 type5 arg5, type6 arg6) { \ 3129 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 3130 LSS_REG(7, arg4); \ 3131 register unsigned long __v0 __asm__("$2") = __NR_##name; \ 3132 __asm__ __volatile__ (".set noreorder\n" \ 3133 "subu $29, 32\n" \ 3134 "sw %5, 16($29)\n" \ 3135 "sw %6, 20($29)\n" \ 3136 "syscall\n" \ 3137 "addiu $29, 32\n" \ 3138 ".set reorder\n" \ 3139 : "+r"(__v0), "+r" (__r7) \ 3140 : "r"(__r4), "r"(__r5), \ 3141 "r"(__r6), "r" ((unsigned long)arg5), \ 3142 "r" ((unsigned long)arg6) \ 3143 : "$8", "$9", "$10", "$11", "$12", \ 3144 "$13", "$14", "$15", "$24", "$25", \ 3145 "memory"); \ 3146 LSS_RETURN(type, __v0, __r7); \ 3147 } 3148 #else 3149 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 3150 type5,arg5,type6,arg6) \ 3151 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3152 type5 arg5,type6 arg6) { \ 3153 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 3154 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \ 3155 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ 3156 "r"(__r8), "r"(__r9)); \ 3157 } 3158 #endif LSS_NAME(clone)3159 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 3160 int flags, void *arg, int *parent_tidptr, 3161 void *newtls, int *child_tidptr) { 3162 register unsigned long __v0 __asm__("$2") = -EINVAL; 3163 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls; 3164 { 3165 register int __flags __asm__("$4") = flags; 3166 register void *__stack __asm__("$5") = child_stack; 3167 register void *__ptid __asm__("$6") = parent_tidptr; 3168 register int *__ctid __asm__("$8") = child_tidptr; 3169 __asm__ __volatile__( 3170 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 3171 "subu $29,24\n" 3172 #elif _MIPS_SIM == _MIPS_SIM_NABI32 3173 "sub $29,16\n" 3174 #else 3175 "dsubu $29,16\n" 3176 #endif 3177 3178 /* if (fn == NULL || child_stack == NULL) 3179 * return -EINVAL; 3180 */ 3181 "beqz %4,1f\n" 3182 "beqz %5,1f\n" 3183 3184 /* Push "arg" and "fn" onto the stack that will be 3185 * used by the child. 3186 */ 3187 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 3188 "subu %5,32\n" 3189 "sw %4,0(%5)\n" 3190 "sw %7,4(%5)\n" 3191 #elif _MIPS_SIM == _MIPS_SIM_NABI32 3192 "sub %5,32\n" 3193 "sw %4,0(%5)\n" 3194 "sw %7,8(%5)\n" 3195 #else 3196 "dsubu %5,32\n" 3197 "sd %4,0(%5)\n" 3198 "sd %7,8(%5)\n" 3199 #endif 3200 3201 /* $7 = syscall($4 = flags, 3202 * $5 = child_stack, 3203 * $6 = parent_tidptr, 3204 * $7 = newtls, 3205 * $8 = child_tidptr) 3206 */ 3207 "li $2,%2\n" 3208 "syscall\n" 3209 3210 /* if ($7 != 0) 3211 * return $2; 3212 */ 3213 "bnez $7,1f\n" 3214 "bnez $2,1f\n" 3215 3216 /* In the child, now. Call "fn(arg)". 3217 */ 3218 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 3219 "lw $25,0($29)\n" 3220 "lw $4,4($29)\n" 3221 #elif _MIPS_SIM == _MIPS_SIM_NABI32 3222 "lw $25,0($29)\n" 3223 "lw $4,8($29)\n" 3224 #else 3225 "ld $25,0($29)\n" 3226 "ld $4,8($29)\n" 3227 #endif 3228 "jalr $25\n" 3229 3230 /* Call _exit($2) 3231 */ 3232 "move $4,$2\n" 3233 "li $2,%3\n" 3234 "syscall\n" 3235 3236 "1:\n" 3237 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 3238 "addu $29, 24\n" 3239 #elif _MIPS_SIM == _MIPS_SIM_NABI32 3240 "add $29, 16\n" 3241 #else 3242 "daddu $29,16\n" 3243 #endif 3244 : "+r" (__v0), "+r" (__r7) 3245 : "i"(__NR_clone), "i"(__NR_exit), "r"(fn), 3246 "r"(__stack), "r"(__flags), "r"(arg), 3247 "r"(__ptid), "r"(__ctid) 3248 : "$9", "$10", "$11", "$12", "$13", "$14", "$15", 3249 "$24", "$25", "memory"); 3250 } 3251 LSS_RETURN(int, __v0, __r7); 3252 } 3253 #elif defined (__PPC__) 3254 #undef LSS_LOADARGS_0 3255 #define LSS_LOADARGS_0(name, dummy...) \ 3256 __sc_0 = __NR_##name 3257 #undef LSS_LOADARGS_1 3258 #define LSS_LOADARGS_1(name, arg1) \ 3259 LSS_LOADARGS_0(name); \ 3260 __sc_3 = (unsigned long) (arg1) 3261 #undef LSS_LOADARGS_2 3262 #define LSS_LOADARGS_2(name, arg1, arg2) \ 3263 LSS_LOADARGS_1(name, arg1); \ 3264 __sc_4 = (unsigned long) (arg2) 3265 #undef LSS_LOADARGS_3 3266 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \ 3267 LSS_LOADARGS_2(name, arg1, arg2); \ 3268 __sc_5 = (unsigned long) (arg3) 3269 #undef LSS_LOADARGS_4 3270 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \ 3271 LSS_LOADARGS_3(name, arg1, arg2, arg3); \ 3272 __sc_6 = (unsigned long) (arg4) 3273 #undef LSS_LOADARGS_5 3274 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \ 3275 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \ 3276 __sc_7 = (unsigned long) (arg5) 3277 #undef LSS_LOADARGS_6 3278 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ 3279 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \ 3280 __sc_8 = (unsigned long) (arg6) 3281 #undef LSS_ASMINPUT_0 3282 #define LSS_ASMINPUT_0 "0" (__sc_0) 3283 #undef LSS_ASMINPUT_1 3284 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3) 3285 #undef LSS_ASMINPUT_2 3286 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4) 3287 #undef LSS_ASMINPUT_3 3288 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5) 3289 #undef LSS_ASMINPUT_4 3290 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6) 3291 #undef LSS_ASMINPUT_5 3292 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7) 3293 #undef LSS_ASMINPUT_6 3294 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8) 3295 #undef LSS_BODY 3296 #define LSS_BODY(nr, type, name, args...) \ 3297 long __sc_ret, __sc_err; \ 3298 { \ 3299 register unsigned long __sc_0 __asm__ ("r0"); \ 3300 register unsigned long __sc_3 __asm__ ("r3"); \ 3301 register unsigned long __sc_4 __asm__ ("r4"); \ 3302 register unsigned long __sc_5 __asm__ ("r5"); \ 3303 register unsigned long __sc_6 __asm__ ("r6"); \ 3304 register unsigned long __sc_7 __asm__ ("r7"); \ 3305 register unsigned long __sc_8 __asm__ ("r8"); \ 3306 \ 3307 LSS_LOADARGS_##nr(name, args); \ 3308 __asm__ __volatile__ \ 3309 ("sc\n\t" \ 3310 "mfcr %0" \ 3311 : "=&r" (__sc_0), \ 3312 "=&r" (__sc_3), "=&r" (__sc_4), \ 3313 "=&r" (__sc_5), "=&r" (__sc_6), \ 3314 "=&r" (__sc_7), "=&r" (__sc_8) \ 3315 : LSS_ASMINPUT_##nr \ 3316 : "cr0", "ctr", "memory", \ 3317 "r9", "r10", "r11", "r12"); \ 3318 __sc_ret = __sc_3; \ 3319 __sc_err = __sc_0; \ 3320 } \ 3321 LSS_RETURN(type, __sc_ret, __sc_err) 3322 #undef _syscall0 3323 #define _syscall0(type, name) \ 3324 type LSS_NAME(name)(void) { \ 3325 LSS_BODY(0, type, name); \ 3326 } 3327 #undef _syscall1 3328 #define _syscall1(type, name, type1, arg1) \ 3329 type LSS_NAME(name)(type1 arg1) { \ 3330 LSS_BODY(1, type, name, arg1); \ 3331 } 3332 #undef _syscall2 3333 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 3334 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 3335 LSS_BODY(2, type, name, arg1, arg2); \ 3336 } 3337 #undef _syscall3 3338 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 3339 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 3340 LSS_BODY(3, type, name, arg1, arg2, arg3); \ 3341 } 3342 #undef _syscall4 3343 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ 3344 type4, arg4) \ 3345 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 3346 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \ 3347 } 3348 #undef _syscall5 3349 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ 3350 type4, arg4, type5, arg5) \ 3351 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3352 type5 arg5) { \ 3353 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \ 3354 } 3355 #undef _syscall6 3356 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ 3357 type4, arg4, type5, arg5, type6, arg6) \ 3358 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3359 type5 arg5, type6 arg6) { \ 3360 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ 3361 } 3362 /* clone function adapted from glibc 2.3.6 clone.S */ 3363 /* TODO(csilvers): consider wrapping some args up in a struct, like we 3364 * do for i386's _syscall6, so we can compile successfully on gcc 2.95 3365 */ LSS_NAME(clone)3366 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 3367 int flags, void *arg, int *parent_tidptr, 3368 void *newtls, int *child_tidptr) { 3369 long __ret, __err; 3370 { 3371 register int (*__fn)(void *) __asm__ ("r8") = fn; 3372 register void *__cstack __asm__ ("r4") = child_stack; 3373 register int __flags __asm__ ("r3") = flags; 3374 register void * __arg __asm__ ("r9") = arg; 3375 register int * __ptidptr __asm__ ("r5") = parent_tidptr; 3376 register void * __newtls __asm__ ("r6") = newtls; 3377 register int * __ctidptr __asm__ ("r7") = child_tidptr; 3378 __asm__ __volatile__( 3379 /* check for fn == NULL 3380 * and child_stack == NULL 3381 */ 3382 "cmpwi cr0, %6, 0\n\t" 3383 "cmpwi cr1, %7, 0\n\t" 3384 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t" 3385 "beq- cr0, 1f\n\t" 3386 3387 /* set up stack frame for child */ 3388 "clrrwi %7, %7, 4\n\t" 3389 "li 0, 0\n\t" 3390 "stwu 0, -16(%7)\n\t" 3391 3392 /* fn, arg, child_stack are saved across the syscall: r28-30 */ 3393 "mr 28, %6\n\t" 3394 "mr 29, %7\n\t" 3395 "mr 27, %9\n\t" 3396 3397 /* syscall */ 3398 "li 0, %4\n\t" 3399 /* flags already in r3 3400 * child_stack already in r4 3401 * ptidptr already in r5 3402 * newtls already in r6 3403 * ctidptr already in r7 3404 */ 3405 "sc\n\t" 3406 3407 /* Test if syscall was successful */ 3408 "cmpwi cr1, 3, 0\n\t" 3409 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" 3410 "bne- cr1, 1f\n\t" 3411 3412 /* Do the function call */ 3413 "mtctr 28\n\t" 3414 "mr 3, 27\n\t" 3415 "bctrl\n\t" 3416 3417 /* Call _exit(r3) */ 3418 "li 0, %5\n\t" 3419 "sc\n\t" 3420 3421 /* Return to parent */ 3422 "1:\n" 3423 "mfcr %1\n\t" 3424 "mr %0, 3\n\t" 3425 : "=r" (__ret), "=r" (__err) 3426 : "0" (-1), "1" (EINVAL), 3427 "i" (__NR_clone), "i" (__NR_exit), 3428 "r" (__fn), "r" (__cstack), "r" (__flags), 3429 "r" (__arg), "r" (__ptidptr), "r" (__newtls), 3430 "r" (__ctidptr) 3431 : "cr0", "cr1", "memory", "ctr", 3432 "r0", "r29", "r27", "r28"); 3433 } 3434 LSS_RETURN(int, __ret, __err); 3435 } 3436 #elif defined(__s390__) 3437 #undef LSS_REG 3438 #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a 3439 #undef LSS_BODY 3440 #define LSS_BODY(type, name, args...) \ 3441 register unsigned long __nr __asm__("r1") \ 3442 = (unsigned long)(__NR_##name); \ 3443 register long __res_r2 __asm__("r2"); \ 3444 long __res; \ 3445 __asm__ __volatile__ \ 3446 ("svc 0\n\t" \ 3447 : "=d"(__res_r2) \ 3448 : "d"(__nr), ## args \ 3449 : "memory"); \ 3450 __res = __res_r2; \ 3451 LSS_RETURN(type, __res) 3452 #undef _syscall0 3453 #define _syscall0(type, name) \ 3454 type LSS_NAME(name)(void) { \ 3455 LSS_BODY(type, name); \ 3456 } 3457 #undef _syscall1 3458 #define _syscall1(type, name, type1, arg1) \ 3459 type LSS_NAME(name)(type1 arg1) { \ 3460 LSS_REG(2, arg1); \ 3461 LSS_BODY(type, name, "0"(__r2)); \ 3462 } 3463 #undef _syscall2 3464 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 3465 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 3466 LSS_REG(2, arg1); LSS_REG(3, arg2); \ 3467 LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \ 3468 } 3469 #undef _syscall3 3470 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 3471 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 3472 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ 3473 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \ 3474 } 3475 #undef _syscall4 3476 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ 3477 type4, arg4) \ 3478 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \ 3479 type4 arg4) { \ 3480 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ 3481 LSS_REG(5, arg4); \ 3482 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \ 3483 "d"(__r5)); \ 3484 } 3485 #undef _syscall5 3486 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ 3487 type4, arg4, type5, arg5) \ 3488 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \ 3489 type4 arg4, type5 arg5) { \ 3490 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ 3491 LSS_REG(5, arg4); LSS_REG(6, arg5); \ 3492 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \ 3493 "d"(__r5), "d"(__r6)); \ 3494 } 3495 #undef _syscall6 3496 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ 3497 type4, arg4, type5, arg5, type6, arg6) \ 3498 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \ 3499 type4 arg4, type5 arg5, type6 arg6) { \ 3500 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ 3501 LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \ 3502 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \ 3503 "d"(__r5), "d"(__r6), "d"(__r7)); \ 3504 } LSS_NAME(clone)3505 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 3506 int flags, void *arg, int *parent_tidptr, 3507 void *newtls, int *child_tidptr) { 3508 long __ret; 3509 { 3510 register int (*__fn)(void *) __asm__ ("r1") = fn; 3511 register void *__cstack __asm__ ("r2") = child_stack; 3512 register int __flags __asm__ ("r3") = flags; 3513 register void *__arg __asm__ ("r0") = arg; 3514 register int *__ptidptr __asm__ ("r4") = parent_tidptr; 3515 register void *__newtls __asm__ ("r6") = newtls; 3516 register int *__ctidptr __asm__ ("r5") = child_tidptr; 3517 __asm__ __volatile__ ( 3518 #ifndef __s390x__ 3519 /* arg already in r0 */ 3520 "ltr %4, %4\n\t" /* check fn, which is already in r1 */ 3521 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */ 3522 "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */ 3523 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */ 3524 /* flags already in r3 */ 3525 /* parent_tidptr already in r4 */ 3526 /* child_tidptr already in r5 */ 3527 /* newtls already in r6 */ 3528 "svc %2\n\t" /* invoke clone syscall */ 3529 "ltr %0,%%r2\n\t" /* load return code into __ret and test */ 3530 "jnz 1f\n\t" /* return to parent if non-zero */ 3531 /* start child thread */ 3532 "lr %%r2, %7\n\t" /* set first parameter to void *arg */ 3533 "ahi %%r15, -96\n\t" /* make room on the stack for the save area */ 3534 "xc 0(4,%%r15), 0(%%r15)\n\t" 3535 "basr %%r14, %4\n\t" /* jump to fn */ 3536 "svc %3\n" /* invoke exit syscall */ 3537 "1:\n" 3538 #else 3539 /* arg already in r0 */ 3540 "ltgr %4, %4\n\t" /* check fn, which is already in r1 */ 3541 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */ 3542 "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */ 3543 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */ 3544 /* flags already in r3 */ 3545 /* parent_tidptr already in r4 */ 3546 /* child_tidptr already in r5 */ 3547 /* newtls already in r6 */ 3548 "svc %2\n\t" /* invoke clone syscall */ 3549 "ltgr %0, %%r2\n\t" /* load return code into __ret and test */ 3550 "jnz 1f\n\t" /* return to parent if non-zero */ 3551 /* start child thread */ 3552 "lgr %%r2, %7\n\t" /* set first parameter to void *arg */ 3553 "aghi %%r15, -160\n\t" /* make room on the stack for the save area */ 3554 "xc 0(8,%%r15), 0(%%r15)\n\t" 3555 "basr %%r14, %4\n\t" /* jump to fn */ 3556 "svc %3\n" /* invoke exit syscall */ 3557 "1:\n" 3558 #endif 3559 : "=r" (__ret) 3560 : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit), 3561 "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg), 3562 "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr) 3563 : "cc", "r14", "memory" 3564 ); 3565 } 3566 LSS_RETURN(int, __ret); 3567 } 3568 #elif defined(__riscv) && __riscv_xlen == 64 3569 #undef LSS_REG 3570 #define LSS_REG(r,a) register int64_t __r##r __asm__("a"#r) = (int64_t)a 3571 #undef LSS_BODY 3572 #define LSS_BODY(type,name,args...) \ 3573 register int64_t __res_a0 __asm__("a0"); \ 3574 register int64_t __a7 __asm__("a7") = __NR_##name; \ 3575 int64_t __res; \ 3576 __asm__ __volatile__ ("scall\n" \ 3577 : "=r"(__res_a0) \ 3578 : "r"(__a7) , ## args \ 3579 : "memory"); \ 3580 __res = __res_a0; \ 3581 LSS_RETURN(type, __res) 3582 #undef _syscall0 3583 #define _syscall0(type, name) \ 3584 type LSS_NAME(name)(void) { \ 3585 LSS_BODY(type, name); \ 3586 } 3587 #undef _syscall1 3588 #define _syscall1(type, name, type1, arg1) \ 3589 type LSS_NAME(name)(type1 arg1) { \ 3590 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ 3591 } 3592 #undef _syscall2 3593 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 3594 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 3595 LSS_REG(0, arg1); LSS_REG(1, arg2); \ 3596 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ 3597 } 3598 #undef _syscall3 3599 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 3600 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 3601 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 3602 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ 3603 } 3604 #undef _syscall4 3605 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 3606 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 3607 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 3608 LSS_REG(3, arg4); \ 3609 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ 3610 } 3611 #undef _syscall5 3612 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 3613 type5,arg5) \ 3614 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3615 type5 arg5) { \ 3616 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 3617 LSS_REG(3, arg4); LSS_REG(4, arg5); \ 3618 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 3619 "r"(__r4)); \ 3620 } 3621 #undef _syscall6 3622 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 3623 type5,arg5,type6,arg6) \ 3624 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3625 type5 arg5, type6 arg6) { \ 3626 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 3627 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ 3628 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 3629 "r"(__r4), "r"(__r5)); \ 3630 } 3631 LSS_NAME(clone)3632 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 3633 int flags, void *arg, int *parent_tidptr, 3634 void *newtls, int *child_tidptr) { 3635 int64_t __res; 3636 { 3637 register int64_t __res_a0 __asm__("a0"); 3638 register uint64_t __flags __asm__("a0") = flags; 3639 register void *__stack __asm__("a1") = child_stack; 3640 register void *__ptid __asm__("a2") = parent_tidptr; 3641 register void *__tls __asm__("a3") = newtls; 3642 register int *__ctid __asm__("a4") = child_tidptr; 3643 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be 3644 * used by the child. 3645 */ 3646 "addi %2,%2,-16\n" 3647 "sd %1, 0(%2)\n" 3648 "sd %4, 8(%2)\n" 3649 3650 /* %a0 = syscall(%a0 = flags, 3651 * %a1 = child_stack, 3652 * %a2 = parent_tidptr, 3653 * %a3 = newtls, 3654 * %a4 = child_tidptr) 3655 */ 3656 "li a7, %8\n" 3657 "scall\n" 3658 3659 /* if (%a0 != 0) 3660 * return %a0; 3661 */ 3662 "bnez %0, 1f\n" 3663 3664 /* In the child, now. Call "fn(arg)". 3665 */ 3666 "ld a1, 0(sp)\n" 3667 "ld a0, 8(sp)\n" 3668 "jalr a1\n" 3669 3670 /* Call _exit(%a0). 3671 */ 3672 "li a7, %9\n" 3673 "scall\n" 3674 "1:\n" 3675 : "=r" (__res_a0) 3676 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), 3677 "r"(__ptid), "r"(__tls), "r"(__ctid), 3678 "i"(__NR_clone), "i"(__NR_exit) 3679 : "cc", "memory"); 3680 __res = __res_a0; 3681 } 3682 LSS_RETURN(int, __res); 3683 } 3684 #elif defined(__e2k__) 3685 3686 #undef _LSS_BODY 3687 #define _LSS_BODY(nr, type, name, ...) \ 3688 register unsigned long long __res; \ 3689 __asm__ __volatile__ \ 3690 ( \ 3691 "{\n\t" \ 3692 " sdisp %%ctpr1, 0x3\n\t" \ 3693 " addd, s 0x0, %[sys_num], %%b[0]\n\t" \ 3694 LSS_BODY_ASM##nr \ 3695 "}\n\t" \ 3696 "{\n\t" \ 3697 " call %%ctpr1, wbs = %#\n\t" \ 3698 "}\n\t" \ 3699 "{\n\t" \ 3700 " addd, s 0x0, %%b[0], %[res]\n\t" \ 3701 "}\n\t" \ 3702 : [res] "=r" (__res) \ 3703 : \ 3704 LSS_BODY_ARG##nr(__VA_ARGS__) \ 3705 [sys_num] "ri" (__NR_##name) \ 3706 : "ctpr1", "ctpr2", "ctpr3", \ 3707 "b[0]", "b[1]", "b[2]", "b[3]", \ 3708 "b[4]", "b[5]", "b[6]", "b[7]" \ 3709 ); \ 3710 LSS_RETURN(type, __res); 3711 3712 #undef LSS_BODY 3713 #define LSS_BODY(nr, type, name, args...) \ 3714 _LSS_BODY(nr, type, name, ## args) 3715 3716 #undef LSS_BODY_ASM0 3717 #undef LSS_BODY_ASM1 3718 #undef LSS_BODY_ASM2 3719 #undef LSS_BODY_ASM3 3720 #undef LSS_BODY_ASM4 3721 #undef LSS_BODY_ASM5 3722 #undef LSS_BODY_ASM6 3723 3724 #define LSS_BODY_ASM0 3725 #define LSS_BODY_ASM1 LSS_BODY_ASM0 \ 3726 " addd, s 0x0, %[arg1], %%b[1]\n\t" 3727 #define LSS_BODY_ASM2 LSS_BODY_ASM1 \ 3728 " addd, s 0x0, %[arg2], %%b[2]\n\t" 3729 #define LSS_BODY_ASM3 LSS_BODY_ASM2 \ 3730 " addd, s 0x0, %[arg3], %%b[3]\n\t" 3731 #define LSS_BODY_ASM4 LSS_BODY_ASM3 \ 3732 " addd, s 0x0, %[arg4], %%b[4]\n\t" 3733 #define LSS_BODY_ASM5 LSS_BODY_ASM4 \ 3734 " addd, s 0x0, %[arg5], %%b[5]\n\t" 3735 #define LSS_BODY_ASM6 LSS_BODY_ASM5 \ 3736 "}\n\t" \ 3737 "{\n\t" \ 3738 " addd, s 0x0, %[arg6], %%b[6]\n\t" 3739 3740 #undef LSS_SYSCALL_ARG 3741 #define LSS_SYSCALL_ARG(a) ((unsigned long long)(uintptr_t)(a)) 3742 3743 #undef LSS_BODY_ARG0 3744 #undef LSS_BODY_ARG1 3745 #undef LSS_BODY_ARG2 3746 #undef LSS_BODY_ARG3 3747 #undef LSS_BODY_ARG4 3748 #undef LSS_BODY_ARG5 3749 #undef LSS_BODY_ARG6 3750 3751 #define LSS_BODY_ARG0() 3752 #define LSS_BODY_ARG1(_arg1) \ 3753 [arg1] "ri" LSS_SYSCALL_ARG(_arg1), 3754 #define LSS_BODY_ARG2(_arg1, _arg2) \ 3755 LSS_BODY_ARG1(_arg1) \ 3756 [arg2] "ri" LSS_SYSCALL_ARG(_arg2), 3757 #define LSS_BODY_ARG3(_arg1, _arg2, _arg3) \ 3758 LSS_BODY_ARG2(_arg1, _arg2) \ 3759 [arg3] "ri" LSS_SYSCALL_ARG(_arg3), 3760 #define LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \ 3761 LSS_BODY_ARG3(_arg1, _arg2, _arg3) \ 3762 [arg4] "ri" LSS_SYSCALL_ARG(_arg4), 3763 #define LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \ 3764 LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \ 3765 [arg5] "ri" LSS_SYSCALL_ARG(_arg5), 3766 #define LSS_BODY_ARG6(_arg1, _arg2, _arg3, _arg4, _arg5, _arg6) \ 3767 LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \ 3768 [arg6] "ri" LSS_SYSCALL_ARG(_arg6), 3769 3770 #undef _syscall0 3771 #define _syscall0(type, name) \ 3772 type LSS_NAME(name)(void) { \ 3773 LSS_BODY(0, type, name); \ 3774 } 3775 3776 #undef _syscall1 3777 #define _syscall1(type, name, type1, arg1) \ 3778 type LSS_NAME(name)(type1 arg1) { \ 3779 LSS_BODY(1, type, name, arg1) \ 3780 } 3781 3782 #undef _syscall2 3783 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 3784 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 3785 LSS_BODY(2, type, name, arg1, arg2) \ 3786 } 3787 3788 #undef _syscall3 3789 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 3790 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 3791 LSS_BODY(3, type, name, arg1, arg2, arg3) \ 3792 } 3793 3794 #undef _syscall4 3795 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ 3796 type4, arg4) \ 3797 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 3798 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4) \ 3799 } 3800 3801 #undef _syscall5 3802 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ 3803 type4, arg4, type5, arg5) \ 3804 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3805 type5 arg5) { \ 3806 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5) \ 3807 } 3808 3809 #undef _syscall6 3810 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ 3811 type4, arg4, type5, arg5, type6, arg6) \ 3812 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3813 type5 arg5, type6 arg6) { \ 3814 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6) \ 3815 } 3816 LSS_NAME(clone)3817 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 3818 int flags, void *arg, int *parent_tidptr, 3819 void *newtls, int *child_tidptr) { 3820 unsigned long long __res; 3821 3822 __asm__ __volatile__ ( 3823 "{\n\t" 3824 " addd,s 0x0, %[nr_clone], %%b[0]\n\t" 3825 " addd,s 0x0, %[flags], %%db[1]\n\t" 3826 " addd,s 0x0, %[child_stack], %%db[2]\n\t" 3827 " addd,s 0x0, %[parent_tidptr], %%db[3]\n\t" 3828 " addd,s 0x0, %[child_tidptr], %%db[4]\n\t" 3829 " addd,s 0x0, %[newtls], %%db[5]\n\t" 3830 "}\n\t" 3831 /* if (fn == NULL) 3832 * return -EINVAL; 3833 */ 3834 3835 "{\n\t" 3836 " disp %%ctpr1, .L1\n\t" 3837 "}\n\t" 3838 "{\n\t" 3839 " cmpesb,s 0x0, %[fn], %%pred0\n\t" 3840 "}\n\t" 3841 "{\n\t" 3842 " ct %%ctpr1 ? %%pred0\n\t" 3843 "}\n\t" 3844 3845 /* if (child_stack == NULL) 3846 * return -EINVAL; 3847 */ 3848 "{\n\t" 3849 " cmpesb,s 0x0, %%db[2], %%pred0\n\t" 3850 "}\n\t" 3851 "{\n\t" 3852 " ct %%ctpr1 ? %%pred0\n\t" 3853 "}\n\t" 3854 3855 /* b[0] = syscall(%b[0] = __NR_clone, 3856 * %db[1] = flags, 3857 * %db[2] = child_stack, 3858 * %db[3] = parent_tidptr, 3859 * %db[4] = child_tidptr, 3860 * %db[5] = newtls) 3861 */ 3862 "{\n\t" 3863 " sdisp %%ctpr1, 0x3\n\t" 3864 "}\n\t" 3865 "{\n\t" 3866 " call %%ctpr1, wbs = %#\n\t" 3867 "}\n\t" 3868 3869 /* if (%[b0] != 0) 3870 * return %b[0]; 3871 */ 3872 "{\n\t" 3873 " disp %%ctpr1, .L2\n\t" 3874 " cmpesb,s 0x0, %%b[0], %%pred0\n\t" 3875 "}\n\t" 3876 "{\n\t" 3877 " ct %%ctpr1 ? ~%%pred0\n\t" 3878 "}\n\t" 3879 /* In the child, now. Call "fn(arg)". 3880 */ 3881 3882 "{\n\t" 3883 " movtd,s %[fn], %%ctpr1\n\t" 3884 "}\n\t" 3885 "{\n\t" 3886 " addd,s 0x0, %[arg], %%db[0]\n\t" 3887 "}\n\t" 3888 "{\n\t" 3889 " call %%ctpr1, wbs = %#\n\t" 3890 "}\n\t" 3891 /* Call _exit(%b[0]). 3892 */ 3893 3894 "{\n\t" 3895 " sdisp %%ctpr1, 0x3\n\t" 3896 " addd,s 0x0, %%b[0], %%b[1]\n\t" 3897 "}\n\t" 3898 "{\n\t" 3899 " addd,s 0x0, %[nr_exit], %%b[0]\n\t" 3900 "}\n\t" 3901 "{\n\t" 3902 " call %%ctpr1, wbs = %#\n\t" 3903 "}\n\t" 3904 "{\n\t" 3905 " disp %%ctpr1, .L2\n\t" 3906 " adds,s 0x0, 0x0, %%b[0]\n\t" 3907 "}\n\t" 3908 "{\n\t" 3909 " ct %%ctpr1\n\t" 3910 "}\n\t" 3911 ".L1:\n\t" 3912 "{\n\t" 3913 " addd,s 0x0, %[einval], %%b[0]\n\t" 3914 "}\n\t" 3915 ".L2:\n\t" 3916 "{\n\t" 3917 " addd,s 0x0, %%b[0], %[res]\n\t" 3918 "}\n\t" 3919 : [res] "=r" LSS_SYSCALL_ARG(__res) 3920 : [nr_clone] "ri" LSS_SYSCALL_ARG(__NR_clone) 3921 [arg] "ri" LSS_SYSCALL_ARG(arg) 3922 [nr_exit] "ri" LSS_SYSCALL_ARG(__NR_exit) 3923 [flags] "ri" LSS_SYSCALL_ARG(flags) 3924 [child_stack] "ri" LSS_SYSCALL_ARG(child_stack) 3925 [parent_tidptr] "ri" 3926 LSS_SYSCALL_ARG(parent_tidptr) 3927 [newtls] "ri" LSS_SYSCALL_ARG(newtls) 3928 [child_tidptr] "ri" 3929 LSS_SYSCALL_ARG(child_tidptr) 3930 [fn] "ri" LSS_SYSCALL_ARG(fn) 3931 [einval] "ri" LSS_SYSCALL_ARG(-EINVAL) 3932 : "ctpr1", "b[0]", "b[1]", "b[2]", "b[3]", 3933 "b[4]", "b[5]", "pred0"); 3934 LSS_RETURN(int, __res); 3935 } 3936 #elif defined(__loongarch_lp64) 3937 /* Most definitions of _syscallX() neglect to mark "memory" as being 3938 * clobbered. This causes problems with compilers, that do a better job 3939 * at optimizing across __asm__ calls. 3940 * So, we just have to redefine all of the _syscallX() macros. 3941 */ 3942 #undef LSS_REG 3943 #define LSS_REG(ar,a) register int64_t __r##ar __asm__("a"#ar) = (int64_t)a 3944 /* syscall is like subroutine calls, all caller-saved registers may be 3945 * clobbered, we should add them to the |Clobbers| list. 3946 * a0 is not included because it's in the output list. 3947 */ 3948 #define LSS_SYSCALL_CLOBBERS "t0", "t1", "t2", "t3", "t4", "t5", "t6", \ 3949 "t7", "t8", "memory" 3950 #undef LSS_BODY 3951 #define LSS_BODY(type,name,args...) \ 3952 register int64_t __res_a0 __asm__("a0"); \ 3953 int64_t __res; \ 3954 __asm__ __volatile__ ("li.d $a7, %1\n" \ 3955 "syscall 0x0\n" \ 3956 : "=r"(__res_a0) \ 3957 : "i"(__NR_##name) , ## args \ 3958 : LSS_SYSCALL_CLOBBERS); \ 3959 __res = __res_a0; \ 3960 LSS_RETURN(type, __res) 3961 #undef _syscall0 3962 #define _syscall0(type, name) \ 3963 type LSS_NAME(name)(void) { \ 3964 LSS_BODY(type, name); \ 3965 } 3966 #undef _syscall1 3967 #define _syscall1(type, name, type1, arg1) \ 3968 type LSS_NAME(name)(type1 arg1) { \ 3969 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ 3970 } 3971 #undef _syscall2 3972 #define _syscall2(type, name, type1, arg1, type2, arg2) \ 3973 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 3974 LSS_REG(0, arg1); LSS_REG(1, arg2); \ 3975 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ 3976 } 3977 #undef _syscall3 3978 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 3979 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 3980 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 3981 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ 3982 } 3983 #undef _syscall4 3984 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 3985 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 3986 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 3987 LSS_REG(3, arg4); \ 3988 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ 3989 } 3990 #undef _syscall5 3991 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 3992 type5,arg5) \ 3993 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 3994 type5 arg5) { \ 3995 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 3996 LSS_REG(3, arg4); LSS_REG(4, arg5); \ 3997 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 3998 "r"(__r4)); \ 3999 } 4000 #undef _syscall6 4001 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 4002 type5,arg5,type6,arg6) \ 4003 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 4004 type5 arg5, type6 arg6) { \ 4005 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ 4006 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ 4007 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 4008 "r"(__r4), "r"(__r5)); \ 4009 } 4010 LSS_NAME(clone)4011 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 4012 int flags, void *arg, int *parent_tidptr, 4013 void *newtls, int *child_tidptr) { 4014 int64_t __res; 4015 { 4016 register int64_t __res_a0 __asm__("a0"); 4017 register uint64_t __flags __asm__("a0") = flags; 4018 register void *__stack __asm__("a1") = child_stack; 4019 register void *__ptid __asm__("a2") = parent_tidptr; 4020 register void *__tls __asm__("a3") = newtls; 4021 register int *__ctid __asm__("a4") = child_tidptr; 4022 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be 4023 * used by the child. 4024 */ 4025 "addi.d %2, %2, -16\n" 4026 "st.d %1, %2, 8\n" 4027 "st.d %4, %2, 0\n" 4028 4029 /* %a0 = syscall(%a0 = flags, 4030 * %a1 = child_stack, 4031 * %a2 = parent_tidptr, 4032 * %a3 = newtls, 4033 * %a4 = child_tidptr) 4034 */ 4035 "li.d $a7, %8\n" 4036 "syscall 0x0\n" 4037 4038 /* if (%a0 != 0) 4039 * return %a0; 4040 */ 4041 "bnez $a0, 1f\n" 4042 4043 /* In the child, now. Call "fn(arg)". 4044 */ 4045 "ld.d $a0, $sp, 0\n" 4046 "ld.d $a1, $sp, 8\n" 4047 "addi.d $sp, $sp, 16\n" 4048 "jirl $ra, $a1, 0\n" 4049 4050 /* Call _exit(%a0). 4051 */ 4052 "li.d $a7, %9\n" 4053 "syscall 0x0\n" 4054 "1:\n" 4055 : "=r" (__res_a0) 4056 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), 4057 "r"(__ptid), "r"(__tls), "r"(__ctid), 4058 "i"(__NR_clone), "i"(__NR_exit) 4059 : LSS_SYSCALL_CLOBBERS); 4060 __res = __res_a0; 4061 } 4062 LSS_RETURN(int, __res); 4063 } 4064 4065 #endif 4066 #define __NR__exit __NR_exit 4067 #define __NR__gettid __NR_gettid 4068 #define __NR__mremap __NR_mremap _syscall1(void *,brk,void *,e)4069 LSS_INLINE _syscall1(void *, brk, void *, e) 4070 LSS_INLINE _syscall1(int, chdir, const char *,p) 4071 LSS_INLINE _syscall1(int, close, int, f) 4072 LSS_INLINE _syscall2(int, clock_getres, int, c, 4073 struct kernel_timespec*, t) 4074 LSS_INLINE _syscall2(int, clock_gettime, int, c, 4075 struct kernel_timespec*, t) 4076 LSS_INLINE _syscall1(int, dup, int, f) 4077 #if defined(__NR_dup2) 4078 // dup2 is polyfilled below when not available. 4079 LSS_INLINE _syscall2(int, dup2, int, s, 4080 int, d) 4081 #endif 4082 #if defined(__NR_dup3) 4083 LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f) 4084 #endif 4085 LSS_INLINE _syscall3(int, execve, const char*, f, 4086 const char*const*,a,const char*const*, e) 4087 LSS_INLINE _syscall1(int, _exit, int, e) 4088 LSS_INLINE _syscall1(int, exit_group, int, e) 4089 LSS_INLINE _syscall3(int, fcntl, int, f, 4090 int, c, long, a) 4091 #if defined(__NR_fork) 4092 // fork is polyfilled below when not available. 4093 LSS_INLINE _syscall0(pid_t, fork) 4094 #endif 4095 #if defined(__NR_fstat) 4096 LSS_INLINE _syscall2(int, fstat, int, f, 4097 struct kernel_stat*, b) 4098 #endif 4099 LSS_INLINE _syscall2(int, fstatfs, int, f, 4100 struct kernel_statfs*, b) 4101 #if defined(__x86_64__) 4102 /* Need to make sure off_t isn't truncated to 32-bits under x32. */ 4103 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) { 4104 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l)); 4105 } 4106 #else 4107 LSS_INLINE _syscall2(int, ftruncate, int, f, 4108 off_t, l) 4109 #endif _syscall6(int,futex,int *,u,int,o,int,v,struct kernel_timespec *,t,int *,u2,int,v2)4110 LSS_INLINE _syscall6(int, futex, int*, u, 4111 int, o, int, v, 4112 struct kernel_timespec*, t, 4113 int*, u2, int, v2) 4114 LSS_INLINE _syscall3(int, getdents, int, f, 4115 struct kernel_dirent*, d, int, c) 4116 LSS_INLINE _syscall3(int, getdents64, int, f, 4117 struct kernel_dirent64*, d, int, c) 4118 LSS_INLINE _syscall0(gid_t, getegid) 4119 LSS_INLINE _syscall0(uid_t, geteuid) 4120 LSS_INLINE _syscall2(int, getitimer, int, w, 4121 struct kernel_itimerval*, c) 4122 #if defined(__NR_getpgrp) 4123 LSS_INLINE _syscall0(pid_t, getpgrp) 4124 #endif 4125 LSS_INLINE _syscall0(pid_t, getpid) 4126 LSS_INLINE _syscall0(pid_t, getppid) 4127 LSS_INLINE _syscall2(int, getpriority, int, a, 4128 int, b) 4129 LSS_INLINE _syscall3(int, getresgid, gid_t *, r, 4130 gid_t *, e, gid_t *, s) 4131 LSS_INLINE _syscall3(int, getresuid, uid_t *, r, 4132 uid_t *, e, uid_t *, s) 4133 #if defined(__NR_getrlimit) 4134 LSS_INLINE _syscall2(int, getrlimit, int, r, 4135 struct kernel_rlimit*, l) 4136 #endif 4137 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p) 4138 LSS_INLINE _syscall0(pid_t, _gettid) 4139 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t, 4140 void*, tz) 4141 LSS_INLINE _syscall5(int, setxattr, const char *,p, 4142 const char *, n, const void *,v, 4143 size_t, s, int, f) 4144 LSS_INLINE _syscall5(int, lsetxattr, const char *,p, 4145 const char *, n, const void *,v, 4146 size_t, s, int, f) 4147 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p, 4148 const char *, n, void *, v, size_t, s) 4149 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p, 4150 const char *, n, void *, v, size_t, s) 4151 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p, 4152 char *, l, size_t, s) 4153 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p, 4154 char *, l, size_t, s) 4155 LSS_INLINE _syscall3(int, ioctl, int, d, 4156 int, r, void *, a) 4157 LSS_INLINE _syscall2(int, ioprio_get, int, which, 4158 int, who) 4159 LSS_INLINE _syscall3(int, ioprio_set, int, which, 4160 int, who, int, ioprio) 4161 LSS_INLINE _syscall2(int, kill, pid_t, p, 4162 int, s) 4163 #if defined(__x86_64__) 4164 /* Need to make sure off_t isn't truncated to 32-bits under x32. */ 4165 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) { 4166 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o), 4167 LSS_SYSCALL_ARG(w)); 4168 } 4169 #else 4170 LSS_INLINE _syscall3(off_t, lseek, int, f, 4171 off_t, o, int, w) 4172 #endif _syscall2(int,munmap,void *,s,size_t,l)4173 LSS_INLINE _syscall2(int, munmap, void*, s, 4174 size_t, l) 4175 LSS_INLINE _syscall6(long, move_pages, pid_t, p, 4176 unsigned long, n, void **,g, int *, d, 4177 int *, s, int, f) 4178 LSS_INLINE _syscall3(int, mprotect, const void *,a, 4179 size_t, l, int, p) 4180 LSS_INLINE _syscall5(void*, _mremap, void*, o, 4181 size_t, os, size_t, ns, 4182 unsigned long, f, void *, a) 4183 #if defined(__NR_open) 4184 // open is polyfilled below when not available. 4185 LSS_INLINE _syscall3(int, open, const char*, p, 4186 int, f, int, m) 4187 #endif 4188 #if defined(__NR_poll) 4189 // poll is polyfilled below when not available. 4190 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u, 4191 unsigned int, n, int, t) 4192 #endif 4193 #if defined(__NR_ppoll) 4194 LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u, 4195 unsigned int, n, const struct kernel_timespec *, t, 4196 const struct kernel_sigset_t *, sigmask, size_t, s) 4197 #endif 4198 LSS_INLINE _syscall5(int, prctl, int, option, 4199 unsigned long, arg2, 4200 unsigned long, arg3, 4201 unsigned long, arg4, 4202 unsigned long, arg5) 4203 LSS_INLINE _syscall4(long, ptrace, int, r, 4204 pid_t, p, void *, a, void *, d) 4205 #if defined(__NR_quotactl) 4206 // Defined on x86_64 / i386 only 4207 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special, 4208 int, id, caddr_t, addr) 4209 #endif 4210 LSS_INLINE _syscall3(ssize_t, read, int, f, 4211 void *, b, size_t, c) 4212 #if defined(__NR_readlink) 4213 // readlink is polyfilled below when not available. 4214 LSS_INLINE _syscall3(int, readlink, const char*, p, 4215 char*, b, size_t, s) 4216 #endif 4217 #if defined(__NR_readlinkat) 4218 LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b, 4219 size_t, s) 4220 #endif 4221 LSS_INLINE _syscall4(int, rt_sigaction, int, s, 4222 const struct kernel_sigaction*, a, 4223 struct kernel_sigaction*, o, size_t, c) 4224 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s, 4225 size_t, c) 4226 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h, 4227 const struct kernel_sigset_t*, s, 4228 struct kernel_sigset_t*, o, size_t, c) 4229 LSS_INLINE _syscall2(int, rt_sigsuspend, 4230 const struct kernel_sigset_t*, s, size_t, c) 4231 LSS_INLINE _syscall4(int, rt_sigtimedwait, const struct kernel_sigset_t*, s, 4232 siginfo_t*, i, const struct timespec*, t, size_t, c) 4233 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p, 4234 unsigned int, l, unsigned long *, m) 4235 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p, 4236 unsigned int, l, unsigned long *, m) 4237 LSS_INLINE _syscall0(int, sched_yield) 4238 LSS_INLINE _syscall1(long, set_tid_address, int *, t) 4239 LSS_INLINE _syscall1(int, setfsgid, gid_t, g) 4240 LSS_INLINE _syscall1(int, setfsuid, uid_t, u) 4241 LSS_INLINE _syscall1(int, setuid, uid_t, u) 4242 LSS_INLINE _syscall1(int, setgid, gid_t, g) 4243 LSS_INLINE _syscall3(int, setitimer, int, w, 4244 const struct kernel_itimerval*, n, 4245 struct kernel_itimerval*, o) 4246 LSS_INLINE _syscall2(int, setpgid, pid_t, p, 4247 pid_t, g) 4248 LSS_INLINE _syscall3(int, setpriority, int, a, 4249 int, b, int, p) 4250 LSS_INLINE _syscall3(int, setresgid, gid_t, r, 4251 gid_t, e, gid_t, s) 4252 LSS_INLINE _syscall3(int, setresuid, uid_t, r, 4253 uid_t, e, uid_t, s) 4254 #if defined(__NR_setrlimit) 4255 LSS_INLINE _syscall2(int, setrlimit, int, r, 4256 const struct kernel_rlimit*, l) 4257 #endif 4258 LSS_INLINE _syscall0(pid_t, setsid) 4259 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s, 4260 const stack_t*, o) 4261 #if defined(__NR_sigreturn) 4262 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u) 4263 #endif 4264 #if defined(__NR_stat) 4265 // stat and lstat are polyfilled below when not available. 4266 LSS_INLINE _syscall2(int, stat, const char*, f, 4267 struct kernel_stat*, b) 4268 #endif 4269 #if defined(__NR_lstat) 4270 LSS_INLINE _syscall2(int, lstat, const char*, f, 4271 struct kernel_stat*, b) 4272 #endif 4273 LSS_INLINE _syscall2(int, statfs, const char*, f, 4274 struct kernel_statfs*, b) 4275 LSS_INLINE _syscall3(int, tgkill, pid_t, p, 4276 pid_t, t, int, s) 4277 LSS_INLINE _syscall2(int, tkill, pid_t, p, 4278 int, s) 4279 #if defined(__NR_unlink) 4280 // unlink is polyfilled below when not available. 4281 LSS_INLINE _syscall1(int, unlink, const char*, f) 4282 #endif 4283 LSS_INLINE _syscall3(ssize_t, write, int, f, 4284 const void *, b, size_t, c) 4285 LSS_INLINE _syscall3(ssize_t, writev, int, f, 4286 const struct kernel_iovec*, v, size_t, c) 4287 #if defined(__NR_getcpu) 4288 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu, 4289 unsigned *, node, void *, unused) 4290 #endif 4291 #if defined(__NR_fadvise64) 4292 #if defined(__x86_64__) 4293 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ 4294 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len, 4295 int advice) { 4296 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset), 4297 (uint64_t)(len), LSS_SYSCALL_ARG(advice)); 4298 } 4299 #else 4300 LSS_INLINE _syscall4(int, fadvise64, 4301 int, fd, loff_t, offset, loff_t, len, int, advice) 4302 #endif 4303 #elif defined(__i386__) 4304 #define __NR__fadvise64_64 __NR_fadvise64_64 4305 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd, 4306 unsigned, offset_lo, unsigned, offset_hi, 4307 unsigned, len_lo, unsigned, len_hi, 4308 int, advice) 4309 4310 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, 4311 loff_t len, int advice) { 4312 return LSS_NAME(_fadvise64_64)(fd, 4313 (unsigned)offset, (unsigned)(offset >>32), 4314 (unsigned)len, (unsigned)(len >> 32), 4315 advice); 4316 } 4317 4318 #elif defined(__s390__) && !defined(__s390x__) 4319 #define __NR__fadvise64_64 __NR_fadvise64_64 4320 struct kernel_fadvise64_64_args { 4321 int fd; 4322 long long offset; 4323 long long len; 4324 int advice; 4325 }; 4326 4327 LSS_INLINE _syscall1(int, _fadvise64_64, 4328 struct kernel_fadvise64_64_args *args) 4329 4330 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, 4331 loff_t len, int advice) { 4332 struct kernel_fadvise64_64_args args = { fd, offset, len, advice }; 4333 return LSS_NAME(_fadvise64_64)(&args); 4334 } 4335 #endif 4336 #if defined(__NR_fallocate) 4337 #if defined(__x86_64__) 4338 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ LSS_NAME(fallocate)4339 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset, 4340 loff_t len) { 4341 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode), 4342 (uint64_t)(offset), (uint64_t)(len)); 4343 } 4344 #elif (defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) \ 4345 || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) \ 4346 || (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) \ 4347 || defined(__PPC__)) 4348 #define __NR__fallocate __NR_fallocate _syscall6(int,_fallocate,int,fd,int,mode,unsigned,offset_lo,unsigned,offset_hi,unsigned,len_lo,unsigned,len_hi)4349 LSS_INLINE _syscall6(int, _fallocate, int, fd, 4350 int, mode, 4351 unsigned, offset_lo, unsigned, offset_hi, 4352 unsigned, len_lo, unsigned, len_hi) 4353 4354 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode, 4355 loff_t offset, loff_t len) { 4356 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len }; 4357 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]); 4358 } 4359 #else _syscall4(int,fallocate,int,f,int,mode,loff_t,offset,loff_t,len)4360 LSS_INLINE _syscall4(int, fallocate, 4361 int, f, int, mode, loff_t, offset, loff_t, len) 4362 #endif 4363 #endif 4364 #if defined(__NR_getrandom) 4365 LSS_INLINE _syscall3(ssize_t, getrandom, void*, buffer, size_t, length, 4366 unsigned int, flags) 4367 #endif 4368 #if defined(__NR_newfstatat) 4369 LSS_INLINE _syscall4(int, newfstatat, int, d, 4370 const char *, p, 4371 struct kernel_stat*, b, int, f) 4372 #endif 4373 #if defined(__NR_statx) 4374 LSS_INLINE _syscall5(int, statx, int, d, 4375 const char *, p, 4376 int, f, int, m, 4377 struct kernel_statx*, b) 4378 #endif 4379 #if defined(__x86_64__) || defined(__s390x__) 4380 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, 4381 gid_t *egid, 4382 gid_t *sgid) { 4383 return LSS_NAME(getresgid)(rgid, egid, sgid); 4384 } 4385 LSS_NAME(getresuid32)4386 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, 4387 uid_t *euid, 4388 uid_t *suid) { 4389 return LSS_NAME(getresuid)(ruid, euid, suid); 4390 } 4391 LSS_NAME(setfsgid32)4392 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { 4393 return LSS_NAME(setfsgid)(gid); 4394 } 4395 LSS_NAME(setfsuid32)4396 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { 4397 return LSS_NAME(setfsuid)(uid); 4398 } 4399 LSS_NAME(setresgid32)4400 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { 4401 return LSS_NAME(setresgid)(rgid, egid, sgid); 4402 } 4403 LSS_NAME(setresuid32)4404 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { 4405 return LSS_NAME(setresuid)(ruid, euid, suid); 4406 } 4407 LSS_NAME(sigaction)4408 LSS_INLINE int LSS_NAME(sigaction)(int signum, 4409 const struct kernel_sigaction *act, 4410 struct kernel_sigaction *oldact) { 4411 #if defined(__x86_64__) 4412 /* On x86_64, the kernel requires us to always set our own 4413 * SA_RESTORER in order to be able to return from a signal handler. 4414 * This function must have a "magic" signature that the "gdb" 4415 * (and maybe the kernel?) can recognize. 4416 */ 4417 if (act != NULL && !(act->sa_flags & SA_RESTORER)) { 4418 struct kernel_sigaction a = *act; 4419 a.sa_flags |= SA_RESTORER; 4420 a.sa_restorer = LSS_NAME(restore_rt)(); 4421 return LSS_NAME(rt_sigaction)(signum, &a, oldact, 4422 (KERNEL_NSIG+7)/8); 4423 } else 4424 #endif 4425 return LSS_NAME(rt_sigaction)(signum, act, oldact, 4426 (KERNEL_NSIG+7)/8); 4427 } 4428 LSS_NAME(sigpending)4429 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { 4430 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); 4431 } 4432 LSS_NAME(sigsuspend)4433 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { 4434 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); 4435 } 4436 #endif 4437 #if defined(__NR_rt_sigprocmask) LSS_NAME(sigprocmask)4438 LSS_INLINE int LSS_NAME(sigprocmask)(int how, 4439 const struct kernel_sigset_t *set, 4440 struct kernel_sigset_t *oldset) { 4441 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); 4442 } 4443 #endif 4444 #if defined(__NR_rt_sigtimedwait) LSS_NAME(sigtimedwait)4445 LSS_INLINE int LSS_NAME(sigtimedwait)(const struct kernel_sigset_t *set, 4446 siginfo_t *info, 4447 const struct timespec *timeout) { 4448 return LSS_NAME(rt_sigtimedwait)(set, info, timeout, (KERNEL_NSIG+7)/8); 4449 } 4450 #endif 4451 #if defined(__NR_wait4) _syscall4(pid_t,wait4,pid_t,p,int *,s,int,o,struct kernel_rusage *,r)4452 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p, 4453 int*, s, int, o, 4454 struct kernel_rusage*, r) 4455 #endif 4456 #if defined(__NR_openat) 4457 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m) 4458 #endif 4459 #if defined(__NR_unlinkat) 4460 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f) 4461 #endif 4462 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ 4463 (defined(__s390__) && !defined(__s390x__)) 4464 #define __NR__getresgid32 __NR_getresgid32 4465 #define __NR__getresuid32 __NR_getresuid32 4466 #define __NR__setfsgid32 __NR_setfsgid32 4467 #define __NR__setfsuid32 __NR_setfsuid32 4468 #define __NR__setresgid32 __NR_setresgid32 4469 #define __NR__setresuid32 __NR_setresuid32 4470 #if defined(__ARM_EABI__) 4471 LSS_INLINE _syscall2(int, ugetrlimit, int, r, 4472 struct kernel_rlimit*, l) 4473 #endif 4474 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r, 4475 gid_t *, e, gid_t *, s) 4476 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r, 4477 uid_t *, e, uid_t *, s) 4478 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f) 4479 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f) 4480 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r, 4481 gid_t, e, gid_t, s) 4482 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r, 4483 uid_t, e, uid_t, s) 4484 4485 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, 4486 gid_t *egid, 4487 gid_t *sgid) { 4488 int rc; 4489 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 && 4490 LSS_ERRNO == ENOSYS) { 4491 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) { 4492 return EFAULT; 4493 } 4494 // Clear the high bits first, since getresgid only sets 16 bits 4495 *rgid = *egid = *sgid = 0; 4496 rc = LSS_NAME(getresgid)(rgid, egid, sgid); 4497 } 4498 return rc; 4499 } 4500 LSS_NAME(getresuid32)4501 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, 4502 uid_t *euid, 4503 uid_t *suid) { 4504 int rc; 4505 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 && 4506 LSS_ERRNO == ENOSYS) { 4507 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) { 4508 return EFAULT; 4509 } 4510 // Clear the high bits first, since getresuid only sets 16 bits 4511 *ruid = *euid = *suid = 0; 4512 rc = LSS_NAME(getresuid)(ruid, euid, suid); 4513 } 4514 return rc; 4515 } 4516 LSS_NAME(setfsgid32)4517 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { 4518 int rc; 4519 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 && 4520 LSS_ERRNO == ENOSYS) { 4521 if ((unsigned int)gid & ~0xFFFFu) { 4522 rc = EINVAL; 4523 } else { 4524 rc = LSS_NAME(setfsgid)(gid); 4525 } 4526 } 4527 return rc; 4528 } 4529 LSS_NAME(setfsuid32)4530 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { 4531 int rc; 4532 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 && 4533 LSS_ERRNO == ENOSYS) { 4534 if ((unsigned int)uid & ~0xFFFFu) { 4535 rc = EINVAL; 4536 } else { 4537 rc = LSS_NAME(setfsuid)(uid); 4538 } 4539 } 4540 return rc; 4541 } 4542 LSS_NAME(setresgid32)4543 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { 4544 int rc; 4545 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 && 4546 LSS_ERRNO == ENOSYS) { 4547 if ((unsigned int)rgid & ~0xFFFFu || 4548 (unsigned int)egid & ~0xFFFFu || 4549 (unsigned int)sgid & ~0xFFFFu) { 4550 rc = EINVAL; 4551 } else { 4552 rc = LSS_NAME(setresgid)(rgid, egid, sgid); 4553 } 4554 } 4555 return rc; 4556 } 4557 LSS_NAME(setresuid32)4558 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { 4559 int rc; 4560 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 && 4561 LSS_ERRNO == ENOSYS) { 4562 if ((unsigned int)ruid & ~0xFFFFu || 4563 (unsigned int)euid & ~0xFFFFu || 4564 (unsigned int)suid & ~0xFFFFu) { 4565 rc = EINVAL; 4566 } else { 4567 rc = LSS_NAME(setresuid)(ruid, euid, suid); 4568 } 4569 } 4570 return rc; 4571 } 4572 #endif LSS_NAME(sigemptyset)4573 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) { 4574 memset(&set->sig, 0, sizeof(set->sig)); 4575 return 0; 4576 } 4577 LSS_NAME(sigfillset)4578 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) { 4579 memset(&set->sig, -1, sizeof(set->sig)); 4580 return 0; 4581 } 4582 LSS_NAME(sigaddset)4583 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set, 4584 int signum) { 4585 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) { 4586 LSS_ERRNO = EINVAL; 4587 return -1; 4588 } else { 4589 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] 4590 |= 1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0]))); 4591 return 0; 4592 } 4593 } 4594 LSS_NAME(sigdelset)4595 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set, 4596 int signum) { 4597 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) { 4598 LSS_ERRNO = EINVAL; 4599 return -1; 4600 } else { 4601 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] 4602 &= ~(1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])))); 4603 return 0; 4604 } 4605 } 4606 LSS_NAME(sigismember)4607 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set, 4608 int signum) { 4609 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) { 4610 LSS_ERRNO = EINVAL; 4611 return -1; 4612 } else { 4613 return !!(set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] & 4614 (1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0]))))); 4615 } 4616 } 4617 #if defined(__i386__) || \ 4618 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ 4619 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ 4620 defined(__PPC__) || \ 4621 (defined(__s390__) && !defined(__s390x__)) || defined(__e2k__) 4622 #define __NR__sigaction __NR_sigaction 4623 #define __NR__sigpending __NR_sigpending 4624 #define __NR__sigsuspend __NR_sigsuspend 4625 #define __NR__socketcall __NR_socketcall _syscall2(int,fstat64,int,f,struct kernel_stat64 *,b)4626 LSS_INLINE _syscall2(int, fstat64, int, f, 4627 struct kernel_stat64 *, b) 4628 LSS_INLINE _syscall5(int, _llseek, uint, fd, 4629 unsigned long, hi, unsigned long, lo, 4630 loff_t *, res, uint, wh) 4631 #if defined(__s390__) && !defined(__s390x__) 4632 /* On s390, mmap2() arguments are passed in memory. */ 4633 LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d, 4634 off_t o) { 4635 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l, 4636 (unsigned long) p, (unsigned long) f, 4637 (unsigned long) d, (unsigned long) o }; 4638 LSS_REG(2, buf); 4639 LSS_BODY(void*, mmap2, "0"(__r2)); 4640 } 4641 #else 4642 #define __NR__mmap2 __NR_mmap2 4643 LSS_INLINE _syscall6(void*, _mmap2, void*, s, 4644 size_t, l, int, p, 4645 int, f, int, d, 4646 off_t, o) 4647 #endif _syscall3(int,_sigaction,int,s,const struct kernel_old_sigaction *,a,struct kernel_old_sigaction *,o)4648 LSS_INLINE _syscall3(int, _sigaction, int, s, 4649 const struct kernel_old_sigaction*, a, 4650 struct kernel_old_sigaction*, o) 4651 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s) 4652 #ifdef __PPC__ 4653 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s) 4654 #else 4655 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a, 4656 int, b, 4657 unsigned long, s) 4658 #endif 4659 LSS_INLINE _syscall2(int, stat64, const char *, p, 4660 struct kernel_stat64 *, b) 4661 4662 LSS_INLINE int LSS_NAME(sigaction)(int signum, 4663 const struct kernel_sigaction *act, 4664 struct kernel_sigaction *oldact) { 4665 int old_errno = LSS_ERRNO; 4666 int rc; 4667 struct kernel_sigaction a; 4668 if (act != NULL) { 4669 a = *act; 4670 #ifdef __i386__ 4671 /* On i386, the kernel requires us to always set our own 4672 * SA_RESTORER when using realtime signals. Otherwise, it does not 4673 * know how to return from a signal handler. This function must have 4674 * a "magic" signature that the "gdb" (and maybe the kernel?) can 4675 * recognize. 4676 * Apparently, a SA_RESTORER is implicitly set by the kernel, when 4677 * using non-realtime signals. 4678 * 4679 * TODO: Test whether ARM needs a restorer 4680 */ 4681 if (!(a.sa_flags & SA_RESTORER)) { 4682 a.sa_flags |= SA_RESTORER; 4683 a.sa_restorer = (a.sa_flags & SA_SIGINFO) 4684 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)(); 4685 } 4686 #endif 4687 } 4688 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact, 4689 (KERNEL_NSIG+7)/8); 4690 if (rc < 0 && LSS_ERRNO == ENOSYS) { 4691 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa; 4692 if (!act) { 4693 ptr_a = NULL; 4694 } else { 4695 oa.sa_handler_ = act->sa_handler_; 4696 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask)); 4697 #ifndef __mips__ 4698 oa.sa_restorer = act->sa_restorer; 4699 #endif 4700 oa.sa_flags = act->sa_flags; 4701 } 4702 if (!oldact) { 4703 ptr_oa = NULL; 4704 } 4705 LSS_ERRNO = old_errno; 4706 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa); 4707 if (rc == 0 && oldact) { 4708 if (act) { 4709 memcpy(oldact, act, sizeof(*act)); 4710 } else { 4711 memset(oldact, 0, sizeof(*oldact)); 4712 } 4713 oldact->sa_handler_ = ptr_oa->sa_handler_; 4714 oldact->sa_flags = ptr_oa->sa_flags; 4715 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask)); 4716 #ifndef __mips__ 4717 oldact->sa_restorer = ptr_oa->sa_restorer; 4718 #endif 4719 } 4720 } 4721 return rc; 4722 } 4723 LSS_NAME(sigpending)4724 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { 4725 int old_errno = LSS_ERRNO; 4726 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); 4727 if (rc < 0 && LSS_ERRNO == ENOSYS) { 4728 LSS_ERRNO = old_errno; 4729 LSS_NAME(sigemptyset)(set); 4730 rc = LSS_NAME(_sigpending)(&set->sig[0]); 4731 } 4732 return rc; 4733 } 4734 LSS_NAME(sigsuspend)4735 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { 4736 int olderrno = LSS_ERRNO; 4737 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); 4738 if (rc < 0 && LSS_ERRNO == ENOSYS) { 4739 LSS_ERRNO = olderrno; 4740 rc = LSS_NAME(_sigsuspend)( 4741 #ifndef __PPC__ 4742 set, 0, 4743 #endif 4744 set->sig[0]); 4745 } 4746 return rc; 4747 } 4748 #endif 4749 #if defined(__i386__) || \ 4750 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ 4751 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ 4752 defined(__PPC__) || \ 4753 (defined(__s390__) && !defined(__s390x__)) 4754 /* On these architectures, implement mmap() with mmap2(). */ LSS_NAME(mmap)4755 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, 4756 int64_t o) { 4757 if (o % 4096) { 4758 LSS_ERRNO = EINVAL; 4759 return (void *) -1; 4760 } 4761 return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096)); 4762 } 4763 #elif defined(__s390x__) 4764 /* On s390x, mmap() arguments are passed in memory. */ LSS_NAME(mmap)4765 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, 4766 int64_t o) { 4767 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l, 4768 (unsigned long) p, (unsigned long) f, 4769 (unsigned long) d, (unsigned long) o }; 4770 LSS_REG(2, buf); 4771 LSS_BODY(void*, mmap, "0"(__r2)); 4772 } 4773 #elif defined(__x86_64__) 4774 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */ LSS_NAME(mmap)4775 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, 4776 int64_t o) { 4777 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l), 4778 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f), 4779 LSS_SYSCALL_ARG(d), (uint64_t)(o)); 4780 } 4781 #else 4782 /* Remaining 64-bit architectures. */ _syscall6(void *,mmap,void *,addr,size_t,length,int,prot,int,flags,int,fd,int64_t,offset)4783 LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot, 4784 int, flags, int, fd, int64_t, offset) 4785 #endif 4786 #if defined(__PPC__) 4787 #undef LSS_SC_LOADARGS_0 4788 #define LSS_SC_LOADARGS_0(dummy...) 4789 #undef LSS_SC_LOADARGS_1 4790 #define LSS_SC_LOADARGS_1(arg1) \ 4791 __sc_4 = (unsigned long) (arg1) 4792 #undef LSS_SC_LOADARGS_2 4793 #define LSS_SC_LOADARGS_2(arg1, arg2) \ 4794 LSS_SC_LOADARGS_1(arg1); \ 4795 __sc_5 = (unsigned long) (arg2) 4796 #undef LSS_SC_LOADARGS_3 4797 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \ 4798 LSS_SC_LOADARGS_2(arg1, arg2); \ 4799 __sc_6 = (unsigned long) (arg3) 4800 #undef LSS_SC_LOADARGS_4 4801 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \ 4802 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \ 4803 __sc_7 = (unsigned long) (arg4) 4804 #undef LSS_SC_LOADARGS_5 4805 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \ 4806 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \ 4807 __sc_8 = (unsigned long) (arg5) 4808 #undef LSS_SC_BODY 4809 #define LSS_SC_BODY(nr, type, opt, args...) \ 4810 long __sc_ret, __sc_err; \ 4811 { \ 4812 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \ 4813 register unsigned long __sc_3 __asm__ ("r3") = opt; \ 4814 register unsigned long __sc_4 __asm__ ("r4"); \ 4815 register unsigned long __sc_5 __asm__ ("r5"); \ 4816 register unsigned long __sc_6 __asm__ ("r6"); \ 4817 register unsigned long __sc_7 __asm__ ("r7"); \ 4818 register unsigned long __sc_8 __asm__ ("r8"); \ 4819 LSS_SC_LOADARGS_##nr(args); \ 4820 __asm__ __volatile__ \ 4821 ("stwu 1, -48(1)\n\t" \ 4822 "stw 4, 20(1)\n\t" \ 4823 "stw 5, 24(1)\n\t" \ 4824 "stw 6, 28(1)\n\t" \ 4825 "stw 7, 32(1)\n\t" \ 4826 "stw 8, 36(1)\n\t" \ 4827 "addi 4, 1, 20\n\t" \ 4828 "sc\n\t" \ 4829 "mfcr %0" \ 4830 : "=&r" (__sc_0), \ 4831 "=&r" (__sc_3), "=&r" (__sc_4), \ 4832 "=&r" (__sc_5), "=&r" (__sc_6), \ 4833 "=&r" (__sc_7), "=&r" (__sc_8) \ 4834 : LSS_ASMINPUT_##nr \ 4835 : "cr0", "ctr", "memory"); \ 4836 __sc_ret = __sc_3; \ 4837 __sc_err = __sc_0; \ 4838 } \ 4839 LSS_RETURN(type, __sc_ret, __sc_err) 4840 4841 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, 4842 int flags){ 4843 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags); 4844 } 4845 LSS_NAME(sendmsg)4846 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, 4847 const struct kernel_msghdr *msg, 4848 int flags) { 4849 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags); 4850 } 4851 4852 // TODO(csilvers): why is this ifdef'ed out? 4853 #if 0 4854 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, 4855 int flags, 4856 const struct kernel_sockaddr *to, 4857 unsigned int tolen) { 4858 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen); 4859 } 4860 #endif 4861 LSS_NAME(shutdown)4862 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { 4863 LSS_SC_BODY(2, int, 13, s, how); 4864 } 4865 LSS_NAME(socket)4866 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { 4867 LSS_SC_BODY(3, int, 1, domain, type, protocol); 4868 } 4869 LSS_NAME(socketpair)4870 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, 4871 int sv[2]) { 4872 LSS_SC_BODY(4, int, 8, d, type, protocol, sv); 4873 } 4874 #endif 4875 #if defined(__NR_recvmsg) _syscall3(ssize_t,recvmsg,int,s,struct kernel_msghdr *,msg,int,flags)4876 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg, 4877 int, flags) 4878 #endif 4879 #if defined(__NR_sendmsg) 4880 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*, 4881 msg, int, flags) 4882 #endif 4883 #if defined(__NR_sendto) 4884 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len, 4885 int, flags, const struct kernel_sockaddr*, to, 4886 unsigned int, tolen) 4887 #endif 4888 #if defined(__NR_shutdown) 4889 LSS_INLINE _syscall2(int, shutdown, int, s, int, how) 4890 #endif 4891 #if defined(__NR_socket) 4892 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol) 4893 #endif 4894 #if defined(__NR_socketpair) 4895 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol, 4896 int*, sv) 4897 #endif 4898 4899 #if defined(__NR_socketcall) 4900 LSS_INLINE _syscall2(int, _socketcall, int, c, 4901 va_list, a) 4902 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) { 4903 int rc; 4904 va_list ap; 4905 va_start(ap, op); 4906 rc = LSS_NAME(_socketcall)(op, ap); 4907 va_end(ap); 4908 return rc; 4909 } 4910 4911 # if !defined(__NR_recvmsg) LSS_NAME(recvmsg)4912 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, 4913 int flags){ 4914 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags); 4915 } 4916 # endif 4917 # if !defined(__NR_sendmsg) LSS_NAME(sendmsg)4918 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, 4919 const struct kernel_msghdr *msg, 4920 int flags) { 4921 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags); 4922 } 4923 # endif 4924 # if !defined(__NR_sendto) LSS_NAME(sendto)4925 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, 4926 int flags, 4927 const struct kernel_sockaddr *to, 4928 unsigned int tolen) { 4929 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen); 4930 } 4931 # endif 4932 # if !defined(__NR_shutdown) LSS_NAME(shutdown)4933 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { 4934 return LSS_NAME(socketcall)(13, s, how); 4935 } 4936 # endif 4937 # if !defined(__NR_socket) LSS_NAME(socket)4938 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { 4939 return LSS_NAME(socketcall)(1, domain, type, protocol); 4940 } 4941 # endif 4942 # if !defined(__NR_socketpair) LSS_NAME(socketpair)4943 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, 4944 int sv[2]) { 4945 return LSS_NAME(socketcall)(8, d, type, protocol, sv); 4946 } 4947 # endif 4948 #endif 4949 #if defined(__NR_fstatat64) _syscall4(int,fstatat64,int,d,const char *,p,struct kernel_stat64 *,b,int,f)4950 LSS_INLINE _syscall4(int, fstatat64, int, d, 4951 const char *, p, 4952 struct kernel_stat64 *, b, int, f) 4953 #endif 4954 #if defined(__NR_waitpid) 4955 // waitpid is polyfilled below when not available. 4956 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p, 4957 int*, s, int, o) 4958 #endif 4959 #if defined(__mips__) 4960 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns 4961 * both file handles through CPU registers. 4962 */ 4963 LSS_INLINE int LSS_NAME(pipe)(int *p) { 4964 register unsigned long __v0 __asm__("$2") = __NR_pipe; 4965 register unsigned long __v1 __asm__("$3"); 4966 register unsigned long __r7 __asm__("$7"); 4967 __asm__ __volatile__ ("syscall\n" 4968 : "=r"(__v0), "=r"(__v1), "=r" (__r7) 4969 : "0"(__v0) 4970 : "$8", "$9", "$10", "$11", "$12", 4971 "$13", "$14", "$15", "$24", "$25", "memory"); 4972 if (__r7) { 4973 unsigned long __errnovalue = __v0; 4974 LSS_ERRNO = __errnovalue; 4975 return -1; 4976 } else { 4977 p[0] = __v0; 4978 p[1] = __v1; 4979 return 0; 4980 } 4981 } 4982 #elif defined(__NR_pipe) 4983 // pipe is polyfilled below when not available. 4984 LSS_INLINE _syscall1(int, pipe, int *, p) 4985 #endif 4986 #if defined(__NR_pipe2) _syscall2(int,pipe2,int *,pipefd,int,flags)4987 LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags) 4988 #endif 4989 /* TODO(csilvers): see if ppc can/should support this as well */ 4990 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ 4991 defined(__ARM_EABI__) || \ 4992 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \ 4993 (defined(__s390__) && !defined(__s390x__)) 4994 #define __NR__statfs64 __NR_statfs64 4995 #define __NR__fstatfs64 __NR_fstatfs64 4996 LSS_INLINE _syscall3(int, _statfs64, const char*, p, 4997 size_t, s,struct kernel_statfs64*, b) 4998 LSS_INLINE _syscall3(int, _fstatfs64, int, f, 4999 size_t, s,struct kernel_statfs64*, b) 5000 LSS_INLINE int LSS_NAME(statfs64)(const char *p, 5001 struct kernel_statfs64 *b) { 5002 return LSS_NAME(_statfs64)(p, sizeof(*b), b); 5003 } LSS_NAME(fstatfs64)5004 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) { 5005 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b); 5006 } 5007 #endif 5008 LSS_NAME(execv)5009 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) { 5010 extern char **environ; 5011 return LSS_NAME(execve)(path, argv, (const char *const *)environ); 5012 } 5013 LSS_NAME(gettid)5014 LSS_INLINE pid_t LSS_NAME(gettid)(void) { 5015 pid_t tid = LSS_NAME(_gettid)(); 5016 if (tid != -1) { 5017 return tid; 5018 } 5019 return LSS_NAME(getpid)(); 5020 } 5021 LSS_NAME(mremap)5022 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size, 5023 size_t new_size, int flags, ...) { 5024 va_list ap; 5025 void *new_address, *rc; 5026 va_start(ap, flags); 5027 new_address = va_arg(ap, void *); 5028 rc = LSS_NAME(_mremap)(old_address, old_size, new_size, 5029 (unsigned long)flags, new_address); 5030 va_end(ap); 5031 return rc; 5032 } 5033 LSS_NAME(ptrace_detach)5034 LSS_INLINE long LSS_NAME(ptrace_detach)(pid_t pid) { 5035 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it 5036 * then sends job control signals to the real parent, rather than to 5037 * the tracer. We reduce the risk of this happening by starting a 5038 * whole new time slice, and then quickly sending a SIGCONT signal 5039 * right after detaching from the tracee. 5040 * 5041 * We use tkill to ensure that we only issue a wakeup for the thread being 5042 * detached. Large multi threaded apps can take a long time in the kernel 5043 * processing SIGCONT. 5044 */ 5045 long rc; 5046 int err; 5047 LSS_NAME(sched_yield)(); 5048 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0); 5049 err = LSS_ERRNO; 5050 LSS_NAME(tkill)(pid, SIGCONT); 5051 /* Old systems don't have tkill */ 5052 if (LSS_ERRNO == ENOSYS) 5053 LSS_NAME(kill)(pid, SIGCONT); 5054 LSS_ERRNO = err; 5055 return rc; 5056 } 5057 LSS_NAME(raise)5058 LSS_INLINE int LSS_NAME(raise)(int sig) { 5059 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig); 5060 } 5061 LSS_NAME(setpgrp)5062 LSS_INLINE int LSS_NAME(setpgrp)(void) { 5063 return LSS_NAME(setpgid)(0, 0); 5064 } 5065 5066 #if defined(__x86_64__) 5067 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ LSS_NAME(pread64)5068 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) { 5069 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), 5070 LSS_SYSCALL_ARG(c), (uint64_t)(o)); 5071 } 5072 LSS_NAME(pwrite64)5073 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c, 5074 loff_t o) { 5075 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), 5076 LSS_SYSCALL_ARG(c), (uint64_t)(o)); 5077 } 5078 LSS_NAME(readahead)5079 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, size_t c) { 5080 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o), 5081 LSS_SYSCALL_ARG(c)); 5082 } 5083 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64 _syscall4(ssize_t,pread64,int,f,void *,b,size_t,c,loff_t,o)5084 LSS_INLINE _syscall4(ssize_t, pread64, int, f, 5085 void *, b, size_t, c, 5086 loff_t, o) 5087 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f, 5088 const void *, b, size_t, c, 5089 loff_t, o) 5090 LSS_INLINE _syscall3(int, readahead, int, f, 5091 loff_t, o, unsigned, c) 5092 #else 5093 #define __NR__pread64 __NR_pread64 5094 #define __NR__pwrite64 __NR_pwrite64 5095 #define __NR__readahead __NR_readahead 5096 #if defined(__ARM_EABI__) || defined(__mips__) 5097 /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register 5098 * pair. Hence these calls ignore their fourth argument (r3) so that their 5099 * fifth and sixth make such a pair (r4,r5). 5100 */ 5101 #define LSS_LLARG_PAD 0, 5102 LSS_INLINE _syscall6(ssize_t, _pread64, int, f, 5103 void *, b, size_t, c, 5104 unsigned, skip, unsigned, o1, unsigned, o2) 5105 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f, 5106 const void *, b, size_t, c, 5107 unsigned, skip, unsigned, o1, unsigned, o2) 5108 LSS_INLINE _syscall5(int, _readahead, int, f, 5109 unsigned, skip, 5110 unsigned, o1, unsigned, o2, size_t, c) 5111 #else 5112 #define LSS_LLARG_PAD 5113 LSS_INLINE _syscall5(ssize_t, _pread64, int, f, 5114 void *, b, size_t, c, unsigned, o1, 5115 unsigned, o2) 5116 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f, 5117 const void *, b, size_t, c, unsigned, o1, 5118 unsigned, o2) 5119 LSS_INLINE _syscall4(int, _readahead, int, f, 5120 unsigned, o1, unsigned, o2, size_t, c) 5121 #endif 5122 /* We force 64bit-wide parameters onto the stack, then access each 5123 * 32-bit component individually. This guarantees that we build the 5124 * correct parameters independent of the native byte-order of the 5125 * underlying architecture. 5126 */ 5127 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count, 5128 loff_t off) { 5129 union { loff_t off; unsigned arg[2]; } o = { off }; 5130 return LSS_NAME(_pread64)(fd, buf, count, 5131 LSS_LLARG_PAD o.arg[0], o.arg[1]); 5132 } 5133 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf, 5134 size_t count, loff_t off) { 5135 union { loff_t off; unsigned arg[2]; } o = { off }; 5136 return LSS_NAME(_pwrite64)(fd, buf, count, 5137 LSS_LLARG_PAD o.arg[0], o.arg[1]); 5138 } 5139 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, size_t count) { 5140 union { loff_t off; unsigned arg[2]; } o = { off }; 5141 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], count); 5142 } 5143 #endif 5144 #endif 5145 5146 /* 5147 * Polyfills for deprecated syscalls. 5148 */ 5149 5150 #if !defined(__NR_dup2) 5151 LSS_INLINE int LSS_NAME(dup2)(int s, int d) { 5152 return LSS_NAME(dup3)(s, d, 0); 5153 } 5154 #endif 5155 5156 #if !defined(__NR_open) LSS_NAME(open)5157 LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) { 5158 return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode); 5159 } 5160 #endif 5161 5162 #if !defined(__NR_unlink) LSS_NAME(unlink)5163 LSS_INLINE int LSS_NAME(unlink)(const char *pathname) { 5164 return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0); 5165 } 5166 #endif 5167 5168 #if !defined(__NR_readlink) LSS_NAME(readlink)5169 LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer, 5170 size_t size) { 5171 return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size); 5172 } 5173 #endif 5174 5175 #if !defined(__NR_pipe) LSS_NAME(pipe)5176 LSS_INLINE int LSS_NAME(pipe)(int *pipefd) { 5177 return LSS_NAME(pipe2)(pipefd, 0); 5178 } 5179 #endif 5180 5181 #if !defined(__NR_poll) LSS_NAME(poll)5182 LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds, 5183 int timeout) { 5184 struct kernel_timespec timeout_ts; 5185 struct kernel_timespec *timeout_ts_p = NULL; 5186 5187 if (timeout >= 0) { 5188 timeout_ts.tv_sec = timeout / 1000; 5189 timeout_ts.tv_nsec = (timeout % 1000) * 1000000; 5190 timeout_ts_p = &timeout_ts; 5191 } 5192 return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0); 5193 } 5194 #endif 5195 5196 #if defined(__NR_statx) 5197 /* copy the contents of kernel_statx to the kernel_stat structure. */ LSS_NAME(cp_stat_statx)5198 LSS_INLINE void LSS_NAME(cp_stat_statx)(struct kernel_stat *to, 5199 struct kernel_statx *from) { 5200 memset(to, 0, sizeof(struct kernel_stat)); 5201 to->st_dev = (kernel_dev_t)((from->stx_dev_minor & 0xff) | 5202 ((from->stx_dev_major & 0xfff) << 8) | 5203 ((from->stx_dev_minor & ~0xffu) << 12)); 5204 to->st_rdev = (kernel_dev_t)((from->stx_rdev_minor & 0xff) | 5205 ((from->stx_rdev_major & 0xfff) << 8) | 5206 ((from->stx_rdev_minor & ~0xffu) << 12)); 5207 to->st_ino = (kernel_ino_t)from->stx_ino; 5208 to->st_mode = (kernel_mode_t)from->stx_mode; 5209 to->st_nlink = (kernel_nlink_t)from->stx_nlink; 5210 to->st_uid = (kernel_uid_t)from->stx_uid; 5211 to->st_gid = (kernel_gid_t)from->stx_gid; 5212 to->st_atime_ = (kernel_time_t)(from->stx_atime.tv_sec); 5213 to->st_atime_nsec_ = from->stx_atime.tv_nsec; 5214 to->st_mtime_ = (kernel_time_t)(from->stx_mtime.tv_sec); 5215 to->st_mtime_nsec_ = from->stx_mtime.tv_nsec; 5216 to->st_ctime_ = (kernel_time_t)(from->stx_ctime.tv_sec); 5217 to->st_ctime_nsec_ = from->stx_ctime.tv_nsec; 5218 to->st_size = (kernel_off_t)(from->stx_size); 5219 to->st_blocks = (kernel_blkcnt_t)(from->stx_blocks); 5220 to->st_blksize = (kernel_blksize_t)from->stx_blksize; 5221 } 5222 #endif 5223 5224 #if !defined(__NR_fstat) LSS_NAME(fstat)5225 LSS_INLINE int LSS_NAME(fstat)(int fd, 5226 struct kernel_stat *buf) { 5227 #if defined(__NR_newfstatat) 5228 return LSS_NAME(newfstatat)(fd, "", buf, AT_EMPTY_PATH); 5229 #elif defined(__NR_statx) 5230 struct kernel_statx stx; 5231 int flags = AT_NO_AUTOMOUNT | AT_EMPTY_PATH; 5232 int mask = STATX_BASIC_STATS; 5233 int res = LSS_NAME(statx)(fd, "", flags, mask, &stx); 5234 LSS_NAME(cp_stat_statx)(buf, &stx); 5235 return res; 5236 #endif 5237 } 5238 #endif 5239 5240 #if !defined(__NR_stat) LSS_NAME(stat)5241 LSS_INLINE int LSS_NAME(stat)(const char *pathname, 5242 struct kernel_stat *buf) { 5243 #if defined(__NR_newfstatat) 5244 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0); 5245 #elif defined(__NR_statx) 5246 struct kernel_statx stx; 5247 int flags = AT_NO_AUTOMOUNT | AT_STATX_SYNC_AS_STAT; 5248 int mask = STATX_BASIC_STATS; 5249 int res = LSS_NAME(statx)(AT_FDCWD, pathname, flags, mask, &stx); 5250 LSS_NAME(cp_stat_statx)(buf, &stx); 5251 return res; 5252 #endif 5253 } 5254 #endif 5255 5256 #if !defined(__NR_lstat) LSS_NAME(lstat)5257 LSS_INLINE int LSS_NAME(lstat)(const char *pathname, 5258 struct kernel_stat *buf) { 5259 #if defined(__NR_newfstatat) 5260 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, AT_SYMLINK_NOFOLLOW); 5261 #elif defined(__NR_statx) 5262 struct kernel_statx stx; 5263 int flags = AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW; 5264 int mask = STATX_BASIC_STATS; 5265 int res = LSS_NAME(statx)(AT_FDCWD, pathname, flags, mask, &stx); 5266 LSS_NAME(cp_stat_statx)(buf, &stx); 5267 return res; 5268 #endif 5269 } 5270 #endif 5271 5272 #if !defined(__NR_waitpid) LSS_NAME(waitpid)5273 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) { 5274 return LSS_NAME(wait4)(pid, status, options, 0); 5275 } 5276 #endif 5277 5278 #if !defined(__NR_fork) 5279 // TODO: define this in an arch-independant way instead of inlining the clone 5280 // syscall body. 5281 5282 # if defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64) LSS_NAME(fork)5283 LSS_INLINE pid_t LSS_NAME(fork)(void) { 5284 // No fork syscall on aarch64 - implement by means of the clone syscall. 5285 // Note that this does not reset glibc's cached view of the PID/TID, so 5286 // some glibc interfaces might go wrong in the forked subprocess. 5287 int flags = SIGCHLD; 5288 void *child_stack = NULL; 5289 void *parent_tidptr = NULL; 5290 void *newtls = NULL; 5291 void *child_tidptr = NULL; 5292 5293 LSS_REG(0, flags); 5294 LSS_REG(1, child_stack); 5295 LSS_REG(2, parent_tidptr); 5296 LSS_REG(3, newtls); 5297 LSS_REG(4, child_tidptr); 5298 LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), 5299 "r"(__r4)); 5300 } 5301 # elif defined(__x86_64__) LSS_NAME(fork)5302 LSS_INLINE pid_t LSS_NAME(fork)(void) { 5303 // Android disallows the fork syscall on x86_64 - implement by means of the 5304 // clone syscall as above for aarch64. 5305 int flags = SIGCHLD; 5306 void *child_stack = NULL; 5307 void *parent_tidptr = NULL; 5308 void *newtls = NULL; 5309 void *child_tidptr = NULL; 5310 5311 LSS_BODY(5, pid_t, clone, LSS_SYSCALL_ARG(flags), 5312 LSS_SYSCALL_ARG(child_stack), LSS_SYSCALL_ARG(parent_tidptr), 5313 LSS_SYSCALL_ARG(newtls), LSS_SYSCALL_ARG(child_tidptr)); 5314 } 5315 # else 5316 # error missing fork polyfill for this architecture 5317 # endif 5318 #endif 5319 5320 /* These restore the original values of these macros saved by the 5321 * corresponding #pragma push_macro near the top of this file. */ 5322 #pragma pop_macro("stat64") 5323 #pragma pop_macro("fstat64") 5324 #pragma pop_macro("lstat64") 5325 #pragma pop_macro("pread64") 5326 #pragma pop_macro("pwrite64") 5327 #pragma pop_macro("getdents64") 5328 5329 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) 5330 } 5331 #endif 5332 5333 #endif 5334 #endif 5335