1 /* Copyright (C) 2015-2022 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 4 The GNU C Library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 The GNU C Library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with the GNU C Library; if not, see 16 <https://www.gnu.org/licenses/>. */ 17 18 #ifndef _SYSDEP_LINUX_H 19 #define _SYSDEP_LINUX_H 20 21 #include <bits/wordsize.h> 22 #include <kernel-features.h> 23 #include <endian.h> 24 #include <errno.h> 25 26 #undef INTERNAL_SYSCALL_ERROR_P 27 #define INTERNAL_SYSCALL_ERROR_P(val) \ 28 ((unsigned long int) (val) > -4096UL) 29 30 #ifndef SYSCALL_ERROR_LABEL 31 # define SYSCALL_ERROR_LABEL(sc_err) \ 32 ({ \ 33 __set_errno (sc_err); \ 34 -1L; \ 35 }) 36 #endif 37 38 /* Define a macro which expands into the inline wrapper code for a system 39 call. It sets the errno and returns -1 on a failure, or the syscall 40 return value otherwise. */ 41 #undef INLINE_SYSCALL 42 #define INLINE_SYSCALL(name, nr, args...) \ 43 ({ \ 44 long int sc_ret = INTERNAL_SYSCALL (name, nr, args); \ 45 __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (sc_ret)) \ 46 ? SYSCALL_ERROR_LABEL (INTERNAL_SYSCALL_ERRNO (sc_ret)) \ 47 : sc_ret; \ 48 }) 49 50 #undef INTERNAL_SYSCALL_ERRNO 51 #define INTERNAL_SYSCALL_ERRNO(val) (-(val)) 52 53 /* Set error number and return -1. A target may choose to return the 54 internal function, __syscall_error, which sets errno and returns -1. 55 We use -1l, instead of -1, so that it can be casted to (void *). */ 56 #define INLINE_SYSCALL_ERROR_RETURN_VALUE(err) \ 57 ({ \ 58 __set_errno (err); \ 59 -1l; \ 60 }) 61 62 /* Provide a dummy argument that can be used to force register 63 alignment for register pairs if required by the syscall ABI. */ 64 #ifdef __ASSUME_ALIGNED_REGISTER_PAIRS 65 #define __ALIGNMENT_ARG 0, 66 #define __ALIGNMENT_COUNT(a,b) b 67 #else 68 #define __ALIGNMENT_ARG 69 #define __ALIGNMENT_COUNT(a,b) a 70 #endif 71 72 /* Provide a common macro to pass 64-bit value on syscalls. */ 73 #if __WORDSIZE == 64 || defined __ASSUME_WORDSIZE64_ILP32 74 # define SYSCALL_LL(val) (val) 75 # define SYSCALL_LL64(val) (val) 76 #else 77 #define SYSCALL_LL(val) \ 78 __LONG_LONG_PAIR ((val) >> 31, (val)) 79 #define SYSCALL_LL64(val) \ 80 __LONG_LONG_PAIR ((long) ((val) >> 32), (long) ((val) & 0xffffffff)) 81 #endif 82 83 /* Provide a common macro to pass 64-bit value on pread and pwrite 84 syscalls. */ 85 #ifdef __ASSUME_PRW_DUMMY_ARG 86 # define SYSCALL_LL_PRW(val) 0, SYSCALL_LL (val) 87 # define SYSCALL_LL64_PRW(val) 0, SYSCALL_LL64 (val) 88 #else 89 # define SYSCALL_LL_PRW(val) __ALIGNMENT_ARG SYSCALL_LL (val) 90 # define SYSCALL_LL64_PRW(val) __ALIGNMENT_ARG SYSCALL_LL64 (val) 91 #endif 92 93 /* Provide a macro to pass the off{64}_t argument on p{readv,writev}{64}. */ 94 #define LO_HI_LONG(val) \ 95 (long) (val), \ 96 (long) (((uint64_t) (val)) >> 32) 97 98 /* Export the ___brk_addr symbol on brk.c implementation (some ABIs export 99 it due and old crtstuff.c code). */ 100 #define HAVE_INTERNAL_BRK_ADDR_SYMBOL 0 101 102 #endif /* _SYSDEP_LINUX_H */ 103