Blame sysdeps/unix/sysv/linux/i386/sysdep.h

Packit Service 82fcde
/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef _LINUX_I386_SYSDEP_H
Packit Service 82fcde
#define _LINUX_I386_SYSDEP_H 1
Packit Service 82fcde
Packit Service 82fcde
/* There is some commonality.  */
Packit Service 82fcde
#include <sysdeps/unix/sysv/linux/sysdep.h>
Packit Service 82fcde
#include <sysdeps/unix/i386/sysdep.h>
Packit Service 82fcde
/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO.  */
Packit Service 82fcde
#include <dl-sysdep.h>
Packit Service 82fcde
#include <tls.h>
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* For Linux we can use the system call table in the header file
Packit Service 82fcde
	/usr/include/asm/unistd.h
Packit Service 82fcde
   of the kernel.  But these symbols do not follow the SYS_* syntax
Packit Service 82fcde
   so we have to redefine the `SYS_ify' macro here.  */
Packit Service 82fcde
#undef SYS_ify
Packit Service 82fcde
#define SYS_ify(syscall_name)	__NR_##syscall_name
Packit Service 82fcde
Packit Service 82fcde
#ifndef I386_USE_SYSENTER
Packit Service 82fcde
# if defined USE_DL_SYSINFO \
Packit Service 82fcde
     && (IS_IN (libc) || IS_IN (libpthread))
Packit Service 82fcde
#  define I386_USE_SYSENTER	1
Packit Service 82fcde
# else
Packit Service 82fcde
#  define I386_USE_SYSENTER	0
Packit Service 82fcde
# endif
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Since GCC 5 and above can properly spill %ebx with PIC when needed,
Packit Service 82fcde
   we can inline syscalls with 6 arguments if GCC 5 or above is used
Packit Service 82fcde
   to compile glibc.  Disable GCC 5 optimization when compiling for
Packit Service 82fcde
   profiling or when -fno-omit-frame-pointer is used since asm ("ebp")
Packit Service 82fcde
   can't be used to put the 6th argument in %ebp for syscall.  */
Packit Service 82fcde
#if __GNUC_PREREQ (5,0) && !defined PROF && CAN_USE_REGISTER_ASM_EBP
Packit Service 82fcde
# define OPTIMIZE_FOR_GCC_5
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef __ASSEMBLER__
Packit Service 82fcde
Packit Service 82fcde
/* Linux uses a negative return value to indicate syscall errors,
Packit Service 82fcde
   unlike most Unices, which use the condition codes' carry flag.
Packit Service 82fcde
Packit Service 82fcde
   Since version 2.1 the return value of a system call might be
Packit Service 82fcde
   negative even if the call succeeded.  E.g., the `lseek' system call
Packit Service 82fcde
   might return a large offset.  Therefore we must not anymore test
Packit Service 82fcde
   for < 0, but test for a real error by making sure the value in %eax
Packit Service 82fcde
   is a real error number.  Linus said he will make sure the no syscall
Packit Service 82fcde
   returns a value in -1 .. -4095 as a valid result so we can savely
Packit Service 82fcde
   test with -4095.  */
Packit Service 82fcde
Packit Service 82fcde
/* We don't want the label for the error handle to be global when we define
Packit Service 82fcde
   it here.  */
Packit Service 82fcde
#define SYSCALL_ERROR_LABEL __syscall_error
Packit Service 82fcde
Packit Service 82fcde
#undef	PSEUDO
Packit Service 82fcde
#define	PSEUDO(name, syscall_name, args)				      \
Packit Service 82fcde
  .text;								      \
Packit Service 82fcde
  ENTRY (name)								      \
Packit Service 82fcde
    DO_CALL (syscall_name, args);					      \
Packit Service 82fcde
    cmpl $-4095, %eax;							      \
Packit Service 82fcde
    jae SYSCALL_ERROR_LABEL
Packit Service 82fcde
Packit Service 82fcde
#undef	PSEUDO_END
Packit Service 82fcde
#define	PSEUDO_END(name)						      \
Packit Service 82fcde
  SYSCALL_ERROR_HANDLER							      \
Packit Service 82fcde
  END (name)
Packit Service 82fcde
Packit Service 82fcde
#undef	PSEUDO_NOERRNO
Packit Service 82fcde
#define	PSEUDO_NOERRNO(name, syscall_name, args)			      \
Packit Service 82fcde
  .text;								      \
Packit Service 82fcde
  ENTRY (name)								      \
Packit Service 82fcde
    DO_CALL (syscall_name, args)
Packit Service 82fcde
Packit Service 82fcde
#undef	PSEUDO_END_NOERRNO
Packit Service 82fcde
#define	PSEUDO_END_NOERRNO(name)					      \
Packit Service 82fcde
  END (name)
Packit Service 82fcde
Packit Service 82fcde
#define ret_NOERRNO ret
Packit Service 82fcde
Packit Service 82fcde
/* The function has to return the error code.  */
Packit Service 82fcde
#undef	PSEUDO_ERRVAL
Packit Service 82fcde
#define	PSEUDO_ERRVAL(name, syscall_name, args) \
Packit Service 82fcde
  .text;								      \
Packit Service 82fcde
  ENTRY (name)								      \
Packit Service 82fcde
    DO_CALL (syscall_name, args);					      \
Packit Service 82fcde
    negl %eax
Packit Service 82fcde
Packit Service 82fcde
#undef	PSEUDO_END_ERRVAL
Packit Service 82fcde
#define	PSEUDO_END_ERRVAL(name) \
Packit Service 82fcde
  END (name)
Packit Service 82fcde
Packit Service 82fcde
#define ret_ERRVAL ret
Packit Service 82fcde
Packit Service 82fcde
#define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.c is used.  */
Packit Service 82fcde
Packit Service 82fcde
/* The original calling convention for system calls on Linux/i386 is
Packit Service 82fcde
   to use int $0x80.  */
Packit Service 82fcde
#if I386_USE_SYSENTER
Packit Service 82fcde
# ifdef PIC
Packit Service 82fcde
#  define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
Packit Service 82fcde
# else
Packit Service 82fcde
#  define ENTER_KERNEL call *_dl_sysinfo
Packit Service 82fcde
# endif
Packit Service 82fcde
#else
Packit Service 82fcde
# define ENTER_KERNEL int $0x80
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Linux takes system call arguments in registers:
Packit Service 82fcde
Packit Service 82fcde
	syscall number	%eax	     call-clobbered
Packit Service 82fcde
	arg 1		%ebx	     call-saved
Packit Service 82fcde
	arg 2		%ecx	     call-clobbered
Packit Service 82fcde
	arg 3		%edx	     call-clobbered
Packit Service 82fcde
	arg 4		%esi	     call-saved
Packit Service 82fcde
	arg 5		%edi	     call-saved
Packit Service 82fcde
	arg 6		%ebp	     call-saved
Packit Service 82fcde
Packit Service 82fcde
   The stack layout upon entering the function is:
Packit Service 82fcde
Packit Service 82fcde
	24(%esp)	Arg# 6
Packit Service 82fcde
	20(%esp)	Arg# 5
Packit Service 82fcde
	16(%esp)	Arg# 4
Packit Service 82fcde
	12(%esp)	Arg# 3
Packit Service 82fcde
	 8(%esp)	Arg# 2
Packit Service 82fcde
	 4(%esp)	Arg# 1
Packit Service 82fcde
	  (%esp)	Return address
Packit Service 82fcde
Packit Service 82fcde
   (Of course a function with say 3 arguments does not have entries for
Packit Service 82fcde
   arguments 4, 5, and 6.)
Packit Service 82fcde
Packit Service 82fcde
   The following code tries hard to be optimal.  A general assumption
Packit Service 82fcde
   (which is true according to the data books I have) is that
Packit Service 82fcde
Packit Service 82fcde
	2 * xchg	is more expensive than	pushl + movl + popl
Packit Service 82fcde
Packit Service 82fcde
   Beside this a neat trick is used.  The calling conventions for Linux
Packit Service 82fcde
   tell that among the registers used for parameters %ecx and %edx need
Packit Service 82fcde
   not be saved.  Beside this we may clobber this registers even when
Packit Service 82fcde
   they are not used for parameter passing.
Packit Service 82fcde
Packit Service 82fcde
   As a result one can see below that we save the content of the %ebx
Packit Service 82fcde
   register in the %edx register when we have less than 3 arguments
Packit Service 82fcde
   (2 * movl is less expensive than pushl + popl).
Packit Service 82fcde
Packit Service 82fcde
   Second unlike for the other registers we don't save the content of
Packit Service 82fcde
   %ecx and %edx when we have more than 1 and 2 registers resp.
Packit Service 82fcde
Packit Service 82fcde
   The code below might look a bit long but we have to take care for
Packit Service 82fcde
   the pipelined processors (i586).  Here the `pushl' and `popl'
Packit Service 82fcde
   instructions are marked as NP (not pairable) but the exception is
Packit Service 82fcde
   two consecutive of these instruction.  This gives no penalty on
Packit Service 82fcde
   other processors though.  */
Packit Service 82fcde
Packit Service 82fcde
#undef	DO_CALL
Packit Service 82fcde
#define DO_CALL(syscall_name, args)			      		      \
Packit Service 82fcde
    PUSHARGS_##args							      \
Packit Service 82fcde
    DOARGS_##args							      \
Packit Service 82fcde
    movl $SYS_ify (syscall_name), %eax;					      \
Packit Service 82fcde
    ENTER_KERNEL							      \
Packit Service 82fcde
    POPARGS_##args
Packit Service 82fcde
Packit Service 82fcde
#define PUSHARGS_0	/* No arguments to push.  */
Packit Service 82fcde
#define	DOARGS_0	/* No arguments to frob.  */
Packit Service 82fcde
#define	POPARGS_0	/* No arguments to pop.  */
Packit Service 82fcde
#define	_PUSHARGS_0	/* No arguments to push.  */
Packit Service 82fcde
#define _DOARGS_0(n)	/* No arguments to frob.  */
Packit Service 82fcde
#define	_POPARGS_0	/* No arguments to pop.  */
Packit Service 82fcde
Packit Service 82fcde
#define PUSHARGS_1	movl %ebx, %edx; L(SAVEBX1): PUSHARGS_0
Packit Service 82fcde
#define	DOARGS_1	_DOARGS_1 (4)
Packit Service 82fcde
#define	POPARGS_1	POPARGS_0; movl %edx, %ebx; L(RESTBX1):
Packit Service 82fcde
#define	_PUSHARGS_1	pushl %ebx; cfi_adjust_cfa_offset (4); \
Packit Service 82fcde
			cfi_rel_offset (ebx, 0); L(PUSHBX1): _PUSHARGS_0
Packit Service 82fcde
#define _DOARGS_1(n)	movl n(%esp), %ebx; _DOARGS_0(n-4)
Packit Service 82fcde
#define	_POPARGS_1	_POPARGS_0; popl %ebx; cfi_adjust_cfa_offset (-4); \
Packit Service 82fcde
			cfi_restore (ebx); L(POPBX1):
Packit Service 82fcde
Packit Service 82fcde
#define PUSHARGS_2	PUSHARGS_1
Packit Service 82fcde
#define	DOARGS_2	_DOARGS_2 (8)
Packit Service 82fcde
#define	POPARGS_2	POPARGS_1
Packit Service 82fcde
#define _PUSHARGS_2	_PUSHARGS_1
Packit Service 82fcde
#define	_DOARGS_2(n)	movl n(%esp), %ecx; _DOARGS_1 (n-4)
Packit Service 82fcde
#define	_POPARGS_2	_POPARGS_1
Packit Service 82fcde
Packit Service 82fcde
#define PUSHARGS_3	_PUSHARGS_2
Packit Service 82fcde
#define DOARGS_3	_DOARGS_3 (16)
Packit Service 82fcde
#define POPARGS_3	_POPARGS_3
Packit Service 82fcde
#define _PUSHARGS_3	_PUSHARGS_2
Packit Service 82fcde
#define _DOARGS_3(n)	movl n(%esp), %edx; _DOARGS_2 (n-4)
Packit Service 82fcde
#define _POPARGS_3	_POPARGS_2
Packit Service 82fcde
Packit Service 82fcde
#define PUSHARGS_4	_PUSHARGS_4
Packit Service 82fcde
#define DOARGS_4	_DOARGS_4 (24)
Packit Service 82fcde
#define POPARGS_4	_POPARGS_4
Packit Service 82fcde
#define _PUSHARGS_4	pushl %esi; cfi_adjust_cfa_offset (4); \
Packit Service 82fcde
			cfi_rel_offset (esi, 0); L(PUSHSI1): _PUSHARGS_3
Packit Service 82fcde
#define _DOARGS_4(n)	movl n(%esp), %esi; _DOARGS_3 (n-4)
Packit Service 82fcde
#define _POPARGS_4	_POPARGS_3; popl %esi; cfi_adjust_cfa_offset (-4); \
Packit Service 82fcde
			cfi_restore (esi); L(POPSI1):
Packit Service 82fcde
Packit Service 82fcde
#define PUSHARGS_5	_PUSHARGS_5
Packit Service 82fcde
#define DOARGS_5	_DOARGS_5 (32)
Packit Service 82fcde
#define POPARGS_5	_POPARGS_5
Packit Service 82fcde
#define _PUSHARGS_5	pushl %edi; cfi_adjust_cfa_offset (4); \
Packit Service 82fcde
			cfi_rel_offset (edi, 0); L(PUSHDI1): _PUSHARGS_4
Packit Service 82fcde
#define _DOARGS_5(n)	movl n(%esp), %edi; _DOARGS_4 (n-4)
Packit Service 82fcde
#define _POPARGS_5	_POPARGS_4; popl %edi; cfi_adjust_cfa_offset (-4); \
Packit Service 82fcde
			cfi_restore (edi); L(POPDI1):
Packit Service 82fcde
Packit Service 82fcde
#define PUSHARGS_6	_PUSHARGS_6
Packit Service 82fcde
#define DOARGS_6	_DOARGS_6 (40)
Packit Service 82fcde
#define POPARGS_6	_POPARGS_6
Packit Service 82fcde
#define _PUSHARGS_6	pushl %ebp; cfi_adjust_cfa_offset (4); \
Packit Service 82fcde
			cfi_rel_offset (ebp, 0); L(PUSHBP1): _PUSHARGS_5
Packit Service 82fcde
#define _DOARGS_6(n)	movl n(%esp), %ebp; _DOARGS_5 (n-4)
Packit Service 82fcde
#define _POPARGS_6	_POPARGS_5; popl %ebp; cfi_adjust_cfa_offset (-4); \
Packit Service 82fcde
			cfi_restore (ebp); L(POPBP1):
Packit Service 82fcde
Packit Service 82fcde
#else	/* !__ASSEMBLER__ */
Packit Service 82fcde
Packit Service 82fcde
extern int __syscall_error (int)
Packit Service 82fcde
  attribute_hidden __attribute__ ((__regparm__ (1)));
Packit Service 82fcde
Packit Service 82fcde
#ifndef OPTIMIZE_FOR_GCC_5
Packit Service 82fcde
/* We need some help from the assembler to generate optimal code.  We
Packit Service 82fcde
   define some macros here which later will be used.  */
Packit Service 82fcde
asm (".L__X'%ebx = 1\n\t"
Packit Service 82fcde
     ".L__X'%ecx = 2\n\t"
Packit Service 82fcde
     ".L__X'%edx = 2\n\t"
Packit Service 82fcde
     ".L__X'%eax = 3\n\t"
Packit Service 82fcde
     ".L__X'%esi = 3\n\t"
Packit Service 82fcde
     ".L__X'%edi = 3\n\t"
Packit Service 82fcde
     ".L__X'%ebp = 3\n\t"
Packit Service 82fcde
     ".L__X'%esp = 3\n\t"
Packit Service 82fcde
     ".macro bpushl name reg\n\t"
Packit Service 82fcde
     ".if 1 - \\name\n\t"
Packit Service 82fcde
     ".if 2 - \\name\n\t"
Packit Service 82fcde
     "error\n\t"
Packit Service 82fcde
     ".else\n\t"
Packit Service 82fcde
     "xchgl \\reg, %ebx\n\t"
Packit Service 82fcde
     ".endif\n\t"
Packit Service 82fcde
     ".endif\n\t"
Packit Service 82fcde
     ".endm\n\t"
Packit Service 82fcde
     ".macro bpopl name reg\n\t"
Packit Service 82fcde
     ".if 1 - \\name\n\t"
Packit Service 82fcde
     ".if 2 - \\name\n\t"
Packit Service 82fcde
     "error\n\t"
Packit Service 82fcde
     ".else\n\t"
Packit Service 82fcde
     "xchgl \\reg, %ebx\n\t"
Packit Service 82fcde
     ".endif\n\t"
Packit Service 82fcde
     ".endif\n\t"
Packit Service 82fcde
     ".endm\n\t");
Packit Service 82fcde
Packit Service 82fcde
/* Six-argument syscalls use an out-of-line helper, because an inline
Packit Service 82fcde
   asm using all registers apart from %esp cannot work reliably and
Packit Service 82fcde
   the assembler does not support describing an asm that saves and
Packit Service 82fcde
   restores %ebp itself as a separate stack frame.  This structure
Packit Service 82fcde
   stores the arguments not passed in registers; %edi is passed with a
Packit Service 82fcde
   pointer to this structure.  */
Packit Service 82fcde
struct libc_do_syscall_args
Packit Service 82fcde
{
Packit Service 82fcde
  int ebx, edi, ebp;
Packit Service 82fcde
};
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Define a macro which expands inline into the wrapper code for a system
Packit Service 82fcde
   call.  */
Packit Service 82fcde
#undef INLINE_SYSCALL
Packit Service 82fcde
#if IS_IN (libc)
Packit Service 82fcde
# define INLINE_SYSCALL(name, nr, args...) \
Packit Service 82fcde
  ({									      \
Packit Service 82fcde
    unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args);	      \
Packit Service 82fcde
    __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, ))		      \
Packit Service 82fcde
    ? __syscall_error (-INTERNAL_SYSCALL_ERRNO (resultvar, ))		      \
Packit Service 82fcde
    : (int) resultvar; })
Packit Service 82fcde
#else
Packit Service 82fcde
# define INLINE_SYSCALL(name, nr, args...) \
Packit Service 82fcde
  ({									      \
Packit Service 82fcde
    unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args);	      \
Packit Service 82fcde
    if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
Packit Service 82fcde
      {									      \
Packit Service 82fcde
	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
Packit Service 82fcde
	resultvar = 0xffffffff;						      \
Packit Service 82fcde
      }									      \
Packit Service 82fcde
    (int) resultvar; })
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Set error number and return -1.  Return the internal function,
Packit Service 82fcde
   __syscall_error, which sets errno from the negative error number
Packit Service 82fcde
   and returns -1, to avoid PIC.  */
Packit Service 82fcde
#undef INLINE_SYSCALL_ERROR_RETURN_VALUE
Packit Service 82fcde
#define INLINE_SYSCALL_ERROR_RETURN_VALUE(resultvar) \
Packit Service 82fcde
  __syscall_error (-(resultvar))
Packit Service 82fcde
Packit Service 82fcde
/* List of system calls which are supported as vsyscalls.  */
Packit Service 82fcde
# define HAVE_CLOCK_GETTIME_VSYSCALL    1
Packit Service 82fcde
# define HAVE_GETTIMEOFDAY_VSYSCALL     1
Packit Service 82fcde
Packit Service 82fcde
/* Define a macro which expands inline into the wrapper code for a system
Packit Service 82fcde
   call.  This use is for internal calls that do not need to handle errors
Packit Service 82fcde
   normally.  It will never touch errno.  This returns just what the kernel
Packit Service 82fcde
   gave back.
Packit Service 82fcde
Packit Service 82fcde
   The _NCS variant allows non-constant syscall numbers but it is not
Packit Service 82fcde
   possible to use more than four parameters.  */
Packit Service 82fcde
#undef INTERNAL_SYSCALL
Packit Service 82fcde
#define INTERNAL_SYSCALL_MAIN_0(name, err, args...) \
Packit Service 82fcde
    INTERNAL_SYSCALL_MAIN_INLINE(name, err, 0, args)
Packit Service 82fcde
#define INTERNAL_SYSCALL_MAIN_1(name, err, args...) \
Packit Service 82fcde
    INTERNAL_SYSCALL_MAIN_INLINE(name, err, 1, args)
Packit Service 82fcde
#define INTERNAL_SYSCALL_MAIN_2(name, err, args...) \
Packit Service 82fcde
    INTERNAL_SYSCALL_MAIN_INLINE(name, err, 2, args)
Packit Service 82fcde
#define INTERNAL_SYSCALL_MAIN_3(name, err, args...) \
Packit Service 82fcde
    INTERNAL_SYSCALL_MAIN_INLINE(name, err, 3, args)
Packit Service 82fcde
#define INTERNAL_SYSCALL_MAIN_4(name, err, args...) \
Packit Service 82fcde
    INTERNAL_SYSCALL_MAIN_INLINE(name, err, 4, args)
Packit Service 82fcde
#define INTERNAL_SYSCALL_MAIN_5(name, err, args...) \
Packit Service 82fcde
    INTERNAL_SYSCALL_MAIN_INLINE(name, err, 5, args)
Packit Service 82fcde
/* Each object using 6-argument inline syscalls must include a
Packit Service 82fcde
   definition of __libc_do_syscall.  */
Packit Service 82fcde
#ifdef OPTIMIZE_FOR_GCC_5
Packit Service 82fcde
# define INTERNAL_SYSCALL_MAIN_6(name, err, args...) \
Packit Service 82fcde
    INTERNAL_SYSCALL_MAIN_INLINE(name, err, 6, args)
Packit Service 82fcde
#else /* GCC 5  */
Packit Service 82fcde
# define INTERNAL_SYSCALL_MAIN_6(name, err, arg1, arg2, arg3,		\
Packit Service 82fcde
				 arg4, arg5, arg6)			\
Packit Service 82fcde
  struct libc_do_syscall_args _xv =					\
Packit Service 82fcde
    {									\
Packit Service 82fcde
      (int) (arg1),							\
Packit Service 82fcde
      (int) (arg5),							\
Packit Service 82fcde
      (int) (arg6)							\
Packit Service 82fcde
    };									\
Packit Service 82fcde
    asm volatile (							\
Packit Service 82fcde
    "movl %1, %%eax\n\t"						\
Packit Service 82fcde
    "call __libc_do_syscall"						\
Packit Service 82fcde
    : "=a" (resultvar)							\
Packit Service 82fcde
    : "i" (__NR_##name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \
Packit Service 82fcde
    : "memory", "cc")
Packit Service 82fcde
#endif /* GCC 5  */
Packit Service 82fcde
#define INTERNAL_SYSCALL(name, err, nr, args...) \
Packit Service 82fcde
  ({									      \
Packit Service 82fcde
    register unsigned int resultvar;					      \
Packit Service 82fcde
    INTERNAL_SYSCALL_MAIN_##nr (name, err, args);			      \
Packit Service 82fcde
    (int) resultvar; })
Packit Service 82fcde
#if I386_USE_SYSENTER
Packit Service 82fcde
# ifdef OPTIMIZE_FOR_GCC_5
Packit Service 82fcde
#  ifdef PIC
Packit Service 82fcde
#   define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
Packit Service 82fcde
    LOADREGS_##nr(args)							\
Packit Service 82fcde
    asm volatile (							\
Packit Service 82fcde
    "call *%%gs:%P2"							\
Packit Service 82fcde
    : "=a" (resultvar)							\
Packit Service 82fcde
    : "a" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo))		\
Packit Service 82fcde
      ASMARGS_##nr(args) : "memory", "cc")
Packit Service 82fcde
#   define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
Packit Service 82fcde
  ({									\
Packit Service 82fcde
    register unsigned int resultvar;					\
Packit Service 82fcde
    LOADREGS_##nr(args)							\
Packit Service 82fcde
    asm volatile (							\
Packit Service 82fcde
    "call *%%gs:%P2"							\
Packit Service 82fcde
    : "=a" (resultvar)							\
Packit Service 82fcde
    : "a" (name), "i" (offsetof (tcbhead_t, sysinfo))			\
Packit Service 82fcde
      ASMARGS_##nr(args) : "memory", "cc");				\
Packit Service 82fcde
    (int) resultvar; })
Packit Service 82fcde
#  else
Packit Service 82fcde
#   define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
Packit Service 82fcde
    LOADREGS_##nr(args)							\
Packit Service 82fcde
    asm volatile (							\
Packit Service 82fcde
    "call *_dl_sysinfo"							\
Packit Service 82fcde
    : "=a" (resultvar)							\
Packit Service 82fcde
    : "a" (__NR_##name) ASMARGS_##nr(args) : "memory", "cc")
Packit Service 82fcde
#   define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
Packit Service 82fcde
  ({									\
Packit Service 82fcde
    register unsigned int resultvar;					\
Packit Service 82fcde
    LOADREGS_##nr(args)							\
Packit Service 82fcde
    asm volatile (							\
Packit Service 82fcde
    "call *_dl_sysinfo"							\
Packit Service 82fcde
    : "=a" (resultvar)							\
Packit Service 82fcde
    : "a" (name) ASMARGS_##nr(args) : "memory", "cc");			\
Packit Service 82fcde
    (int) resultvar; })
Packit Service 82fcde
#  endif
Packit Service 82fcde
# else /* GCC 5  */
Packit Service 82fcde
#  ifdef PIC
Packit Service 82fcde
#   define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
Packit Service 82fcde
    EXTRAVAR_##nr							      \
Packit Service 82fcde
    asm volatile (							      \
Packit Service 82fcde
    LOADARGS_##nr							      \
Packit Service 82fcde
    "movl %1, %%eax\n\t"						      \
Packit Service 82fcde
    "call *%%gs:%P2\n\t"						      \
Packit Service 82fcde
    RESTOREARGS_##nr							      \
Packit Service 82fcde
    : "=a" (resultvar)							      \
Packit Service 82fcde
    : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo))		      \
Packit Service 82fcde
      ASMFMT_##nr(args) : "memory", "cc")
Packit Service 82fcde
#   define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
Packit Service 82fcde
  ({									      \
Packit Service 82fcde
    register unsigned int resultvar;					      \
Packit Service 82fcde
    EXTRAVAR_##nr							      \
Packit Service 82fcde
    asm volatile (							      \
Packit Service 82fcde
    LOADARGS_##nr							      \
Packit Service 82fcde
    "call *%%gs:%P2\n\t"						      \
Packit Service 82fcde
    RESTOREARGS_##nr							      \
Packit Service 82fcde
    : "=a" (resultvar)							      \
Packit Service 82fcde
    : "0" (name), "i" (offsetof (tcbhead_t, sysinfo))			      \
Packit Service 82fcde
      ASMFMT_##nr(args) : "memory", "cc");				      \
Packit Service 82fcde
    (int) resultvar; })
Packit Service 82fcde
#  else
Packit Service 82fcde
#   define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
Packit Service 82fcde
    EXTRAVAR_##nr							      \
Packit Service 82fcde
    asm volatile (							      \
Packit Service 82fcde
    LOADARGS_##nr							      \
Packit Service 82fcde
    "movl %1, %%eax\n\t"						      \
Packit Service 82fcde
    "call *_dl_sysinfo\n\t"						      \
Packit Service 82fcde
    RESTOREARGS_##nr							      \
Packit Service 82fcde
    : "=a" (resultvar)							      \
Packit Service 82fcde
    : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc")
Packit Service 82fcde
#   define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
Packit Service 82fcde
  ({									      \
Packit Service 82fcde
    register unsigned int resultvar;					      \
Packit Service 82fcde
    EXTRAVAR_##nr							      \
Packit Service 82fcde
    asm volatile (							      \
Packit Service 82fcde
    LOADARGS_##nr							      \
Packit Service 82fcde
    "call *_dl_sysinfo\n\t"						      \
Packit Service 82fcde
    RESTOREARGS_##nr							      \
Packit Service 82fcde
    : "=a" (resultvar)							      \
Packit Service 82fcde
    : "0" (name) ASMFMT_##nr(args) : "memory", "cc");			      \
Packit Service 82fcde
    (int) resultvar; })
Packit Service 82fcde
#  endif
Packit Service 82fcde
# endif /* GCC 5  */
Packit Service 82fcde
#else
Packit Service 82fcde
# ifdef OPTIMIZE_FOR_GCC_5
Packit Service 82fcde
#  define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
Packit Service 82fcde
    LOADREGS_##nr(args)							\
Packit Service 82fcde
    asm volatile (							\
Packit Service 82fcde
    "int $0x80"								\
Packit Service 82fcde
    : "=a" (resultvar)							\
Packit Service 82fcde
    : "a" (__NR_##name) ASMARGS_##nr(args) : "memory", "cc")
Packit Service 82fcde
#  define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
Packit Service 82fcde
  ({									\
Packit Service 82fcde
    register unsigned int resultvar;					\
Packit Service 82fcde
    LOADREGS_##nr(args)							\
Packit Service 82fcde
    asm volatile (							\
Packit Service 82fcde
    "int $0x80"								\
Packit Service 82fcde
    : "=a" (resultvar)							\
Packit Service 82fcde
    : "a" (name) ASMARGS_##nr(args) : "memory", "cc");			\
Packit Service 82fcde
    (int) resultvar; })
Packit Service 82fcde
# else /* GCC 5  */
Packit Service 82fcde
#  define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
Packit Service 82fcde
    EXTRAVAR_##nr							      \
Packit Service 82fcde
    asm volatile (							      \
Packit Service 82fcde
    LOADARGS_##nr							      \
Packit Service 82fcde
    "movl %1, %%eax\n\t"						      \
Packit Service 82fcde
    "int $0x80\n\t"							      \
Packit Service 82fcde
    RESTOREARGS_##nr							      \
Packit Service 82fcde
    : "=a" (resultvar)							      \
Packit Service 82fcde
    : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc")
Packit Service 82fcde
#  define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
Packit Service 82fcde
  ({									      \
Packit Service 82fcde
    register unsigned int resultvar;					      \
Packit Service 82fcde
    EXTRAVAR_##nr							      \
Packit Service 82fcde
    asm volatile (							      \
Packit Service 82fcde
    LOADARGS_##nr							      \
Packit Service 82fcde
    "int $0x80\n\t"							      \
Packit Service 82fcde
    RESTOREARGS_##nr							      \
Packit Service 82fcde
    : "=a" (resultvar)							      \
Packit Service 82fcde
    : "0" (name) ASMFMT_##nr(args) : "memory", "cc");			      \
Packit Service 82fcde
    (int) resultvar; })
Packit Service 82fcde
# endif /* GCC 5  */
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#undef INTERNAL_SYSCALL_DECL
Packit Service 82fcde
#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
Packit Service 82fcde
Packit Service 82fcde
#undef INTERNAL_SYSCALL_ERROR_P
Packit Service 82fcde
#define INTERNAL_SYSCALL_ERROR_P(val, err) \
Packit Service 82fcde
  ((unsigned int) (val) >= 0xfffff001u)
Packit Service 82fcde
Packit Service 82fcde
#undef INTERNAL_SYSCALL_ERRNO
Packit Service 82fcde
#define INTERNAL_SYSCALL_ERRNO(val, err)	(-(val))
Packit Service 82fcde
Packit Service 82fcde
#define LOADARGS_0
Packit Service 82fcde
#ifdef __PIC__
Packit Service 82fcde
# if I386_USE_SYSENTER && defined PIC
Packit Service 82fcde
#  define LOADARGS_1 \
Packit Service 82fcde
    "bpushl .L__X'%k3, %k3\n\t"
Packit Service 82fcde
#  define LOADARGS_5 \
Packit Service 82fcde
    "movl %%ebx, %4\n\t"						      \
Packit Service 82fcde
    "movl %3, %%ebx\n\t"
Packit Service 82fcde
# else
Packit Service 82fcde
#  define LOADARGS_1 \
Packit Service 82fcde
    "bpushl .L__X'%k2, %k2\n\t"
Packit Service 82fcde
#  define LOADARGS_5 \
Packit Service 82fcde
    "movl %%ebx, %3\n\t"						      \
Packit Service 82fcde
    "movl %2, %%ebx\n\t"
Packit Service 82fcde
# endif
Packit Service 82fcde
# define LOADARGS_2	LOADARGS_1
Packit Service 82fcde
# define LOADARGS_3 \
Packit Service 82fcde
    "xchgl %%ebx, %%edi\n\t"
Packit Service 82fcde
# define LOADARGS_4	LOADARGS_3
Packit Service 82fcde
#else
Packit Service 82fcde
# define LOADARGS_1
Packit Service 82fcde
# define LOADARGS_2
Packit Service 82fcde
# define LOADARGS_3
Packit Service 82fcde
# define LOADARGS_4
Packit Service 82fcde
# define LOADARGS_5
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#define RESTOREARGS_0
Packit Service 82fcde
#ifdef __PIC__
Packit Service 82fcde
# if I386_USE_SYSENTER && defined PIC
Packit Service 82fcde
#  define RESTOREARGS_1 \
Packit Service 82fcde
    "bpopl .L__X'%k3, %k3\n\t"
Packit Service 82fcde
#  define RESTOREARGS_5 \
Packit Service 82fcde
    "movl %4, %%ebx"
Packit Service 82fcde
# else
Packit Service 82fcde
#  define RESTOREARGS_1 \
Packit Service 82fcde
    "bpopl .L__X'%k2, %k2\n\t"
Packit Service 82fcde
#  define RESTOREARGS_5 \
Packit Service 82fcde
    "movl %3, %%ebx"
Packit Service 82fcde
# endif
Packit Service 82fcde
# define RESTOREARGS_2	RESTOREARGS_1
Packit Service 82fcde
# define RESTOREARGS_3 \
Packit Service 82fcde
    "xchgl %%edi, %%ebx\n\t"
Packit Service 82fcde
# define RESTOREARGS_4	RESTOREARGS_3
Packit Service 82fcde
#else
Packit Service 82fcde
# define RESTOREARGS_1
Packit Service 82fcde
# define RESTOREARGS_2
Packit Service 82fcde
# define RESTOREARGS_3
Packit Service 82fcde
# define RESTOREARGS_4
Packit Service 82fcde
# define RESTOREARGS_5
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef OPTIMIZE_FOR_GCC_5
Packit Service 82fcde
# define LOADREGS_0()
Packit Service 82fcde
# define ASMARGS_0()
Packit Service 82fcde
# define LOADREGS_1(arg1) \
Packit Service 82fcde
	LOADREGS_0 ()
Packit Service 82fcde
# define ASMARGS_1(arg1) \
Packit Service 82fcde
	ASMARGS_0 (), "b" ((unsigned int) (arg1))
Packit Service 82fcde
# define LOADREGS_2(arg1, arg2) \
Packit Service 82fcde
	LOADREGS_1 (arg1)
Packit Service 82fcde
# define ASMARGS_2(arg1, arg2) \
Packit Service 82fcde
	ASMARGS_1 (arg1), "c" ((unsigned int) (arg2))
Packit Service 82fcde
# define LOADREGS_3(arg1, arg2, arg3) \
Packit Service 82fcde
	LOADREGS_2 (arg1, arg2)
Packit Service 82fcde
# define ASMARGS_3(arg1, arg2, arg3) \
Packit Service 82fcde
	ASMARGS_2 (arg1, arg2), "d" ((unsigned int) (arg3))
Packit Service 82fcde
# define LOADREGS_4(arg1, arg2, arg3, arg4) \
Packit Service 82fcde
	LOADREGS_3 (arg1, arg2, arg3)
Packit Service 82fcde
# define ASMARGS_4(arg1, arg2, arg3, arg4) \
Packit Service 82fcde
	ASMARGS_3 (arg1, arg2, arg3), "S" ((unsigned int) (arg4))
Packit Service 82fcde
# define LOADREGS_5(arg1, arg2, arg3, arg4, arg5) \
Packit Service 82fcde
	LOADREGS_4 (arg1, arg2, arg3, arg4)
Packit Service 82fcde
# define ASMARGS_5(arg1, arg2, arg3, arg4, arg5) \
Packit Service 82fcde
	ASMARGS_4 (arg1, arg2, arg3, arg4), "D" ((unsigned int) (arg5))
Packit Service 82fcde
# define LOADREGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
Packit Service 82fcde
	register unsigned int _a6 asm ("ebp") = (unsigned int) (arg6); \
Packit Service 82fcde
	LOADREGS_5 (arg1, arg2, arg3, arg4, arg5)
Packit Service 82fcde
# define ASMARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
Packit Service 82fcde
	ASMARGS_5 (arg1, arg2, arg3, arg4, arg5), "r" (_a6)
Packit Service 82fcde
#endif /* GCC 5  */
Packit Service 82fcde
Packit Service 82fcde
#define ASMFMT_0()
Packit Service 82fcde
#ifdef __PIC__
Packit Service 82fcde
# define ASMFMT_1(arg1) \
Packit Service 82fcde
	, "cd" (arg1)
Packit Service 82fcde
# define ASMFMT_2(arg1, arg2) \
Packit Service 82fcde
	, "d" (arg1), "c" (arg2)
Packit Service 82fcde
# define ASMFMT_3(arg1, arg2, arg3) \
Packit Service 82fcde
	, "D" (arg1), "c" (arg2), "d" (arg3)
Packit Service 82fcde
# define ASMFMT_4(arg1, arg2, arg3, arg4) \
Packit Service 82fcde
	, "D" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
Packit Service 82fcde
# define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
Packit Service 82fcde
	, "0" (arg1), "m" (_xv), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
Packit Service 82fcde
#else
Packit Service 82fcde
# define ASMFMT_1(arg1) \
Packit Service 82fcde
	, "b" (arg1)
Packit Service 82fcde
# define ASMFMT_2(arg1, arg2) \
Packit Service 82fcde
	, "b" (arg1), "c" (arg2)
Packit Service 82fcde
# define ASMFMT_3(arg1, arg2, arg3) \
Packit Service 82fcde
	, "b" (arg1), "c" (arg2), "d" (arg3)
Packit Service 82fcde
# define ASMFMT_4(arg1, arg2, arg3, arg4) \
Packit Service 82fcde
	, "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
Packit Service 82fcde
# define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
Packit Service 82fcde
	, "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#define EXTRAVAR_0
Packit Service 82fcde
#define EXTRAVAR_1
Packit Service 82fcde
#define EXTRAVAR_2
Packit Service 82fcde
#define EXTRAVAR_3
Packit Service 82fcde
#define EXTRAVAR_4
Packit Service 82fcde
#ifdef __PIC__
Packit Service 82fcde
# define EXTRAVAR_5 int _xv;
Packit Service 82fcde
#else
Packit Service 82fcde
# define EXTRAVAR_5
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Consistency check for position-independent code.  */
Packit Service 82fcde
#if defined __PIC__ && !defined OPTIMIZE_FOR_GCC_5
Packit Service 82fcde
# define check_consistency()						      \
Packit Service 82fcde
  ({ int __res;								      \
Packit Service 82fcde
     __asm__ __volatile__						      \
Packit Service 82fcde
       (LOAD_PIC_REG_STR (cx) ";"					      \
Packit Service 82fcde
	"subl %%ebx, %%ecx;"						      \
Packit Service 82fcde
	"je 1f;"							      \
Packit Service 82fcde
	"ud2;"								      \
Packit Service 82fcde
	"1:\n"								      \
Packit Service 82fcde
	: "=c" (__res));						      \
Packit Service 82fcde
     __res; })
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#endif	/* __ASSEMBLER__ */
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Pointer mangling support.  */
Packit Service 82fcde
#if IS_IN (rtld)
Packit Service 82fcde
/* We cannot use the thread descriptor because in ld.so we use setjmp
Packit Service 82fcde
   earlier than the descriptor is initialized.  Using a global variable
Packit Service 82fcde
   is too complicated here since we have no PC-relative addressing mode.  */
Packit Service 82fcde
#else
Packit Service 82fcde
# ifdef __ASSEMBLER__
Packit Service 82fcde
#  define PTR_MANGLE(reg)	xorl %gs:POINTER_GUARD, reg;		      \
Packit Service 82fcde
				roll $9, reg
Packit Service 82fcde
#  define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
Packit Service 82fcde
				xorl %gs:POINTER_GUARD, reg
Packit Service 82fcde
# else
Packit Service 82fcde
#  define PTR_MANGLE(var)	asm ("xorl %%gs:%c2, %0\n"		      \
Packit Service 82fcde
				     "roll $9, %0"			      \
Packit Service 82fcde
				     : "=r" (var)			      \
Packit Service 82fcde
				     : "0" (var),			      \
Packit Service 82fcde
				       "i" (offsetof (tcbhead_t,	      \
Packit Service 82fcde
						      pointer_guard)))
Packit Service 82fcde
#  define PTR_DEMANGLE(var)	asm ("rorl $9, %0\n"			      \
Packit Service 82fcde
				     "xorl %%gs:%c2, %0"		      \
Packit Service 82fcde
				     : "=r" (var)			      \
Packit Service 82fcde
				     : "0" (var),			      \
Packit Service 82fcde
				       "i" (offsetof (tcbhead_t,	      \
Packit Service 82fcde
						      pointer_guard)))
Packit Service 82fcde
# endif
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#endif /* linux/i386/sysdep.h */