1  /* Copyright (C) 2015-2023 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  */