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

Packit 6c4009
/* Copyright (C) 2001-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
#ifndef _LINUX_X86_64_SYSDEP_H
Packit 6c4009
#define _LINUX_X86_64_SYSDEP_H 1
Packit 6c4009
Packit 6c4009
/* There is some commonality.  */
Packit 6c4009
#include <sysdeps/unix/sysv/linux/sysdep.h>
Packit 6c4009
#include <sysdeps/unix/x86_64/sysdep.h>
Packit 6c4009
#include <tls.h>
Packit 6c4009
Packit 6c4009
/* Defines RTLD_PRIVATE_ERRNO.  */
Packit 6c4009
#include <dl-sysdep.h>
Packit 6c4009
Packit 6c4009
/* For Linux we can use the system call table in the header file
Packit 6c4009
	/usr/include/asm/unistd.h
Packit 6c4009
   of the kernel.  But these symbols do not follow the SYS_* syntax
Packit 6c4009
   so we have to redefine the `SYS_ify' macro here.  */
Packit 6c4009
#undef SYS_ify
Packit 6c4009
#define SYS_ify(syscall_name)	__NR_##syscall_name
Packit 6c4009
Packit 6c4009
/* This is a kludge to make syscalls.list find these under the names
Packit 6c4009
   pread and pwrite, since some kernel headers define those names
Packit 6c4009
   and some define the *64 names for the same system calls.  */
Packit 6c4009
#if !defined __NR_pread && defined __NR_pread64
Packit 6c4009
# define __NR_pread __NR_pread64
Packit 6c4009
#endif
Packit 6c4009
#if !defined __NR_pwrite && defined __NR_pwrite64
Packit 6c4009
# define __NR_pwrite __NR_pwrite64
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* This is to help the old kernel headers where __NR_semtimedop is not
Packit 6c4009
   available.  */
Packit 6c4009
#ifndef __NR_semtimedop
Packit 6c4009
# define __NR_semtimedop 220
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
#ifdef __ASSEMBLER__
Packit 6c4009
Packit 6c4009
/* Linux uses a negative return value to indicate syscall errors,
Packit 6c4009
   unlike most Unices, which use the condition codes' carry flag.
Packit 6c4009
Packit 6c4009
   Since version 2.1 the return value of a system call might be
Packit 6c4009
   negative even if the call succeeded.	 E.g., the `lseek' system call
Packit 6c4009
   might return a large offset.	 Therefore we must not anymore test
Packit 6c4009
   for < 0, but test for a real error by making sure the value in %eax
Packit 6c4009
   is a real error number.  Linus said he will make sure the no syscall
Packit 6c4009
   returns a value in -1 .. -4095 as a valid result so we can savely
Packit 6c4009
   test with -4095.  */
Packit 6c4009
Packit 6c4009
/* We don't want the label for the error handle to be global when we define
Packit 6c4009
   it here.  */
Packit 6c4009
# ifdef PIC
Packit 6c4009
#  define SYSCALL_ERROR_LABEL 0f
Packit 6c4009
# else
Packit 6c4009
#  define SYSCALL_ERROR_LABEL syscall_error
Packit 6c4009
# endif
Packit 6c4009
Packit 6c4009
# undef	PSEUDO
Packit 6c4009
# define PSEUDO(name, syscall_name, args)				      \
Packit 6c4009
  .text;								      \
Packit 6c4009
  ENTRY (name)								      \
Packit 6c4009
    DO_CALL (syscall_name, args);					      \
Packit 6c4009
    cmpq $-4095, %rax;							      \
Packit 6c4009
    jae SYSCALL_ERROR_LABEL
Packit 6c4009
Packit 6c4009
# undef	PSEUDO_END
Packit 6c4009
# define PSEUDO_END(name)						      \
Packit 6c4009
  SYSCALL_ERROR_HANDLER							      \
Packit 6c4009
  END (name)
Packit 6c4009
Packit 6c4009
# undef	PSEUDO_NOERRNO
Packit 6c4009
# define PSEUDO_NOERRNO(name, syscall_name, args) \
Packit 6c4009
  .text;								      \
Packit 6c4009
  ENTRY (name)								      \
Packit 6c4009
    DO_CALL (syscall_name, args)
Packit 6c4009
Packit 6c4009
# undef	PSEUDO_END_NOERRNO
Packit 6c4009
# define PSEUDO_END_NOERRNO(name) \
Packit 6c4009
  END (name)
Packit 6c4009
Packit 6c4009
# define ret_NOERRNO ret
Packit 6c4009
Packit 6c4009
# undef	PSEUDO_ERRVAL
Packit 6c4009
# define PSEUDO_ERRVAL(name, syscall_name, args) \
Packit 6c4009
  .text;								      \
Packit 6c4009
  ENTRY (name)								      \
Packit 6c4009
    DO_CALL (syscall_name, args);					      \
Packit 6c4009
    negq %rax
Packit 6c4009
Packit 6c4009
# undef	PSEUDO_END_ERRVAL
Packit 6c4009
# define PSEUDO_END_ERRVAL(name) \
Packit 6c4009
  END (name)
Packit 6c4009
Packit 6c4009
# define ret_ERRVAL ret
Packit 6c4009
Packit 6c4009
# if defined PIC && RTLD_PRIVATE_ERRNO
Packit 6c4009
#  define SYSCALL_SET_ERRNO			\
Packit 6c4009
  lea rtld_errno(%rip), %RCX_LP;		\
Packit 6c4009
  neg %eax;					\
Packit 6c4009
  movl %eax, (%rcx)
Packit 6c4009
# else
Packit 6c4009
#  if IS_IN (libc)
Packit 6c4009
#   define SYSCALL_ERROR_ERRNO __libc_errno
Packit 6c4009
#  else
Packit 6c4009
#   define SYSCALL_ERROR_ERRNO errno
Packit 6c4009
#  endif
Packit 6c4009
#  define SYSCALL_SET_ERRNO			\
Packit 6c4009
  movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\
Packit 6c4009
  neg %eax;					\
Packit 6c4009
  movl %eax, %fs:(%rcx);
Packit 6c4009
# endif
Packit 6c4009
Packit 6c4009
# ifndef PIC
Packit 6c4009
#  define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
Packit 6c4009
# else
Packit 6c4009
#  define SYSCALL_ERROR_HANDLER			\
Packit 6c4009
0:						\
Packit 6c4009
  SYSCALL_SET_ERRNO;				\
Packit 6c4009
  or $-1, %RAX_LP;				\
Packit 6c4009
  ret;
Packit 6c4009
# endif	/* PIC */
Packit 6c4009
Packit 6c4009
/* The Linux/x86-64 kernel expects the system call parameters in
Packit 6c4009
   registers according to the following table:
Packit 6c4009
Packit 6c4009
    syscall number	rax
Packit 6c4009
    arg 1		rdi
Packit 6c4009
    arg 2		rsi
Packit 6c4009
    arg 3		rdx
Packit 6c4009
    arg 4		r10
Packit 6c4009
    arg 5		r8
Packit 6c4009
    arg 6		r9
Packit 6c4009
Packit 6c4009
    The Linux kernel uses and destroys internally these registers:
Packit 6c4009
    return address from
Packit 6c4009
    syscall		rcx
Packit 6c4009
    eflags from syscall	r11
Packit 6c4009
Packit 6c4009
    Normal function call, including calls to the system call stub
Packit 6c4009
    functions in the libc, get the first six parameters passed in
Packit 6c4009
    registers and the seventh parameter and later on the stack.  The
Packit 6c4009
    register use is as follows:
Packit 6c4009
Packit 6c4009
     system call number	in the DO_CALL macro
Packit 6c4009
     arg 1		rdi
Packit 6c4009
     arg 2		rsi
Packit 6c4009
     arg 3		rdx
Packit 6c4009
     arg 4		rcx
Packit 6c4009
     arg 5		r8
Packit 6c4009
     arg 6		r9
Packit 6c4009
Packit 6c4009
    We have to take care that the stack is aligned to 16 bytes.  When
Packit 6c4009
    called the stack is not aligned since the return address has just
Packit 6c4009
    been pushed.
Packit 6c4009
Packit 6c4009
Packit 6c4009
    Syscalls of more than 6 arguments are not supported.  */
Packit 6c4009
Packit 6c4009
# undef	DO_CALL
Packit 6c4009
# define DO_CALL(syscall_name, args)		\
Packit 6c4009
    DOARGS_##args				\
Packit 6c4009
    movl $SYS_ify (syscall_name), %eax;		\
Packit 6c4009
    syscall;
Packit 6c4009
Packit 6c4009
# define DOARGS_0 /* nothing */
Packit 6c4009
# define DOARGS_1 /* nothing */
Packit 6c4009
# define DOARGS_2 /* nothing */
Packit 6c4009
# define DOARGS_3 /* nothing */
Packit 6c4009
# define DOARGS_4 movq %rcx, %r10;
Packit 6c4009
# define DOARGS_5 DOARGS_4
Packit 6c4009
# define DOARGS_6 DOARGS_5
Packit 6c4009
Packit 6c4009
#else	/* !__ASSEMBLER__ */
Packit 6c4009
/* Define a macro which expands inline into the wrapper code for a system
Packit 6c4009
   call.  */
Packit 6c4009
# undef INLINE_SYSCALL
Packit 6c4009
# define INLINE_SYSCALL(name, nr, args...) \
Packit 6c4009
  ({									      \
Packit 6c4009
    unsigned long int resultvar = INTERNAL_SYSCALL (name, , nr, args);	      \
Packit 6c4009
    if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
Packit 6c4009
      {									      \
Packit 6c4009
	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
Packit 6c4009
	resultvar = (unsigned long int) -1;				      \
Packit 6c4009
      }									      \
Packit 6c4009
    (long int) resultvar; })
Packit 6c4009
Packit 6c4009
/* Define a macro with explicit types for arguments, which expands inline
Packit 6c4009
   into the wrapper code for a system call.  It should be used when size
Packit 6c4009
   of any argument > size of long int.  */
Packit 6c4009
# undef INLINE_SYSCALL_TYPES
Packit 6c4009
# define INLINE_SYSCALL_TYPES(name, nr, args...) \
Packit 6c4009
  ({									      \
Packit 6c4009
    unsigned long int resultvar = INTERNAL_SYSCALL_TYPES (name, , nr, args);  \
Packit 6c4009
    if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
Packit 6c4009
      {									      \
Packit 6c4009
	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
Packit 6c4009
	resultvar = (unsigned long int) -1;				      \
Packit 6c4009
      }									      \
Packit 6c4009
    (long int) resultvar; })
Packit 6c4009
Packit 6c4009
# undef INTERNAL_SYSCALL_DECL
Packit 6c4009
# define INTERNAL_SYSCALL_DECL(err) do { } while (0)
Packit 6c4009
Packit 6c4009
/* Registers clobbered by syscall.  */
Packit 6c4009
# define REGISTERS_CLOBBERED_BY_SYSCALL "cc", "r11", "cx"
Packit 6c4009
Packit 6c4009
/* Create a variable 'name' based on type 'X' to avoid explicit types.
Packit 6c4009
   This is mainly used set use 64-bits arguments in x32.   */
Packit 6c4009
#define TYPEFY(X, name) __typeof__ ((X) - (X)) name
Packit 6c4009
/* Explicit cast the argument to avoid integer from pointer warning on
Packit 6c4009
   x32.  */
Packit 6c4009
#define ARGIFY(X) ((__typeof__ ((X) - (X))) (X))
Packit 6c4009
Packit 6c4009
#undef INTERNAL_SYSCALL
Packit 6c4009
#define INTERNAL_SYSCALL(name, err, nr, args...)			\
Packit 6c4009
	internal_syscall##nr (SYS_ify (name), err, args)
Packit 6c4009
Packit 6c4009
#undef INTERNAL_SYSCALL_NCS
Packit 6c4009
#define INTERNAL_SYSCALL_NCS(number, err, nr, args...)			\
Packit 6c4009
	internal_syscall##nr (number, err, args)
Packit 6c4009
Packit 6c4009
#undef internal_syscall0
Packit 6c4009
#define internal_syscall0(number, err, dummy...)			\
Packit 6c4009
({									\
Packit 6c4009
    unsigned long int resultvar;					\
Packit 6c4009
    asm volatile (							\
Packit 6c4009
    "syscall\n\t"							\
Packit 6c4009
    : "=a" (resultvar)							\
Packit 6c4009
    : "0" (number)							\
Packit 6c4009
    : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
Packit 6c4009
    (long int) resultvar;						\
Packit 6c4009
})
Packit 6c4009
Packit 6c4009
#undef internal_syscall1
Packit 6c4009
#define internal_syscall1(number, err, arg1)				\
Packit 6c4009
({									\
Packit 6c4009
    unsigned long int resultvar;					\
Packit 6c4009
    TYPEFY (arg1, __arg1) = ARGIFY (arg1);			 	\
Packit 6c4009
    register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
Packit 6c4009
    asm volatile (							\
Packit 6c4009
    "syscall\n\t"							\
Packit 6c4009
    : "=a" (resultvar)							\
Packit 6c4009
    : "0" (number), "r" (_a1)						\
Packit 6c4009
    : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
Packit 6c4009
    (long int) resultvar;						\
Packit 6c4009
})
Packit 6c4009
Packit 6c4009
#undef internal_syscall2
Packit 6c4009
#define internal_syscall2(number, err, arg1, arg2)			\
Packit 6c4009
({									\
Packit 6c4009
    unsigned long int resultvar;					\
Packit 6c4009
    TYPEFY (arg2, __arg2) = ARGIFY (arg2);			 	\
Packit 6c4009
    TYPEFY (arg1, __arg1) = ARGIFY (arg1);			 	\
Packit 6c4009
    register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
Packit 6c4009
    register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
Packit 6c4009
    asm volatile (							\
Packit 6c4009
    "syscall\n\t"							\
Packit 6c4009
    : "=a" (resultvar)							\
Packit 6c4009
    : "0" (number), "r" (_a1), "r" (_a2)				\
Packit 6c4009
    : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
Packit 6c4009
    (long int) resultvar;						\
Packit 6c4009
})
Packit 6c4009
Packit 6c4009
#undef internal_syscall3
Packit 6c4009
#define internal_syscall3(number, err, arg1, arg2, arg3)		\
Packit 6c4009
({									\
Packit 6c4009
    unsigned long int resultvar;					\
Packit 6c4009
    TYPEFY (arg3, __arg3) = ARGIFY (arg3);			 	\
Packit 6c4009
    TYPEFY (arg2, __arg2) = ARGIFY (arg2);			 	\
Packit 6c4009
    TYPEFY (arg1, __arg1) = ARGIFY (arg1);			 	\
Packit 6c4009
    register TYPEFY (arg3, _a3) asm ("rdx") = __arg3;			\
Packit 6c4009
    register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
Packit 6c4009
    register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
Packit 6c4009
    asm volatile (							\
Packit 6c4009
    "syscall\n\t"							\
Packit 6c4009
    : "=a" (resultvar)							\
Packit 6c4009
    : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3)			\
Packit 6c4009
    : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
Packit 6c4009
    (long int) resultvar;						\
Packit 6c4009
})
Packit 6c4009
Packit 6c4009
#undef internal_syscall4
Packit 6c4009
#define internal_syscall4(number, err, arg1, arg2, arg3, arg4)		\
Packit 6c4009
({									\
Packit 6c4009
    unsigned long int resultvar;					\
Packit 6c4009
    TYPEFY (arg4, __arg4) = ARGIFY (arg4);			 	\
Packit 6c4009
    TYPEFY (arg3, __arg3) = ARGIFY (arg3);			 	\
Packit 6c4009
    TYPEFY (arg2, __arg2) = ARGIFY (arg2);			 	\
Packit 6c4009
    TYPEFY (arg1, __arg1) = ARGIFY (arg1);			 	\
Packit 6c4009
    register TYPEFY (arg4, _a4) asm ("r10") = __arg4;			\
Packit 6c4009
    register TYPEFY (arg3, _a3) asm ("rdx") = __arg3;			\
Packit 6c4009
    register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
Packit 6c4009
    register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
Packit 6c4009
    asm volatile (							\
Packit 6c4009
    "syscall\n\t"							\
Packit 6c4009
    : "=a" (resultvar)							\
Packit 6c4009
    : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4)		\
Packit 6c4009
    : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
Packit 6c4009
    (long int) resultvar;						\
Packit 6c4009
})
Packit 6c4009
Packit 6c4009
#undef internal_syscall5
Packit 6c4009
#define internal_syscall5(number, err, arg1, arg2, arg3, arg4, arg5)	\
Packit 6c4009
({									\
Packit 6c4009
    unsigned long int resultvar;					\
Packit 6c4009
    TYPEFY (arg5, __arg5) = ARGIFY (arg5);			 	\
Packit 6c4009
    TYPEFY (arg4, __arg4) = ARGIFY (arg4);			 	\
Packit 6c4009
    TYPEFY (arg3, __arg3) = ARGIFY (arg3);			 	\
Packit 6c4009
    TYPEFY (arg2, __arg2) = ARGIFY (arg2);			 	\
Packit 6c4009
    TYPEFY (arg1, __arg1) = ARGIFY (arg1);			 	\
Packit 6c4009
    register TYPEFY (arg5, _a5) asm ("r8") = __arg5;			\
Packit 6c4009
    register TYPEFY (arg4, _a4) asm ("r10") = __arg4;			\
Packit 6c4009
    register TYPEFY (arg3, _a3) asm ("rdx") = __arg3;			\
Packit 6c4009
    register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
Packit 6c4009
    register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
Packit 6c4009
    asm volatile (							\
Packit 6c4009
    "syscall\n\t"							\
Packit 6c4009
    : "=a" (resultvar)							\
Packit 6c4009
    : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4),		\
Packit 6c4009
      "r" (_a5)								\
Packit 6c4009
    : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
Packit 6c4009
    (long int) resultvar;						\
Packit 6c4009
})
Packit 6c4009
Packit 6c4009
#undef internal_syscall6
Packit 6c4009
#define internal_syscall6(number, err, arg1, arg2, arg3, arg4, arg5, arg6) \
Packit 6c4009
({									\
Packit 6c4009
    unsigned long int resultvar;					\
Packit 6c4009
    TYPEFY (arg6, __arg6) = ARGIFY (arg6);			 	\
Packit 6c4009
    TYPEFY (arg5, __arg5) = ARGIFY (arg5);			 	\
Packit 6c4009
    TYPEFY (arg4, __arg4) = ARGIFY (arg4);			 	\
Packit 6c4009
    TYPEFY (arg3, __arg3) = ARGIFY (arg3);			 	\
Packit 6c4009
    TYPEFY (arg2, __arg2) = ARGIFY (arg2);			 	\
Packit 6c4009
    TYPEFY (arg1, __arg1) = ARGIFY (arg1);			 	\
Packit 6c4009
    register TYPEFY (arg6, _a6) asm ("r9") = __arg6;			\
Packit 6c4009
    register TYPEFY (arg5, _a5) asm ("r8") = __arg5;			\
Packit 6c4009
    register TYPEFY (arg4, _a4) asm ("r10") = __arg4;			\
Packit 6c4009
    register TYPEFY (arg3, _a3) asm ("rdx") = __arg3;			\
Packit 6c4009
    register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
Packit 6c4009
    register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
Packit 6c4009
    asm volatile (							\
Packit 6c4009
    "syscall\n\t"							\
Packit 6c4009
    : "=a" (resultvar)							\
Packit 6c4009
    : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4),		\
Packit 6c4009
      "r" (_a5), "r" (_a6)						\
Packit 6c4009
    : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
Packit 6c4009
    (long int) resultvar;						\
Packit 6c4009
})
Packit 6c4009
Packit 6c4009
# undef INTERNAL_SYSCALL_ERROR_P
Packit 6c4009
# define INTERNAL_SYSCALL_ERROR_P(val, err) \
Packit 6c4009
  ((unsigned long int) (long int) (val) >= -4095L)
Packit 6c4009
Packit 6c4009
# undef INTERNAL_SYSCALL_ERRNO
Packit 6c4009
# define INTERNAL_SYSCALL_ERRNO(val, err)	(-(val))
Packit 6c4009
Packit 6c4009
/* List of system calls which are supported as vsyscalls.  */
Packit 6c4009
# define HAVE_CLOCK_GETTIME_VSYSCALL    1
Packit 6c4009
# define HAVE_GETTIMEOFDAY_VSYSCALL     1
Packit 6c4009
# define HAVE_GETCPU_VSYSCALL		1
Packit 6c4009
Packit 6c4009
# define SINGLE_THREAD_BY_GLOBAL		1
Packit 6c4009
Packit 6c4009
#endif	/* __ASSEMBLER__ */
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Pointer mangling support.  */
Packit 6c4009
#if IS_IN (rtld)
Packit 6c4009
/* We cannot use the thread descriptor because in ld.so we use setjmp
Packit 6c4009
   earlier than the descriptor is initialized.  */
Packit 6c4009
# ifdef __ASSEMBLER__
Packit 6c4009
#  define PTR_MANGLE(reg)	xor __pointer_chk_guard_local(%rip), reg;    \
Packit 6c4009
				rol $2*LP_SIZE+1, reg
Packit 6c4009
#  define PTR_DEMANGLE(reg)	ror $2*LP_SIZE+1, reg;			     \
Packit 6c4009
				xor __pointer_chk_guard_local(%rip), reg
Packit 6c4009
# else
Packit 6c4009
#  define PTR_MANGLE(reg)	asm ("xor __pointer_chk_guard_local(%%rip), %0\n" \
Packit 6c4009
				     "rol $2*" LP_SIZE "+1, %0"			  \
Packit 6c4009
				     : "=r" (reg) : "0" (reg))
Packit 6c4009
#  define PTR_DEMANGLE(reg)	asm ("ror $2*" LP_SIZE "+1, %0\n"		  \
Packit 6c4009
				     "xor __pointer_chk_guard_local(%%rip), %0"   \
Packit 6c4009
				     : "=r" (reg) : "0" (reg))
Packit 6c4009
# endif
Packit 6c4009
#else
Packit 6c4009
# ifdef __ASSEMBLER__
Packit 6c4009
#  define PTR_MANGLE(reg)	xor %fs:POINTER_GUARD, reg;		      \
Packit 6c4009
				rol $2*LP_SIZE+1, reg
Packit 6c4009
#  define PTR_DEMANGLE(reg)	ror $2*LP_SIZE+1, reg;			      \
Packit 6c4009
				xor %fs:POINTER_GUARD, reg
Packit 6c4009
# else
Packit 6c4009
#  define PTR_MANGLE(var)	asm ("xor %%fs:%c2, %0\n"		      \
Packit 6c4009
				     "rol $2*" LP_SIZE "+1, %0"		      \
Packit 6c4009
				     : "=r" (var)			      \
Packit 6c4009
				     : "0" (var),			      \
Packit 6c4009
				       "i" (offsetof (tcbhead_t,	      \
Packit 6c4009
						      pointer_guard)))
Packit 6c4009
#  define PTR_DEMANGLE(var)	asm ("ror $2*" LP_SIZE "+1, %0\n"	      \
Packit 6c4009
				     "xor %%fs:%c2, %0"			      \
Packit 6c4009
				     : "=r" (var)			      \
Packit 6c4009
				     : "0" (var),			      \
Packit 6c4009
				       "i" (offsetof (tcbhead_t,	      \
Packit 6c4009
						      pointer_guard)))
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* How to pass the off{64}_t argument on p{readv,writev}{64}.  */
Packit 6c4009
#undef LO_HI_LONG
Packit 6c4009
#define LO_HI_LONG(val) (val), 0
Packit 6c4009
Packit 6c4009
/* Each shadow stack slot takes 8 bytes.  Assuming that each stack
Packit 6c4009
   frame takes 256 bytes, this is used to compute shadow stack size
Packit 6c4009
   from stack size.  */
Packit 6c4009
#define STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT 5
Packit 6c4009
Packit 6c4009
#endif /* linux/x86_64/sysdep.h */