diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 19:01:57 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 19:01:57 +0000 |
commit | cab56836b146bc129f1ad43f0393d95a9deca63a (patch) | |
tree | 4f4e655319bbac78fca170da05275c127429b460 /sysdeps/unix/sysv/linux/x86 | |
parent | 04ac1241a4cd004872282c2c82ec37fa33925292 (diff) | |
parent | 82dd75a7f436a19047325d62182590c9f9e23a78 (diff) |
Merge branch 't/tls' into refs/top-bases/t/tls-threadvar
Diffstat (limited to 'sysdeps/unix/sysv/linux/x86')
55 files changed, 1233 insertions, 506 deletions
diff --git a/sysdeps/unix/sysv/linux/x86/Implies b/sysdeps/unix/sysv/linux/x86/Implies new file mode 100644 index 0000000000..e454b288aa --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/Implies @@ -0,0 +1 @@ +x86/nptl diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile index 9e6ec44b3a..7dc4e61756 100644 --- a/sysdeps/unix/sysv/linux/x86/Makefile +++ b/sysdeps/unix/sysv/linux/x86/Makefile @@ -3,11 +3,8 @@ abi-includes := abi-variants := 32 64 x32 -abi-32-options := -D__i386__ -U__x86_64__ abi-32-condition := !defined __x86_64__ -abi-64-options := -U__i386__ -D__x86_64__ -U__ILP32__ -D__LP64__ abi-64-condition := defined __x86_64__ && defined __LP64__ -abi-x32-options := -U__i386__ -D__x86_64__ -D__ILP32__ -U__LP64__ abi-x32-condition := defined __x86_64__ && defined __ILP32__ ifeq ($(subdir),misc) @@ -22,3 +19,29 @@ endif ifeq ($(subdir),elf) sysdep_routines += dl-vdso endif + +ifeq ($(subdir),setjmp) +tests += tst-saved_mask-1 +endif + +ifeq ($(enable-cet),yes) +ifeq ($(subdir),elf) +tests += tst-cet-property-1 tst-cet-property-2 + +CFLAGS-tst-cet-property-1.o += -fcf-protection +ASFLAGS-tst-cet-property-dep-2.o += -fcf-protection + +$(objpfx)tst-cet-property-2: $(objpfx)tst-cet-property-dep-2.o +$(objpfx)tst-cet-property-2.out: $(objpfx)tst-cet-property-2 \ + $(objpfx)tst-cet-property-1.out + env $(run-program-env) $(test-via-rtld-prefix) \ + $(objpfx)tst-cet-property-2 \ + < $(objpfx)tst-cet-property-1.out > $@; \ + $(evaluate-test) +endif + +ifeq ($(subdir),stdlib) +tests += tst-cet-setcontext-1 +CFLAGS-tst-cet-setcontext-1.c += -mshstk +endif +endif diff --git a/sysdeps/unix/sysv/linux/x86/arch-pkey.h b/sysdeps/unix/sysv/linux/x86/arch-pkey.h new file mode 100644 index 0000000000..b33956b6a2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/arch-pkey.h @@ -0,0 +1,40 @@ +/* Helper functions for manipulating memory protection keys. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _ARCH_PKEY_H +#define _ARCH_PKEY_H + +/* Return the value of the PKRU register. */ +static inline unsigned int +pkey_read (void) +{ + unsigned int result; + __asm__ volatile (".byte 0x0f, 0x01, 0xee" + : "=a" (result) : "c" (0) : "rdx"); + return result; +} + +/* Overwrite the PKRU register with VALUE. */ +static inline void +pkey_write (unsigned int value) +{ + __asm__ volatile (".byte 0x0f, 0x01, 0xef" + : : "a" (value), "c" (0), "d" (0)); +} + +#endif /* _ARCH_PKEY_H */ diff --git a/sysdeps/unix/sysv/linux/x86/bits/environments.h b/sysdeps/unix/sysv/linux/x86/bits/environments.h index a7e8fb00e6..478c1cb718 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/environments.h +++ b/sysdeps/unix/sysv/linux/x86/bits/environments.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2016 Free Software Foundation, Inc. +/* Copyright (C) 1999-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/bits/epoll.h b/sysdeps/unix/sysv/linux/x86/bits/epoll.h index 84a24da650..577899c3db 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/epoll.h +++ b/sysdeps/unix/sysv/linux/x86/bits/epoll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2016 Free Software Foundation, Inc. +/* Copyright (C) 2002-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/bits/fcntl.h b/sysdeps/unix/sysv/linux/x86/bits/fcntl.h index 0a01a67081..f26077c9cb 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/fcntl.h +++ b/sysdeps/unix/sysv/linux/x86/bits/fcntl.h @@ -1,5 +1,5 @@ /* O_*, F_*, FD_* bit values for Linux/x86. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/bits/ipctypes.h b/sysdeps/unix/sysv/linux/x86/bits/ipctypes.h index aeb00903b6..be0fc92cae 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/ipctypes.h +++ b/sysdeps/unix/sysv/linux/x86/bits/ipctypes.h @@ -1,5 +1,5 @@ /* bits/ipctypes.h -- Define some types used by SysV IPC/MSG/SHM. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/bits/mman.h b/sysdeps/unix/sysv/linux/x86/bits/mman.h index c1d3147d0b..d897b8a2b2 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/mman.h +++ b/sysdeps/unix/sysv/linux/x86/bits/mman.h @@ -1,5 +1,5 @@ /* Definitions for POSIX memory map interface. Linux/x86_64 version. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -39,6 +39,10 @@ # define MAP_NONBLOCK 0x10000 /* Do not block on IO. */ # define MAP_STACK 0x20000 /* Allocation is for a stack. */ # define MAP_HUGETLB 0x40000 /* Create huge page mapping. */ +# define MAP_SYNC 0x80000 /* Perform synchronous page + faults for the mapping. */ +# define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED but do not unmap + underlying mapping. */ #endif /* Include generic Linux declarations. */ diff --git a/sysdeps/unix/sysv/linux/x86/bits/msq.h b/sysdeps/unix/sysv/linux/x86/bits/msq.h index 467419486f..bc2e3bd13d 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/msq.h +++ b/sysdeps/unix/sysv/linux/x86/bits/msq.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2016 Free Software Foundation, Inc. +/* Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -65,6 +65,7 @@ struct msqid_ds /* ipcs ctl commands */ # define MSG_STAT 11 # define MSG_INFO 12 +# define MSG_STAT_ANY 13 /* buffer for msgctl calls IPC_INFO, MSG_INFO */ struct msginfo diff --git a/sysdeps/unix/sysv/linux/x86/bits/sem.h b/sysdeps/unix/sysv/linux/x86/bits/sem.h index fe757dcae9..6771966a06 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/sem.h +++ b/sysdeps/unix/sysv/linux/x86/bits/sem.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2016 Free Software Foundation, Inc. +/* Copyright (C) 2002-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -68,6 +68,7 @@ struct semid_ds /* ipcs ctl cmds */ # define SEM_STAT 18 # define SEM_INFO 19 +# define SEM_STAT_ANY 20 struct seminfo { diff --git a/sysdeps/unix/sysv/linux/x86/bits/shm.h b/sysdeps/unix/sysv/linux/x86/bits/shm.h index e593cbeb6b..767bb78573 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/shm.h +++ b/sysdeps/unix/sysv/linux/x86/bits/shm.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2016 Free Software Foundation, Inc. +/* Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -74,6 +74,7 @@ struct shmid_ds /* ipcs ctl commands */ # define SHM_STAT 13 # define SHM_INFO 14 +# define SHM_STAT_ANY 15 /* shm_mode upper byte flags */ # define SHM_DEST 01000 /* segment will be destroyed on last detach */ diff --git a/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h b/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h index 255738d7b2..5f19c48817 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h +++ b/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2016 Free Software Foundation, Inc. +/* Copyright (C) 2002-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,6 +22,8 @@ # error "Never use <bits/sigcontext.h> directly; include <signal.h> instead." #endif +#include <bits/types.h> + #define FP_XSTATE_MAGIC1 0x46505853U #define FP_XSTATE_MAGIC2 0x46505845U #define FP_XSTATE_MAGIC2_SIZE sizeof(FP_XSTATE_MAGIC2) @@ -32,7 +34,7 @@ struct _fpx_sw_bytes __uint32_t extended_size; __uint64_t xstate_bv; __uint32_t xstate_size; - __uint32_t padding[7]; + __uint32_t __glibc_reserved1[7]; }; struct _fpreg @@ -45,7 +47,7 @@ struct _fpxreg { unsigned short significand[4]; unsigned short exponent; - unsigned short padding[3]; + unsigned short __glibc_reserved1[3]; }; struct _xmmreg @@ -74,10 +76,10 @@ struct _fpstate /* FXSR FPU environment. */ __uint32_t _fxsr_env[6]; __uint32_t mxcsr; - __uint32_t reserved; + __uint32_t __glibc_reserved1; struct _fpxreg _fxsr_st[8]; struct _xmmreg _xmm[8]; - __uint32_t padding[56]; + __uint32_t __glibc_reserved2[56]; }; #ifndef sigcontext_struct @@ -131,7 +133,7 @@ struct _fpstate __uint32_t mxcr_mask; struct _fpxreg _st[8]; struct _xmmreg _xmm[16]; - __uint32_t padding[24]; + __uint32_t __glibc_reserved1[24]; }; struct sigcontext @@ -175,8 +177,8 @@ struct sigcontext struct _xsave_hdr { __uint64_t xstate_bv; - __uint64_t reserved1[2]; - __uint64_t reserved2[5]; + __uint64_t __glibc_reserved1[2]; + __uint64_t __glibc_reserved2[5]; }; struct _ymmh_state diff --git a/sysdeps/unix/sysv/linux/x86/bits/siginfo-arch.h b/sysdeps/unix/sysv/linux/x86/bits/siginfo-arch.h new file mode 100644 index 0000000000..7688a8d66d --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/bits/siginfo-arch.h @@ -0,0 +1,17 @@ +/* Architecture-specific adjustments to siginfo_t. x86 version. */ +#ifndef _BITS_SIGINFO_ARCH_H +#define _BITS_SIGINFO_ARCH_H 1 + +#if defined __x86_64__ && __WORDSIZE == 32 +/* si_utime and si_stime must be 4 byte aligned for x32 to match the + kernel. We align siginfo_t to 8 bytes so that si_utime and + si_stime are actually aligned to 8 bytes since their offsets are + multiple of 8 bytes. Note: with some compilers, the alignment + attribute would be ignored if it were put in __SI_CLOCK_T instead + of encapsulated in a typedef. */ +typedef __clock_t __attribute__ ((__aligned__ (4))) __sigchld_clock_t; +# define __SI_ALIGNMENT __attribute__ ((__aligned__ (8))) +# define __SI_CLOCK_T __sigchld_clock_t +#endif + +#endif diff --git a/sysdeps/unix/sysv/linux/x86/bits/siginfo.h b/sysdeps/unix/sysv/linux/x86/bits/siginfo.h deleted file mode 100644 index dbf253a3bc..0000000000 --- a/sysdeps/unix/sysv/linux/x86/bits/siginfo.h +++ /dev/null @@ -1,360 +0,0 @@ -/* siginfo_t, sigevent and constants. Linux x86-64 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#if !defined _SIGNAL_H && !defined __need_siginfo_t \ - && !defined __need_sigevent_t -# error "Never include this file directly. Use <signal.h> instead" -#endif - -#include <bits/wordsize.h> - -#if (!defined __have_sigval_t \ - && (defined _SIGNAL_H || defined __need_siginfo_t \ - || defined __need_sigevent_t)) -# define __have_sigval_t 1 - -/* Type for data associated with a signal. */ -typedef union sigval - { - int sival_int; - void *sival_ptr; - } sigval_t; -#endif - -#if (!defined __have_siginfo_t \ - && (defined _SIGNAL_H || defined __need_siginfo_t)) -# define __have_siginfo_t 1 - -# define __SI_MAX_SIZE 128 -# if __WORDSIZE == 64 -# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4) -# else -# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3) -# endif - -# if defined __x86_64__ && __WORDSIZE == 32 -/* si_utime and si_stime must be 4 byte aligned for x32 to match the - kernel. We align siginfo_t to 8 bytes so that si_utime and si_stime - are actually aligned to 8 bytes since their offsets are multiple of - 8 bytes. */ -typedef __clock_t __attribute__ ((__aligned__ (4))) __sigchld_clock_t; -# define __SI_ALIGNMENT __attribute__ ((__aligned__ (8))) -# else -typedef __clock_t __sigchld_clock_t; -# define __SI_ALIGNMENT -# endif - -typedef struct - { - int si_signo; /* Signal number. */ - int si_errno; /* If non-zero, an errno value associated with - this signal, as defined in <errno.h>. */ - int si_code; /* Signal code. */ - - union - { - int _pad[__SI_PAD_SIZE]; - - /* kill(). */ - struct - { - __pid_t si_pid; /* Sending process ID. */ - __uid_t si_uid; /* Real user ID of sending process. */ - } _kill; - - /* POSIX.1b timers. */ - struct - { - int si_tid; /* Timer ID. */ - int si_overrun; /* Overrun count. */ - sigval_t si_sigval; /* Signal value. */ - } _timer; - - /* POSIX.1b signals. */ - struct - { - __pid_t si_pid; /* Sending process ID. */ - __uid_t si_uid; /* Real user ID of sending process. */ - sigval_t si_sigval; /* Signal value. */ - } _rt; - - /* SIGCHLD. */ - struct - { - __pid_t si_pid; /* Which child. */ - __uid_t si_uid; /* Real user ID of sending process. */ - int si_status; /* Exit value or signal. */ - __sigchld_clock_t si_utime; - __sigchld_clock_t si_stime; - } _sigchld; - - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */ - struct - { - void *si_addr; /* Faulting insn/memory ref. */ - short int si_addr_lsb; /* Valid LSB of the reported address. */ - struct - { - void *_lower; - void *_upper; - } si_addr_bnd; - } _sigfault; - - /* SIGPOLL. */ - struct - { - long int si_band; /* Band event for SIGPOLL. */ - int si_fd; - } _sigpoll; - - /* SIGSYS. */ - struct - { - void *_call_addr; /* Calling user insn. */ - int _syscall; /* Triggering system call number. */ - unsigned int _arch; /* AUDIT_ARCH_* of syscall. */ - } _sigsys; - } _sifields; - } siginfo_t __SI_ALIGNMENT; - - -/* X/Open requires some more fields with fixed names. */ -# define si_pid _sifields._kill.si_pid -# define si_uid _sifields._kill.si_uid -# define si_timerid _sifields._timer.si_tid -# define si_overrun _sifields._timer.si_overrun -# define si_status _sifields._sigchld.si_status -# define si_utime _sifields._sigchld.si_utime -# define si_stime _sifields._sigchld.si_stime -# define si_value _sifields._rt.si_sigval -# define si_int _sifields._rt.si_sigval.sival_int -# define si_ptr _sifields._rt.si_sigval.sival_ptr -# define si_addr _sifields._sigfault.si_addr -# define si_addr_lsb _sifields._sigfault.si_addr_lsb -# define si_lower _sifields._sigfault.si_addr_bnd._lower -# define si_upper _sifields._sigfault.si_addr_bnd._upper -# define si_band _sifields._sigpoll.si_band -# define si_fd _sifields._sigpoll.si_fd -# define si_call_addr _sifields._sigsys._call_addr -# define si_syscall _sifields._sigsys._syscall -# define si_arch _sifields._sigsys._arch - - -/* Values for `si_code'. Positive values are reserved for kernel-generated - signals. */ -enum -{ - SI_ASYNCNL = -60, /* Sent by asynch name lookup completion. */ -# define SI_ASYNCNL SI_ASYNCNL - SI_TKILL = -6, /* Sent by tkill. */ -# define SI_TKILL SI_TKILL - SI_SIGIO, /* Sent by queued SIGIO. */ -# define SI_SIGIO SI_SIGIO - SI_ASYNCIO, /* Sent by AIO completion. */ -# define SI_ASYNCIO SI_ASYNCIO - SI_MESGQ, /* Sent by real time mesq state change. */ -# define SI_MESGQ SI_MESGQ - SI_TIMER, /* Sent by timer expiration. */ -# define SI_TIMER SI_TIMER - SI_QUEUE, /* Sent by sigqueue. */ -# define SI_QUEUE SI_QUEUE - SI_USER, /* Sent by kill, sigsend. */ -# define SI_USER SI_USER - SI_KERNEL = 0x80 /* Send by kernel. */ -#define SI_KERNEL SI_KERNEL -}; - - -# if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 -/* `si_code' values for SIGILL signal. */ -enum -{ - ILL_ILLOPC = 1, /* Illegal opcode. */ -# define ILL_ILLOPC ILL_ILLOPC - ILL_ILLOPN, /* Illegal operand. */ -# define ILL_ILLOPN ILL_ILLOPN - ILL_ILLADR, /* Illegal addressing mode. */ -# define ILL_ILLADR ILL_ILLADR - ILL_ILLTRP, /* Illegal trap. */ -# define ILL_ILLTRP ILL_ILLTRP - ILL_PRVOPC, /* Privileged opcode. */ -# define ILL_PRVOPC ILL_PRVOPC - ILL_PRVREG, /* Privileged register. */ -# define ILL_PRVREG ILL_PRVREG - ILL_COPROC, /* Coprocessor error. */ -# define ILL_COPROC ILL_COPROC - ILL_BADSTK /* Internal stack error. */ -# define ILL_BADSTK ILL_BADSTK -}; - -/* `si_code' values for SIGFPE signal. */ -enum -{ - FPE_INTDIV = 1, /* Integer divide by zero. */ -# define FPE_INTDIV FPE_INTDIV - FPE_INTOVF, /* Integer overflow. */ -# define FPE_INTOVF FPE_INTOVF - FPE_FLTDIV, /* Floating point divide by zero. */ -# define FPE_FLTDIV FPE_FLTDIV - FPE_FLTOVF, /* Floating point overflow. */ -# define FPE_FLTOVF FPE_FLTOVF - FPE_FLTUND, /* Floating point underflow. */ -# define FPE_FLTUND FPE_FLTUND - FPE_FLTRES, /* Floating point inexact result. */ -# define FPE_FLTRES FPE_FLTRES - FPE_FLTINV, /* Floating point invalid operation. */ -# define FPE_FLTINV FPE_FLTINV - FPE_FLTSUB /* Subscript out of range. */ -# define FPE_FLTSUB FPE_FLTSUB -}; - -/* `si_code' values for SIGSEGV signal. */ -enum -{ - SEGV_MAPERR = 1, /* Address not mapped to object. */ -# define SEGV_MAPERR SEGV_MAPERR - SEGV_ACCERR /* Invalid permissions for mapped object. */ -# define SEGV_ACCERR SEGV_ACCERR -}; - -/* `si_code' values for SIGBUS signal. */ -enum -{ - BUS_ADRALN = 1, /* Invalid address alignment. */ -# define BUS_ADRALN BUS_ADRALN - BUS_ADRERR, /* Non-existant physical address. */ -# define BUS_ADRERR BUS_ADRERR - BUS_OBJERR, /* Object specific hardware error. */ -# define BUS_OBJERR BUS_OBJERR - BUS_MCEERR_AR, /* Hardware memory error: action required. */ -# define BUS_MCEERR_AR BUS_MCEERR_AR - BUS_MCEERR_AO /* Hardware memory error: action optional. */ -# define BUS_MCEERR_AO BUS_MCEERR_AO -}; -# endif - -# ifdef __USE_XOPEN_EXTENDED -/* `si_code' values for SIGTRAP signal. */ -enum -{ - TRAP_BRKPT = 1, /* Process breakpoint. */ -# define TRAP_BRKPT TRAP_BRKPT - TRAP_TRACE /* Process trace trap. */ -# define TRAP_TRACE TRAP_TRACE -}; -# endif - -# if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 -/* `si_code' values for SIGCHLD signal. */ -enum -{ - CLD_EXITED = 1, /* Child has exited. */ -# define CLD_EXITED CLD_EXITED - CLD_KILLED, /* Child was killed. */ -# define CLD_KILLED CLD_KILLED - CLD_DUMPED, /* Child terminated abnormally. */ -# define CLD_DUMPED CLD_DUMPED - CLD_TRAPPED, /* Traced child has trapped. */ -# define CLD_TRAPPED CLD_TRAPPED - CLD_STOPPED, /* Child has stopped. */ -# define CLD_STOPPED CLD_STOPPED - CLD_CONTINUED /* Stopped child has continued. */ -# define CLD_CONTINUED CLD_CONTINUED -}; - -/* `si_code' values for SIGPOLL signal. */ -enum -{ - POLL_IN = 1, /* Data input available. */ -# define POLL_IN POLL_IN - POLL_OUT, /* Output buffers available. */ -# define POLL_OUT POLL_OUT - POLL_MSG, /* Input message available. */ -# define POLL_MSG POLL_MSG - POLL_ERR, /* I/O error. */ -# define POLL_ERR POLL_ERR - POLL_PRI, /* High priority input available. */ -# define POLL_PRI POLL_PRI - POLL_HUP /* Device disconnected. */ -# define POLL_HUP POLL_HUP -}; -# endif - -# undef __need_siginfo_t -#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */ - - -#if (defined _SIGNAL_H || defined __need_sigevent_t) \ - && !defined __have_sigevent_t -# define __have_sigevent_t 1 - -/* Structure to transport application-defined values with signals. */ -# define __SIGEV_MAX_SIZE 64 -# if __WORDSIZE == 64 -# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4) -# else -# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 3) -# endif - -/* Forward declaration. */ -# ifndef __have_pthread_attr_t -typedef union pthread_attr_t pthread_attr_t; -# define __have_pthread_attr_t 1 -# endif - -typedef struct sigevent - { - sigval_t sigev_value; - int sigev_signo; - int sigev_notify; - - union - { - int _pad[__SIGEV_PAD_SIZE]; - - /* When SIGEV_SIGNAL and SIGEV_THREAD_ID set, LWP ID of the - thread to receive the signal. */ - __pid_t _tid; - - struct - { - void (*_function) (sigval_t); /* Function to start. */ - pthread_attr_t *_attribute; /* Thread attributes. */ - } _sigev_thread; - } _sigev_un; - } sigevent_t; - -/* POSIX names to access some of the members. */ -# define sigev_notify_function _sigev_un._sigev_thread._function -# define sigev_notify_attributes _sigev_un._sigev_thread._attribute - -/* `sigev_notify' values. */ -enum -{ - SIGEV_SIGNAL = 0, /* Notify via signal. */ -# define SIGEV_SIGNAL SIGEV_SIGNAL - SIGEV_NONE, /* Other notification: meaningless. */ -# define SIGEV_NONE SIGEV_NONE - SIGEV_THREAD, /* Deliver via thread creation. */ -# define SIGEV_THREAD SIGEV_THREAD - - SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */ -#define SIGEV_THREAD_ID SIGEV_THREAD_ID -}; - -#endif /* have _SIGNAL_H. */ diff --git a/sysdeps/unix/sysv/linux/x86/bits/stat.h b/sysdeps/unix/sysv/linux/x86/bits/stat.h index 5ea0d2a711..2ae248691d 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/stat.h +++ b/sysdeps/unix/sysv/linux/x86/bits/stat.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2016 Free Software Foundation, Inc. +/* Copyright (C) 1999-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/bits/sysctl.h b/sysdeps/unix/sysv/linux/x86/bits/sysctl.h index 6133da0458..8d76ed89db 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/sysctl.h +++ b/sysdeps/unix/sysv/linux/x86/bits/sysctl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2012-2016 Free Software Foundation, Inc. +/* Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h index 5817ef3f86..e6f7481a19 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h @@ -1,5 +1,5 @@ /* bits/typesizes.h -- underlying types for *_t. Linux/x86-64 version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -81,6 +81,11 @@ /* Same for ino_t and ino64_t. */ # define __INO_T_MATCHES_INO64_T 1 + +/* And for __rlim_t and __rlim64_t. */ +# define __RLIM_T_MATCHES_RLIM64_T 1 +#else +# define __RLIM_T_MATCHES_RLIM64_T 0 #endif /* Number of descriptors that can fit in an `fd_set'. */ diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c new file mode 100644 index 0000000000..8566a265b8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c @@ -0,0 +1,46 @@ +/* Initialize CPU feature data for Linux/x86. + This file is part of the GNU C Library. + Copyright (C) 2018 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#if CET_ENABLED +# include <sys/prctl.h> +# include <asm/prctl.h> + +static inline int __attribute__ ((always_inline)) +get_cet_status (void) +{ + unsigned long long cet_status[3]; + INTERNAL_SYSCALL_DECL (err); + if (INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_STATUS, + cet_status) == 0) + return cet_status[0]; + return 0; +} + +# ifndef SHARED +static inline void +x86_setup_tls (void) +{ + __libc_setup_tls (); + THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1)[0]); +} + +# define ARCH_SETUP_TLS() x86_setup_tls () +# endif +#endif + +#include <sysdeps/x86/cpu-features.c> diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h new file mode 100644 index 0000000000..3fbcfebed5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h @@ -0,0 +1,55 @@ +/* Linux/x86 CET initializers function. + Copyright (C) 2018 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/prctl.h> +#include <asm/prctl.h> + +static inline int __attribute__ ((always_inline)) +dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap) +{ + /* Allocate legacy bitmap. */ + INTERNAL_SYSCALL_DECL (err); +#ifdef __LP64__ + return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, + ARCH_CET_LEGACY_BITMAP, legacy_bitmap); +#else + unsigned long long legacy_bitmap_u64[2]; + int res = INTERNAL_SYSCALL (arch_prctl, err, 2, + ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64); + if (res == 0) + { + legacy_bitmap[0] = legacy_bitmap_u64[0]; + legacy_bitmap[1] = legacy_bitmap_u64[1]; + } + return res; +#endif +} + +static inline int __attribute__ ((always_inline)) +dl_cet_disable_cet (unsigned int cet_feature) +{ + INTERNAL_SYSCALL_DECL (err); + return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_DISABLE, + cet_feature); +} + +static inline int __attribute__ ((always_inline)) +dl_cet_lock_cet (void) +{ + INTERNAL_SYSCALL_DECL (err); + return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_LOCK, 0); +} diff --git a/sysdeps/unix/sysv/linux/x86/dl-sysdep.c b/sysdeps/unix/sysv/linux/x86/dl-sysdep.c new file mode 100644 index 0000000000..f4478b1389 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/dl-sysdep.c @@ -0,0 +1,21 @@ +/* Operating system support for run-time dynamic linker. X86 version. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <config.h> +#include <sysdeps/x86/cpu-tunables.c> +#include <sysdeps/unix/sysv/linux/dl-sysdep.c> diff --git a/sysdeps/unix/sysv/linux/x86/elision-conf.c b/sysdeps/unix/sysv/linux/x86/elision-conf.c index 0d98133804..22af294426 100644 --- a/sysdeps/unix/sysv/linux/x86/elision-conf.c +++ b/sysdeps/unix/sysv/linux/x86/elision-conf.c @@ -1,5 +1,5 @@ /* elision-conf.c: Lock elision tunable parameters. - Copyright (C) 2013-2016 Free Software Foundation, Inc. + Copyright (C) 2013-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,6 +22,11 @@ #include <elision-conf.h> #include <unistd.h> +#if HAVE_TUNABLES +# define TUNABLE_NAMESPACE elision +#endif +#include <elf/dl-tunables.h> + /* Reasonable initial tuning values, may be revised in the future. This is a conservative initial value. */ @@ -43,31 +48,81 @@ struct elision_config __elision_aconf = .skip_trylock_internal_abort = 3, }; -/* Set when the CPU supports elision. When false elision is never attempted. - */ - -int __elision_available attribute_hidden; - /* Force elision for all new locks. This is used to decide whether existing DEFAULT locks should be automatically upgraded to elision in pthread_mutex_lock(). Disabled for suid programs. Only used when elision is available. */ -int __pthread_force_elision attribute_hidden; +int __pthread_force_elision attribute_hidden = 0; -/* Initialize elison. */ +#if HAVE_TUNABLES +static inline void +__always_inline +do_set_elision_enable (int32_t elision_enable) +{ + /* Enable elision if it's avaliable in hardware. It's not necessary to check + if __libc_enable_secure isn't enabled since elision_enable will be set + according to the default, which is disabled. */ + if (elision_enable == 1) + __pthread_force_elision = HAS_CPU_FEATURE (RTM) ? 1 : 0; +} + +/* The pthread->elision_enable tunable is 0 or 1 indicating that elision + should be disabled or enabled respectively. The feature will only be used + if it's supported by the hardware. */ + +void +TUNABLE_CALLBACK (set_elision_enable) (tunable_val_t *valp) +{ + int32_t elision_enable = (int32_t) valp->numval; + do_set_elision_enable (elision_enable); +} + +#define TUNABLE_CALLBACK_FNDECL(__name, __type) \ +static inline void \ +__always_inline \ +do_set_elision_ ## __name (__type value) \ +{ \ + __elision_aconf.__name = value; \ +} \ +void \ +TUNABLE_CALLBACK (set_elision_ ## __name) (tunable_val_t *valp) \ +{ \ + __type value = (__type) (valp)->numval; \ + do_set_elision_ ## __name (value); \ +} + +TUNABLE_CALLBACK_FNDECL (skip_lock_busy, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_lock_internal_abort, int32_t); +TUNABLE_CALLBACK_FNDECL (retry_try_xbegin, int32_t); +TUNABLE_CALLBACK_FNDECL (skip_trylock_internal_abort, int32_t); +#endif + +/* Initialize elision. */ static void elision_init (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)), char **environ) { - __elision_available = HAS_CPU_FEATURE (RTM); -#ifdef ENABLE_LOCK_ELISION - __pthread_force_elision = __libc_enable_secure ? 0 : __elision_available; +#if HAVE_TUNABLES + /* Elision depends on tunables and must be explicitly turned on by setting + the appropriate tunable on a supported platform. */ + + TUNABLE_GET (enable, int32_t, + TUNABLE_CALLBACK (set_elision_enable)); + TUNABLE_GET (skip_lock_busy, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_busy)); + TUNABLE_GET (skip_lock_internal_abort, int32_t, + TUNABLE_CALLBACK (set_elision_skip_lock_internal_abort)); + TUNABLE_GET (tries, int32_t, + TUNABLE_CALLBACK (set_elision_retry_try_xbegin)); + TUNABLE_GET (skip_trylock_internal_abort, int32_t, + TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort)); #endif - if (!HAS_CPU_FEATURE (RTM)) - __elision_aconf.retry_try_xbegin = 0; /* Disable elision on rwlocks */ + + if (!__pthread_force_elision) + __elision_aconf.retry_try_xbegin = 0; /* Disable elision on rwlocks. */ } #ifdef SHARED diff --git a/sysdeps/unix/sysv/linux/x86/elision-conf.h b/sysdeps/unix/sysv/linux/x86/elision-conf.h index 6c479b31e7..0979d95086 100644 --- a/sysdeps/unix/sysv/linux/x86/elision-conf.h +++ b/sysdeps/unix/sysv/linux/x86/elision-conf.h @@ -1,5 +1,5 @@ /* elision-conf.h: Lock elision tunable parameters. - Copyright (C) 2013-2016 Free Software Foundation, Inc. + Copyright (C) 2013-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -33,7 +33,6 @@ struct elision_config extern struct elision_config __elision_aconf attribute_hidden; -extern int __elision_available attribute_hidden; extern int __pthread_force_elision attribute_hidden; /* Tell the test suite to test elision for this architecture. */ diff --git a/sysdeps/unix/sysv/linux/x86/elision-lock.c b/sysdeps/unix/sysv/linux/x86/elision-lock.c index 5e66960123..c534131ab4 100644 --- a/sysdeps/unix/sysv/linux/x86/elision-lock.c +++ b/sysdeps/unix/sysv/linux/x86/elision-lock.c @@ -1,5 +1,5 @@ /* elision-lock.c: Elided pthread mutex lock. - Copyright (C) 2011-2016 Free Software Foundation, Inc. + Copyright (C) 2011-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -44,7 +44,13 @@ int __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private) { - if (*adapt_count <= 0) + /* adapt_count can be accessed concurrently; these accesses can be both + inside of transactions (if critical sections are nested and the outer + critical section uses lock elision) and outside of transactions. Thus, + we need to use atomic accesses to avoid data races. However, the + value of adapt_count is just a hint, so relaxed MO accesses are + sufficient. */ + if (atomic_load_relaxed (adapt_count) <= 0) { unsigned status; int try_xbegin; @@ -70,15 +76,20 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private) && _XABORT_CODE (status) == _ABORT_LOCK_BUSY) { /* Right now we skip here. Better would be to wait a bit - and retry. This likely needs some spinning. */ - if (*adapt_count != aconf.skip_lock_busy) - *adapt_count = aconf.skip_lock_busy; + and retry. This likely needs some spinning. See + above for why relaxed MO is sufficient. */ + if (atomic_load_relaxed (adapt_count) + != aconf.skip_lock_busy) + atomic_store_relaxed (adapt_count, aconf.skip_lock_busy); } /* Internal abort. There is no chance for retry. Use the normal locking and next time use lock. - Be careful to avoid writing to the lock. */ - else if (*adapt_count != aconf.skip_lock_internal_abort) - *adapt_count = aconf.skip_lock_internal_abort; + Be careful to avoid writing to the lock. See above for why + relaxed MO is sufficient. */ + else if (atomic_load_relaxed (adapt_count) + != aconf.skip_lock_internal_abort) + atomic_store_relaxed (adapt_count, + aconf.skip_lock_internal_abort); break; } } @@ -87,7 +98,8 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private) { /* Use a normal lock until the threshold counter runs out. Lost updates possible. */ - (*adapt_count)--; + atomic_store_relaxed (adapt_count, + atomic_load_relaxed (adapt_count) - 1); } /* Use a normal lock here. */ diff --git a/sysdeps/unix/sysv/linux/x86/elision-timed.c b/sysdeps/unix/sysv/linux/x86/elision-timed.c index 2e7d1efa76..f0be3ea6a5 100644 --- a/sysdeps/unix/sysv/linux/x86/elision-timed.c +++ b/sysdeps/unix/sysv/linux/x86/elision-timed.c @@ -1,5 +1,5 @@ /* elision-timed.c: Lock elision timed lock. - Copyright (C) 2013-2016 Free Software Foundation, Inc. + Copyright (C) 2013-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/elision-trylock.c b/sysdeps/unix/sysv/linux/x86/elision-trylock.c index 65d9c18584..7c55fb878e 100644 --- a/sysdeps/unix/sysv/linux/x86/elision-trylock.c +++ b/sysdeps/unix/sysv/linux/x86/elision-trylock.c @@ -1,5 +1,5 @@ /* elision-trylock.c: Lock eliding trylock for pthreads. - Copyright (C) 2013-2016 Free Software Foundation, Inc. + Copyright (C) 2013-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -36,8 +36,10 @@ __lll_trylock_elision (int *futex, short *adapt_count) return an error. */ _xabort (_ABORT_NESTED_TRYLOCK); - /* Only try a transaction if it's worth it. */ - if (*adapt_count <= 0) + /* Only try a transaction if it's worth it. See __lll_lock_elision for + why we need atomic accesses. Relaxed MO is sufficient because this is + just a hint. */ + if (atomic_load_relaxed (adapt_count) <= 0) { unsigned status; @@ -55,16 +57,18 @@ __lll_trylock_elision (int *futex, short *adapt_count) if (!(status & _XABORT_RETRY)) { /* Internal abort. No chance for retry. For future - locks don't try speculation for some time. */ - if (*adapt_count != aconf.skip_trylock_internal_abort) - *adapt_count = aconf.skip_trylock_internal_abort; + locks don't try speculation for some time. See above for MO. */ + if (atomic_load_relaxed (adapt_count) + != aconf.skip_lock_internal_abort) + atomic_store_relaxed (adapt_count, aconf.skip_lock_internal_abort); } /* Could do some retries here. */ } else { - /* Lost updates are possible, but harmless. */ - (*adapt_count)--; + /* Lost updates are possible but harmless (see above). */ + atomic_store_relaxed (adapt_count, + atomic_load_relaxed (adapt_count) - 1); } return lll_trylock (*futex); diff --git a/sysdeps/unix/sysv/linux/x86/elision-unlock.c b/sysdeps/unix/sysv/linux/x86/elision-unlock.c index 8ce5d79acd..bdf6386bd6 100644 --- a/sysdeps/unix/sysv/linux/x86/elision-unlock.c +++ b/sysdeps/unix/sysv/linux/x86/elision-unlock.c @@ -1,5 +1,5 @@ /* elision-unlock.c: Commit an elided pthread lock. - Copyright (C) 2013-2016 Free Software Foundation, Inc. + Copyright (C) 2013-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/force-elision.h b/sysdeps/unix/sysv/linux/x86/force-elision.h index 19298b2af9..dd659c908f 100644 --- a/sysdeps/unix/sysv/linux/x86/force-elision.h +++ b/sysdeps/unix/sysv/linux/x86/force-elision.h @@ -1,5 +1,5 @@ /* force-elision.h: Automatic enabling of elision for mutexes - Copyright (C) 2013-2016 Free Software Foundation, Inc. + Copyright (C) 2013-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c index 36f7c26ffb..e125859c1a 100644 --- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c +++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c @@ -1,5 +1,5 @@ /* gettimeofday - get the time. Linux/x86 version. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,20 +29,20 @@ __gettimeofday_syscall (struct timeval *tv, struct timezone *tz) return INLINE_SYSCALL (gettimeofday, 2, tv, tz); } -void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday"); - -void * -gettimeofday_ifunc (void) -{ - PREPARE_VERSION_KNOWN (linux26, LINUX_2_6); - - /* If the vDSO is not available we fall back to syscall. */ - return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26) - ?: (void*) (&__gettimeofday_syscall)); -} -asm (".type __gettimeofday, %gnu_indirect_function"); - -libc_ifunc_hidden_def(__gettimeofday) +# ifndef __gettimeofday_type +/* The i386 gettimeofday.c includes this file with a defined + __gettimeofday_type macro. For x86_64 we have to define it to __gettimeofday + as the internal symbol is the ifunc'ed one. */ +# define __gettimeofday_type __gettimeofday +# endif + +# undef INIT_ARCH +# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6) +/* If the vDSO is not available we fall back to syscall. */ +libc_ifunc_hidden (__gettimeofday_type, __gettimeofday, + (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26) + ?: &__gettimeofday_syscall)) +libc_hidden_def (__gettimeofday) #else diff --git a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h new file mode 100644 index 0000000000..f67f3299b9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h @@ -0,0 +1,32 @@ +/* FIXME: CET arch_prctl bits should come from the kernel header files. + This file should be removed if <asm/prctl.h> from the required kernel + header files contains CET arch_prctl bits. */ + +#include_next <asm/prctl.h> + +#ifndef ARCH_CET_STATUS +/* CET features: + IBT: GNU_PROPERTY_X86_FEATURE_1_IBT + SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK + */ +/* Return CET features in unsigned long long *addr: + features: addr[0]. + shadow stack base address: addr[1]. + shadow stack size: addr[2]. + */ +# define ARCH_CET_STATUS 0x3001 +/* Disable CET features in unsigned int features. */ +# define ARCH_CET_DISABLE 0x3002 +/* Lock all CET features. */ +# define ARCH_CET_LOCK 0x3003 +/* Allocate a new shadow stack with unsigned long long *addr: + IN: requested shadow stack size: *addr. + OUT: allocated shadow stack address: *addr. + */ +# define ARCH_CET_ALLOC_SHSTK 0x3004 +/* Return legacy region bitmap info in unsigned long long *addr: + address: addr[0]. + size: addr[1]. + */ +# define ARCH_CET_LEGACY_BITMAP 0x3005 +#endif /* ARCH_CET_STATUS */ diff --git a/sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym b/sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym new file mode 100644 index 0000000000..12829196db --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym @@ -0,0 +1,5 @@ +#include <setjmpP.h> +#undef __saved_mask + +-- +SHADOW_STACK_POINTER_OFFSET offsetof(struct __jmp_buf_tag, __saved_mask.__saved.__shadow_stack_pointer) diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h index f1a1b13a92..6f86073dae 100644 --- a/sysdeps/unix/sysv/linux/x86/libc-vdso.h +++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h @@ -1,5 +1,5 @@ /* Resolve function pointers to VDSO functions. - Copyright (C) 2005-2016 Free Software Foundation, Inc. + Copyright (C) 2005-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,7 +29,8 @@ extern long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *) attribute_hidden; -extern long int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *); +extern long int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *) + attribute_hidden; #endif diff --git a/sysdeps/unix/sysv/linux/x86/pkey_get.c b/sysdeps/unix/sysv/linux/x86/pkey_get.c new file mode 100644 index 0000000000..da05ba7f84 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/pkey_get.c @@ -0,0 +1,33 @@ +/* Reading the per-thread memory protection key, x86_64 version. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <arch-pkey.h> +#include <errno.h> + +int +pkey_get (int key) +{ + if (key < 0 || key > 15) + { + __set_errno (EINVAL); + return -1; + } + unsigned int pkru = pkey_read (); + return (pkru >> (2 * key)) & 3; + return 0; +} diff --git a/sysdeps/unix/sysv/linux/x86/pkey_set.c b/sysdeps/unix/sysv/linux/x86/pkey_set.c new file mode 100644 index 0000000000..ea061d6dd7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/pkey_set.c @@ -0,0 +1,35 @@ +/* Changing the per-thread memory protection key, x86_64 version. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <arch-pkey.h> +#include <errno.h> + +int +pkey_set (int key, unsigned int rights) +{ + if (key < 0 || key > 15 || rights > 3) + { + __set_errno (EINVAL); + return -1; + } + unsigned int mask = 3 << (2 * key); + unsigned int pkru = pkey_read (); + pkru = (pkru & ~mask) | (rights << (2 * key)); + pkey_write (pkru); + return 0; +} diff --git a/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c b/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c index 5d9b14c2a5..967d00748d 100644 --- a/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c +++ b/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2016 Free Software Foundation, Inc. +/* Copyright (C) 2013-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c b/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c index ea0769e74a..c23678f922 100644 --- a/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c +++ b/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c @@ -1,5 +1,5 @@ /* Elided version of pthread_mutex_lock. - Copyright (C) 2011-2016 Free Software Foundation, Inc. + Copyright (C) 2011-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c b/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c index 009a6cfea7..7997580178 100644 --- a/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c +++ b/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c @@ -1,5 +1,5 @@ /* Elided version of pthread_mutex_timedlock. - Copyright (C) 2011-2016 Free Software Foundation, Inc. + Copyright (C) 2011-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c b/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c index b9cebe47e5..03db974095 100644 --- a/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c +++ b/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c @@ -1,5 +1,5 @@ /* Elided version of pthread_mutex_trylock. - Copyright (C) 2011-2016 Free Software Foundation, Inc. + Copyright (C) 2011-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/setjmpP.h b/sysdeps/unix/sysv/linux/x86/setjmpP.h new file mode 100644 index 0000000000..6b2608453d --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/setjmpP.h @@ -0,0 +1,128 @@ +/* Internal header file for <setjmp.h>. Linux/x86 version. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SETJMPP_H +#define _SETJMPP_H 1 + +#include <bits/types/__sigset_t.h> +#include <libc-pointer-arith.h> + +/* <setjmp/setjmp.h> has + +struct __jmp_buf_tag + { + __jmp_buf __jmpbuf; + int __mask_was_saved; + __sigset_t __saved_mask; + }; + + struct __jmp_buf_tag is 32 bits aligned on i386 and is 64 bits + aligned on x32 and x86-64. __saved_mask is aligned to 32 bits + on i386/x32 without padding and is aligned to 64 bits on x86-64 + with 32 bit padding. + + and <nptl/descr.h> has + +struct pthread_unwind_buf +{ + struct + { + __jmp_buf jmp_buf; + int mask_was_saved; + } cancel_jmp_buf[1]; + + union + { + void *pad[4]; + struct + { + struct pthread_unwind_buf *prev; + struct _pthread_cleanup_buffer *cleanup; + int canceltype; + } data; + } priv; +}; + + struct pthread_unwind_buf is 32 bits aligned on i386 and 64 bits + aligned on x32/x86-64. cancel_jmp_buf is aligned to 32 bits on + i386 and is aligned to 64 bits on x32/x86-64. + + The pad array in struct pthread_unwind_buf is used by setjmp to save + shadow stack register. The usable space in __saved_mask for sigset + and shadow stack pointer: + 1. i386: The 4x4 byte pad array which can be used for 4 byte shadow + stack pointer and maximum 12 byte sigset. + 2. x32: 4 byte padding + the 4x4 byte pad array which can be used + for 8 byte shadow stack pointer and maximum 12 byte sigset. + 3. x86-64: The 4x8 byte pad array which can be used for 8 byte + shadow stack pointer and maximum 24 byte sigset. + + NB: We use setjmp in thread cancellation and this saves the shadow + stack register, but __libc_unwind_longjmp doesn't restore the shadow + stack register since cancellation never returns after longjmp. */ + +/* Number of bits per long. */ +#define _JUMP_BUF_SIGSET_BITS_PER_WORD (8 * sizeof (unsigned long int)) +/* The biggest signal number. As of kernel 4.14, x86 _NSIG is 64. The + common maximum sigset for i386, x32 and x86-64 is 12 bytes (96 bits). + Define it to 96 to leave some rooms for future use. */ +#define _JUMP_BUF_SIGSET_NSIG 96 +/* Number of longs to hold all signals. */ +#define _JUMP_BUF_SIGSET_NWORDS \ + (ALIGN_UP (_JUMP_BUF_SIGSET_NSIG, _JUMP_BUF_SIGSET_BITS_PER_WORD) \ + / _JUMP_BUF_SIGSET_BITS_PER_WORD) + +typedef struct + { + unsigned long int __val[_JUMP_BUF_SIGSET_NWORDS]; + } __jmp_buf_sigset_t; + +typedef union + { + __sigset_t __saved_mask_compat; + struct + { + __jmp_buf_sigset_t __saved_mask; + /* Used for shadow stack pointer. NB: Shadow stack pointer + must have the same alignment as __saved_mask. Otherwise + offset of __saved_mask will be changed. */ + unsigned long int __shadow_stack_pointer; + } __saved; + } __jmpbuf_arch_t; + +#undef __sigset_t +#define __sigset_t __jmpbuf_arch_t +#include <setjmp.h> +#undef __saved_mask +#define __saved_mask __saved_mask.__saved.__saved_mask + +#include <signal.h> + +#define _SIGPROCMASK_NSIG_WORDS (_NSIG / (8 * sizeof (unsigned long int))) + +typedef struct + { + unsigned long int __val[_SIGPROCMASK_NSIG_WORDS]; + } __sigprocmask_sigset_t; + +extern jmp_buf ___buf; +extern __typeof (___buf[0].__saved_mask) ___saved_mask; +_Static_assert (sizeof (___saved_mask) >= sizeof (__sigprocmask_sigset_t), + "size of ___saved_mask < size of __sigprocmask_sigset_t"); + +#endif /* setjmpP.h */ diff --git a/sysdeps/unix/sysv/linux/x86/sys/debugreg.h b/sysdeps/unix/sysv/linux/x86/sys/debugreg.h index 6054c5f731..b8bbb31117 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/debugreg.h +++ b/sysdeps/unix/sysv/linux/x86/sys/debugreg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2016 Free Software Foundation, Inc. +/* Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/sys/elf.h b/sysdeps/unix/sysv/linux/x86/sys/elf.h index 29842e2b91..2e5b2489f9 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/elf.h +++ b/sysdeps/unix/sysv/linux/x86/sys/elf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1998-2016 Free Software Foundation, Inc. +/* Copyright (C) 1998-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/sys/io.h b/sysdeps/unix/sysv/linux/x86/sys/io.h index d3dc885979..34bfea53a1 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/io.h +++ b/sysdeps/unix/sysv/linux/x86/sys/io.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/sys/perm.h b/sysdeps/unix/sysv/linux/x86/sys/perm.h index a6f139d7d6..d9a241775d 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/perm.h +++ b/sysdeps/unix/sysv/linux/x86/sys/perm.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/sys/procfs.h b/sysdeps/unix/sysv/linux/x86/sys/procfs.h index 7616243c2e..9203963afe 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/procfs.h +++ b/sysdeps/unix/sysv/linux/x86/sys/procfs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2016 Free Software Foundation, Inc. +/* Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/sys/ptrace.h b/sysdeps/unix/sysv/linux/x86/sys/ptrace.h new file mode 100644 index 0000000000..6d4605b6ed --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/sys/ptrace.h @@ -0,0 +1,198 @@ +/* `ptrace' debugger support interface. Linux/x86 version. + Copyright (C) 1996-2018 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_PTRACE_H +#define _SYS_PTRACE_H 1 + +#include <features.h> +#include <bits/types.h> + +__BEGIN_DECLS + +/* Type of the REQUEST argument to `ptrace.' */ +enum __ptrace_request +{ + /* Indicate that the process making this request should be traced. + All signals received by this process can be intercepted by its + parent, and its parent can use the other `ptrace' requests. */ + PTRACE_TRACEME = 0, +#define PT_TRACE_ME PTRACE_TRACEME + + /* Return the word in the process's text space at address ADDR. */ + PTRACE_PEEKTEXT = 1, +#define PT_READ_I PTRACE_PEEKTEXT + + /* Return the word in the process's data space at address ADDR. */ + PTRACE_PEEKDATA = 2, +#define PT_READ_D PTRACE_PEEKDATA + + /* Return the word in the process's user area at offset ADDR. */ + PTRACE_PEEKUSER = 3, +#define PT_READ_U PTRACE_PEEKUSER + + /* Write the word DATA into the process's text space at address ADDR. */ + PTRACE_POKETEXT = 4, +#define PT_WRITE_I PTRACE_POKETEXT + + /* Write the word DATA into the process's data space at address ADDR. */ + PTRACE_POKEDATA = 5, +#define PT_WRITE_D PTRACE_POKEDATA + + /* Write the word DATA into the process's user area at offset ADDR. */ + PTRACE_POKEUSER = 6, +#define PT_WRITE_U PTRACE_POKEUSER + + /* Continue the process. */ + PTRACE_CONT = 7, +#define PT_CONTINUE PTRACE_CONT + + /* Kill the process. */ + PTRACE_KILL = 8, +#define PT_KILL PTRACE_KILL + + /* Single step the process. */ + PTRACE_SINGLESTEP = 9, +#define PT_STEP PTRACE_SINGLESTEP + + /* Get all general purpose registers used by a processes. */ + PTRACE_GETREGS = 12, +#define PT_GETREGS PTRACE_GETREGS + + /* Set all general purpose registers used by a processes. */ + PTRACE_SETREGS = 13, +#define PT_SETREGS PTRACE_SETREGS + + /* Get all floating point registers used by a processes. */ + PTRACE_GETFPREGS = 14, +#define PT_GETFPREGS PTRACE_GETFPREGS + + /* Set all floating point registers used by a processes. */ + PTRACE_SETFPREGS = 15, +#define PT_SETFPREGS PTRACE_SETFPREGS + + /* Attach to a process that is already running. */ + PTRACE_ATTACH = 16, +#define PT_ATTACH PTRACE_ATTACH + + /* Detach from a process attached to with PTRACE_ATTACH. */ + PTRACE_DETACH = 17, +#define PT_DETACH PTRACE_DETACH + + /* Get all extended floating point registers used by a processes. */ + PTRACE_GETFPXREGS = 18, +#define PT_GETFPXREGS PTRACE_GETFPXREGS + + /* Set all extended floating point registers used by a processes. */ + PTRACE_SETFPXREGS = 19, +#define PT_SETFPXREGS PTRACE_SETFPXREGS + + /* Continue and stop at the next entry to or return from syscall. */ + PTRACE_SYSCALL = 24, +#define PT_SYSCALL PTRACE_SYSCALL + + /* Get a TLS entry in the GDT. */ + PTRACE_GET_THREAD_AREA = 25, +#define PT_GET_THREAD_AREA PTRACE_GET_THREAD_AREA + + /* Change a TLS entry in the GDT. */ + PTRACE_SET_THREAD_AREA = 26, +#define PT_SET_THREAD_AREA PTRACE_SET_THREAD_AREA + +#ifdef __x86_64__ + /* Access TLS data. */ + PTRACE_ARCH_PRCTL = 30, +# define PT_ARCH_PRCTL PTRACE_ARCH_PRCTL +#endif + + /* Continue and stop at the next syscall, it will not be executed. */ + PTRACE_SYSEMU = 31, +#define PT_SYSEMU PTRACE_SYSEMU + + /* Single step the process, the next syscall will not be executed. */ + PTRACE_SYSEMU_SINGLESTEP = 32, +#define PT_SYSEMU_SINGLESTEP PTRACE_SYSEMU_SINGLESTEP + + /* Execute process until next taken branch. */ + PTRACE_SINGLEBLOCK = 33, +#define PT_STEPBLOCK PTRACE_SINGLEBLOCK + + /* Set ptrace filter options. */ + PTRACE_SETOPTIONS = 0x4200, +#define PT_SETOPTIONS PTRACE_SETOPTIONS + + /* Get last ptrace message. */ + PTRACE_GETEVENTMSG = 0x4201, +#define PT_GETEVENTMSG PTRACE_GETEVENTMSG + + /* Get siginfo for process. */ + PTRACE_GETSIGINFO = 0x4202, +#define PT_GETSIGINFO PTRACE_GETSIGINFO + + /* Set new siginfo for process. */ + PTRACE_SETSIGINFO = 0x4203, +#define PT_SETSIGINFO PTRACE_SETSIGINFO + + /* Get register content. */ + PTRACE_GETREGSET = 0x4204, +#define PTRACE_GETREGSET PTRACE_GETREGSET + + /* Set register content. */ + PTRACE_SETREGSET = 0x4205, +#define PTRACE_SETREGSET PTRACE_SETREGSET + + /* Like PTRACE_ATTACH, but do not force tracee to trap and do not affect + signal or group stop state. */ + PTRACE_SEIZE = 0x4206, +#define PTRACE_SEIZE PTRACE_SEIZE + + /* Trap seized tracee. */ + PTRACE_INTERRUPT = 0x4207, +#define PTRACE_INTERRUPT PTRACE_INTERRUPT + + /* Wait for next group event. */ + PTRACE_LISTEN = 0x4208, +#define PTRACE_LISTEN PTRACE_LISTEN + + /* Retrieve siginfo_t structures without removing signals from a queue. */ + PTRACE_PEEKSIGINFO = 0x4209, +#define PTRACE_PEEKSIGINFO PTRACE_PEEKSIGINFO + + /* Get the mask of blocked signals. */ + PTRACE_GETSIGMASK = 0x420a, +#define PTRACE_GETSIGMASK PTRACE_GETSIGMASK + + /* Change the mask of blocked signals. */ + PTRACE_SETSIGMASK = 0x420b, +#define PTRACE_SETSIGMASK PTRACE_SETSIGMASK + + /* Get seccomp BPF filters. */ + PTRACE_SECCOMP_GET_FILTER = 0x420c, +#define PTRACE_SECCOMP_GET_FILTER PTRACE_SECCOMP_GET_FILTER + + /* Get seccomp BPF filter metadata. */ + PTRACE_SECCOMP_GET_METADATA = 0x420d +#define PTRACE_SECCOMP_GET_METADATA PTRACE_SECCOMP_GET_METADATA +}; + + +#include <bits/ptrace-shared.h> + +__END_DECLS + +#endif /* _SYS_PTRACE_H */ diff --git a/sysdeps/unix/sysv/linux/x86/sys/reg.h b/sysdeps/unix/sysv/linux/x86/sys/reg.h index 980468114e..0a543b502e 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/reg.h +++ b/sysdeps/unix/sysv/linux/x86/sys/reg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2016 Free Software Foundation, Inc. +/* Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/sys/ucontext.h b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h index 062063526b..7367726a50 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/ucontext.h +++ b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2016 Free Software Foundation, Inc. +/* Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -19,11 +19,17 @@ #define _SYS_UCONTEXT_H 1 #include <features.h> -#include <signal.h> -/* We need the signal context definitions even if they are not used - included in <signal.h>. */ -#include <bits/sigcontext.h> +#include <bits/types.h> +#include <bits/types/sigset_t.h> +#include <bits/types/stack_t.h> + + +#ifdef __USE_MISC +# define __ctx(fld) fld +#else +# define __ctx(fld) __ ## fld +#endif #ifdef __x86_64__ @@ -31,10 +37,13 @@ __extension__ typedef long long int greg_t; /* Number of general registers. */ -#define NGREG 23 +#define __NGREG 23 +#ifdef __USE_MISC +# define NGREG __NGREG +#endif /* Container for all general registers. */ -typedef greg_t gregset_t[NGREG]; +typedef greg_t gregset_t[__NGREG]; #ifdef __USE_GNU /* Number of each register in the `gregset_t' array. */ @@ -91,30 +100,30 @@ enum struct _libc_fpxreg { - unsigned short int significand[4]; - unsigned short int exponent; - unsigned short int padding[3]; + unsigned short int __ctx(significand)[4]; + unsigned short int __ctx(exponent); + unsigned short int __glibc_reserved1[3]; }; struct _libc_xmmreg { - __uint32_t element[4]; + __uint32_t __ctx(element)[4]; }; struct _libc_fpstate { /* 64-bit FXSAVE format. */ - __uint16_t cwd; - __uint16_t swd; - __uint16_t ftw; - __uint16_t fop; - __uint64_t rip; - __uint64_t rdp; - __uint32_t mxcsr; - __uint32_t mxcr_mask; + __uint16_t __ctx(cwd); + __uint16_t __ctx(swd); + __uint16_t __ctx(ftw); + __uint16_t __ctx(fop); + __uint64_t __ctx(rip); + __uint64_t __ctx(rdp); + __uint32_t __ctx(mxcsr); + __uint32_t __ctx(mxcr_mask); struct _libc_fpxreg _st[8]; struct _libc_xmmreg _xmm[16]; - __uint32_t padding[24]; + __uint32_t __glibc_reserved1[24]; }; /* Structure to describe FPU registers. */ @@ -123,21 +132,22 @@ typedef struct _libc_fpstate *fpregset_t; /* Context to describe whole processor state. */ typedef struct { - gregset_t gregs; + gregset_t __ctx(gregs); /* Note that fpregs is a pointer. */ - fpregset_t fpregs; + fpregset_t __ctx(fpregs); __extension__ unsigned long long __reserved1 [8]; } mcontext_t; /* Userlevel context. */ -typedef struct ucontext +typedef struct ucontext_t { - unsigned long int uc_flags; - struct ucontext *uc_link; + unsigned long int __ctx(uc_flags); + struct ucontext_t *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; - __sigset_t uc_sigmask; + sigset_t uc_sigmask; struct _libc_fpstate __fpregs_mem; + __extension__ unsigned long long int __ssp[4]; } ucontext_t; #else /* !__x86_64__ */ @@ -146,10 +156,13 @@ typedef struct ucontext typedef int greg_t; /* Number of general registers. */ -#define NGREG 19 +#define __NGREG 19 +#ifdef __USE_MISC +# define NGREG __NGREG +#endif /* Container for all general registers. */ -typedef greg_t gregset_t[NGREG]; +typedef greg_t gregset_t[__NGREG]; #ifdef __USE_GNU /* Number of each register is the `gregset_t' array. */ @@ -199,21 +212,21 @@ enum /* Definitions taken from the kernel headers. */ struct _libc_fpreg { - unsigned short int significand[4]; - unsigned short int exponent; + unsigned short int __ctx(significand)[4]; + unsigned short int __ctx(exponent); }; struct _libc_fpstate { - unsigned long int cw; - unsigned long int sw; - unsigned long int tag; - unsigned long int ipoff; - unsigned long int cssel; - unsigned long int dataoff; - unsigned long int datasel; + unsigned long int __ctx(cw); + unsigned long int __ctx(sw); + unsigned long int __ctx(tag); + unsigned long int __ctx(ipoff); + unsigned long int __ctx(cssel); + unsigned long int __ctx(dataoff); + unsigned long int __ctx(datasel); struct _libc_fpreg _st[8]; - unsigned long int status; + unsigned long int __ctx(status); }; /* Structure to describe FPU registers. */ @@ -222,25 +235,28 @@ typedef struct _libc_fpstate *fpregset_t; /* Context to describe whole processor state. */ typedef struct { - gregset_t gregs; + gregset_t __ctx(gregs); /* Due to Linux's history we have to use a pointer here. The SysV/i386 ABI requires a struct with the values. */ - fpregset_t fpregs; - unsigned long int oldmask; - unsigned long int cr2; + fpregset_t __ctx(fpregs); + unsigned long int __ctx(oldmask); + unsigned long int __ctx(cr2); } mcontext_t; /* Userlevel context. */ -typedef struct ucontext +typedef struct ucontext_t { - unsigned long int uc_flags; - struct ucontext *uc_link; + unsigned long int __ctx(uc_flags); + struct ucontext_t *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; - __sigset_t uc_sigmask; + sigset_t uc_sigmask; struct _libc_fpstate __fpregs_mem; + unsigned long int __ssp[4]; } ucontext_t; #endif /* !__x86_64__ */ +#undef __ctx + #endif /* sys/ucontext.h */ diff --git a/sysdeps/unix/sysv/linux/x86/sys/user.h b/sysdeps/unix/sysv/linux/x86/sys/user.h index 7ead5b30b5..03c80fbb20 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/user.h +++ b/sysdeps/unix/sysv/linux/x86/sys/user.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2016 Free Software Foundation, Inc. +/* Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/sys/vm86.h b/sysdeps/unix/sysv/linux/x86/sys/vm86.h index e9c5307e9f..3919812dfa 100644 --- a/sysdeps/unix/sysv/linux/x86/sys/vm86.h +++ b/sysdeps/unix/sysv/linux/x86/sys/vm86.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/sysconf.c b/sysdeps/unix/sysv/linux/x86/sysconf.c index 18aaac8122..199b3c4178 100644 --- a/sysdeps/unix/sysv/linux/x86/sysconf.c +++ b/sysdeps/unix/sysv/linux/x86/sysconf.c @@ -1,5 +1,5 @@ /* Get file-specific information about a file. Linux version. - Copyright (C) 2003-2016 Free Software Foundation, Inc. + Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c index f5f7f918c9..d19cccd6f6 100644 --- a/sysdeps/unix/sysv/linux/x86/time.c +++ b/sysdeps/unix/sysv/linux/x86/time.c @@ -1,5 +1,5 @@ /* time -- Get number of seconds since Epoch. Linux/x86 version. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,20 +30,20 @@ __time_syscall (time_t *t) return INTERNAL_SYSCALL (time, err, 1, t); } -void *time_ifunc (void) __asm__ ("time"); - -void * -time_ifunc (void) -{ - PREPARE_VERSION_KNOWN (linux26, LINUX_2_6); +# ifndef time_type +/* The i386 time.c includes this file with a defined time_type macro. + For x86_64 we have to define it to time as the internal symbol is the + ifunc'ed one. */ +# define time_type time +# endif +#undef INIT_ARCH +#define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6); /* If the vDSO is not available we fall back on the syscall. */ - return _dl_vdso_vsym ("__vdso_time", &linux26) - ?: (void*) &__time_syscall; -} -asm (".type time, %gnu_indirect_function"); - -libc_ifunc_hidden_def(time) +libc_ifunc_hidden (time_type, time, + (_dl_vdso_vsym ("__vdso_time", &linux26) + ?: &__time_syscall)) +libc_hidden_def (time) #else diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-property-1.c b/sysdeps/unix/sysv/linux/x86/tst-cet-property-1.c new file mode 100644 index 0000000000..21130faefc --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/tst-cet-property-1.c @@ -0,0 +1,44 @@ +/* Test CET property note parser. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <elf.h> +#include <tcb-offsets.h> + +/* This test prints out "IBT" if Intel indirect branch tracking (IBT) + is enabled at run-time, which is checked by tst-cet-property-2 to + verify that the IBT violation is caught on IBT machines. */ + +static int +do_test (void) +{ + unsigned int feature_1; +#ifdef __x86_64__ +# define SEG_REG "fs" +#else +# define SEG_REG "gs" +#endif + asm ("movl %%" SEG_REG ":%P1, %0" + : "=r" (feature_1) : "i" (FEATURE_1_OFFSET)); + if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0) + printf ("IBT\n"); + + return 0; +} + +#include <support/test-driver.c> diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-property-2.c b/sysdeps/unix/sysv/linux/x86/tst-cet-property-2.c new file mode 100644 index 0000000000..0531074ceb --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/tst-cet-property-2.c @@ -0,0 +1,63 @@ +/* Test CET property note parser for [BZ #23467]. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <support/check.h> + +extern void bar (void); + +void +__attribute__ ((noclone, noinline)) +test (void (*func_p) (void)) +{ + func_p (); +} + +/* bar contains an IBT violation if it is called indirectly via a + function pointer. On IBT machines, it should lead to segfault + unless IBT is disabled by error. */ + +static void +sig_handler (int signo) +{ + exit (EXIT_SUCCESS); +} + +static int +do_test (void) +{ + char buf[20]; + + if (scanf ("%20s", buf) != 1) + FAIL_UNSUPPORTED ("IBT not supported"); + + if (strcmp (buf, "IBT") != 0) + FAIL_UNSUPPORTED ("IBT not supported"); + + TEST_VERIFY_EXIT (signal (SIGSEGV, &sig_handler) != SIG_ERR); + + /* Call bar via a function pointer to force an IBT violation. */ + test (bar); + + return EXIT_FAILURE; +} + +#include <support/test-driver.c> diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-property-dep-2.S b/sysdeps/unix/sysv/linux/x86/tst-cet-property-dep-2.S new file mode 100644 index 0000000000..5f5cad34d9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/tst-cet-property-dep-2.S @@ -0,0 +1,63 @@ +/* Test CET property note parser. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <cet.h> + + .text + .p2align 4,,15 + .globl bar + .type bar, @function +/* Since this function doesn't start with ENDBR, it should lead to the + IBT violation when called indirectly. */ +bar: + .cfi_startproc + ret + .cfi_endproc + .size bar, .-bar + +#if __SIZEOF_PTRDIFF_T__ == 8 +# define ALIGN 3 +#elif __SIZEOF_PTRDIFF_T__ == 4 +# define ALIGN 2 +#endif + +/* In NT_GNU_PROPERTY_TYPE_0 note, add a GNU_PROPERTY_STACK_SIZE property + before the GNU_PROPERTY_X86_FEATURE_1_AND property. */ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: + .long 1 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: +#if __SIZEOF_PTRDIFF_T__ == 8 + .long 0x800 + .long 0x800 +#else + .long 0x08000800 +#endif +4: + .p2align ALIGN +5: + + .section .note.GNU-stack,"",@progbits diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c b/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c new file mode 100644 index 0000000000..ecf86a9e16 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c @@ -0,0 +1,127 @@ +/* Check getcontext and setcontext on the context from makecontext + with shadow stack. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <ucontext.h> +#include <unistd.h> +#include <sys/mman.h> +#include <stdatomic.h> +#include <x86intrin.h> + +static ucontext_t ctx[5]; +static atomic_int done; + +static void +__attribute__((noinline, noclone)) +f2 (void) +{ + printf ("start f2\n"); + done++; + if (setcontext (&ctx[2]) != 0) + { + printf ("%s: setcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } +} + +static void +f1 (void) +{ + printf ("start f1\n"); + if (getcontext (&ctx[2]) != 0) + { + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + if (done) + exit (EXIT_SUCCESS); + f2 (); +} + +static int +do_test (void) +{ + char st1[32768]; + puts ("making contexts"); + if (getcontext (&ctx[0]) != 0) + { + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + if (getcontext (&ctx[1]) != 0) + { + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + + ctx[3].uc_stack.ss_sp = st1; + ctx[3].uc_stack.ss_size = sizeof st1; + ctx[3].uc_link = &ctx[0]; + makecontext (&ctx[3], (void (*) (void)) f1, 0); + + ctx[1].uc_stack.ss_sp = st1; + ctx[1].uc_stack.ss_size = sizeof st1; + ctx[1].uc_link = &ctx[0]; + makecontext (&ctx[1], (void (*) (void)) f1, 0); + + ctx[4].uc_stack.ss_sp = st1; + ctx[4].uc_stack.ss_size = sizeof st1; + ctx[4].uc_link = &ctx[0]; + makecontext (&ctx[4], (void (*) (void)) f1, 0); + + /* NB: When shadow stack is enabled, makecontext calls arch_prctl + with ARCH_CET_ALLOC_SHSTK to allocate a new shadow stack which + can be unmapped. The base address and size of the new shadow + stack are returned in __ssp[1] and __ssp[2]. makecontext is + called for CTX1, CTX3 and CTX4. But only CTX1 is used. New + shadow stacks are allocated in the order of CTX3, CTX1, CTX4. + It is very likely that CTX1's shadow stack is placed between + CTX3 and CTX4. We munmap CTX3's and CTX4's shadow stacks to + create gaps above and below CTX1's shadow stack. We check + that setcontext CTX1 works correctly in this case. */ + if (_get_ssp () != 0) + { + if (ctx[3].__ssp[1] != 0 + && munmap ((void *) (uintptr_t) ctx[3].__ssp[1], + (size_t) ctx[3].__ssp[2]) != 0) + { + printf ("%s: munmap: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + + if (ctx[4].__ssp[1] != 0 + && munmap ((void *) (uintptr_t) ctx[4].__ssp[1], + (size_t) ctx[4].__ssp[2]) != 0) + { + printf ("%s: munmap: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + } + + if (setcontext (&ctx[1]) != 0) + { + printf ("%s: setcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + exit (EXIT_FAILURE); +} + +#include <support/test-driver.c> diff --git a/sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c b/sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c new file mode 100644 index 0000000000..56e680527c --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c @@ -0,0 +1,55 @@ +/* Test that sigprocmask does not read from the unused part of jmpbuf. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <errno.h> +#include <setjmpP.h> +#include <support/next_to_fault.h> + +#define SIZEOF_SIGSET_T sizeof (__jmp_buf_sigset_t) + +static int +do_test (void) +{ + sigjmp_buf sj; + struct support_next_to_fault sigset_t_buf + = support_next_to_fault_allocate (SIZEOF_SIGSET_T); + sigset_t *m_p = (sigset_t *) sigset_t_buf.buffer; + sigset_t m; + + sigemptyset (&m); + memcpy (m_p, &m, SIZEOF_SIGSET_T); + sigprocmask (SIG_SETMASK, m_p, NULL); + memcpy (&m, m_p, SIZEOF_SIGSET_T); + if (sigsetjmp (sj, 0) == 0) + { + sigaddset (&m, SIGUSR1); + memcpy (m_p, &m, SIZEOF_SIGSET_T); + sigprocmask (SIG_SETMASK, m_p, NULL); + memcpy (&m, m_p, SIZEOF_SIGSET_T); + siglongjmp (sj, 1); + return EXIT_FAILURE; + } + sigprocmask (SIG_SETMASK, NULL, m_p); + memcpy (&m, m_p, SIZEOF_SIGSET_T); + return sigismember (&m, SIGUSR1) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +#include <support/test-driver.c> |