Blame sysdeps/unix/sysdep.h

Packit 6c4009
/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <sysdeps/generic/sysdep.h>
Packit 6c4009
Packit 6c4009
#include <sys/syscall.h>
Packit 6c4009
#define	HAVE_SYSCALLS
Packit 6c4009
Packit 6c4009
/* Note that using a `PASTE' macro loses.  */
Packit 6c4009
#define	SYSCALL__(name, args)	PSEUDO (__##name, name, args)
Packit 6c4009
#define	SYSCALL(name, args)	PSEUDO (name, name, args)
Packit 6c4009
Packit 6c4009
#define __SYSCALL_CONCAT_X(a,b)     a##b
Packit 6c4009
#define __SYSCALL_CONCAT(a,b)       __SYSCALL_CONCAT_X (a, b)
Packit 6c4009
Packit 6c4009
Packit 6c4009
#define __INTERNAL_SYSCALL0(name, err) \
Packit 6c4009
  INTERNAL_SYSCALL (name, err, 0)
Packit 6c4009
#define __INTERNAL_SYSCALL1(name, err, a1) \
Packit 6c4009
  INTERNAL_SYSCALL (name, err, 1, a1)
Packit 6c4009
#define __INTERNAL_SYSCALL2(name, err, a1, a2) \
Packit 6c4009
  INTERNAL_SYSCALL (name, err, 2, a1, a2)
Packit 6c4009
#define __INTERNAL_SYSCALL3(name, err, a1, a2, a3) \
Packit 6c4009
  INTERNAL_SYSCALL (name, err, 3, a1, a2, a3)
Packit 6c4009
#define __INTERNAL_SYSCALL4(name, err, a1, a2, a3, a4) \
Packit 6c4009
  INTERNAL_SYSCALL (name, err, 4, a1, a2, a3, a4)
Packit 6c4009
#define __INTERNAL_SYSCALL5(name, err, a1, a2, a3, a4, a5) \
Packit 6c4009
  INTERNAL_SYSCALL (name, err, 5, a1, a2, a3, a4, a5)
Packit 6c4009
#define __INTERNAL_SYSCALL6(name, err, a1, a2, a3, a4, a5, a6) \
Packit 6c4009
  INTERNAL_SYSCALL (name, err, 6, a1, a2, a3, a4, a5, a6)
Packit 6c4009
#define __INTERNAL_SYSCALL7(name, err, a1, a2, a3, a4, a5, a6, a7) \
Packit 6c4009
  INTERNAL_SYSCALL (name, err, 7, a1, a2, a3, a4, a5, a6, a7)
Packit 6c4009
Packit 6c4009
#define __INTERNAL_SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,o,...) o
Packit 6c4009
#define __INTERNAL_SYSCALL_NARGS(...) \
Packit 6c4009
  __INTERNAL_SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)
Packit 6c4009
#define __INTERNAL_SYSCALL_DISP(b,...) \
Packit 6c4009
  __SYSCALL_CONCAT (b,__INTERNAL_SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
Packit 6c4009
Packit 6c4009
/* Issue a syscall defined by syscall number plus any other argument required.
Packit 6c4009
   It is similar to INTERNAL_SYSCALL macro, but without the need to pass the
Packit 6c4009
   expected argument number as second parameter.  */
Packit 6c4009
#define INTERNAL_SYSCALL_CALL(...) \
Packit 6c4009
  __INTERNAL_SYSCALL_DISP (__INTERNAL_SYSCALL, __VA_ARGS__)
Packit 6c4009
Packit 6c4009
#define __INLINE_SYSCALL0(name) \
Packit 6c4009
  INLINE_SYSCALL (name, 0)
Packit 6c4009
#define __INLINE_SYSCALL1(name, a1) \
Packit 6c4009
  INLINE_SYSCALL (name, 1, a1)
Packit 6c4009
#define __INLINE_SYSCALL2(name, a1, a2) \
Packit 6c4009
  INLINE_SYSCALL (name, 2, a1, a2)
Packit 6c4009
#define __INLINE_SYSCALL3(name, a1, a2, a3) \
Packit 6c4009
  INLINE_SYSCALL (name, 3, a1, a2, a3)
Packit 6c4009
#define __INLINE_SYSCALL4(name, a1, a2, a3, a4) \
Packit 6c4009
  INLINE_SYSCALL (name, 4, a1, a2, a3, a4)
Packit 6c4009
#define __INLINE_SYSCALL5(name, a1, a2, a3, a4, a5) \
Packit 6c4009
  INLINE_SYSCALL (name, 5, a1, a2, a3, a4, a5)
Packit 6c4009
#define __INLINE_SYSCALL6(name, a1, a2, a3, a4, a5, a6) \
Packit 6c4009
  INLINE_SYSCALL (name, 6, a1, a2, a3, a4, a5, a6)
Packit 6c4009
#define __INLINE_SYSCALL7(name, a1, a2, a3, a4, a5, a6, a7) \
Packit 6c4009
  INLINE_SYSCALL (name, 7, a1, a2, a3, a4, a5, a6, a7)
Packit 6c4009
Packit 6c4009
#define __INLINE_SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
Packit 6c4009
#define __INLINE_SYSCALL_NARGS(...) \
Packit 6c4009
  __INLINE_SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)
Packit 6c4009
#define __INLINE_SYSCALL_DISP(b,...) \
Packit 6c4009
  __SYSCALL_CONCAT (b,__INLINE_SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
Packit 6c4009
Packit 6c4009
/* Issue a syscall defined by syscall number plus any other argument
Packit 6c4009
   required.  Any error will be handled using arch defined macros and errno
Packit 6c4009
   will be set accordingly.
Packit 6c4009
   It is similar to INLINE_SYSCALL macro, but without the need to pass the
Packit 6c4009
   expected argument number as second parameter.  */
Packit 6c4009
#define INLINE_SYSCALL_CALL(...) \
Packit 6c4009
  __INLINE_SYSCALL_DISP (__INLINE_SYSCALL, __VA_ARGS__)
Packit 6c4009
Packit 6c4009
#define SYSCALL_CANCEL(...) \
Packit 6c4009
  ({									     \
Packit 6c4009
    long int sc_ret;							     \
Packit 6c4009
    if (SINGLE_THREAD_P) 						     \
Packit 6c4009
      sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__); 			     \
Packit 6c4009
    else								     \
Packit 6c4009
      {									     \
Packit 6c4009
	int sc_cancel_oldtype = LIBC_CANCEL_ASYNC ();			     \
Packit 6c4009
	sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__);			     \
Packit 6c4009
        LIBC_CANCEL_RESET (sc_cancel_oldtype);				     \
Packit 6c4009
      }									     \
Packit 6c4009
    sc_ret;								     \
Packit 6c4009
  })
Packit 6c4009
Packit 6c4009
/* Issue a syscall defined by syscall number plus any other argument
Packit 6c4009
   required.  Any error will be returned unmodified (including errno).  */
Packit 6c4009
#define INTERNAL_SYSCALL_CANCEL(...) \
Packit 6c4009
  ({									     \
Packit 6c4009
    long int sc_ret;							     \
Packit 6c4009
    if (SINGLE_THREAD_P) 						     \
Packit 6c4009
      sc_ret = INTERNAL_SYSCALL_CALL (__VA_ARGS__); 			     \
Packit 6c4009
    else								     \
Packit 6c4009
      {									     \
Packit 6c4009
	int sc_cancel_oldtype = LIBC_CANCEL_ASYNC ();			     \
Packit 6c4009
	sc_ret = INTERNAL_SYSCALL_CALL (__VA_ARGS__);			     \
Packit 6c4009
        LIBC_CANCEL_RESET (sc_cancel_oldtype);				     \
Packit 6c4009
      }									     \
Packit 6c4009
    sc_ret;								     \
Packit 6c4009
  })
Packit 6c4009
Packit 6c4009
/* Machine-dependent sysdep.h files are expected to define the macro
Packit 6c4009
   PSEUDO (function_name, syscall_name) to emit assembly code to define the
Packit 6c4009
   C-callable function FUNCTION_NAME to do system call SYSCALL_NAME.
Packit 6c4009
   r0 and r1 are the system call outputs.  MOVE(x, y) should be defined as
Packit 6c4009
   an instruction such that "MOVE(r1, r0)" works.  ret should be defined
Packit 6c4009
   as the return instruction.  */
Packit 6c4009
Packit 6c4009
#ifndef SYS_ify
Packit 6c4009
#define SYS_ify(syscall_name) SYS_##syscall_name
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Terminate a system call named SYM.  This is used on some platforms
Packit 6c4009
   to generate correct debugging information.  */
Packit 6c4009
#ifndef PSEUDO_END
Packit 6c4009
#define PSEUDO_END(sym)
Packit 6c4009
#endif
Packit 6c4009
#ifndef PSEUDO_END_NOERRNO
Packit 6c4009
#define PSEUDO_END_NOERRNO(sym)	PSEUDO_END(sym)
Packit 6c4009
#endif
Packit 6c4009
#ifndef PSEUDO_END_ERRVAL
Packit 6c4009
#define PSEUDO_END_ERRVAL(sym)	PSEUDO_END(sym)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Wrappers around system calls should normally inline the system call code.
Packit 6c4009
   But sometimes it is not possible or implemented and we use this code.  */
Packit 6c4009
#ifndef INLINE_SYSCALL
Packit 6c4009
#define INLINE_SYSCALL(name, nr, args...) __syscall_##name (args)
Packit 6c4009
#endif