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