From a64e3aadbf99dd99baab4b3b650eb6be68b3a4aa Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 17 Mar 2016 19:07:39 +0000 Subject: Remove __ASSUME_EVENTFD2, move eventfd to syscalls.list. Given current Linux kernel version requirements, we can assume the presence of the eventfd2 syscall. This means that __ASSUME_EVENTFD2 can be removed, and a syscalls.list entry suffices for eventfd instead of needing a .c file. This patch implements those changes. Tested for x86_64 and x86 (not that that means much, given the lack of testsuite coverage for eventfd). * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_EVENTFD2): Remove macro. * sysdeps/unix/sysv/linux/eventfd.c: Remove file. * sysdeps/unix/sysv/linux/syscalls.list (eventfd): New syscall entry. --- sysdeps/unix/sysv/linux/syscalls.list | 1 + 1 file changed, 1 insertion(+) (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index afaf0337bd..7ae2541f8f 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -13,6 +13,7 @@ epoll_create EXTRA epoll_create i:i epoll_create epoll_create1 EXTRA epoll_create1 i:i epoll_create1 epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl epoll_wait EXTRA epoll_wait Ci:ipii epoll_wait +eventfd EXTRA eventfd2 i:ii eventfd execve - execve i:spp __execve execve fdatasync - fdatasync Ci:i fdatasync flock - flock i:ii __flock flock -- cgit v1.2.3 From 045c13d18554ae626dfc62f392afb33856c6321d Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Tue, 18 Oct 2016 09:41:56 -0200 Subject: Consolidate Linux setrlimit and getrlimit implementation This patch consolidates all Linux setrlimit and getrlimit on the default sysdeps/unix/sysv/linux/{set,get}rlimit{64}.c. It contains two exceptions: 1. mips32 and mips64n32 which requires a versioned symbol for GLIBC 2.19 and higher due a broken RLIM64_INFINITY constant. 2. sparc32 does not define a compat symbol for getrlimit64 for old 2GB limit. I am not sure if it is required, but a RLIM_INFINITY fix [1] change its definition without adding a compat symbol. This patch does not aim to address this possible issue, it follow current symbol export. The default implementation uses prlimit64 for 64 bit rlim_t ({set,get}rlimit64) and if it fails with ENOSYS it fall back to {get,set}rlimit syscall. This code path is only used on kernel older than 2.6.36 (basically now only x86) and I avoid to user __ASSUME_PRLIMTI64 to simplify the implementation. Once x86 moves to be on par with other architectures regarding minimum kernel supported we can get rid of using old syscalls and default path. A new type size define is added, __RLIM_T_MATCHES_RLIM64_T, where is set as default for 64 bits ports. This allows the default implementation to avoid {get,set}rlimit building and alias {get,set}rlimit64 to {get,set}rlimit. Checked on x86_64, i386, armhf, aarch64, and powerpc64le. I also did a sanity build plus check-abi on all other supported architectures. [1] Commit 9c96ff23858b0759e12ad69e3c4599931c90bee8 Adhemerval Zanella Yury Norov * bits/typesizes.h (__RLIM_T_MATCHES_RLIM64_T): define. * sysdeps/unix/sysv/linux/alpha/bits/typesizes.h (__RLIM_T_MATCHES_RLIM64_T): Likewise. * sysdeps/unix/sysv/linux/generic/bits/typesizes.h (__RLIM_T_MATCHES_RLIM64_T): Likewise. * sysdeps/unix/sysv/linux/s390/bits/typesizes.h [__s390x__] (__RLIM_T_MATCHES_RLIM64_T): Likewise. * sysdeps/unix/sysv/linux/sparc/bits/typesizes.h [__arch64__ || __sparcv9] (__RLIM_T_MATCHES_RLIM64_T): Likewise. * sysdeps/unix/sysv/linux/x86/bits/typesizes.h [__86_64__] (__RLIM_T_MATCHES_RLIM64_T): Likewise. * sysdeps/unix/sysv/linux/arm/Makefile [$(subdir) = resource] (sysdep_routines): Remove oldgetrlimit64. * sysdeps/unix/sysv/linux/i386/Makefile [$(subdir) = resource] (sysdep_routines): Likewise. * sysdeps/unix/sysv/linux/m68k/Makefile [$(subdir) = resource] (sysdep_routines): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile [$(subdir) = resource] (sysdep_routines): Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/Makefile [$(subdir) = resource] (sysdep_routines): Likewise. * sysdeps/unix/sysv/linux/arm/getrlimit64.c: Remove file. * sysdeps/unix/sysv/linux/arm/oldgetrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/hppa/getrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/i386/getrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/m68k/getrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/m68k/oldgetrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/powerpc/getrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/sh/getrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c: Likewise. * sysdeps/sysv/linux/generic/wordsize-32/syscalls.list: Remove setrlimit and getrlimit. * sysdeps/unix/sysv/linux/hppa/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/i386/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/wordsize-64/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/getrlimit.c: New file. * sysdeps/unix/sysv/linux/sparc/getrlimit64.c: Likewise. * sysdeps/unix/sysv/linux/setrlimit.c: Likewise. * sysdeps/unix/sysv/linux/getrlimit64.c (__getrlimit64): Handle __RLIM_T_MATCHES_RLIM64_T and add alias if defined. (__old_getrlimit64): Add compatibility symbol. * sysdeps/unix/sysv/linux/setrlimit64.c (__setrlimit): Likewise. --- ChangeLog | 59 +++++++++++++++ bits/typesizes.h | 5 ++ sysdeps/unix/sysv/linux/alpha/bits/typesizes.h | 3 + sysdeps/unix/sysv/linux/arm/Makefile | 4 - sysdeps/unix/sysv/linux/arm/getrlimit64.c | 1 - sysdeps/unix/sysv/linux/arm/oldgetrlimit.c | 1 - sysdeps/unix/sysv/linux/arm/oldgetrlimit64.c | 1 - sysdeps/unix/sysv/linux/arm/oldsetrlimit.c | 1 - sysdeps/unix/sysv/linux/generic/bits/typesizes.h | 5 ++ .../sysv/linux/generic/wordsize-32/syscalls.list | 2 - sysdeps/unix/sysv/linux/getrlimit.c | 56 ++++++++++++++ sysdeps/unix/sysv/linux/getrlimit64.c | 86 +++++++++++++++++++--- sysdeps/unix/sysv/linux/hppa/getrlimit64.c | 1 - sysdeps/unix/sysv/linux/hppa/syscalls.list | 2 - sysdeps/unix/sysv/linux/i386/Makefile | 4 - sysdeps/unix/sysv/linux/i386/getrlimit64.c | 25 ------- sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c | 57 -------------- sysdeps/unix/sysv/linux/i386/syscalls.list | 2 - sysdeps/unix/sysv/linux/m68k/Makefile | 4 - sysdeps/unix/sysv/linux/m68k/getrlimit64.c | 1 - sysdeps/unix/sysv/linux/m68k/m680x0/syscalls.list | 4 - sysdeps/unix/sysv/linux/m68k/oldgetrlimit64.c | 1 - sysdeps/unix/sysv/linux/powerpc/getrlimit64.c | 1 - sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c | 1 - sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile | 4 - .../sysv/linux/powerpc/powerpc32/syscalls.list | 4 - .../sysv/linux/powerpc/powerpc64/syscalls.list | 3 - sysdeps/unix/sysv/linux/s390/bits/typesizes.h | 5 ++ sysdeps/unix/sysv/linux/s390/s390-32/Makefile | 4 - sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c | 1 - .../unix/sysv/linux/s390/s390-32/oldgetrlimit64.c | 1 - sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list | 3 - sysdeps/unix/sysv/linux/setrlimit.c | 64 ++++++++++++++++ sysdeps/unix/sysv/linux/setrlimit64.c | 48 +++++++++--- sysdeps/unix/sysv/linux/sh/getrlimit64.c | 1 - sysdeps/unix/sysv/linux/sparc/bits/typesizes.h | 5 ++ sysdeps/unix/sysv/linux/sparc/getrlimit64.c | 24 ++++++ .../unix/sysv/linux/sparc/sparc32/syscalls.list | 2 - sysdeps/unix/sysv/linux/syscalls.list | 1 - sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c | 1 - sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c | 1 - sysdeps/unix/sysv/linux/wordsize-64/syscalls.list | 2 - sysdeps/unix/sysv/linux/x86/bits/typesizes.h | 5 ++ 43 files changed, 341 insertions(+), 165 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/arm/getrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/arm/oldgetrlimit.c delete mode 100644 sysdeps/unix/sysv/linux/arm/oldgetrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/arm/oldsetrlimit.c create mode 100644 sysdeps/unix/sysv/linux/getrlimit.c delete mode 100644 sysdeps/unix/sysv/linux/hppa/getrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/i386/getrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/m68k/getrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/m68k/m680x0/syscalls.list delete mode 100644 sysdeps/unix/sysv/linux/m68k/oldgetrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/powerpc/getrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c create mode 100644 sysdeps/unix/sysv/linux/setrlimit.c delete mode 100644 sysdeps/unix/sysv/linux/sh/getrlimit64.c create mode 100644 sysdeps/unix/sysv/linux/sparc/getrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c delete mode 100644 sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 721ea68d24..330a631331 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,62 @@ +2016-11-17 Adhemerval Zanella + Yury Norov + + * bits/typesizes.h (__RLIM_T_MATCHES_RLIM64_T): define. + * sysdeps/unix/sysv/linux/alpha/bits/typesizes.h + (__RLIM_T_MATCHES_RLIM64_T): Likewise. + * sysdeps/unix/sysv/linux/generic/bits/typesizes.h + (__RLIM_T_MATCHES_RLIM64_T): Likewise. + * sysdeps/unix/sysv/linux/s390/bits/typesizes.h [__s390x__] + (__RLIM_T_MATCHES_RLIM64_T): Likewise. + * sysdeps/unix/sysv/linux/sparc/bits/typesizes.h + [__arch64__ || __sparcv9] (__RLIM_T_MATCHES_RLIM64_T): Likewise. + * sysdeps/unix/sysv/linux/x86/bits/typesizes.h [__86_64__] + (__RLIM_T_MATCHES_RLIM64_T): Likewise. + * sysdeps/unix/sysv/linux/arm/Makefile [$(subdir) = resource] + (sysdep_routines): Remove oldgetrlimit64. + * sysdeps/unix/sysv/linux/i386/Makefile [$(subdir) = resource] + (sysdep_routines): Likewise. + * sysdeps/unix/sysv/linux/m68k/Makefile [$(subdir) = resource] + (sysdep_routines): Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile + [$(subdir) = resource] (sysdep_routines): Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/Makefile + [$(subdir) = resource] (sysdep_routines): Likewise. + * sysdeps/unix/sysv/linux/arm/getrlimit64.c: Remove file. + * sysdeps/unix/sysv/linux/arm/oldgetrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/arm/oldgetrlimit.c: Likewise. + * sysdeps/unix/sysv/linux/arm/oldsetrlimit.c: Likewise. + * sysdeps/unix/sysv/linux/hppa/getrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/i386/getrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/m68k/getrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/m68k/oldgetrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/powerpc/getrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/sh/getrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c: Likewise. + * sysdeps/sysv/linux/generic/wordsize-32/syscalls.list: Remove + setrlimit and getrlimit. + * sysdeps/unix/sysv/linux/hppa/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/i386/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/m68k/m680x0/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/wordsize-64/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/getrlimit.c: New file. + * sysdeps/unix/sysv/linux/sparc/getrlimit64.c: Likewise. + * sysdeps/unix/sysv/linux/setrlimit.c: Likewise. + * sysdeps/unix/sysv/linux/getrlimit64.c (__getrlimit64): Handle + __RLIM_T_MATCHES_RLIM64_T and add alias if defined. + (__old_getrlimit64): Add compatibility symbol. + * sysdeps/unix/sysv/linux/setrlimit64.c (__setrlimit): Likewise. + 2016-11-17 Joseph Myers * scripts/build-many-glibcs.py (Config.build_gcc): Configure with diff --git a/bits/typesizes.h b/bits/typesizes.h index 53047b8531..ff20601046 100644 --- a/bits/typesizes.h +++ b/bits/typesizes.h @@ -69,6 +69,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/alpha/bits/typesizes.h b/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h index 3cfd887c39..ce96501bdb 100644 --- a/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h @@ -66,6 +66,9 @@ for C type-checking purposes. */ #define __OFF_T_MATCHES_OFF64_T 1 +/* And for __rlim_t and __rlim64_t. */ +#define __RLIM_T_MATCHES_RLIM64_T 1 + /* Number of descriptors that can fit in an `fd_set'. */ #define __FD_SETSIZE 1024 diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile index 270cb73f70..b9b8f71721 100644 --- a/sysdeps/unix/sysv/linux/arm/Makefile +++ b/sysdeps/unix/sysv/linux/arm/Makefile @@ -12,10 +12,6 @@ ifeq ($(subdir),signal) sysdep_routines += sigrestorer endif -ifeq ($(subdir),resource) -sysdep_routines += oldgetrlimit64 -endif - ifeq ($(subdir),stdlib) gen-as-const-headers += ucontext_i.sym endif diff --git a/sysdeps/unix/sysv/linux/arm/getrlimit64.c b/sysdeps/unix/sysv/linux/arm/getrlimit64.c deleted file mode 100644 index fef018f471..0000000000 --- a/sysdeps/unix/sysv/linux/arm/getrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/arm/oldgetrlimit.c b/sysdeps/unix/sysv/linux/arm/oldgetrlimit.c deleted file mode 100644 index 6e25b021ab..0000000000 --- a/sysdeps/unix/sysv/linux/arm/oldgetrlimit.c +++ /dev/null @@ -1 +0,0 @@ -/* Empty. */ diff --git a/sysdeps/unix/sysv/linux/arm/oldgetrlimit64.c b/sysdeps/unix/sysv/linux/arm/oldgetrlimit64.c deleted file mode 100644 index 4c27e957bf..0000000000 --- a/sysdeps/unix/sysv/linux/arm/oldgetrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/arm/oldsetrlimit.c b/sysdeps/unix/sysv/linux/arm/oldsetrlimit.c deleted file mode 100644 index 6e25b021ab..0000000000 --- a/sysdeps/unix/sysv/linux/arm/oldsetrlimit.c +++ /dev/null @@ -1 +0,0 @@ -/* Empty. */ diff --git a/sysdeps/unix/sysv/linux/generic/bits/typesizes.h b/sysdeps/unix/sysv/linux/generic/bits/typesizes.h index c31bba2f7c..f7766c788e 100644 --- a/sysdeps/unix/sysv/linux/generic/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/generic/bits/typesizes.h @@ -70,6 +70,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/generic/wordsize-32/syscalls.list b/sysdeps/unix/sysv/linux/generic/wordsize-32/syscalls.list index f055c68519..b775008a37 100644 --- a/sysdeps/unix/sysv/linux/generic/wordsize-32/syscalls.list +++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/syscalls.list @@ -1,7 +1,5 @@ # File name Caller Syscall name # args Strong name Weak names # rlimit APIs -getrlimit - getrlimit i:ip __getrlimit getrlimit -setrlimit - setrlimit i:ip __setrlimit setrlimit prlimit64 EXTRA prlimit64 i:iipp prlimit64 fanotify_mark EXTRA fanotify_mark i:iiiiis fanotify_mark diff --git a/sysdeps/unix/sysv/linux/getrlimit.c b/sysdeps/unix/sysv/linux/getrlimit.c new file mode 100644 index 0000000000..bd340fb73e --- /dev/null +++ b/sysdeps/unix/sysv/linux/getrlimit.c @@ -0,0 +1,56 @@ +/* Linux getrlimit implementation (32 bits rlim_t). + Copyright (C) 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 + . */ + +#include +#include +#include +#include + +#if !__RLIM_T_MATCHES_RLIM64_T + +/* The __NR_getrlimit compatibility implementation is required iff + __NR_ugetrlimit is also defined (meaning an old broken RLIM_INFINITY + definition). */ +# ifndef __NR_ugetrlimit +# define __NR_ugetrlimit __NR_getrlimit +# undef SHLIB_COMPAT +# define SHLIB_COMPAT(a, b, c) 0 +# endif + +int +__new_getrlimit (enum __rlimit_resource resource, struct rlimit *rlim) +{ + return INLINE_SYSCALL_CALL (ugetrlimit, resource, rlim); +} +weak_alias (__new_getrlimit, __getrlimit) +hidden_weak (__getrlimit) + +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) +/* Back compatible 2Gig limited rlimit. */ +int +__old_getrlimit (enum __rlimit_resource resource, struct rlimit *rlim) +{ + return INLINE_SYSCALL_CALL (getrlimit, resource, rlim); +} +compat_symbol (libc, __old_getrlimit, getrlimit, GLIBC_2_0); +versioned_symbol (libc, __new_getrlimit, getrlimit, GLIBC_2_2); +# else +weak_alias (__new_getrlimit, getrlimit) +# endif + +#endif /* __RLIM_T_MATCHES_RLIM64_T */ diff --git a/sysdeps/unix/sysv/linux/getrlimit64.c b/sysdeps/unix/sysv/linux/getrlimit64.c index d055a7f839..cb3d0080d8 100644 --- a/sysdeps/unix/sysv/linux/getrlimit64.c +++ b/sysdeps/unix/sysv/linux/getrlimit64.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2010-2016 Free Software Foundation, Inc. +/* Linux getrlimit64 implementation (64 bits rlim_t). + Copyright (C) 2010-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 @@ -16,29 +17,46 @@ . */ #include -#include #include -#include -#include +#include + +/* Add this redirection so the strong_alias for __RLIM_T_MATCHES_RLIM64_T + linking getlimit64 to {__}getrlimit does not throw a type error. */ +#undef getrlimit +#undef __getrlimit +#define getrlimit getrlimit_redirect +#define __getrlimit __getrlimit_redirect +#include +#undef getrlimit +#undef __getrlimit /* Put the soft and hard limits for RESOURCE in *RLIMITS. Returns 0 if successful, -1 if not (and sets errno). */ int __getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) { -#ifdef __ASSUME_PRLIMIT64 - return INLINE_SYSCALL (prlimit64, 4, 0, resource, NULL, rlimits); -#else -# ifdef __NR_prlimit64 - int res = INLINE_SYSCALL (prlimit64, 4, 0, resource, NULL, rlimits); +#ifdef __NR_prlimit64 + int res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, rlimits); if (res == 0 || errno != ENOSYS) return res; +#endif + +/* The fallback code only makes sense if the platform supports either + __NR_ugetrlimit and/or __NR_getrlimit. */ +#if defined (__NR_ugetrlimit) || defined (__NR_getrlimit) +# ifndef __NR_ugetrlimit +# define __NR_ugetrlimit __NR_getrlimit # endif +# if __RLIM_T_MATCHES_RLIM64_T +# define rlimits32 (*rlimits) +# else struct rlimit rlimits32; +# endif - if (__getrlimit (resource, &rlimits32) < 0) + if (INLINE_SYSCALL_CALL (ugetrlimit, resource, &rlimits32) < 0) return -1; +# if !__RLIM_T_MATCHES_RLIM64_T if (rlimits32.rlim_cur == RLIM_INFINITY) rlimits->rlim_cur = RLIM64_INFINITY; else @@ -47,12 +65,56 @@ __getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) rlimits->rlim_max = RLIM64_INFINITY; else rlimits->rlim_max = rlimits32.rlim_max; +# endif /* !__RLIM_T_MATCHES_RLIM64_T */ +#endif /* defined (__NR_ugetrlimit) || defined (__NR_getrlimit) */ return 0; -#endif } libc_hidden_def (__getrlimit64) -#ifndef getrlimit64 + +#if __RLIM_T_MATCHES_RLIM64_T +/* If both rlim_t and rlimt64_t are essentially the same type we can use + alias both interfaces. */ +strong_alias (__getrlimit64, __GI_getrlimit) +strong_alias (__getrlimit64, __GI___getrlimit) +strong_alias (__getrlimit64, __getrlimit) +weak_alias (__getrlimit64, getrlimit) +/* And there is no need for compat symbols. */ +# undef SHLIB_COMPAT +# define SHLIB_COMPAT(a, b, c) 0 +#endif + +#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) +/* Back compatible 2GiB limited rlimit. */ +extern int __new_getrlimit (enum __rlimit_resource, struct rlimit *); + +int +attribute_compat_text_section +__old_getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) +{ +# if __RLIM_T_MATCHES_RLIM64_T +# define rlimits32 (*rlimits) +# else + struct rlimit rlimits32; +# endif + + if (__new_getrlimit (resource, &rlimits32) < 0) + return -1; + + if (rlimits32.rlim_cur == RLIM_INFINITY) + rlimits->rlim_cur = RLIM64_INFINITY >> 1; + else + rlimits->rlim_cur = rlimits32.rlim_cur; + if (rlimits32.rlim_max == RLIM_INFINITY) + rlimits->rlim_max = RLIM64_INFINITY >> 1; + else + rlimits->rlim_max = rlimits32.rlim_max; + + return 0; +} +versioned_symbol (libc, __getrlimit64, getrlimit64, GLIBC_2_2); +compat_symbol (libc, __old_getrlimit64, getrlimit64, GLIBC_2_1); +#else weak_alias (__getrlimit64, getrlimit64) libc_hidden_weak (getrlimit64) #endif diff --git a/sysdeps/unix/sysv/linux/hppa/getrlimit64.c b/sysdeps/unix/sysv/linux/hppa/getrlimit64.c deleted file mode 100644 index fef018f471..0000000000 --- a/sysdeps/unix/sysv/linux/hppa/getrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/hppa/syscalls.list b/sysdeps/unix/sysv/linux/hppa/syscalls.list index 1f3dfb01e8..a95c3ddf18 100644 --- a/sysdeps/unix/sysv/linux/hppa/syscalls.list +++ b/sysdeps/unix/sysv/linux/hppa/syscalls.list @@ -31,8 +31,6 @@ shutdown - shutdown i:ii __shutdown shutdown socket - socket i:iii __socket socket socketpair - socketpair i:iiif __socketpair socketpair -setrlimit - setrlimit i:ip __setrlimit setrlimit -getrlimit - getrlimit i:ip __getrlimit getrlimit prlimit64 EXTRA prlimit64 i:iipp __prlimit64 prlimit64@@GLIBC_2.17 fanotify_mark EXTRA fanotify_mark i:iiiiis __fanotify_mark fanotify_mark@@GLIBC_2.19 personality EXTRA personality Ei:i __personality personality diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile index 2596cdfbb2..9609752256 100644 --- a/sysdeps/unix/sysv/linux/i386/Makefile +++ b/sysdeps/unix/sysv/linux/i386/Makefile @@ -49,10 +49,6 @@ libpthread-sysdep_routines += libc-do-syscall libpthread-shared-only-routines += libc-do-syscall endif -ifeq ($(subdir),resource) -sysdep_routines += oldgetrlimit64 -endif - ifeq ($(subdir),stdlib) gen-as-const-headers += ucontext_i.sym endif diff --git a/sysdeps/unix/sysv/linux/i386/getrlimit64.c b/sysdeps/unix/sysv/linux/i386/getrlimit64.c deleted file mode 100644 index 7f3d227beb..0000000000 --- a/sysdeps/unix/sysv/linux/i386/getrlimit64.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (C) 1999-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 - . */ - -#define getrlimit64 __new_getrlimit64 - -#include "../getrlimit64.c" - -#undef getrlimit64 -#include -versioned_symbol (libc, __getrlimit64, getrlimit64, GLIBC_2_2); -strong_alias (__getrlimit64, __GI_getrlimit64) diff --git a/sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c b/sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c deleted file mode 100644 index ad86a07203..0000000000 --- a/sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 1991-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 - . */ - -/* This is a compatibility file. If we don't build the libc with - versioning don't compile this file. */ -#include -#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) - -#include -#include -#include - -extern int __new_getrlimit (enum __rlimit_resource, struct rlimit *); -extern int __old_getrlimit64 (enum __rlimit_resource resource, - struct rlimit64 *rlimits); - - -/* Put the soft and hard limits for RESOURCE in *RLIMITS. - Returns 0 if successful, -1 if not (and sets errno). */ -int -attribute_compat_text_section -__old_getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) -{ - struct rlimit rlimits32; - - if (__new_getrlimit (resource, &rlimits32) < 0) - return -1; - - if (rlimits32.rlim_cur == RLIM_INFINITY) - rlimits->rlim_cur = RLIM64_INFINITY >> 1; - else - rlimits->rlim_cur = rlimits32.rlim_cur; - if (rlimits32.rlim_max == RLIM_INFINITY) - rlimits->rlim_max = RLIM64_INFINITY >> 1; - else - rlimits->rlim_max = rlimits32.rlim_max; - - return 0; -} - -compat_symbol (libc, __old_getrlimit64, getrlimit64, GLIBC_2_1); - -#endif /* SHLIB_COMPAT */ diff --git a/sysdeps/unix/sysv/linux/i386/syscalls.list b/sysdeps/unix/sysv/linux/i386/syscalls.list index 6282ff8e2f..145393f780 100644 --- a/sysdeps/unix/sysv/linux/i386/syscalls.list +++ b/sysdeps/unix/sysv/linux/i386/syscalls.list @@ -18,8 +18,6 @@ setfsuid - setfsuid32 Ei:i setfsuid modify_ldt EXTRA modify_ldt i:ipi __modify_ldt modify_ldt vm86old EXTRA vm86old i:p __vm86old vm86@GLIBC_2.0 vm86 - vm86 i:ip __vm86 vm86@@GLIBC_2.3.4 -oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 -setrlimit - setrlimit i:ip __setrlimit setrlimit@GLIBC_2.0 setrlimit@@GLIBC_2.2 waitpid - waitpid Ci:ipi __waitpid waitpid prlimit64 EXTRA prlimit64 i:iipp prlimit64 diff --git a/sysdeps/unix/sysv/linux/m68k/Makefile b/sysdeps/unix/sysv/linux/m68k/Makefile index 61c355ac2a..5c50ce6927 100644 --- a/sysdeps/unix/sysv/linux/m68k/Makefile +++ b/sysdeps/unix/sysv/linux/m68k/Makefile @@ -18,7 +18,3 @@ sysdep-rtld-routines += m68k-vdso sysdep-others += lddlibc4 install-bin += lddlibc4 endif - -ifeq ($(subdir),resource) -sysdep_routines += oldgetrlimit64 -endif diff --git a/sysdeps/unix/sysv/linux/m68k/getrlimit64.c b/sysdeps/unix/sysv/linux/m68k/getrlimit64.c deleted file mode 100644 index fef018f471..0000000000 --- a/sysdeps/unix/sysv/linux/m68k/getrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/syscalls.list b/sysdeps/unix/sysv/linux/m68k/m680x0/syscalls.list deleted file mode 100644 index b0ad68936d..0000000000 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/syscalls.list +++ /dev/null @@ -1,4 +0,0 @@ -# File name Caller Syscall name Args Strong name Weak names - -oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 -setrlimit - setrlimit i:ip __setrlimit setrlimit@GLIBC_2.0 setrlimit@@GLIBC_2.2 diff --git a/sysdeps/unix/sysv/linux/m68k/oldgetrlimit64.c b/sysdeps/unix/sysv/linux/m68k/oldgetrlimit64.c deleted file mode 100644 index 4c27e957bf..0000000000 --- a/sysdeps/unix/sysv/linux/m68k/oldgetrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c b/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c deleted file mode 100644 index fef018f471..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c b/sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c deleted file mode 100644 index 4c27e957bf..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile b/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile index 84324aa7e1..3d6c150582 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile @@ -1,6 +1,2 @@ # See Makeconfig regarding the use of default-abi. default-abi := 32 - -ifeq ($(subdir),resource) -sysdep_routines += oldgetrlimit64 -endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list b/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list index 451d50884b..931374776a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list @@ -3,10 +3,6 @@ chown - chown i:sii __chown chown@@GLIBC_2.1 lchown - lchown i:sii __lchown lchown@@GLIBC_2.0 chown@GLIBC_2.0 -# System calls with wrappers. -oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 -setrlimit - setrlimit i:ip __setrlimit setrlimit@GLIBC_2.0 setrlimit@@GLIBC_2.2 - # Due to 64bit alignment there is a dummy second parameter readahead - readahead i:iiiii __readahead readahead diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list b/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list deleted file mode 100644 index 6ba6f9b1e9..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list +++ /dev/null @@ -1,3 +0,0 @@ -# File name Caller Syscall name # args Strong name Weak names - -getrlimit - ugetrlimit i:ip __getrlimit getrlimit getrlimit64 __getrlimit64 diff --git a/sysdeps/unix/sysv/linux/s390/bits/typesizes.h b/sysdeps/unix/sysv/linux/s390/bits/typesizes.h index 7ee0cef9fb..62b2418fef 100644 --- a/sysdeps/unix/sysv/linux/s390/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/s390/bits/typesizes.h @@ -75,6 +75,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/s390/s390-32/Makefile b/sysdeps/unix/sysv/linux/s390/s390-32/Makefile index 626a96f04f..da3b3c76b4 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/Makefile +++ b/sysdeps/unix/sysv/linux/s390/s390-32/Makefile @@ -10,10 +10,6 @@ ifeq ($(subdir),misc) sysdep_headers += sys/elf.h endif -ifeq ($(subdir),resource) -sysdep_routines += oldgetrlimit64 -endif - ifeq ($(subdir),elf) ifeq (yes,$(build-shared)) # This is needed to support g++ v2 and v3. diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c b/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c deleted file mode 100644 index fef018f471..0000000000 --- a/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c b/sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c deleted file mode 100644 index 4c27e957bf..0000000000 --- a/sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list b/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list index 141b16523d..300b13dd01 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list +++ b/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list @@ -15,9 +15,6 @@ getgroups - getgroups32 i:ip __getgroups getgroups setfsgid - setfsgid32 Ei:i setfsgid setfsuid - setfsuid32 Ei:i setfsuid -oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 -setrlimit - setrlimit i:ip __setrlimit setrlimit@GLIBC_2.0 setrlimit@@GLIBC_2.2 - prlimit64 EXTRA prlimit64 i:iipp prlimit64 fanotify_mark EXTRA fanotify_mark i:iiiiis fanotify_mark personality EXTRA personality Ei:i __personality personality diff --git a/sysdeps/unix/sysv/linux/setrlimit.c b/sysdeps/unix/sysv/linux/setrlimit.c new file mode 100644 index 0000000000..78a3c33738 --- /dev/null +++ b/sysdeps/unix/sysv/linux/setrlimit.c @@ -0,0 +1,64 @@ +/* Linux setrlimit implementation (32 bits off_t). + Copyright (C) 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 + . */ + +#include +#include +#include +#include + +#if !__RLIM_T_MATCHES_RLIM64_T + +/* The compatibility symbol is meant to match the old __NR_getrlimit syscall + (with broken RLIM_INFINITY definition). It should be provided iff + __NR_getrlimit and __NR_ugetrlimit are both defined. */ +# ifndef __NR_ugetrlimit +# undef SHLIB_COMPAT +# define SHLIB_COMPAT(a, b, c) 0 +# endif + +int +__setrlimit (enum __rlimit_resource resource, const struct rlimit *rlim) +{ +# ifdef __NR_prlimit64 + struct rlimit64 rlim64; + + if (rlim->rlim_cur == RLIM_INFINITY) + rlim64.rlim_cur = RLIM64_INFINITY; + else + rlim64.rlim_cur = rlim->rlim_cur; + if (rlim->rlim_max == RLIM_INFINITY) + rlim64.rlim_max = RLIM64_INFINITY; + else + rlim64.rlim_max = rlim->rlim_max; + + int res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, &rlim64, NULL); + if (res == 0 || errno != ENOSYS) + return res; +# endif + return INLINE_SYSCALL_CALL (setrlimit, resource, rlim); +} + +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) +strong_alias (__setrlimit, __setrlimit_1) +compat_symbol (libc, __setrlimit, setrlimit, GLIBC_2_0); +versioned_symbol (libc, __setrlimit_1, setrlimit, GLIBC_2_2); +# else +weak_alias (__setrlimit, setrlimit) +# endif + +#endif /* __RLIM_T_MATCHES_RLIM64_T */ diff --git a/sysdeps/unix/sysv/linux/setrlimit64.c b/sysdeps/unix/sysv/linux/setrlimit64.c index 5f444d2ae7..8d2f7c6e53 100644 --- a/sysdeps/unix/sysv/linux/setrlimit64.c +++ b/sysdeps/unix/sysv/linux/setrlimit64.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2010-2016 Free Software Foundation, Inc. +/* Linux setrlimit64 implementation (64 bits off_t). + Copyright (C) 2010-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 @@ -16,25 +17,37 @@ . */ #include -#include #include -#include -#include +#include + +/* Add this redirection so the strong_alias for __RLIM_T_MATCHES_RLIM64_T + linking setlimit64 to {__}setrlimit does not throw a type error. */ +#undef settrlimit +#undef __sttrlimit +#define setrlimit setrlimit_redirect +#define __setrlimit __setrlimit_redirect +#include +#undef setrlimit +#undef __setrlimit /* Set the soft and hard limits for RESOURCE to *RLIMITS. Only the super-user can increase hard limits. Return 0 if successful, -1 if not (and sets errno). */ int -setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) +__setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) { -#ifdef __ASSUME_PRLIMIT64 - return INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL); -#else -# ifdef __NR_prlimit64 - int res = INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL); + int res; + +#ifdef __NR_prlimit64 + res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL); if (res == 0 || errno != ENOSYS) return res; -# endif +#endif + +/* The fallback code only makes sense if the platform supports + __NR_setrlimit. */ +#ifdef __NR_setrlimit +# if !__RLIM_T_MATCHES_RLIM64_T struct rlimit rlimits32; if (rlimits->rlim_cur >= RLIM_INFINITY) @@ -45,7 +58,18 @@ setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) rlimits32.rlim_max = RLIM_INFINITY; else rlimits32.rlim_max = rlimits->rlim_max; +# else +# define rlimits32 (*rlimits) +# endif - return __setrlimit (resource, &rlimits32); + res = INLINE_SYSCALL_CALL (setrlimit, resource, &rlimits32); #endif + + return res; } +weak_alias (__setrlimit64, setrlimit64) + +#if __RLIM_T_MATCHES_RLIM64_T +strong_alias (__setrlimit64, __setrlimit) +weak_alias (__setrlimit64, setrlimit) +#endif diff --git a/sysdeps/unix/sysv/linux/sh/getrlimit64.c b/sysdeps/unix/sysv/linux/sh/getrlimit64.c deleted file mode 100644 index fef018f471..0000000000 --- a/sysdeps/unix/sysv/linux/sh/getrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h b/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h index f98dd83f93..705c8773b3 100644 --- a/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h @@ -69,6 +69,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/sparc/getrlimit64.c b/sysdeps/unix/sysv/linux/sparc/getrlimit64.c new file mode 100644 index 0000000000..3a198521b6 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/getrlimit64.c @@ -0,0 +1,24 @@ +/* Linux getrlimit64 sparc32 implementation (64 bits rlim_t). + Copyright (C) 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 + . */ + +#include + +#undef SHLIB_COMPAT +#define SHLIB_COMPAT(a,b,c) 0 + +#include diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list index 6240cd3a52..0b6095ffab 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list @@ -4,8 +4,6 @@ chown - chown32 i:sii __chown chown lchown - lchown32 i:sii __lchown lchown fchown - fchown32 i:iii __fchown fchown -setrlimit - setrlimit 2 __setrlimit setrlimit -getrlimit - getrlimit 2 __getrlimit getrlimit getegid - getegid32 Ei: __getegid getegid geteuid - geteuid32 Ei: __geteuid geteuid getgid - getgid32 Ei: __getgid getgid diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 7ae2541f8f..68af897e39 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -26,7 +26,6 @@ getpmsg - getpmsg i:ipppp getpmsg getppid - getppid Ei: __getppid getppid getresuid - getresuid i:ppp getresuid getresgid - getresgid i:ppp getresgid -getrlimit - ugetrlimit i:ip __new_getrlimit __getrlimit getrlimit@@GLIBC_2.2 getsid - getsid i:i getsid init_module EXTRA init_module 5 init_module inotify_add_watch EXTRA inotify_add_watch i:isi inotify_add_watch diff --git a/sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c b/sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c deleted file mode 100644 index 9feab0e6b8..0000000000 --- a/sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -/* getrlimit64 is the same as getrlimit. */ diff --git a/sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c b/sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c deleted file mode 100644 index 8edcff0086..0000000000 --- a/sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c +++ /dev/null @@ -1 +0,0 @@ -/* setrlimit64 is the same as setrlimit. */ diff --git a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list index 99236ba9bf..e71cd7b156 100644 --- a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list +++ b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list @@ -3,8 +3,6 @@ fstatfs - fstatfs i:ip __fstatfs fstatfs fstatfs64 __fstatfs64 statfs - statfs i:sp __statfs statfs statfs64 mmap - mmap b:aniiii __mmap mmap __mmap64 mmap64 -getrlimit - getrlimit i:ip __getrlimit getrlimit getrlimit64 __getrlimit64 -setrlimit - setrlimit i:ip __setrlimit setrlimit setrlimit64 readahead - readahead i:iii __readahead readahead sendfile - sendfile i:iipi sendfile sendfile64 sync_file_range - sync_file_range Ci:iiii sync_file_range diff --git a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h index 5817ef3f86..1fd90d3e85 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h @@ -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'. */ -- cgit v1.2.3 From c579f48edba88380635ab98cb612030e3ed8691e Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 10 Oct 2016 15:08:39 -0300 Subject: Remove cached PID/TID in clone This patch remove the PID cache and usage in current GLIBC code. Current usage is mainly used a performance optimization to avoid the syscall, however it adds some issues: - The exposed clone syscall will try to set pid/tid to make the new thread somewhat compatible with current GLIBC assumptions. This cause a set of issue with new workloads and usecases (such as BZ#17214 and [1]) as well for new internal usage of clone to optimize other algorithms (such as clone plus CLONE_VM for posix_spawn, BZ#19957). - The caching complexity also added some bugs in the past [2] [3] and requires more effort of each port to handle such requirements (for both clone and vfork implementation). - Caching performance gain in mainly on getpid and some specific code paths. The getpid performance leverage is questionable [4], either by the idea of getpid being a hotspot as for the getpid implementation itself (if it is indeed a justifiable hotspot a vDSO symbol could let to a much more simpler solution). Other usage is mainly for non usual code paths, such as pthread cancellation signal and handling. For thread creation (on stack allocation) the code simplification in fact adds some performance gain due the no need of transverse the stack cache and invalidate each element pid. Other thread usages will require a direct getpid syscall, such as cancellation/setxid signal, thread cancellation, thread fail path (at create_thread), and thread signal (pthread_kill and pthread_sigqueue). However these are hardly usual hotspots and I think adding a syscall is justifiable. It also simplifies both the clone and vfork arch-specific implementation. And by review each fork implementation there are some discrepancies that this patch also solves: - microblaze clone/vfork does not set/reset the pid/tid field - hppa uses the default vfork implementation that fallback to fork. Since vfork is deprecated I do not think we should bother with it. The patch also removes the TID caching in clone. My understanding for such semantic is try provide some pthread usage after a user program issue clone directly (as done by thread creation with CLONE_PARENT_SETTID and pthread tid member). However, as stated before in multiple discussions threads, GLIBC provides clone syscalls without further supporting all this semantics. I ran a full make check on x86_64, x32, i686, armhf, aarch64, and powerpc64le. For sparc32, sparc64, and mips I ran the basic fork and vfork tests from posix/ folder (on a qemu system). So it would require further testing on alpha, hppa, ia64, m68k, nios2, s390, sh, and tile (I excluded microblaze because it is already implementing the patch semantic regarding clone/vfork). [1] https://codereview.chromium.org/800183004/ [2] https://sourceware.org/ml/libc-alpha/2006-07/msg00123.html [3] https://sourceware.org/bugzilla/show_bug.cgi?id=15368 [4] http://yarchive.net/comp/linux/getpid_caching.html * sysdeps/nptl/fork.c (__libc_fork): Remove pid cache setting. * nptl/allocatestack.c (allocate_stack): Likewise. (__reclaim_stacks): Likewise. (setxid_signal_thread): Obtain pid through syscall. * nptl/nptl-init.c (sigcancel_handler): Likewise. (sighandle_setxid): Likewise. * nptl/pthread_cancel.c (pthread_cancel): Likewise. * sysdeps/unix/sysv/linux/pthread_kill.c (__pthread_kill): Likewise. * sysdeps/unix/sysv/linux/pthread_sigqueue.c (pthread_sigqueue): Likewise. * sysdeps/unix/sysv/linux/createthread.c (create_thread): Likewise. * sysdeps/unix/sysv/linux/getpid.c: Remove file. * nptl/descr.h (struct pthread): Change comment about pid value. * nptl/pthread_getattr_np.c (pthread_getattr_np): Remove thread pid assert. * sysdeps/unix/sysv/linux/pthread-pids.h (__pthread_initialize_pids): Do not set pid value. * nptl_db/td_ta_thr_iter.c (iterate_thread_list): Remove thread pid cache check. * nptl_db/td_thr_validate.c (td_thr_validate): Likewise. * sysdeps/aarch64/nptl/tcb-offsets.sym: Remove pid offset. * sysdeps/alpha/nptl/tcb-offsets.sym: Likewise. * sysdeps/arm/nptl/tcb-offsets.sym: Likewise. * sysdeps/hppa/nptl/tcb-offsets.sym: Likewise. * sysdeps/i386/nptl/tcb-offsets.sym: Likewise. * sysdeps/ia64/nptl/tcb-offsets.sym: Likewise. * sysdeps/m68k/nptl/tcb-offsets.sym: Likewise. * sysdeps/microblaze/nptl/tcb-offsets.sym: Likewise. * sysdeps/mips/nptl/tcb-offsets.sym: Likewise. * sysdeps/nios2/nptl/tcb-offsets.sym: Likewise. * sysdeps/powerpc/nptl/tcb-offsets.sym: Likewise. * sysdeps/s390/nptl/tcb-offsets.sym: Likewise. * sysdeps/sh/nptl/tcb-offsets.sym: Likewise. * sysdeps/sparc/nptl/tcb-offsets.sym: Likewise. * sysdeps/tile/nptl/tcb-offsets.sym: Likewise. * sysdeps/x86_64/nptl/tcb-offsets.sym: Likewise. * sysdeps/unix/sysv/linux/aarch64/clone.S: Remove pid and tid caching. * sysdeps/unix/sysv/linux/alpha/clone.S: Likewise. * sysdeps/unix/sysv/linux/arm/clone.S: Likewise. * sysdeps/unix/sysv/linux/hppa/clone.S: Likewise. * sysdeps/unix/sysv/linux/i386/clone.S: Likewise. * sysdeps/unix/sysv/linux/ia64/clone2.S: Likewise. * sysdeps/unix/sysv/linux/mips/clone.S: Likewise. * sysdeps/unix/sysv/linux/nios2/clone.S: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/clone.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/clone.S: Likewise. * sysdeps/unix/sysv/linux/sh/clone.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/clone.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/clone.S: Likewise. * sysdeps/unix/sysv/linux/tile/clone.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/clone.S: Likewise. * sysdeps/unix/sysv/linux/aarch64/vfork.S: Remove pid set and reset. * sysdeps/unix/sysv/linux/alpha/vfork.S: Likewise. * sysdeps/unix/sysv/linux/arm/vfork.S: Likewise. * sysdeps/unix/sysv/linux/i386/vfork.S: Likewise. * sysdeps/unix/sysv/linux/ia64/vfork.S: Likewise. * sysdeps/unix/sysv/linux/m68k/clone.S: Likewise. * sysdeps/unix/sysv/linux/m68k/vfork.S: Likewise. * sysdeps/unix/sysv/linux/mips/vfork.S: Likewise. * sysdeps/unix/sysv/linux/nios2/vfork.S: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/vfork.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/vfork.S: Likewise. * sysdeps/unix/sysv/linux/sh/vfork.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: Likewise. * sysdeps/unix/sysv/linux/tile/vfork.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/vfork.S: Likewise. * sysdeps/unix/sysv/linux/tst-clone2.c (f): Remove direct pthread struct access. (clone_test): Remove function. (do_test): Rewrite to take in consideration pid is not cached anymore. --- ChangeLog | 81 ++++++++++++++++ nptl/allocatestack.c | 20 +--- nptl/descr.h | 4 +- nptl/nptl-init.c | 15 +-- nptl/pthread_cancel.c | 18 +--- nptl/pthread_getattr_np.c | 1 - nptl_db/structs.def | 1 - nptl_db/td_ta_thr_iter.c | 56 ++++------- nptl_db/td_thr_validate.c | 23 ----- sysdeps/aarch64/nptl/tcb-offsets.sym | 1 - sysdeps/alpha/nptl/tcb-offsets.sym | 1 - sysdeps/arm/nptl/tcb-offsets.sym | 1 - sysdeps/hppa/nptl/tcb-offsets.sym | 2 - sysdeps/i386/nptl/tcb-offsets.sym | 1 - sysdeps/ia64/nptl/tcb-offsets.sym | 1 - sysdeps/m68k/nptl/tcb-offsets.sym | 1 - sysdeps/microblaze/nptl/tcb-offsets.sym | 1 - sysdeps/mips/nptl/tcb-offsets.sym | 1 - sysdeps/nios2/nptl/tcb-offsets.sym | 1 - sysdeps/nptl/fork.c | 12 --- sysdeps/powerpc/nptl/tcb-offsets.sym | 1 - sysdeps/s390/nptl/tcb-offsets.sym | 1 - sysdeps/sh/nptl/tcb-offsets.sym | 1 - sysdeps/sparc/nptl/tcb-offsets.sym | 1 - sysdeps/tile/nptl/tcb-offsets.sym | 1 - sysdeps/unix/sysv/linux/aarch64/clone.S | 10 -- sysdeps/unix/sysv/linux/aarch64/vfork.S | 17 ---- sysdeps/unix/sysv/linux/alpha/clone.S | 16 ---- sysdeps/unix/sysv/linux/alpha/vfork.S | 15 --- sysdeps/unix/sysv/linux/arm/clone.S | 10 -- sysdeps/unix/sysv/linux/arm/vfork.S | 15 --- sysdeps/unix/sysv/linux/createthread.c | 6 +- sysdeps/unix/sysv/linux/getpid.c | 64 ------------- sysdeps/unix/sysv/linux/hppa/clone.S | 12 --- sysdeps/unix/sysv/linux/hppa/pt-vfork.S | 26 ----- sysdeps/unix/sysv/linux/i386/clone.S | 15 --- sysdeps/unix/sysv/linux/i386/vfork.S | 19 ---- sysdeps/unix/sysv/linux/ia64/clone2.S | 14 +-- sysdeps/unix/sysv/linux/ia64/vfork.S | 20 ---- sysdeps/unix/sysv/linux/m68k/clone.S | 13 --- sysdeps/unix/sysv/linux/m68k/vfork.S | 20 ---- sysdeps/unix/sysv/linux/mips/clone.S | 13 --- sysdeps/unix/sysv/linux/mips/vfork.S | 19 ---- sysdeps/unix/sysv/linux/nios2/clone.S | 8 -- sysdeps/unix/sysv/linux/nios2/vfork.S | 10 -- sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S | 9 -- sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S | 26 ----- sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S | 9 -- sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S | 23 ----- sysdeps/unix/sysv/linux/pthread-pids.h | 2 +- sysdeps/unix/sysv/linux/pthread_kill.c | 11 +-- sysdeps/unix/sysv/linux/pthread_sigqueue.c | 15 +-- sysdeps/unix/sysv/linux/raise.c | 7 -- sysdeps/unix/sysv/linux/s390/s390-32/clone.S | 7 -- sysdeps/unix/sysv/linux/s390/s390-32/vfork.S | 12 --- sysdeps/unix/sysv/linux/s390/s390-64/clone.S | 9 -- sysdeps/unix/sysv/linux/s390/s390-64/vfork.S | 13 --- sysdeps/unix/sysv/linux/sh/clone.S | 22 +---- sysdeps/unix/sysv/linux/sh/vfork.S | 21 ---- sysdeps/unix/sysv/linux/sparc/sparc32/clone.S | 7 -- sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S | 10 -- sysdeps/unix/sysv/linux/sparc/sparc64/clone.S | 7 -- sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S | 10 -- sysdeps/unix/sysv/linux/syscalls.list | 1 + sysdeps/unix/sysv/linux/tile/clone.S | 16 ---- sysdeps/unix/sysv/linux/tile/vfork.S | 28 ------ sysdeps/unix/sysv/linux/tst-clone2.c | 111 ++++++++-------------- sysdeps/unix/sysv/linux/x86_64/clone.S | 8 -- sysdeps/unix/sysv/linux/x86_64/vfork.S | 18 ---- sysdeps/x86_64/nptl/tcb-offsets.sym | 1 - 70 files changed, 165 insertions(+), 827 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/getpid.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 7b4b183703..6985be2218 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,84 @@ +2016-11-24 Adhemerval Zanella + + * sysdeps/nptl/fork.c (__libc_fork): Remove pid cache setting. + * nptl/allocatestack.c (allocate_stack): Likewise. + (__reclaim_stacks): Likewise. + (setxid_signal_thread): Obtain pid through syscall. + * nptl/nptl-init.c (sigcancel_handler): Likewise. + (sighandle_setxid): Likewise. + * nptl/pthread_cancel.c (pthread_cancel): Likewise. + * sysdeps/unix/sysv/linux/pthread_kill.c (__pthread_kill): Likewise. + * sysdeps/unix/sysv/linux/pthread_sigqueue.c (pthread_sigqueue): + Likewise. + * sysdeps/unix/sysv/linux/createthread.c (create_thread): Likewise. + * sysdeps/unix/sysv/linux/raise.c (raise): Remove old behaviour + comment. + * sysdeps/unix/sysv/linux/getpid.c: Remove file. + * nptl/descr.h (struct pthread): Change comment about pid value. + * nptl/pthread_getattr_np.c (pthread_getattr_np): Remove thread + pid assert. + * sysdeps/unix/sysv/linux/pthread-pids.h (__pthread_initialize_pids): + Do not set pid value. + * nptl_db/td_ta_thr_iter.c (iterate_thread_list): Remove thread + pid cache check. + * nptl_db/td_thr_validate.c (td_thr_validate): Likewise. + * sysdeps/aarch64/nptl/tcb-offsets.sym: Remove pid offset. + * sysdeps/alpha/nptl/tcb-offsets.sym: Likewise. + * sysdeps/arm/nptl/tcb-offsets.sym: Likewise. + * sysdeps/hppa/nptl/tcb-offsets.sym: Likewise. + * sysdeps/i386/nptl/tcb-offsets.sym: Likewise. + * sysdeps/ia64/nptl/tcb-offsets.sym: Likewise. + * sysdeps/m68k/nptl/tcb-offsets.sym: Likewise. + * sysdeps/microblaze/nptl/tcb-offsets.sym: Likewise. + * sysdeps/mips/nptl/tcb-offsets.sym: Likewise. + * sysdeps/nios2/nptl/tcb-offsets.sym: Likewise. + * sysdeps/powerpc/nptl/tcb-offsets.sym: Likewise. + * sysdeps/s390/nptl/tcb-offsets.sym: Likewise. + * sysdeps/sh/nptl/tcb-offsets.sym: Likewise. + * sysdeps/sparc/nptl/tcb-offsets.sym: Likewise. + * sysdeps/tile/nptl/tcb-offsets.sym: Likewise. + * sysdeps/x86_64/nptl/tcb-offsets.sym: Likewise. + * sysdeps/unix/sysv/linux/aarch64/clone.S: Remove pid and tid caching. + * sysdeps/unix/sysv/linux/alpha/clone.S: Likewise. + * sysdeps/unix/sysv/linux/arm/clone.S: Likewise. + * sysdeps/unix/sysv/linux/hppa/clone.S: Likewise. + * sysdeps/unix/sysv/linux/i386/clone.S: Likewise. + * sysdeps/unix/sysv/linux/ia64/clone2.S: Likewise. + * sysdeps/unix/sysv/linux/mips/clone.S: Likewise. + * sysdeps/unix/sysv/linux/nios2/clone.S: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/clone.S: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/clone.S: Likewise. + * sysdeps/unix/sysv/linux/sh/clone.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/clone.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/clone.S: Likewise. + * sysdeps/unix/sysv/linux/tile/clone.S: Likewise. + * sysdeps/unix/sysv/linux/x86_64/clone.S: Likewise. + * sysdeps/unix/sysv/linux/aarch64/vfork.S: Remove pid set and reset. + * sysdeps/unix/sysv/linux/alpha/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/arm/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/i386/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/ia64/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/m68k/clone.S: Likewise. + * sysdeps/unix/sysv/linux/m68k/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/mips/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/nios2/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/sh/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/tile/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/x86_64/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/hppa/pt-vfork.S: Likewise. + * sysdeps/unix/sysv/linux/tst-clone2.c (f): Remove direct pthread + struct access. + (clone_test): Remove function. + (do_test): Rewrite to take in consideration pid is not cached anymore. + 2016-11-24 Joseph Myers * bits/flt-eval-method.h: New file. diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 3016a2ed5c..98a0ea2862 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -438,9 +438,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, SETUP_THREAD_SYSINFO (pd); #endif - /* The process ID is also the same as that of the caller. */ - pd->pid = THREAD_GETMEM (THREAD_SELF, pid); - /* Don't allow setxid until cloned. */ pd->setxid_futex = -1; @@ -577,9 +574,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* Don't allow setxid until cloned. */ pd->setxid_futex = -1; - /* The process ID is also the same as that of the caller. */ - pd->pid = THREAD_GETMEM (THREAD_SELF, pid); - /* Allocate the DTV for this thread. */ if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL) { @@ -873,9 +867,6 @@ __reclaim_stacks (void) /* This marks the stack as free. */ curp->tid = 0; - /* The PID field must be initialized for the new process. */ - curp->pid = self->pid; - /* Account for the size of the stack. */ stack_cache_actsize += curp->stackblock_size; @@ -901,13 +892,6 @@ __reclaim_stacks (void) } } - /* Reset the PIDs in any cached stacks. */ - list_for_each (runp, &stack_cache) - { - struct pthread *curp = list_entry (runp, struct pthread, list); - curp->pid = self->pid; - } - /* Add the stack of all running threads to the cache. */ list_splice (&stack_used, &stack_cache); @@ -1052,9 +1036,9 @@ setxid_signal_thread (struct xid_command *cmdp, struct pthread *t) return 0; int val; + pid_t pid = __getpid (); INTERNAL_SYSCALL_DECL (err); - val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid), - t->tid, SIGSETXID); + val = INTERNAL_SYSCALL_CALL (tgkill, err, pid, t->tid, SIGSETXID); /* If this failed, it must have had not started yet or else exited. */ if (!INTERNAL_SYSCALL_ERROR_P (val, err)) diff --git a/nptl/descr.h b/nptl/descr.h index 8e4938deb5..bc92abf010 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -167,8 +167,8 @@ struct pthread therefore stack) used' flag. */ pid_t tid; - /* Process ID - thread group ID in kernel speak. */ - pid_t pid; + /* Ununsed. */ + pid_t pid_ununsed; /* List of robust mutexes the thread is holding. */ #ifdef __PTHREAD_MUTEX_HAVE_PREV diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c index bdbdfedcef..48fab50c4e 100644 --- a/nptl/nptl-init.c +++ b/nptl/nptl-init.c @@ -184,18 +184,12 @@ __nptl_set_robust (struct pthread *self) static void sigcancel_handler (int sig, siginfo_t *si, void *ctx) { - /* Determine the process ID. It might be negative if the thread is - in the middle of a fork() call. */ - pid_t pid = THREAD_GETMEM (THREAD_SELF, pid); - if (__glibc_unlikely (pid < 0)) - pid = -pid; - /* Safety check. It would be possible to call this function for other signals and send a signal from another process. This is not correct and might even be a security problem. Try to catch as many incorrect invocations as possible. */ if (sig != SIGCANCEL - || si->si_pid != pid + || si->si_pid != __getpid() || si->si_code != SI_TKILL) return; @@ -243,19 +237,14 @@ struct xid_command *__xidcmd attribute_hidden; static void sighandler_setxid (int sig, siginfo_t *si, void *ctx) { - /* Determine the process ID. It might be negative if the thread is - in the middle of a fork() call. */ - pid_t pid = THREAD_GETMEM (THREAD_SELF, pid); int result; - if (__glibc_unlikely (pid < 0)) - pid = -pid; /* Safety check. It would be possible to call this function for other signals and send a signal from another process. This is not correct and might even be a security problem. Try to catch as many incorrect invocations as possible. */ if (sig != SIGSETXID - || si->si_pid != pid + || si->si_pid != __getpid () || si->si_code != SI_TKILL) return; diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c index 1419baf988..89d02e1741 100644 --- a/nptl/pthread_cancel.c +++ b/nptl/pthread_cancel.c @@ -22,7 +22,7 @@ #include "pthreadP.h" #include #include - +#include int pthread_cancel (pthread_t th) @@ -66,19 +66,11 @@ pthread_cancel (pthread_t th) #ifdef SIGCANCEL /* The cancellation handler will take care of marking the thread as canceled. */ - INTERNAL_SYSCALL_DECL (err); - - /* One comment: The PID field in the TCB can temporarily be - changed (in fork). But this must not affect this code - here. Since this function would have to be called while - the thread is executing fork, it would have to happen in - a signal handler. But this is no allowed, pthread_cancel - is not guaranteed to be async-safe. */ - int val; - val = INTERNAL_SYSCALL (tgkill, err, 3, - THREAD_GETMEM (THREAD_SELF, pid), pd->tid, - SIGCANCEL); + pid_t pid = getpid (); + INTERNAL_SYSCALL_DECL (err); + int val = INTERNAL_SYSCALL_CALL (tgkill, err, pid, pd->tid, + SIGCANCEL); if (INTERNAL_SYSCALL_ERROR_P (val, err)) result = INTERNAL_SYSCALL_ERRNO (val, err); #else diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c index fb906f0484..32d7484bf8 100644 --- a/nptl/pthread_getattr_np.c +++ b/nptl/pthread_getattr_np.c @@ -68,7 +68,6 @@ pthread_getattr_np (pthread_t thread_id, pthread_attr_t *attr) { /* No stack information available. This must be for the initial thread. Get the info in some magical way. */ - assert (abs (thread->pid) == thread->tid); /* Stack size limit. */ struct rlimit rl; diff --git a/nptl_db/structs.def b/nptl_db/structs.def index a9b621b126..1cb6a46391 100644 --- a/nptl_db/structs.def +++ b/nptl_db/structs.def @@ -48,7 +48,6 @@ DB_STRUCT (pthread) DB_STRUCT_FIELD (pthread, list) DB_STRUCT_FIELD (pthread, report_events) DB_STRUCT_FIELD (pthread, tid) -DB_STRUCT_FIELD (pthread, pid) DB_STRUCT_FIELD (pthread, start_routine) DB_STRUCT_FIELD (pthread, cancelhandling) DB_STRUCT_FIELD (pthread, schedpolicy) diff --git a/nptl_db/td_ta_thr_iter.c b/nptl_db/td_ta_thr_iter.c index a990fed150..9e5059956b 100644 --- a/nptl_db/td_ta_thr_iter.c +++ b/nptl_db/td_ta_thr_iter.c @@ -76,48 +76,28 @@ iterate_thread_list (td_thragent_t *ta, td_thr_iter_f *callback, if (ps_pdread (ta->ph, addr, copy, ta->ta_sizeof_pthread) != PS_OK) return TD_ERR; - /* Verify that this thread's pid field matches the child PID. - If its pid field is negative, it's about to do a fork or it - is the sole thread in a fork child. */ - psaddr_t pid; - err = DB_GET_FIELD_LOCAL (pid, ta, copy, pthread, pid, 0); - if (err == TD_OK && (pid_t) (uintptr_t) pid < 0) - { - if (-(pid_t) (uintptr_t) pid == match_pid) - /* It is about to do a fork, but is really still the parent PID. */ - pid = (psaddr_t) (uintptr_t) match_pid; - else - /* It must be a fork child, whose new PID is in the tid field. */ - err = DB_GET_FIELD_LOCAL (pid, ta, copy, pthread, tid, 0); - } + err = DB_GET_FIELD_LOCAL (schedpolicy, ta, copy, pthread, + schedpolicy, 0); if (err != TD_OK) break; + err = DB_GET_FIELD_LOCAL (schedprio, ta, copy, pthread, + schedparam_sched_priority, 0); + if (err != TD_OK) + break; + + /* Now test whether this thread matches the specified conditions. */ - if ((pid_t) (uintptr_t) pid == match_pid) + /* Only if the priority level is as high or higher. */ + int descr_pri = ((uintptr_t) schedpolicy == SCHED_OTHER + ? 0 : (uintptr_t) schedprio); + if (descr_pri >= ti_pri) { - err = DB_GET_FIELD_LOCAL (schedpolicy, ta, copy, pthread, - schedpolicy, 0); - if (err != TD_OK) - break; - err = DB_GET_FIELD_LOCAL (schedprio, ta, copy, pthread, - schedparam_sched_priority, 0); - if (err != TD_OK) - break; - - /* Now test whether this thread matches the specified conditions. */ - - /* Only if the priority level is as high or higher. */ - int descr_pri = ((uintptr_t) schedpolicy == SCHED_OTHER - ? 0 : (uintptr_t) schedprio); - if (descr_pri >= ti_pri) - { - /* Yep, it matches. Call the callback function. */ - td_thrhandle_t th; - th.th_ta_p = (td_thragent_t *) ta; - th.th_unique = addr; - if (callback (&th, cbdata_p) != 0) - return TD_DBERR; - } + /* Yep, it matches. Call the callback function. */ + td_thrhandle_t th; + th.th_ta_p = (td_thragent_t *) ta; + th.th_unique = addr; + if (callback (&th, cbdata_p) != 0) + return TD_DBERR; } /* Get the pointer to the next element. */ diff --git a/nptl_db/td_thr_validate.c b/nptl_db/td_thr_validate.c index f3c8a7bed6..9b89fecad2 100644 --- a/nptl_db/td_thr_validate.c +++ b/nptl_db/td_thr_validate.c @@ -80,28 +80,5 @@ td_thr_validate (const td_thrhandle_t *th) err = TD_OK; } - if (err == TD_OK) - { - /* Verify that this is not a stale element in a fork child. */ - pid_t match_pid = ps_getpid (th->th_ta_p->ph); - psaddr_t pid; - err = DB_GET_FIELD (pid, th->th_ta_p, th->th_unique, pthread, pid, 0); - if (err == TD_OK && (pid_t) (uintptr_t) pid < 0) - { - /* This was a thread that was about to fork, or it is the new sole - thread in a fork child. In the latter case, its tid was stored - via CLONE_CHILD_SETTID and so is already the proper child PID. */ - if (-(pid_t) (uintptr_t) pid == match_pid) - /* It is about to do a fork, but is really still the parent PID. */ - pid = (psaddr_t) (uintptr_t) match_pid; - else - /* It must be a fork child, whose new PID is in the tid field. */ - err = DB_GET_FIELD (pid, th->th_ta_p, th->th_unique, - pthread, tid, 0); - } - if (err == TD_OK && (pid_t) (uintptr_t) pid != match_pid) - err = TD_NOTHR; - } - return err; } diff --git a/sysdeps/aarch64/nptl/tcb-offsets.sym b/sysdeps/aarch64/nptl/tcb-offsets.sym index 0677aeabff..238647dd47 100644 --- a/sysdeps/aarch64/nptl/tcb-offsets.sym +++ b/sysdeps/aarch64/nptl/tcb-offsets.sym @@ -2,6 +2,5 @@ #include PTHREAD_MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) -PTHREAD_PID_OFFSET offsetof (struct pthread, pid) PTHREAD_TID_OFFSET offsetof (struct pthread, tid) PTHREAD_SIZEOF sizeof (struct pthread) diff --git a/sysdeps/alpha/nptl/tcb-offsets.sym b/sysdeps/alpha/nptl/tcb-offsets.sym index c21a791040..1005621b37 100644 --- a/sysdeps/alpha/nptl/tcb-offsets.sym +++ b/sysdeps/alpha/nptl/tcb-offsets.sym @@ -10,5 +10,4 @@ #define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - sizeof(struct pthread)) MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) -PID_OFFSET thread_offsetof (pid) TID_OFFSET thread_offsetof (tid) diff --git a/sysdeps/arm/nptl/tcb-offsets.sym b/sysdeps/arm/nptl/tcb-offsets.sym index 92cc441d3d..bf9c0a1c17 100644 --- a/sysdeps/arm/nptl/tcb-offsets.sym +++ b/sysdeps/arm/nptl/tcb-offsets.sym @@ -7,5 +7,4 @@ #define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - sizeof(struct pthread)) MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) -PID_OFFSET thread_offsetof (pid) TID_OFFSET thread_offsetof (tid) diff --git a/sysdeps/hppa/nptl/tcb-offsets.sym b/sysdeps/hppa/nptl/tcb-offsets.sym index c2f326ee3d..6e852f35b1 100644 --- a/sysdeps/hppa/nptl/tcb-offsets.sym +++ b/sysdeps/hppa/nptl/tcb-offsets.sym @@ -3,7 +3,6 @@ RESULT offsetof (struct pthread, result) TID offsetof (struct pthread, tid) -PID offsetof (struct pthread, pid) CANCELHANDLING offsetof (struct pthread, cancelhandling) CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf) MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) @@ -14,6 +13,5 @@ MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) -- This way we get the offset of a member in the struct pthread that -- preceeds the thread pointer (which points to the dtv). #define thread_offsetof(mem) (unsigned int)(offsetof(struct pthread, mem) - sizeof(struct pthread)) -PID_THREAD_OFFSET thread_offsetof (pid) TID_THREAD_OFFSET thread_offsetof (tid) MULTIPLE_THREADS_THREAD_OFFSET thread_offsetof (header.multiple_threads) diff --git a/sysdeps/i386/nptl/tcb-offsets.sym b/sysdeps/i386/nptl/tcb-offsets.sym index 7bdf161b29..695a810386 100644 --- a/sysdeps/i386/nptl/tcb-offsets.sym +++ b/sysdeps/i386/nptl/tcb-offsets.sym @@ -4,7 +4,6 @@ RESULT offsetof (struct pthread, result) TID offsetof (struct pthread, tid) -PID offsetof (struct pthread, pid) CANCELHANDLING offsetof (struct pthread, cancelhandling) CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf) MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) diff --git a/sysdeps/ia64/nptl/tcb-offsets.sym b/sysdeps/ia64/nptl/tcb-offsets.sym index e1707ab1c8..b01f712be2 100644 --- a/sysdeps/ia64/nptl/tcb-offsets.sym +++ b/sysdeps/ia64/nptl/tcb-offsets.sym @@ -1,7 +1,6 @@ #include #include -PID offsetof (struct pthread, pid) - TLS_PRE_TCB_SIZE TID offsetof (struct pthread, tid) - TLS_PRE_TCB_SIZE MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) - TLS_PRE_TCB_SIZE SYSINFO_OFFSET offsetof (tcbhead_t, __private) diff --git a/sysdeps/m68k/nptl/tcb-offsets.sym b/sysdeps/m68k/nptl/tcb-offsets.sym index b1bba65868..241fb8b47c 100644 --- a/sysdeps/m68k/nptl/tcb-offsets.sym +++ b/sysdeps/m68k/nptl/tcb-offsets.sym @@ -7,5 +7,4 @@ #define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) -PID_OFFSET thread_offsetof (pid) TID_OFFSET thread_offsetof (tid) diff --git a/sysdeps/microblaze/nptl/tcb-offsets.sym b/sysdeps/microblaze/nptl/tcb-offsets.sym index 18afbee291..614f0dfed6 100644 --- a/sysdeps/microblaze/nptl/tcb-offsets.sym +++ b/sysdeps/microblaze/nptl/tcb-offsets.sym @@ -7,5 +7,4 @@ #define thread_offsetof(mem) (long)(offsetof (struct pthread, mem) - sizeof (struct pthread)) MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) -PID_OFFSET thread_offsetof (pid) TID_OFFSET thread_offsetof (tid) diff --git a/sysdeps/mips/nptl/tcb-offsets.sym b/sysdeps/mips/nptl/tcb-offsets.sym index e0e71dc430..9ea25b94a8 100644 --- a/sysdeps/mips/nptl/tcb-offsets.sym +++ b/sysdeps/mips/nptl/tcb-offsets.sym @@ -7,5 +7,4 @@ #define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) -PID_OFFSET thread_offsetof (pid) TID_OFFSET thread_offsetof (tid) diff --git a/sysdeps/nios2/nptl/tcb-offsets.sym b/sysdeps/nios2/nptl/tcb-offsets.sym index d9ae952585..3cd8d984ac 100644 --- a/sysdeps/nios2/nptl/tcb-offsets.sym +++ b/sysdeps/nios2/nptl/tcb-offsets.sym @@ -9,6 +9,5 @@ # define thread_offsetof(mem) ((ptrdiff_t) THREAD_SELF + offsetof (struct pthread, mem)) MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) -PID_OFFSET thread_offsetof (pid) TID_OFFSET thread_offsetof (tid) POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c index ea135f8e18..32ceccef8a 100644 --- a/sysdeps/nptl/fork.c +++ b/sysdeps/nptl/fork.c @@ -135,12 +135,6 @@ __libc_fork (void) pid_t ppid = THREAD_GETMEM (THREAD_SELF, tid); #endif - /* We need to prevent the getpid() code to update the PID field so - that, if a signal arrives in the child very early and the signal - handler uses getpid(), the value returned is correct. */ - pid_t parentpid = THREAD_GETMEM (THREAD_SELF, pid); - THREAD_SETMEM (THREAD_SELF, pid, -parentpid); - #ifdef ARCH_FORK pid = ARCH_FORK (); #else @@ -159,9 +153,6 @@ __libc_fork (void) if (__fork_generation_pointer != NULL) *__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR; - /* Adjust the PID field for the new process. */ - THREAD_SETMEM (self, pid, THREAD_GETMEM (self, tid)); - #if HP_TIMING_AVAIL /* The CPU clock of the thread and process have to be set to zero. */ hp_timing_t now; @@ -233,9 +224,6 @@ __libc_fork (void) { assert (THREAD_GETMEM (THREAD_SELF, tid) == ppid); - /* Restore the PID value. */ - THREAD_SETMEM (THREAD_SELF, pid, parentpid); - /* Release acquired locks in the multi-threaded case. */ if (multiple_threads) { diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym index f580e69555..7c9fd33562 100644 --- a/sysdeps/powerpc/nptl/tcb-offsets.sym +++ b/sysdeps/powerpc/nptl/tcb-offsets.sym @@ -13,7 +13,6 @@ #if TLS_MULTIPLE_THREADS_IN_TCB MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) #endif -PID thread_offsetof (pid) TID thread_offsetof (tid) POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) TAR_SAVE (offsetof (tcbhead_t, tar_save) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) diff --git a/sysdeps/s390/nptl/tcb-offsets.sym b/sysdeps/s390/nptl/tcb-offsets.sym index 9cfae211e0..9c1c01f353 100644 --- a/sysdeps/s390/nptl/tcb-offsets.sym +++ b/sysdeps/s390/nptl/tcb-offsets.sym @@ -3,5 +3,4 @@ MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) STACK_GUARD offsetof (tcbhead_t, stack_guard) -PID offsetof (struct pthread, pid) TID offsetof (struct pthread, tid) diff --git a/sysdeps/sh/nptl/tcb-offsets.sym b/sysdeps/sh/nptl/tcb-offsets.sym index ac63b5b93b..4963e1506f 100644 --- a/sysdeps/sh/nptl/tcb-offsets.sym +++ b/sysdeps/sh/nptl/tcb-offsets.sym @@ -4,7 +4,6 @@ RESULT offsetof (struct pthread, result) TID offsetof (struct pthread, tid) -PID offsetof (struct pthread, pid) CANCELHANDLING offsetof (struct pthread, cancelhandling) CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf) MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) diff --git a/sysdeps/sparc/nptl/tcb-offsets.sym b/sysdeps/sparc/nptl/tcb-offsets.sym index 923af8a5b7..f75d02065e 100644 --- a/sysdeps/sparc/nptl/tcb-offsets.sym +++ b/sysdeps/sparc/nptl/tcb-offsets.sym @@ -3,5 +3,4 @@ MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) POINTER_GUARD offsetof (tcbhead_t, pointer_guard) -PID offsetof (struct pthread, pid) TID offsetof (struct pthread, tid) diff --git a/sysdeps/tile/nptl/tcb-offsets.sym b/sysdeps/tile/nptl/tcb-offsets.sym index 6740bc976f..0147ffafb7 100644 --- a/sysdeps/tile/nptl/tcb-offsets.sym +++ b/sysdeps/tile/nptl/tcb-offsets.sym @@ -9,7 +9,6 @@ #define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) -PID_OFFSET thread_offsetof (pid) TID_OFFSET thread_offsetof (tid) POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) FEEDBACK_DATA_OFFSET (offsetof (tcbhead_t, feedback_data) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) diff --git a/sysdeps/unix/sysv/linux/aarch64/clone.S b/sysdeps/unix/sysv/linux/aarch64/clone.S index 76baa7a698..96482e53c0 100644 --- a/sysdeps/unix/sysv/linux/aarch64/clone.S +++ b/sysdeps/unix/sysv/linux/aarch64/clone.S @@ -72,16 +72,6 @@ thread_start: cfi_undefined (x30) mov x29, 0 - tbnz x11, #CLONE_VM_BIT, 1f - - mov x8, #SYS_ify(getpid) - svc 0x0 - mrs x1, tpidr_el0 - sub x1, x1, #PTHREAD_SIZEOF - str w0, [x1, #PTHREAD_PID_OFFSET] - str w0, [x1, #PTHREAD_TID_OFFSET] -1: - /* Pick the function arg and execute. */ mov x0, x12 blr x10 diff --git a/sysdeps/unix/sysv/linux/aarch64/vfork.S b/sysdeps/unix/sysv/linux/aarch64/vfork.S index 577895eeb2..aeed0b29ce 100644 --- a/sysdeps/unix/sysv/linux/aarch64/vfork.S +++ b/sysdeps/unix/sysv/linux/aarch64/vfork.S @@ -27,27 +27,10 @@ ENTRY (__vfork) - /* Save the TCB-cached PID away in w3, and then negate the TCB - field. But if it's zero, set it to 0x80000000 instead. See - raise.c for the logic that relies on this value. */ - mrs x2, tpidr_el0 - sub x2, x2, #PTHREAD_SIZEOF - ldr w3, [x2, #PTHREAD_PID_OFFSET] - mov w1, #0x80000000 - negs w0, w3 - csel w0, w1, w0, eq - str w0, [x2, #PTHREAD_PID_OFFSET] - mov x0, #0x4111 /* CLONE_VM | CLONE_VFORK | SIGCHLD */ mov x1, sp DO_CALL (clone, 2) - /* Restore the original value of the TCB cache of the PID, if we're - the parent. But in the child (syscall return value equals zero), - leave things as they are. */ - cbz x0, 1f - str w3, [x2, #PTHREAD_PID_OFFSET] -1: cmn x0, #4095 b.cs .Lsyscall_error RET diff --git a/sysdeps/unix/sysv/linux/alpha/clone.S b/sysdeps/unix/sysv/linux/alpha/clone.S index 6a3154f9a7..2757bf20c3 100644 --- a/sysdeps/unix/sysv/linux/alpha/clone.S +++ b/sysdeps/unix/sysv/linux/alpha/clone.S @@ -91,13 +91,6 @@ thread_start: cfi_def_cfa_register(fp) cfi_undefined(ra) - /* Check and see if we need to reset the PID. */ - ldq t0, 16(sp) - lda t1, CLONE_VM - and t0, t1, t2 - beq t2, 2f -1: - /* Load up the arguments. */ ldq pv, 0(sp) ldq a0, 8(sp) @@ -120,15 +113,6 @@ thread_start: halt .align 4 -2: - rduniq - mov v0, s0 - lda v0, __NR_getxpid - callsys -3: - stl v0, PID_OFFSET(s0) - stl v0, TID_OFFSET(s0) - br 1b cfi_endproc .end thread_start diff --git a/sysdeps/unix/sysv/linux/alpha/vfork.S b/sysdeps/unix/sysv/linux/alpha/vfork.S index 9fc199ac41..e5f7ed0661 100644 --- a/sysdeps/unix/sysv/linux/alpha/vfork.S +++ b/sysdeps/unix/sysv/linux/alpha/vfork.S @@ -25,24 +25,9 @@ ENTRY(__libc_vfork) rduniq mov v0, a1 - /* Save the TCB-cached PID away in A2, and then negate the TCB - field. But if it's zero, set it to 0x80000000 instead. See - raise.c for the logic that relies on this value. */ - ldl a2, PID_OFFSET(v0) - ldah t0, -0x8000 - negl a2, t1 - cmovne a2, t1, t0 - stl t0, PID_OFFSET(v0); - lda v0, SYS_ify(vfork) call_pal PAL_callsys - /* Restore the original value of the TCB cache of the PID, if we're - the parent. But in the child (syscall return value equals zero), - leave things as they are. */ - beq v0, 1f - stl a2, PID_OFFSET(a1) -1: /* Normal error check and return. */ bne a3, SYSCALL_ERROR_LABEL ret diff --git a/sysdeps/unix/sysv/linux/arm/clone.S b/sysdeps/unix/sysv/linux/arm/clone.S index 7ff681804b..4c6325d088 100644 --- a/sysdeps/unix/sysv/linux/arm/clone.S +++ b/sysdeps/unix/sysv/linux/arm/clone.S @@ -70,16 +70,6 @@ PSEUDO_END (__clone) 1: .fnstart .cantunwind - tst ip, #CLONE_VM - bne 2f - GET_TLS (lr) - mov r1, r0 - ldr r7, =SYS_ify(getpid) - swi 0x0 - NEGOFF_ADJ_BASE (r1, TID_OFFSET) - str r0, NEGOFF_OFF1 (r1, TID_OFFSET) - str r0, NEGOFF_OFF2 (r1, PID_OFFSET, TID_OFFSET) -2: @ pick the function arg and call address off the stack and execute ldr r0, [sp, #4] ldr ip, [sp], #8 diff --git a/sysdeps/unix/sysv/linux/arm/vfork.S b/sysdeps/unix/sysv/linux/arm/vfork.S index 500f5ca4be..794372ee12 100644 --- a/sysdeps/unix/sysv/linux/arm/vfork.S +++ b/sysdeps/unix/sysv/linux/arm/vfork.S @@ -28,16 +28,6 @@ and the process ID of the new process to the old process. */ ENTRY (__vfork) - /* Save the PID value. */ - GET_TLS (r2) - NEGOFF_ADJ_BASE2 (r2, r0, PID_OFFSET) /* Save the TLS addr in r2. */ - ldr r3, NEGOFF_OFF1 (r2, PID_OFFSET) /* Load the saved PID. */ - rsbs r0, r3, #0 /* Negate it, and test for zero. */ - /* Use 0x80000000 if it was 0. See raise.c for how this is used. */ - it eq - moveq r0, #0x80000000 - str r0, NEGOFF_OFF1 (r2, PID_OFFSET) /* Store the temp PID. */ - /* The DO_CALL macro saves r7 on the stack, to enable generation of ARM unwind info. Since the stack is initially shared between parent and child of vfork, that saved value could be corrupted. @@ -57,11 +47,6 @@ ENTRY (__vfork) mov r7, ip cfi_restore (r7) - /* Restore the old PID value in the parent. */ - cmp r0, #0 /* If we are the parent... */ - it ne - strne r3, NEGOFF_OFF1 (r2, PID_OFFSET) /* restore the saved PID. */ - cmn a1, #4096 it cc RETINSTR(cc, lr) diff --git a/sysdeps/unix/sysv/linux/createthread.c b/sysdeps/unix/sysv/linux/createthread.c index 6d32cece48..ec86f50814 100644 --- a/sysdeps/unix/sysv/linux/createthread.c +++ b/sysdeps/unix/sysv/linux/createthread.c @@ -128,10 +128,10 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr, /* The operation failed. We have to kill the thread. We let the normal cancellation mechanism do the work. */ + pid_t pid = __getpid (); INTERNAL_SYSCALL_DECL (err2); - (void) INTERNAL_SYSCALL (tgkill, err2, 3, - THREAD_GETMEM (THREAD_SELF, pid), - pd->tid, SIGCANCEL); + (void) INTERNAL_SYSCALL_CALL (tgkill, err2, pid, pd->tid, + SIGCANCEL); return INTERNAL_SYSCALL_ERRNO (res, err); } diff --git a/sysdeps/unix/sysv/linux/getpid.c b/sysdeps/unix/sysv/linux/getpid.c deleted file mode 100644 index 1124549326..0000000000 --- a/sysdeps/unix/sysv/linux/getpid.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2003. - - 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 - . */ - -#include -#include -#include - - -#if IS_IN (libc) -static inline __attribute__((always_inline)) pid_t really_getpid (pid_t oldval); - -static inline __attribute__((always_inline)) pid_t -really_getpid (pid_t oldval) -{ - if (__glibc_likely (oldval == 0)) - { - pid_t selftid = THREAD_GETMEM (THREAD_SELF, tid); - if (__glibc_likely (selftid != 0)) - return selftid; - } - - INTERNAL_SYSCALL_DECL (err); - pid_t result = INTERNAL_SYSCALL (getpid, err, 0); - - /* We do not set the PID field in the TID here since we might be - called from a signal handler while the thread executes fork. */ - if (oldval == 0) - THREAD_SETMEM (THREAD_SELF, tid, result); - return result; -} -#endif - -pid_t -__getpid (void) -{ -#if !IS_IN (libc) - INTERNAL_SYSCALL_DECL (err); - pid_t result = INTERNAL_SYSCALL (getpid, err, 0); -#else - pid_t result = THREAD_GETMEM (THREAD_SELF, pid); - if (__glibc_unlikely (result <= 0)) - result = really_getpid (result); -#endif - return result; -} - -libc_hidden_def (__getpid) -weak_alias (__getpid, getpid) -libc_hidden_def (getpid) diff --git a/sysdeps/unix/sysv/linux/hppa/clone.S b/sysdeps/unix/sysv/linux/hppa/clone.S index 3d037f1430..25fcd497f7 100644 --- a/sysdeps/unix/sysv/linux/hppa/clone.S +++ b/sysdeps/unix/sysv/linux/hppa/clone.S @@ -132,18 +132,6 @@ ENTRY(__clone) ldwm -64(%sp), %r4 .LthreadStart: -# define CLONE_VM_BIT 23 /* 0x00000100 */ - /* Load original clone flags. - If CLONE_VM was passed, don't modify PID/TID. - Otherwise store the result of getpid to PID/TID. */ - ldw -56(%sp), %r26 - bb,<,n %r26, CLONE_VM_BIT, 1f - ble 0x100(%sr2, %r0) - ldi __NR_getpid, %r20 - mfctl %cr27, %r26 - stw %ret0, PID_THREAD_OFFSET(%r26) - stw %ret0, TID_THREAD_OFFSET(%r26) -1: /* Load up the arguments. */ ldw -60(%sp), %arg0 ldw -64(%sp), %r22 diff --git a/sysdeps/unix/sysv/linux/hppa/pt-vfork.S b/sysdeps/unix/sysv/linux/hppa/pt-vfork.S index df532362d2..4684048502 100644 --- a/sysdeps/unix/sysv/linux/hppa/pt-vfork.S +++ b/sysdeps/unix/sysv/linux/hppa/pt-vfork.S @@ -25,26 +25,6 @@ replaced by a call to `execve'. Return -1 for errors, 0 to the new process, and the process ID of the new process to the old process. */ -/* Load the thread register. - Load the saved PID value. - Negate the value. - Store the temporary PID. */ -#define SAVE_PID \ - mfctl %cr27, %r26 ASM_LINE_SEP \ - ldw PID_THREAD_OFFSET(%r26),%r1 ASM_LINE_SEP \ - sub %r0,%r1,%r1 ASM_LINE_SEP \ - stw %r1,PID_THREAD_OFFSET(%r26) ASM_LINE_SEP -/* If we are the parent... - Get the thread pointer. - Load the saved PID. - Negate the value (got back original) - Restore the PID. */ -#define RESTORE_PID \ - cmpb,=,n %r0,%ret0,.Lthread_start ASM_LINE_SEP \ - mfctl %cr27, %r26 ASM_LINE_SEP \ - ldw PID_THREAD_OFFSET(%r26),%r1 ASM_LINE_SEP \ - sub %r0,%r1,%r1 ASM_LINE_SEP \ - stw %r1,PID_THREAD_OFFSET(%r26) ASM_LINE_SEP \ .Lthread_start: ASM_LINE_SEP /* r26, r25, r24, r23 are free since vfork has no arguments */ @@ -58,16 +38,10 @@ ENTRY(__vfork) copy %r19, %r25 /* parent */ #endif - /* Save the process PID */ - SAVE_PID - /* Syscall saves and restores all register states */ ble 0x100(%sr2,%r0) ldi __NR_vfork,%r20 - /* Conditionally restore the PID */ - RESTORE_PID - /* Check for error */ ldi -4096,%r1 comclr,>>= %r1,%ret0,%r0 /* Note: unsigned compare. */ diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S index 25f2a9c340..feae504ce6 100644 --- a/sysdeps/unix/sysv/linux/i386/clone.S +++ b/sysdeps/unix/sysv/linux/i386/clone.S @@ -107,9 +107,6 @@ L(thread_start): cfi_undefined (eip); /* Note: %esi is zero. */ movl %esi,%ebp /* terminate the stack frame */ - testl $CLONE_VM, %edi - je L(newpid) -L(haspid): call *%ebx #ifdef PIC call L(here) @@ -121,18 +118,6 @@ L(here): movl $SYS_ify(exit), %eax ENTER_KERNEL - .subsection 2 -L(newpid): - movl $SYS_ify(getpid), %eax - ENTER_KERNEL -L(nomoregetpid): - movl %eax, %gs:PID - movl %eax, %gs:TID - jmp L(haspid) - .previous - cfi_endproc; - - cfi_startproc PSEUDO_END (__clone) libc_hidden_def (__clone) diff --git a/sysdeps/unix/sysv/linux/i386/vfork.S b/sysdeps/unix/sysv/linux/i386/vfork.S index 7a1d3373bb..a865de2201 100644 --- a/sysdeps/unix/sysv/linux/i386/vfork.S +++ b/sysdeps/unix/sysv/linux/i386/vfork.S @@ -34,17 +34,6 @@ ENTRY (__vfork) cfi_adjust_cfa_offset (-4) cfi_register (%eip, %ecx) - /* Save the TCB-cached PID away in %edx, and then negate the TCB - field. But if it's zero, set it to 0x80000000 instead. See - raise.c for the logic that relies on this value. */ - movl %gs:PID, %edx - movl %edx, %eax - negl %eax - jne 1f - movl $0x80000000, %eax -1: movl %eax, %gs:PID - - /* Stuff the syscall number in EAX and enter into the kernel. */ movl $SYS_ify (vfork), %eax int $0x80 @@ -55,14 +44,6 @@ ENTRY (__vfork) pushl %ecx cfi_adjust_cfa_offset (4) - /* Restore the original value of the TCB cache of the PID, if we're - the parent. But in the child (syscall return value equals zero), - leave things as they are. */ - testl %eax, %eax - je 1f - movl %edx, %gs:PID -1: - cmpl $-4095, %eax /* Branch forward if it failed. */ jae SYSCALL_ERROR_LABEL diff --git a/sysdeps/unix/sysv/linux/ia64/clone2.S b/sysdeps/unix/sysv/linux/ia64/clone2.S index b4cfdfc959..e637b6d4a5 100644 --- a/sysdeps/unix/sysv/linux/ia64/clone2.S +++ b/sysdeps/unix/sysv/linux/ia64/clone2.S @@ -67,19 +67,7 @@ ENTRY(__clone2) (CHILD) mov loc0=gp (PARENT) ret ;; - tbit.nz p6,p0=in3,8 /* CLONE_VM */ -(p6) br.cond.dptk 1f - ;; - mov r15=SYS_ify (getpid) -(p7) break __BREAK_SYSCALL - ;; - add r9=PID,r13 - add r10=TID,r13 - ;; - st4 [r9]=r8 - st4 [r10]=r8 - ;; -1: ld8 out1=[in0],8 /* Retrieve code pointer. */ + ld8 out1=[in0],8 /* Retrieve code pointer. */ mov out0=in4 /* Pass proper argument to fn */ ;; ld8 gp=[in0] /* Load function gp. */ diff --git a/sysdeps/unix/sysv/linux/ia64/vfork.S b/sysdeps/unix/sysv/linux/ia64/vfork.S index 9154d7c0fd..84bfdd5d8a 100644 --- a/sysdeps/unix/sysv/linux/ia64/vfork.S +++ b/sysdeps/unix/sysv/linux/ia64/vfork.S @@ -33,32 +33,12 @@ ENTRY (__libc_vfork) .prologue // work around a GAS bug which triggers if .body // first .prologue is not at the beginning of proc. alloc r2=ar.pfs,0,0,2,0 - adds r14=PID,r13 - ;; - ld4 r16=[r14] - ;; - sub r15=0,r16 - cmp.eq p6,p0=0,r16 - ;; -(p6) movl r15=0x80000000 mov out0=CLONE_VM+CLONE_VFORK+SIGCHLD mov out1=0 /* Standard sp value. */ ;; - st4 [r14]=r15 DO_CALL (SYS_ify (clone)) cmp.eq p6,p0=0,r8 - adds r14=PID,r13 (p6) br.cond.dptk 1f - ;; - ld4 r15=[r14] - ;; - extr.u r16=r15,0,31 - ;; - cmp.eq p0,p6=0,r16 - ;; -(p6) sub r16=0,r15 - ;; - st4 [r14]=r16 1: cmp.eq p6,p0=-1,r10 (p6) br.cond.spnt.few __syscall_error diff --git a/sysdeps/unix/sysv/linux/m68k/clone.S b/sysdeps/unix/sysv/linux/m68k/clone.S index 3a828443dc..630a29209d 100644 --- a/sysdeps/unix/sysv/linux/m68k/clone.S +++ b/sysdeps/unix/sysv/linux/m68k/clone.S @@ -98,19 +98,6 @@ ENTRY (__clone) cfi_startproc cfi_undefined (pc) /* Mark end of stack */ subl %fp, %fp /* terminate the stack frame */ - /* Check and see if we need to reset the PID. */ - andl #CLONE_VM, %d1 - jne 1f - movel #SYS_ify (getpid), %d0 - trap #0 - movel %a0, -(%sp) - movel %d0, -(%sp) - bsrl __m68k_read_tp@PLTPC - movel (%sp)+, %d0 - movel %d0, PID_OFFSET(%a0) - movel %d0, TID_OFFSET(%a0) - movel (%sp)+, %a0 -1: jsr (%a0) movel %d0, %d1 movel #SYS_ify (exit), %d0 diff --git a/sysdeps/unix/sysv/linux/m68k/vfork.S b/sysdeps/unix/sysv/linux/m68k/vfork.S index 1625a7b7a0..e27479361b 100644 --- a/sysdeps/unix/sysv/linux/m68k/vfork.S +++ b/sysdeps/unix/sysv/linux/m68k/vfork.S @@ -28,18 +28,6 @@ ENTRY (__vfork) - /* Save the TCB-cached PID away in %d1, and then negate the TCB - field. But if it's zero, set it to 0x80000000 instead. See - raise.c for the logic that relies on this value. */ - jbsr __m68k_read_tp@PLTPC - movel %a0, %a1 - movel PID_OFFSET(%a1), %d0 - movel %d0, %d1 - negl %d0 - jne 1f - movel #0x80000000, %d0 -1: movel %d0, PID_OFFSET(%a1) - /* Pop the return PC value into A0. */ movel %sp@+, %a0 cfi_adjust_cfa_offset (-4) @@ -49,14 +37,6 @@ ENTRY (__vfork) movel #SYS_ify (vfork), %d0 trap #0 - /* Restore the original value of the TCB cache of the PID, if we're - the parent. But in the child (syscall return value equals zero), - leave things as they are. */ - tstl %d0 - jeq 1f - movel %d1, PID_OFFSET(%a1) -1: - tstl %d0 jmi .Lerror /* Branch forward if it failed. */ diff --git a/sysdeps/unix/sysv/linux/mips/clone.S b/sysdeps/unix/sysv/linux/mips/clone.S index 39634c5cf0..7ae65ef723 100644 --- a/sysdeps/unix/sysv/linux/mips/clone.S +++ b/sysdeps/unix/sysv/linux/mips/clone.S @@ -130,11 +130,6 @@ L(thread_start): SAVE_GP (GPOFF) /* The stackframe has been created on entry of clone(). */ - /* Check and see if we need to reset the PID. */ - and a1,a0,CLONE_VM - beqz a1,L(restore_pid) -L(donepid): - /* Restore the arg for user's function. */ PTR_L t9,0(sp) /* Function pointer. */ PTR_L a0,PTRSIZE(sp) /* Argument pointer. */ @@ -151,14 +146,6 @@ L(donepid): jal _exit #endif -L(restore_pid): - li v0,__NR_getpid - syscall - READ_THREAD_POINTER(v1) - INT_S v0,PID_OFFSET(v1) - INT_S v0,TID_OFFSET(v1) - b L(donepid) - END(__thread_start) libc_hidden_def (__clone) diff --git a/sysdeps/unix/sysv/linux/mips/vfork.S b/sysdeps/unix/sysv/linux/mips/vfork.S index 1867c8626e..0b9244b7f8 100644 --- a/sysdeps/unix/sysv/linux/mips/vfork.S +++ b/sysdeps/unix/sysv/linux/mips/vfork.S @@ -60,14 +60,6 @@ NESTED(__libc_vfork,FRAMESZ,sp) PTR_ADDU sp, FRAMESZ cfi_adjust_cfa_offset (-FRAMESZ) - /* Save the PID value. */ - READ_THREAD_POINTER(v1) /* Get the thread pointer. */ - lw a2, PID_OFFSET(v1) /* Load the saved PID. */ - subu a2, $0, a2 /* Negate it. */ - bnez a2, 1f /* If it was zero... */ - lui a2, 0x8000 /* use 0x80000000 instead. */ -1: sw a2, PID_OFFSET(v1) /* Store the temporary PID. */ - li a0, 0x4112 /* CLONE_VM | CLONE_VFORK | SIGCHLD */ move a1, sp @@ -75,17 +67,6 @@ NESTED(__libc_vfork,FRAMESZ,sp) li v0,__NR_clone syscall - /* Restore the old PID value in the parent. */ - beqz v0, 1f /* If we are the parent... */ - READ_THREAD_POINTER(v1) /* Get the thread pointer. */ - lw a2, PID_OFFSET(v1) /* Load the saved PID. */ - subu a2, $0, a2 /* Re-negate it. */ - lui a0, 0x8000 /* Load 0x80000000... */ - bne a2, a0, 2f /* ... compare against it... */ - li a2, 0 /* ... use 0 instead. */ -2: sw a2, PID_OFFSET(v1) /* Restore the PID. */ -1: - cfi_remember_state bnez a3,L(error) diff --git a/sysdeps/unix/sysv/linux/nios2/clone.S b/sysdeps/unix/sysv/linux/nios2/clone.S index 30b6e4a6c8..c9fa00f94c 100644 --- a/sysdeps/unix/sysv/linux/nios2/clone.S +++ b/sysdeps/unix/sysv/linux/nios2/clone.S @@ -68,14 +68,6 @@ thread_start: cfi_startproc cfi_undefined (ra) - /* We expect the argument registers to be preserved across system - calls and across task cloning, so flags should be in r4 here. */ - andi r2, r4, CLONE_VM - bne r2, zero, 2f - DO_CALL (getpid, 0) - stw r2, PID_OFFSET(r23) - stw r2, TID_OFFSET(r23) -2: ldw r5, 4(sp) /* Function pointer. */ ldw r4, 0(sp) /* Argument pointer. */ addi sp, sp, 8 diff --git a/sysdeps/unix/sysv/linux/nios2/vfork.S b/sysdeps/unix/sysv/linux/nios2/vfork.S index c1bb9c7134..8997269199 100644 --- a/sysdeps/unix/sysv/linux/nios2/vfork.S +++ b/sysdeps/unix/sysv/linux/nios2/vfork.S @@ -21,20 +21,10 @@ ENTRY(__vfork) - ldw r6, PID_OFFSET(r23) - sub r7, zero, r6 - bne r7, zero, 2f - movhi r7, %hi(0x80000000) -2: - stw r7, PID_OFFSET(r23) - movi r4, 0x4111 /* (CLONE_VM | CLONE_VFORK | SIGCHLD) */ mov r5, zero DO_CALL (clone, 2) - beq r2, zero, 1f - stw r6, PID_OFFSET(r23) -1: bne r7, zero, SYSCALL_ERROR_LABEL ret diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S index bebadbfbb9..49fe01ecde 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S @@ -76,15 +76,6 @@ ENTRY (__clone) crandc cr1*4+eq,cr1*4+eq,cr0*4+so bne- cr1,L(parent) /* The '-' is to minimise the race. */ - /* If CLONE_VM is set do not update the pid/tid field. */ - andi. r0,r28,CLONE_VM - bne+ cr0,L(oldpid) - - DO_CALL(SYS_ify(getpid)) - stw r3,TID(r2) - stw r3,PID(r2) -L(oldpid): - /* Call procedure. */ mtctr r30 mr r3,r31 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S index edbc7de1e6..0a724953a4 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S @@ -27,34 +27,8 @@ ENTRY (__vfork) - /* Load the TCB-cached PID value and negates it. If It it is zero - sets it to 0x800000. And then sets its value again on TCB field. - See raise.c for the logic that relies on this value. */ - - lwz r0,PID(r2) - cmpwi cr0,r0,0 - neg r0,r0 - bne- cr0,1f - lis r0,0x8000 -1: stw r0,PID(r2) - DO_CALL (SYS_ify (vfork)) - cmpwi cr1,r3,0 - beqlr- 1 - - /* Restore the original value of the TCB cache of the PID, if we're - the parent. But in the child (syscall return value equals zero), - leave things as they are. */ - lwz r0,PID(r2) - /* Cannot use clrlwi. here, because cr0 needs to be preserved - until PSEUDO_RET. */ - clrlwi r4,r0,1 - cmpwi cr1,r4,0 - beq- cr1,1f - neg r4,r0 -1: stw r4,PID(r2) - PSEUDO_RET PSEUDO_END (__vfork) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S index df824f5a69..2a66fef520 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S @@ -78,15 +78,6 @@ ENTRY (__clone) crandc cr1*4+eq,cr1*4+eq,cr0*4+so bne- cr1,L(parent) /* The '-' is to minimise the race. */ - /* If CLONE_VM is set do not update the pid/tid field. */ - rldicl. r0,r29,56,63 /* flags & CLONE_VM. */ - bne+ cr0,L(oldpid) - - DO_CALL(SYS_ify(getpid)) - stw r3,TID(r13) - stw r3,PID(r13) -L(oldpid): - std r2,FRAME_TOC_SAVE(r1) /* Call procedure. */ PPC64_LOAD_FUNCPTR r30 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S index 3083ab7b3c..6b4cf432c1 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S @@ -28,31 +28,8 @@ ENTRY (__vfork) CALL_MCOUNT 0 - /* Load the TCB-cached PID value and negates it. If It it is zero - sets it to 0x800000. And then sets its value again on TCB field. - See raise.c for the logic that relies on this value. */ - lwz r0,PID(r13) - cmpwi cr0,r0,0 - neg r0,r0 - bne- cr0,1f - lis r0,0x8000 -1: stw r0,PID(r13) - DO_CALL (SYS_ify (vfork)) - cmpwi cr1,r3,0 - beqlr- 1 - - /* Restore the original value of the TCB cache of the PID, if we're - the parent. But in the child (syscall return value equals zero), - leave things as they are. */ - lwz r0,PID(r13) - clrlwi r4,r0,1 - cmpwi cr1,r4,0 - beq- cr1,1f - neg r4,r0 -1: stw r4,PID(r13) - PSEUDO_RET PSEUDO_END (__vfork) diff --git a/sysdeps/unix/sysv/linux/pthread-pids.h b/sysdeps/unix/sysv/linux/pthread-pids.h index d42bba03cf..618a5b1b9f 100644 --- a/sysdeps/unix/sysv/linux/pthread-pids.h +++ b/sysdeps/unix/sysv/linux/pthread-pids.h @@ -26,5 +26,5 @@ static inline void __pthread_initialize_pids (struct pthread *pd) { INTERNAL_SYSCALL_DECL (err); - pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid); + pd->tid = INTERNAL_SYSCALL_CALL (set_tid_address, err, &pd->tid); } diff --git a/sysdeps/unix/sysv/linux/pthread_kill.c b/sysdeps/unix/sysv/linux/pthread_kill.c index bcb3009675..cc109973cc 100644 --- a/sysdeps/unix/sysv/linux/pthread_kill.c +++ b/sysdeps/unix/sysv/linux/pthread_kill.c @@ -21,6 +21,7 @@ #include #include #include +#include int @@ -49,15 +50,9 @@ __pthread_kill (pthread_t threadid, int signo) /* We have a special syscall to do the work. */ INTERNAL_SYSCALL_DECL (err); - /* One comment: The PID field in the TCB can temporarily be changed - (in fork). But this must not affect this code here. Since this - function would have to be called while the thread is executing - fork, it would have to happen in a signal handler. But this is - no allowed, pthread_kill is not guaranteed to be async-safe. */ - int val; - val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid), - tid, signo); + pid_t pid = __getpid (); + int val = INTERNAL_SYSCALL_CALL (tgkill, err, pid, tid, signo); return (INTERNAL_SYSCALL_ERROR_P (val, err) ? INTERNAL_SYSCALL_ERRNO (val, err) : 0); } diff --git a/sysdeps/unix/sysv/linux/pthread_sigqueue.c b/sysdeps/unix/sysv/linux/pthread_sigqueue.c index 7694d5467c..e393e0bd73 100644 --- a/sysdeps/unix/sysv/linux/pthread_sigqueue.c +++ b/sysdeps/unix/sysv/linux/pthread_sigqueue.c @@ -49,27 +49,22 @@ pthread_sigqueue (pthread_t threadid, int signo, const union sigval value) if (signo == SIGCANCEL || signo == SIGTIMER || signo == SIGSETXID) return EINVAL; + pid_t pid = getpid (); + /* Set up the siginfo_t structure. */ siginfo_t info; memset (&info, '\0', sizeof (siginfo_t)); info.si_signo = signo; info.si_code = SI_QUEUE; - info.si_pid = THREAD_GETMEM (THREAD_SELF, pid); + info.si_pid = pid; info.si_uid = getuid (); info.si_value = value; /* We have a special syscall to do the work. */ INTERNAL_SYSCALL_DECL (err); - /* One comment: The PID field in the TCB can temporarily be changed - (in fork). But this must not affect this code here. Since this - function would have to be called while the thread is executing - fork, it would have to happen in a signal handler. But this is - no allowed, pthread_sigqueue is not guaranteed to be async-safe. */ - int val = INTERNAL_SYSCALL (rt_tgsigqueueinfo, err, 4, - THREAD_GETMEM (THREAD_SELF, pid), - tid, signo, &info); - + int val = INTERNAL_SYSCALL_CALL (rt_tgsigqueueinfo, err, pid, tid, signo, + &info); return (INTERNAL_SYSCALL_ERROR_P (val, err) ? INTERNAL_SYSCALL_ERRNO (val, err) : 0); #else diff --git a/sysdeps/unix/sysv/linux/raise.c b/sysdeps/unix/sysv/linux/raise.c index 470033e83d..49bb7cb0d4 100644 --- a/sysdeps/unix/sysv/linux/raise.c +++ b/sysdeps/unix/sysv/linux/raise.c @@ -26,13 +26,6 @@ int raise (int sig) { - /* raise is an async-safe function so it could be called while the - fork/vfork function temporarily invalidated the PID field. To avoid - relying on cached value we block all user-defined signal handler - (which might call fork/vfork) and issue the getpid and gettid - syscalls directly. */ - - /* rt_sigprocmask may fail if: 1. sigsetsize != sizeof (sigset_t) (EINVAL) diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/clone.S b/sysdeps/unix/sysv/linux/s390/s390-32/clone.S index 2f8fa0b840..b1de1480d1 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/clone.S +++ b/sysdeps/unix/sysv/linux/s390/s390-32/clone.S @@ -54,13 +54,6 @@ error: PSEUDO_END (__clone) thread_start: - tml %r3,256 /* CLONE_VM == 0x00000100 */ - jne 1f - svc SYS_ify(getpid) - ear %r3,%a0 - st %r2,PID(%r3) - st %r2,TID(%r3) -1: /* fn is in gpr 1, arg in gpr 0 */ lr %r2,%r0 /* set first parameter to void *arg */ ahi %r15,-96 /* make room on the stack for the save area */ diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S b/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S index b7588ebd7c..cc60e139ba 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S +++ b/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S @@ -28,21 +28,9 @@ and the process ID of the new process to the old process. */ ENTRY (__libc_vfork) - ear %r4,%a0 - lhi %r1,1 - icm %r3,15,PID(%r4) - sll %r1,31 - je 1f - lcr %r1,%r3 -1: st %r1,PID(%r4) - /* Do vfork system call. */ svc SYS_ify (vfork) - ltr %r2,%r2 - je 1f - st %r3,PID(%r4) -1: /* Check for error. */ lhi %r4,-4095 clr %r2,%r4 diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/clone.S b/sysdeps/unix/sysv/linux/s390/s390-64/clone.S index fb816922ca..29606acf03 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/clone.S +++ b/sysdeps/unix/sysv/linux/s390/s390-64/clone.S @@ -55,15 +55,6 @@ error: PSEUDO_END (__clone) thread_start: - tmll %r3,256 /* CLONE_VM == 0x00000100 */ - jne 1f - svc SYS_ify(getpid) - ear %r3,%a0 - sllg %r3,%r3,32 - ear %r3,%a1 - st %r2,PID(%r3) - st %r2,TID(%r3) -1: /* fn is in gpr 1, arg in gpr 0 */ lgr %r2,%r0 /* set first parameter to void *arg */ aghi %r15,-160 /* make room on the stack for the save area */ diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S b/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S index 0bd2161381..b9a813f2cc 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S +++ b/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S @@ -28,22 +28,9 @@ and the process ID of the new process to the old process. */ ENTRY (__libc_vfork) - ear %r4,%a0 - sllg %r4,%r4,32 - ear %r4,%a1 - icm %r3,15,PID(%r4) - llilh %r1,32768 - je 1f - lcr %r1,%r3 -1: st %r1,PID(%r4) - /* Do vfork system call. */ svc SYS_ify (vfork) - ltgr %r2,%r2 - je 1f - st %r3,PID(%r4) -1: /* Check for error. */ lghi %r4,-4095 clgr %r2,%r4 diff --git a/sysdeps/unix/sysv/linux/sh/clone.S b/sysdeps/unix/sysv/linux/sh/clone.S index 4cd7df117c..ce7cddcb19 100644 --- a/sysdeps/unix/sysv/linux/sh/clone.S +++ b/sysdeps/unix/sysv/linux/sh/clone.S @@ -66,23 +66,7 @@ ENTRY(__clone) 2: /* terminate the stack frame */ mov #0, r14 - mov r4, r0 - shlr8 r0 - tst #1, r0 // CLONE_VM = (1 << 8) - bf/s 4f - mov r4, r0 - /* new pid */ - mov #+SYS_ify(getpid), r3 - trapa #0x15 -3: - stc gbr, r1 - mov.w .Lpidoff, r2 - add r1, r2 - mov.l r0, @r2 - mov.w .Ltidoff, r2 - add r1, r2 - mov.l r0, @r2 -4: + /* thread starts */ mov.l @r15, r1 jsr @r1 @@ -113,10 +97,6 @@ ENTRY(__clone) .long _GLOBAL_OFFSET_TABLE_ .L3: .long PLTJMP(C_SYMBOL_NAME(_exit)) -.Lpidoff: - .word PID - TLS_PRE_TCB_SIZE -.Ltidoff: - .word TID - TLS_PRE_TCB_SIZE PSEUDO_END (__clone) libc_hidden_def (__clone) diff --git a/sysdeps/unix/sysv/linux/sh/vfork.S b/sysdeps/unix/sysv/linux/sh/vfork.S index 6895bc5491..df559cb439 100644 --- a/sysdeps/unix/sysv/linux/sh/vfork.S +++ b/sysdeps/unix/sysv/linux/sh/vfork.S @@ -26,30 +26,11 @@ and the process ID of the new process to the old process. */ ENTRY (__libc_vfork) - /* Save the PID value. */ - stc gbr, r2 - mov.w .L2, r0 - mov.l @(r0,r2), r4 - neg r4, r1 - tst r1, r1 - bf 1f - mov #1, r1 - rotr r1 -1: - mov.l r1, @(r0,r2) mov.w .L1, r3 trapa #0x10 mov r0, r1 - /* Restore the old PID value in the parent. */ - tst r0, r0 - bt.s 2f - stc gbr, r2 - mov.w .L2, r0 - mov.l r4, @(r0,r2) - mov r1, r0 -2: mov #-12, r2 shad r2, r1 not r1, r1 // r1=0 means r0 = -1 to -4095 @@ -61,8 +42,6 @@ ENTRY (__libc_vfork) nop .L1: .word __NR_vfork -.L2: - .word PID - TLS_PRE_TCB_SIZE .align 2 PSEUDO_END (__libc_vfork) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S index d6c92f6133..0456a0d16e 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S @@ -79,13 +79,6 @@ END(__clone) .type __thread_start,@function __thread_start: - andcc %g4, CLONE_VM, %g0 - bne 1f - set __NR_getpid,%g1 - ta 0x10 - st %o0,[%g7 + PID] - st %o0,[%g7 + TID] -1: mov %g0, %fp /* terminate backtrace */ call %g2 mov %g3,%o0 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S b/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S index 0d0a3b5298..6d985034f0 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S @@ -22,24 +22,14 @@ .text .globl __syscall_error ENTRY(__libc_vfork) - ld [%g7 + PID], %o5 - cmp %o5, 0 - bne 1f - sub %g0, %o5, %o4 - sethi %hi(0x80000000), %o4 -1: st %o4, [%g7 + PID] - LOADSYSCALL(vfork) ta 0x10 bcc 2f mov %o7, %g1 - st %o5, [%g7 + PID] call __syscall_error mov %g1, %o7 2: sub %o1, 1, %o1 andcc %o0, %o1, %o0 - bne,a 1f - st %o5, [%g7 + PID] 1: retl nop END(__libc_vfork) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S index b0f62660a7..6ffead88e2 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S @@ -76,13 +76,6 @@ END(__clone) .type __thread_start,@function __thread_start: - andcc %g4, CLONE_VM, %g0 - bne,pt %icc, 1f - set __NR_getpid,%g1 - ta 0x6d - st %o0,[%g7 + PID] - st %o0,[%g7 + TID] -1: mov %g0, %fp /* terminate backtrace */ call %g2 mov %g3,%o0 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S b/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S index 0818eba02e..298dd197a9 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S @@ -22,24 +22,14 @@ .text .globl __syscall_error ENTRY(__libc_vfork) - ld [%g7 + PID], %o5 - sethi %hi(0x80000000), %o3 - cmp %o5, 0 - sub %g0, %o5, %o4 - move %icc, %o3, %o4 - st %o4, [%g7 + PID] - LOADSYSCALL(vfork) ta 0x6d bcc,pt %xcc, 2f mov %o7, %g1 - st %o5, [%g7 + PID] call __syscall_error mov %g1, %o7 2: sub %o1, 1, %o1 andcc %o0, %o1, %o0 - bne,a,pt %icc, 1f - st %o5, [%g7 + PID] 1: retl nop END(__libc_vfork) diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 68af897e39..98b3bb94c2 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -18,6 +18,7 @@ execve - execve i:spp __execve execve fdatasync - fdatasync Ci:i fdatasync flock - flock i:ii __flock flock get_kernel_syms EXTRA get_kernel_syms i:p __compat_get_kernel_syms get_kernel_syms@GLIBC_2.0:GLIBC_2.23 +getpid - getpid Ei: __getpid getpid getegid - getegid Ei: __getegid getegid geteuid - geteuid Ei: __geteuid geteuid getpgid - getpgid i:i __getpgid getpgid diff --git a/sysdeps/unix/sysv/linux/tile/clone.S b/sysdeps/unix/sysv/linux/tile/clone.S index d1d36462e7..3f9e3d56c4 100644 --- a/sysdeps/unix/sysv/linux/tile/clone.S +++ b/sysdeps/unix/sysv/linux/tile/clone.S @@ -163,22 +163,6 @@ ENTRY (__clone) .Lthread_start: cfi_def_cfa_offset (FRAME_SIZE) cfi_undefined (lr) - /* Check and see if we need to reset the PID, which we do if - CLONE_VM isn't set, i.e. it's a fork-like clone with a new - address space. In that case we update the cached values - from the true system pid (retrieved via __NR_getpid syscall). */ - moveli r0, CLONE_VM - and r0, r30, r0 - BNEZ r0, .Lno_reset_pid /* CLONE_VM is set */ - moveli TREG_SYSCALL_NR_NAME, __NR_getpid - swint1 - ADDLI_PTR r2, tp, PID_OFFSET - { - ST4 r2, r0 - ADDLI_PTR r2, tp, TID_OFFSET - } - ST4 r2, r0 -.Lno_reset_pid: { /* Invoke user function with specified argument. */ move r0, r31 diff --git a/sysdeps/unix/sysv/linux/tile/vfork.S b/sysdeps/unix/sysv/linux/tile/vfork.S index d8c5ce3e24..2272777187 100644 --- a/sysdeps/unix/sysv/linux/tile/vfork.S +++ b/sysdeps/unix/sysv/linux/tile/vfork.S @@ -29,18 +29,6 @@ .text ENTRY (__vfork) - { - addli r11, tp, PID_OFFSET /* Point at PID. */ - movei r13, 1 - } - { - LD4U r12, r11 /* Load the saved PID. */ - shli r13, r13, 31 /* Build 0x80000000. */ - } - sub r12, zero, r12 /* Negate it. */ - CMOVEQZ r12, r12, r13 /* Replace zero pids. */ - ST4 r11, r12 /* Store the temporary PID. */ - { moveli r0, CLONE_VFORK | CLONE_VM | SIGCHLD move r1, zero @@ -52,22 +40,6 @@ ENTRY (__vfork) moveli TREG_SYSCALL_NR_NAME, __NR_clone swint1 - BEQZ r0, 1f /* If we are the parent... */ - { - addli r11, tp, PID_OFFSET /* Point at PID. */ - movei r13, 1 - } - { - LD4U r12, r11 /* Load the saved PID. */ - shli r13, r13, 31 /* Build 0x80000000. */ - } - { - CMPEQ r13, r12, r12 /* Test for that value. */ - sub r12, zero, r12 /* Re-negate it. */ - } - CMOVNEZ r12, r13, zero /* Replace zero pids. */ - ST4 r11, r12 /* Restore the PID. */ -1: BNEZ r1, 0f jrp lr PSEUDO_END (__vfork) diff --git a/sysdeps/unix/sysv/linux/tst-clone2.c b/sysdeps/unix/sysv/linux/tst-clone2.c index 68a7e6d6e2..0da9e54ba2 100644 --- a/sysdeps/unix/sysv/linux/tst-clone2.c +++ b/sysdeps/unix/sysv/linux/tst-clone2.c @@ -28,8 +28,14 @@ #include #include #include +#include -#include /* for THREAD_* macros. */ +#include /* For _STACK_GROWS_{UP,DOWN}. */ + +static int do_test (void); + +#define TEST_FUNCTION do_test () +#include static int sig; static int pipefd[2]; @@ -39,39 +45,35 @@ f (void *a) { close (pipefd[0]); - pid_t pid = THREAD_GETMEM (THREAD_SELF, pid); - pid_t tid = THREAD_GETMEM (THREAD_SELF, tid); + pid_t ppid = getppid (); + pid_t pid = getpid (); + pid_t tid = syscall (__NR_gettid); - while (write (pipefd[1], &pid, sizeof pid) < 0) - continue; - while (write (pipefd[1], &tid, sizeof tid) < 0) - continue; + if (write (pipefd[1], &ppid, sizeof ppid) != sizeof (ppid)) + FAIL_EXIT1 ("write ppid failed\n"); + if (write (pipefd[1], &pid, sizeof pid) != sizeof (pid)) + FAIL_EXIT1 ("write pid failed\n"); + if (write (pipefd[1], &tid, sizeof tid) != sizeof (tid)) + FAIL_EXIT1 ("write tid failed\n"); return 0; } static int -clone_test (int clone_flags) +do_test (void) { sig = SIGRTMIN; sigset_t ss; sigemptyset (&ss); sigaddset (&ss, sig); if (sigprocmask (SIG_BLOCK, &ss, NULL) != 0) - { - printf ("sigprocmask failed: %m\n"); - return 1; - } + FAIL_EXIT1 ("sigprocmask failed: %m"); if (pipe2 (pipefd, O_CLOEXEC)) - { - printf ("sigprocmask failed: %m\n"); - return 1; - } - - pid_t ppid = getpid (); + FAIL_EXIT1 ("pipe failed: %m"); + int clone_flags = 0; #ifdef __ia64__ extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base, size_t __child_stack_size, int __flags, @@ -88,61 +90,47 @@ clone_test (int clone_flags) #error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" #endif #endif + close (pipefd[1]); if (p == -1) + FAIL_EXIT1("clone failed: %m"); + + pid_t ppid, pid, tid; + if (read (pipefd[0], &ppid, sizeof pid) != sizeof pid) { - printf ("clone failed: %m\n"); - return 1; + kill (p, SIGKILL); + FAIL_EXIT1 ("read ppid failed: %m"); } - - pid_t pid, tid; if (read (pipefd[0], &pid, sizeof pid) != sizeof pid) { - printf ("read pid failed: %m\n"); kill (p, SIGKILL); - return 1; + FAIL_EXIT1 ("read pid failed: %m"); } if (read (pipefd[0], &tid, sizeof tid) != sizeof tid) { - printf ("read pid failed: %m\n"); kill (p, SIGKILL); - return 1; + FAIL_EXIT1 ("read tid failed: %m"); } close (pipefd[0]); int ret = 0; - /* For CLONE_VM glibc clone implementation does not change the pthread - pid/tid field. */ - if ((clone_flags & CLONE_VM) == CLONE_VM) - { - if ((ppid != pid) || (ppid != tid)) - { - printf ("parent pid (%i) != received pid/tid (%i/%i)\n", - (int)ppid, (int)pid, (int)tid); - ret = 1; - } - } - /* For any other flag clone updates the new pthread pid and tid with - the clone return value. */ - else - { - if ((p != pid) || (p != tid)) - { - printf ("child pid (%i) != received pid/tid (%i/%i)\n", - (int)p, (int)pid, (int)tid); - ret = 1; - } - } + pid_t own_pid = getpid (); + pid_t own_tid = syscall (__NR_gettid); + + /* Some sanity checks for clone syscall: returned ppid should be current + pid and both returned tid/pid should be different from current one. */ + if ((ppid != own_pid) || (pid == own_pid) || (tid == own_tid)) + FAIL_RET ("ppid=%i pid=%i tid=%i | own_pid=%i own_tid=%i", + (int)ppid, (int)pid, (int)tid, (int)own_pid, (int)own_tid); int e; if (waitpid (p, &e, __WCLONE) != p) { - puts ("waitpid failed"); kill (p, SIGKILL); - return 1; + FAIL_EXIT1 ("waitpid failed"); } if (!WIFEXITED (e)) { @@ -150,29 +138,10 @@ clone_test (int clone_flags) printf ("died from signal %s\n", strsignal (WTERMSIG (e))); else puts ("did not terminate correctly"); - return 1; + exit (EXIT_FAILURE); } if (WEXITSTATUS (e) != 0) - { - printf ("exit code %d\n", WEXITSTATUS (e)); - return 1; - } + FAIL_EXIT1 ("exit code %d", WEXITSTATUS (e)); return ret; } - -int -do_test (void) -{ - /* First, check that the clone implementation, without any flag, updates - the struct pthread to contain the new PID and TID. */ - int ret = clone_test (0); - /* Second, check that with CLONE_VM the struct pthread PID and TID fields - remain unmodified after the clone. Any modifications would cause problem - for the parent as described in bug 19957. */ - ret += clone_test (CLONE_VM); - return ret; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S index 66f4b11490..5629aed395 100644 --- a/sysdeps/unix/sysv/linux/x86_64/clone.S +++ b/sysdeps/unix/sysv/linux/x86_64/clone.S @@ -91,14 +91,6 @@ L(thread_start): the outermost frame obviously. */ xorl %ebp, %ebp - andq $CLONE_VM, %rdi - jne 1f - movl $SYS_ify(getpid), %eax - syscall - movl %eax, %fs:PID - movl %eax, %fs:TID -1: - /* Set up arguments for the function call. */ popq %rax /* Function to call. */ popq %rdi /* Argument. */ diff --git a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S index 8332ade9fb..cdd2dea32a 100644 --- a/sysdeps/unix/sysv/linux/x86_64/vfork.S +++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S @@ -34,16 +34,6 @@ ENTRY (__vfork) cfi_adjust_cfa_offset(-8) cfi_register(%rip, %rdi) - /* Save the TCB-cached PID away in %esi, and then negate the TCB - field. But if it's zero, set it to 0x80000000 instead. See - raise.c for the logic that relies on this value. */ - movl %fs:PID, %esi - movl $0x80000000, %ecx - movl %esi, %edx - negl %edx - cmove %ecx, %edx - movl %edx, %fs:PID - /* Stuff the syscall number in RAX and enter into the kernel. */ movl $SYS_ify (vfork), %eax syscall @@ -52,14 +42,6 @@ ENTRY (__vfork) pushq %rdi cfi_adjust_cfa_offset(8) - /* Restore the original value of the TCB cache of the PID, if we're - the parent. But in the child (syscall return value equals zero), - leave things as they are. */ - testq %rax, %rax - je 1f - movl %esi, %fs:PID -1: - cmpl $-4095, %eax jae SYSCALL_ERROR_LABEL /* Branch forward if it failed. */ diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym index aeb752673a..8a25c482cb 100644 --- a/sysdeps/x86_64/nptl/tcb-offsets.sym +++ b/sysdeps/x86_64/nptl/tcb-offsets.sym @@ -4,7 +4,6 @@ RESULT offsetof (struct pthread, result) TID offsetof (struct pthread, tid) -PID offsetof (struct pthread, pid) CANCELHANDLING offsetof (struct pthread, cancelhandling) CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf) CLEANUP offsetof (struct pthread, cleanup) -- cgit v1.2.3 From 8b9283dabd5ab3524c9a76fabbb379f950a86e6d Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Tue, 13 Dec 2016 16:50:06 -0200 Subject: Consolidate renameat Linux implementation This patch consolidates the Linux renameat implementation on sysdeps/unix/sysv/linux/renameat.c. The renameat syscall was deprecated at b0da6d44 for newer architectures, so using the auto-generation list may generate wrappers that returns ENOSYS. Current code try to use __NR_renameat and if it is not define it uses __NR_renameat2. Checked on x86_64 and aarch64. * sysdeps/unix/sysv/linux/renameat.c: New file. * sysdeps/unix/sysv/linux/syscalls.list: Remove renameat. --- ChangeLog | 3 +++ sysdeps/unix/sysv/linux/renameat.c | 32 ++++++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/syscalls.list | 1 - 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/renameat.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index a9e69a3364..f40e09fcb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-12-14 Adhemerval Zanella + * sysdeps/unix/sysv/linux/renameat.c: New file. + * sysdeps/unix/sysv/linux/syscalls.list: Remove renameat. + * sysdeps/unix/sysv/linux/rename.c: New file. * sysdeps/unix/sysv/linux/generic/rename.c: Remove file. diff --git a/sysdeps/unix/sysv/linux/renameat.c b/sysdeps/unix/sysv/linux/renameat.c new file mode 100644 index 0000000000..ac52947995 --- /dev/null +++ b/sysdeps/unix/sysv/linux/renameat.c @@ -0,0 +1,32 @@ +/* Linux implementation for renameat function. + Copyright (C) 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 + . */ + +#include +#include +#include +#include + +int +renameat (int oldfd, const char *old, int newfd, const char *new) +{ +#ifdef __NR_renameat + return INLINE_SYSCALL_CALL (renameat, oldfd, old, newfd, new); +#else + return INLINE_SYSCALL_CALL (renameat2, oldfd, old, newfd, new, 0); +#endif +} diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 98b3bb94c2..5d3c417d51 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -89,7 +89,6 @@ fchownat - fchownat i:isiii fchownat linkat - linkat i:isisi linkat mkdirat - mkdirat i:isi mkdirat readlinkat - readlinkat i:issi readlinkat -renameat - renameat i:isis renameat symlinkat - symlinkat i:sis symlinkat unlinkat - unlinkat i:isi unlinkat -- cgit v1.2.3 From b5eede9730eccec155c2374d20d401cd032519fd Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Fri, 18 Nov 2016 13:56:05 -0200 Subject: Consolidate Linux poll implementation This patch consolidates the poll Linux syscall implementation on sysdeps/unix/sysv/linux/poll.c. It basically removes poll from auto-generation list and add a default implementation that either call __NR_poll directly (if the kernel headers defines it) or ppoll adjusting the timeout argument (as the generic implementation). Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, aarch64-linux-gnu, arm-linux-gnueabihf, and powerpc64le-linux-gnu. * sysdeps/unix/sysv/linux/generic/poll.c: Remove file. * sysdeps/unix/sysv/linux/poll.c: New file. * sysdeps/unix/sysv/linux/syscalls.list: Remove poll from auto-generation list. --- ChangeLog | 7 ++++++ sysdeps/unix/sysv/linux/generic/poll.c | 42 ------------------------------- sysdeps/unix/sysv/linux/poll.c | 46 ++++++++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/syscalls.list | 1 - 4 files changed, 53 insertions(+), 43 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/generic/poll.c create mode 100644 sysdeps/unix/sysv/linux/poll.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index d58176667d..3aadc27b59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2016-04-03 Adhemerval Zanella + + * sysdeps/unix/sysv/linux/generic/poll.c: Remove file. + * sysdeps/unix/sysv/linux/poll.c: New file. + * sysdeps/unix/sysv/linux/syscalls.list: Remove poll from + auto-generation list. + 2017-05-03 Joseph Myers * sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h (HWCAP_ASIMDRDM): diff --git a/sysdeps/unix/sysv/linux/generic/poll.c b/sysdeps/unix/sysv/linux/generic/poll.c deleted file mode 100644 index c06d383e2c..0000000000 --- a/sysdeps/unix/sysv/linux/generic/poll.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2011-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Chris Metcalf , 2011. - - 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 - . */ - -#include -#include - -#include -#include - -int -__poll (struct pollfd *fds, nfds_t nfds, int timeout) -{ - struct timespec timeout_ts; - struct timespec *timeout_ts_p = NULL; - - if (timeout >= 0) - { - timeout_ts.tv_sec = timeout / 1000; - timeout_ts.tv_nsec = (timeout % 1000) * 1000000; - timeout_ts_p = &timeout_ts; - } - - return SYSCALL_CANCEL (ppoll, fds, nfds, timeout_ts_p, NULL, 0); -} -libc_hidden_def (__poll) -weak_alias (__poll, poll) -strong_alias (__poll, __libc_poll) diff --git a/sysdeps/unix/sysv/linux/poll.c b/sysdeps/unix/sysv/linux/poll.c new file mode 100644 index 0000000000..5a781ddf48 --- /dev/null +++ b/sysdeps/unix/sysv/linux/poll.c @@ -0,0 +1,46 @@ +/* Linux poll implementation. + Copyright (C) 2017 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 + . */ + +#include +#include + +#include +#include + +int +__poll (struct pollfd *fds, nfds_t nfds, int timeout) +{ +#ifdef __NR_poll + return SYSCALL_CANCEL (poll, fds, nfds, timeout); +#else + struct timespec timeout_ts; + struct timespec *timeout_ts_p = NULL; + + if (timeout >= 0) + { + timeout_ts.tv_sec = timeout / 1000; + timeout_ts.tv_nsec = (timeout % 1000) * 1000000; + timeout_ts_p = &timeout_ts; + } + + return SYSCALL_CANCEL (ppoll, fds, nfds, timeout_ts_p, NULL, 0); +#endif +} +libc_hidden_def (__poll) +weak_alias (__poll, poll) +strong_alias (__poll, __libc_poll) diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 5d3c417d51..fcefefcad2 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -50,7 +50,6 @@ pause - pause Ci: __libc_pause pause pipe - pipe i:f __pipe pipe pipe2 - pipe2 i:fi __pipe2 pipe2 pivot_root EXTRA pivot_root i:ss pivot_root -poll - poll Ci:pii __libc_poll __poll poll prctl EXTRA prctl i:iiiii __prctl prctl putpmsg - putpmsg i:ippii putpmsg query_module EXTRA query_module i:sipip __compat_query_module query_module@GLIBC_2.0:GLIBC_2.23 -- cgit v1.2.3 From 26f28fd73d20df8847d93f88b6e2a7bd3bd9bf51 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Fri, 18 Nov 2016 14:27:03 -0200 Subject: Consolidate Linux select implementation This patch consolidates the select Linux syscall implementation on sysdeps/unix/sysv/linux/select.c. The changes are: 1. Remove select from auto-generation syscalls.list on the architecture that uses __NR_select. 2. Remove generic implementation add a default one that handle all current cases (with the expection of alpha) The new default implementation will either use __NR_select if available of fallback to __NR_pselect6 otherwise. 3. Add a alpha outlier implementation which requires old compatibility symbols. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, and powerpc64le-linux-gnu. * sysdeps/unix/sysv/linux/alpha/Makefile (sysdep_routines): Add osf_select. * sysdeps/unix/sysv/linux/alpha/select.c: New file. * sysdeps/unix/sysv/linux/alpha/syscalls.list: Remove select and osf_select from auto-generation list. * sysdeps/unix/sysv/linux/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/generic/select.c: Remove file. * sysdeps/unix/sysv/linux/select.c: New file. --- ChangeLog | 10 +++ sysdeps/unix/sysv/linux/alpha/Makefile | 2 +- sysdeps/unix/sysv/linux/alpha/select.c | 53 ++++++++++++++++ sysdeps/unix/sysv/linux/alpha/syscalls.list | 2 - sysdeps/unix/sysv/linux/generic/select.c | 62 ------------------- sysdeps/unix/sysv/linux/select.c | 71 ++++++++++++++++++++++ .../unix/sysv/linux/sparc/sparc64/syscalls.list | 2 - sysdeps/unix/sysv/linux/syscalls.list | 1 - 8 files changed, 135 insertions(+), 68 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/alpha/select.c delete mode 100644 sysdeps/unix/sysv/linux/generic/select.c create mode 100644 sysdeps/unix/sysv/linux/select.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 3aadc27b59..a48b9fb7d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2016-04-03 Adhemerval Zanella + * sysdeps/unix/sysv/linux/alpha/Makefile (sysdep_routines): Add + osf_select. + * sysdeps/unix/sysv/linux/alpha/select.c: New file. + * sysdeps/unix/sysv/linux/alpha/syscalls.list: Remove select and + osf_select from auto-generation list. + * sysdeps/unix/sysv/linux/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/generic/select.c: Remove file. + * sysdeps/unix/sysv/linux/select.c: New file. + * sysdeps/unix/sysv/linux/generic/poll.c: Remove file. * sysdeps/unix/sysv/linux/poll.c: New file. * sysdeps/unix/sysv/linux/syscalls.list: Remove poll from diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile index 37bdd5a3d0..47bd189f94 100644 --- a/sysdeps/unix/sysv/linux/alpha/Makefile +++ b/sysdeps/unix/sysv/linux/alpha/Makefile @@ -13,7 +13,7 @@ sysdep_routines += ieee_get_fp_control ieee_set_fp_control \ ioperm # Support old timeval32 entry points -sysdep_routines += osf_select osf_gettimeofday osf_settimeofday \ +sysdep_routines += osf_gettimeofday osf_settimeofday \ osf_getitimer osf_setitimer osf_utimes \ osf_getrusage osf_wait4 diff --git a/sysdeps/unix/sysv/linux/alpha/select.c b/sysdeps/unix/sysv/linux/alpha/select.c new file mode 100644 index 0000000000..bb0298f6a4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/select.c @@ -0,0 +1,53 @@ +/* Linux/alpha select implementation. + Copyright (C) 2017 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 + . */ + +#include +#include +#include +#include +#include +#include + +int +__new_select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ + return SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds, timeout); +} +strong_alias (__new_select, __select) +libc_hidden_def (__select) + +default_symbol_version (__new_select, select, GLIBC_2.1); + +strong_alias (__new_select, __new_select_private); +symbol_version (__new_select_private, __select, GLIBC_2.1); + +/* Old timeval32 compat calls. */ +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) +int +__select_tv32 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ + return SYSCALL_CANCEL (osf_select, nfds, readfds, writefds, exceptfds, + timeout); +} +strong_alias (__select_tv32, __select_tv32_1) + +compat_symbol (libc, __select_tv32, __select, GLIBC_2_0); +compat_symbol (libc, __select_tv32_1, select, GLIBC_2_0); +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list index aa21b10a25..12cd021b60 100644 --- a/sysdeps/unix/sysv/linux/alpha/syscalls.list +++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list @@ -23,7 +23,6 @@ pciconfig_write EXTRA pciconfig_write 5 pciconfig_write pciconfig_iobase EXTRA pciconfig_iobase 3 __pciconfig_iobase pciconfig_iobase # support old timeval32 entry points -osf_select - osf_select C:5 __select_tv32 __select@GLIBC_2.0 select@GLIBC_2.0 osf_gettimeofday - osf_gettimeofday 2 __gettimeofday_tv32 __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0 osf_settimeofday - osf_settimeofday 2 __settimeofday_tv32 settimeofday@GLIBC_2.0 osf_getitimer - osf_getitimer 2 __getitimer_tv32 getitimer@GLIBC_2.0 @@ -33,7 +32,6 @@ osf_getrusage - osf_getrusage 2 __getrusage_tv32 getrusage@GLIBC_2.0 osf_wait4 - osf_wait4 4 __wait4_tv32 wait4@GLIBC_2.0 # support new timeval64 entry points -select - select C:5 __GI___select select@@GLIBC_2.1 __select@@GLIBC_2.1 gettimeofday - gettimeofday 2 __GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1 settimeofday - settimeofday 2 __settimeofday settimeofday@@GLIBC_2.1 getitimer - getitimer 2 __getitimer getitimer@@GLIBC_2.1 diff --git a/sysdeps/unix/sysv/linux/generic/select.c b/sysdeps/unix/sysv/linux/generic/select.c deleted file mode 100644 index 7743ea3f3a..0000000000 --- a/sysdeps/unix/sysv/linux/generic/select.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2011-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Chris Metcalf , 2011. - - 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 - . */ - -#include -#include -#include -#include -#include - -/* Check the first NFDS descriptors each in READFDS (if not NULL) for read - readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS - (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out - after waiting the interval specified therein. Returns the number of ready - descriptors, or -1 for errors. */ - -int -__select(int nfds, fd_set *readfds, - fd_set *writefds, fd_set *exceptfds, - struct timeval *timeout) -{ - int result; - struct timespec ts, *tsp = NULL; - - if (timeout) - { - TIMEVAL_TO_TIMESPEC (timeout, &ts); - tsp = &ts; - } - - result = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, tsp, - NULL); - - if (timeout) - { - /* Linux by default will update the timeout after a pselect6 syscall - (though the pselect() glibc call suppresses this behavior). - Since select() on Linux has the same behavior as the pselect6 - syscall, we update the timeout here. */ - TIMESPEC_TO_TIMEVAL (timeout, &ts); - } - - return result; -} -libc_hidden_def (__select) - -weak_alias (__select, select) -weak_alias (__select, __libc_select) diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c new file mode 100644 index 0000000000..be4a456a51 --- /dev/null +++ b/sysdeps/unix/sysv/linux/select.c @@ -0,0 +1,71 @@ +/* Linux select implementation. + Copyright (C) 2017 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 + . */ + +#include +#include +#include +#include +#include + +/* Check the first NFDS descriptors each in READFDS (if not NULL) for read + readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS + (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out + after waiting the interval specified therein. Returns the number of ready + descriptors, or -1 for errors. */ + +#ifdef __NR__newselect +# undef __NR_select +# define __NR_select __NR__newselect +#endif + +int +__select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ +#ifdef __NR_select + return SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds, + timeout); +#else + int result; + struct timespec ts, *tsp = NULL; + + if (timeout) + { + TIMEVAL_TO_TIMESPEC (timeout, &ts); + tsp = &ts; + } + + result = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, tsp, + NULL); + + if (timeout) + { + /* Linux by default will update the timeout after a pselect6 syscall + (though the pselect() glibc call suppresses this behavior). + Since select() on Linux has the same behavior as the pselect6 + syscall, we update the timeout here. */ + TIMESPEC_TO_TIMEVAL (timeout, &ts); + } + + return result; +#endif +} +libc_hidden_def (__select) + +weak_alias (__select, select) +weak_alias (__select, __libc_select) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list b/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list index 1e85118e36..33082f31eb 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list @@ -1,7 +1,5 @@ # File name Caller Syscall name # args Strong name Weak names -# Override select.S in parent directory: -select - select C:5 __select select bind - bind 3 __bind bind getpeername - getpeername 3 __getpeername getpeername getsockname - getsockname 3 __getsockname getsockname diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index fcefefcad2..4d550b8804 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -63,7 +63,6 @@ sched_rr_gi - sched_rr_get_interval i:ip __sched_rr_get_interval sched_rr_get_in sched_setp - sched_setparam i:ip __sched_setparam sched_setparam sched_sets - sched_setscheduler i:iip __sched_setscheduler sched_setscheduler sched_yield - sched_yield i: __sched_yield sched_yield -select - _newselect Ci:iPPPP __select __libc_select select sendfile - sendfile i:iipi sendfile sendfile64 - sendfile64 i:iipi sendfile64 setfsgid EXTRA setfsgid i:i setfsgid -- cgit v1.2.3 From b62c3815912bc679a966134affdedd3f35ae8621 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 21 Nov 2016 17:40:19 -0200 Subject: Consolidate Linux epoll_wait syscall This patch consolidates the epoll_wait Linux syscall generation on sysdeps/unix/sysv/linux/epoll_wait.c. The implementation tries to use __NR_epoll_wait if defined, otherwise calls epoll_pwait. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, and powerpc64le-linux-gnu. * sysdeps/unix/sysv/linux/epoll_wait.c: New file. * sysdeps/unix/sysv/linux/generic/epoll_wait.c: Remove file. * sysdeps/unix/sysv/linux/syscalls.list: Remove epoll_wait from auto-generation list. --- ChangeLog | 9 ++++++++ sysdeps/unix/sysv/linux/Makefile | 2 +- sysdeps/unix/sysv/linux/epoll_wait.c | 32 ++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/generic/Makefile | 2 +- sysdeps/unix/sysv/linux/generic/epoll_wait.c | 28 ------------------------ sysdeps/unix/sysv/linux/syscalls.list | 1 - 6 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/epoll_wait.c delete mode 100644 sysdeps/unix/sysv/linux/generic/epoll_wait.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index a48b9fb7d9..fa61e5fdb7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2016-04-03 Adhemerval Zanella + * sysdeps/unix/sysv/linux/epoll_wait.c: New file. + * sysdeps/unix/sysv/linux/generic/epoll_wait.c: Remove file. + * sysdeps/unix/sysv/linux/syscalls.list: Remove epoll_wait from + auto-generation list. + * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add + epoll_wait. + * sysdeps/unix/sysv/linux/generic/Makefile (sysdep_routines): + Remove epoll_wait. + * sysdeps/unix/sysv/linux/alpha/Makefile (sysdep_routines): Add osf_select. * sysdeps/unix/sysv/linux/alpha/select.c: New file. diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 1872cdb179..a8790b1e51 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -17,7 +17,7 @@ include $(firstword $(wildcard $(sysdirs:=/sysctl.mk))) sysdep_routines += clone umount umount2 readahead \ setfsuid setfsgid epoll_pwait signalfd \ eventfd eventfd_read eventfd_write prlimit \ - personality + personality epoll_wait CFLAGS-gethostid.c = -fexceptions CFLAGS-tst-writev.c += "-DARTIFICIAL_LIMIT=(0x80000000-sysconf(_SC_PAGESIZE))" diff --git a/sysdeps/unix/sysv/linux/epoll_wait.c b/sysdeps/unix/sysv/linux/epoll_wait.c new file mode 100644 index 0000000000..eb6e6d3ace --- /dev/null +++ b/sysdeps/unix/sysv/linux/epoll_wait.c @@ -0,0 +1,32 @@ +/* Linux epoll_wait syscall implementation. + Copyright (C) 2017 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 + . */ + +#include +#include +#include +#include + +int +epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout) +{ +#ifdef __NR_epoll_wait + return SYSCALL_CANCEL (epoll_wait, epfd, events, maxevents, timeout); +#else + return epoll_pwait (epfd, events, maxevents, timeout, NULL); +#endif +} diff --git a/sysdeps/unix/sysv/linux/generic/Makefile b/sysdeps/unix/sysv/linux/generic/Makefile index c1daee2396..7e27e79772 100644 --- a/sysdeps/unix/sysv/linux/generic/Makefile +++ b/sysdeps/unix/sysv/linux/generic/Makefile @@ -1,3 +1,3 @@ ifeq ($(subdir),misc) -sysdep_routines += epoll_create epoll_wait inotify_init +sysdep_routines += epoll_create inotify_init endif diff --git a/sysdeps/unix/sysv/linux/generic/epoll_wait.c b/sysdeps/unix/sysv/linux/generic/epoll_wait.c deleted file mode 100644 index d9363f1d8d..0000000000 --- a/sysdeps/unix/sysv/linux/generic/epoll_wait.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (C) 2011-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Chris Metcalf , 2011. - - 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 - . */ - -#include -#include -#include -#include - -int -epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout) -{ - return epoll_pwait (epfd, events, maxevents, timeout, NULL); -} diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 4d550b8804..1a1090311c 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -12,7 +12,6 @@ delete_module EXTRA delete_module 3 delete_module epoll_create EXTRA epoll_create i:i epoll_create epoll_create1 EXTRA epoll_create1 i:i epoll_create1 epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl -epoll_wait EXTRA epoll_wait Ci:ipii epoll_wait eventfd EXTRA eventfd2 i:ii eventfd execve - execve i:spp __execve execve fdatasync - fdatasync Ci:i fdatasync -- cgit v1.2.3 From cab6e5af9d51d4398522af782e20c743daf37461 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Fri, 11 Nov 2016 14:50:03 -0200 Subject: Consolidate Linux creat implementation This patch consolidates the creat Linux syscall implementation on sysdeps/unix/sysv/linux/creat{64}.c. The changes are: 1. Remove creat{64} from auto-generation syscalls.list. 2. Add a new creat{64}.c implementation. For architectures that define __OFF_T_MATCHES_OFF64_T the default creat64 will create alias to required creat symbols. 3. Use __NR_creat where possible, otherwise use internal open{64} call with expected flags. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, and powerpc64le-linux-gnu. * io/Makefile (CFLAGS-creat.c): New rule. (CFLAGS-creat64.c): Likewise. * sysdeps/unix/sysv/linux/alpha/creat.c: Remove file. * sysdeps/unix/sysv/linux/generic/creat.c: Likewise. * sysdeps/unix/sysv/linux/wordsize-64/creat64.c: Likewise. * sysdeps/unix/sysv/linux/creat.c: New file. * sysdeps/unix/sysv/linux/creat64.c: Likewise. * sysdeps/unix/sysv/linux/syscalls.list: Remove create from auto-generated list. * sysdeps/unix/sysv/linux/wordsize-64/syscalls.list: Likewise. --- ChangeLog | 11 ++++++ io/Makefile | 2 ++ sysdeps/unix/sysv/linux/alpha/creat.c | 8 ----- sysdeps/unix/sysv/linux/creat.c | 40 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/creat64.c | 41 +++++++++++++++++++++++ sysdeps/unix/sysv/linux/generic/creat.c | 37 -------------------- sysdeps/unix/sysv/linux/syscalls.list | 1 - sysdeps/unix/sysv/linux/wordsize-64/creat64.c | 1 - sysdeps/unix/sysv/linux/wordsize-64/syscalls.list | 1 - 9 files changed, 94 insertions(+), 48 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/alpha/creat.c create mode 100644 sysdeps/unix/sysv/linux/creat.c create mode 100644 sysdeps/unix/sysv/linux/creat64.c delete mode 100644 sysdeps/unix/sysv/linux/generic/creat.c delete mode 100644 sysdeps/unix/sysv/linux/wordsize-64/creat64.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 0431df8701..a924f87c2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2016-05-10 Adhemerval Zanella + * io/Makefile (CFLAGS-creat.c): New rule. + (CFLAGS-creat64.c): Likewise. + * sysdeps/unix/sysv/linux/alpha/creat.c: Remove file. + * sysdeps/unix/sysv/linux/generic/creat.c: Likewise. + * sysdeps/unix/sysv/linux/wordsize-64/creat64.c: Likewise. + * sysdeps/unix/sysv/linux/creat.c: New file. + * sysdeps/unix/sysv/linux/creat64.c: Likewise. + * sysdeps/unix/sysv/linux/syscalls.list: Remove create from + auto-generated list. + * sysdeps/unix/sysv/linux/wordsize-64/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/generic/open.c: Remove file. * sysdeps/unix/sysv/linux/generic/open64.c: Likewise. * sysdeps/unix/sysv/linux/wordsize-64/open64.c: Likewise. diff --git a/io/Makefile b/io/Makefile index 95e04b241b..8b1c250fda 100644 --- a/io/Makefile +++ b/io/Makefile @@ -80,6 +80,8 @@ include ../Rules CFLAGS-open.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-open64.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-creat.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-creat64.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-fcntl.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-poll.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-ppoll.c = -fexceptions -fasynchronous-unwind-tables diff --git a/sysdeps/unix/sysv/linux/alpha/creat.c b/sysdeps/unix/sysv/linux/alpha/creat.c deleted file mode 100644 index 7a5afed58c..0000000000 --- a/sysdeps/unix/sysv/linux/alpha/creat.c +++ /dev/null @@ -1,8 +0,0 @@ -/* sysdeps/unix/sysv/linux/wordsize-64/syscalls.list defines creat and - creat64 for most linux targets, but on alpha creat is not a syscall. - If we do nothing, we'll wind up with creat64 being undefined, because - the syscalls.list assumes the creat->creat64 alias was created. We - could have overridden that with a create64.c, but we might as well do - the right thing and set up creat64 as an alias. */ -#include -weak_alias(creat, creat64) diff --git a/sysdeps/unix/sysv/linux/creat.c b/sysdeps/unix/sysv/linux/creat.c new file mode 100644 index 0000000000..31e024838c --- /dev/null +++ b/sysdeps/unix/sysv/linux/creat.c @@ -0,0 +1,40 @@ +/* Linux default implementation for creat. + Copyright (C) 2017 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 + . */ + +#include +#include + +#include + +#ifndef __OFF_T_MATCHES_OFF64_T + +/* Create FILE with protections MODE. */ +int +__creat (const char *file, mode_t mode) +{ +# ifdef __NR_creat + return SYSCALL_CANCEL (creat, file, mode); +# else + return __open (file, O_WRONLY | O_CREAT | O_TRUNC, mode); +# endif +} +weak_alias (__creat, creat) + +LIBC_CANCEL_HANDLED (); + +#endif diff --git a/sysdeps/unix/sysv/linux/creat64.c b/sysdeps/unix/sysv/linux/creat64.c new file mode 100644 index 0000000000..709c66091a --- /dev/null +++ b/sysdeps/unix/sysv/linux/creat64.c @@ -0,0 +1,41 @@ +/* Linux default implementation for LFS creat. + Copyright (C) 2017 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 + . */ + +#include +#include +#include + +/* Create FILE with protections MODE. */ +int +__creat64 (const char *file, mode_t mode) +{ +#if defined __OFF_T_MATCHES_OFF64_T && defined __NR_creat + return SYSCALL_CANCEL (creat, file, mode); +#else + /* We need to pass O_LARGEFILE. */ + return __open64 (file, O_WRONLY | O_CREAT | O_TRUNC, mode); +#endif +} +weak_alias (__creat64, creat64) + +#ifdef __OFF_T_MATCHES_OFF64_T +strong_alias (__creat64, __creat) +weak_alias (__creat64, creat) +#endif + +LIBC_CANCEL_HANDLED (); diff --git a/sysdeps/unix/sysv/linux/generic/creat.c b/sysdeps/unix/sysv/linux/generic/creat.c deleted file mode 100644 index 34cb210e77..0000000000 --- a/sysdeps/unix/sysv/linux/generic/creat.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2011-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Chris Metcalf , 2011. - - 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 - . */ - -#include -#include -#include - -#undef creat - -/* Create FILE with protections MODE. */ -int -creat (const char *file, mode_t mode) -{ - return __open (file, O_WRONLY | O_CREAT | O_TRUNC, mode); -} - -/* __open handles cancellation. */ -LIBC_CANCEL_HANDLED (); - -#if __WORDSIZE == 64 -weak_alias (creat, creat64) -#endif diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 1a1090311c..f4abf3e6c8 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -6,7 +6,6 @@ bdflush EXTRA bdflush i:ii __compat_bdflush bdflush@GLIBC_2.0:GLIBC_2.23 capget EXTRA capget i:pp capget capset EXTRA capset i:pp capset clock_adjtime EXTRA clock_adjtime i:ip clock_adjtime -creat - creat Ci:si creat create_module EXTRA create_module 3 __compat_create_module create_module@GLIBC_2.0:GLIBC_2.23 delete_module EXTRA delete_module 3 delete_module epoll_create EXTRA epoll_create i:i epoll_create diff --git a/sysdeps/unix/sysv/linux/wordsize-64/creat64.c b/sysdeps/unix/sysv/linux/wordsize-64/creat64.c deleted file mode 100644 index c106e2b362..0000000000 --- a/sysdeps/unix/sysv/linux/wordsize-64/creat64.c +++ /dev/null @@ -1 +0,0 @@ -/* Defined as alias for the syscall. */ diff --git a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list index 6549ed8258..5c78677d77 100644 --- a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list +++ b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list @@ -5,7 +5,6 @@ statfs - statfs i:sp __statfs statfs statfs64 readahead - readahead i:iii __readahead readahead sendfile - sendfile i:iipi sendfile sendfile64 sync_file_range - sync_file_range Ci:iiii sync_file_range -creat - creat Ci:si creat creat64 prlimit EXTRA prlimit64 i:iipp prlimit prlimit64 fanotify_mark EXTRA fanotify_mark i:iiiis fanotify_mark -- cgit v1.2.3 From 88499a87cef0a70f381524b9c4951b53bc5184e3 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 21 Nov 2016 17:26:35 -0200 Subject: posix: Consolidate Linux pause syscall This patch consolidates the pause Linux implementation on sysdeps/unix/sysv/linux/pause.c. If defined the pause syscall (__NR_pause) will be used, other ppoll with 0 arguments will be used instead. It has the small advantage of generic pause implementation with uses rt_sigprocmask plus rt_sigsuspend because it requires only one syscall and the pause is done atomically regarding signal handling (for instance, pause may not be interrupted if the signal arrives between the rt_sigprocmask and rt_sigsuspend syscall). Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. * sysdeps/unix/sysv/linux/generic/pause.c: Remove file. * sysdeps/unix/sysv/linux/sparc/sparc64/pause.c: Likewise. * sysdeps/unix/sysv/linux/sparc/kernel-features.h [__arch64__] (__NR_pause): Undefine. * sysdeps/unix/sysv/linux/pause.c: New file. * sysdeps/unix/sysv/linux/syscalls.list: Remove pause from auto-generation list. --- ChangeLog | 13 +++++++++ posix/Makefile | 1 - sysdeps/unix/sysv/linux/generic/pause.c | 39 ------------------------- sysdeps/unix/sysv/linux/pause.c | 35 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/sparc/kernel-features.h | 4 +++ sysdeps/unix/sysv/linux/sparc/sparc64/Makefile | 1 - sysdeps/unix/sysv/linux/sparc/sparc64/pause.c | 9 ------ sysdeps/unix/sysv/linux/syscalls.list | 1 - 8 files changed, 52 insertions(+), 51 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/generic/pause.c create mode 100644 sysdeps/unix/sysv/linux/pause.c delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/pause.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 5ebd3a04ab..135b5a5e87 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2017-05-18 Adhemerval Zanella + + * sysdeps/unix/sysv/linux/generic/pause.c: Remove file. + * sysdeps/unix/sysv/linux/sparc/sparc64/pause.c: Likewise. + * sysdeps/unix/sysv/linux/sparc/kernel-features.h [__arch64__] + (__NR_pause): Undefine. + * sysdeps/unix/sysv/linux/pause.c: New file. + * sysdeps/unix/sysv/linux/syscalls.list: Remove pause from + auto-generation list. + * sysdeps/unix/sysv/linux/sparc/sparc64/Makefile (CFLAGS-pause.c): + Remove rule. + * posix/Makefile (CFLAGS-pause.c): Remove redundant rule. + 2017-05-18 H.J. Lu * sysdeps/x86_64/multiarch/memcmp.S (__GI_memcmp): Correct diff --git a/posix/Makefile b/posix/Makefile index 0025d8af53..a78ca3dd71 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -221,7 +221,6 @@ CFLAGS-spawnp.c = -fexceptions CFLAGS-spawnp.os = -fomit-frame-pointer CFLAGS-spawni.c = -fexceptions CFLAGS-spawni.os = -fomit-frame-pointer -CFLAGS-pause.c = -fexceptions CFLAGS-glob.c = $(uses-callbacks) -fexceptions CFLAGS-glob64.c = $(uses-callbacks) -fexceptions CFLAGS-getconf.c = -DGETCONF_DIR='"$(libexecdir)/getconf"' diff --git a/sysdeps/unix/sysv/linux/generic/pause.c b/sysdeps/unix/sysv/linux/generic/pause.c deleted file mode 100644 index a8b3e33a6c..0000000000 --- a/sysdeps/unix/sysv/linux/generic/pause.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2011-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Chris Metcalf , 2011. - - 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 - . */ - -#include -#include -#include - -/* Suspend the process until a signal arrives. - This always returns -1 and sets errno to EINTR. */ - -int -__libc_pause (void) -{ - sigset_t set; - - int rc = - SYSCALL_CANCEL (rt_sigprocmask, SIG_BLOCK, NULL, &set, _NSIG / 8); - if (rc == 0) - rc = SYSCALL_CANCEL (rt_sigsuspend, &set, _NSIG / 8); - - return rc; -} - -weak_alias (__libc_pause, pause) diff --git a/sysdeps/unix/sysv/linux/pause.c b/sysdeps/unix/sysv/linux/pause.c new file mode 100644 index 0000000000..4ccce9ebd8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/pause.c @@ -0,0 +1,35 @@ +/* Linux pause syscall implementation. + Copyright (C) 2017 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 + . */ + +#include +#include +#include + +/* Suspend the process until a signal arrives. + This always returns -1 and sets errno to EINTR. */ + +int +__libc_pause (void) +{ +#ifdef __NR_pause + return SYSCALL_CANCEL (pause); +#else + return SYSCALL_CANCEL (ppoll, NULL, 0, NULL, NULL); +#endif +} +weak_alias (__libc_pause, pause) diff --git a/sysdeps/unix/sysv/linux/sparc/kernel-features.h b/sysdeps/unix/sysv/linux/sparc/kernel-features.h index 72065a0248..3fafab359c 100644 --- a/sysdeps/unix/sysv/linux/sparc/kernel-features.h +++ b/sysdeps/unix/sysv/linux/sparc/kernel-features.h @@ -32,6 +32,10 @@ # undef __ASSUME_ACCEPT_SYSCALL # undef __ASSUME_CONNECT_SYSCALL # undef __ASSUME_RECVFROM_SYSCALL +#else +/* sparc64 defines __NR_pause, however it is not supported (ENOSYS). + Undefine so pause.c can use a correct alternative. */ +# undef __NR_pause #endif /* sparc only supports ipc syscall. */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile index 7ea433f21f..3a7f4aa84a 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile @@ -9,6 +9,5 @@ sysdep_routines += __start_context endif ifeq ($(subdir),nptl) -CFLAGS-pause.c += -fexceptions CFLAGS-sigsuspend.c += -fexceptions endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c deleted file mode 100644 index e399e7c7eb..0000000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include -#include -#include - -#define __sigprocmask(how, set, oset) \ - INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8) - -#include diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index f4abf3e6c8..eab30dda06 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -44,7 +44,6 @@ munlock - munlock i:ai munlock munlockall - munlockall i: munlockall nanosleep - nanosleep Ci:pp __nanosleep nanosleep nfsservctl EXTRA nfsservctl i:ipp nfsservctl -pause - pause Ci: __libc_pause pause pipe - pipe i:f __pipe pipe pipe2 - pipe2 i:fi __pipe2 pipe2 pivot_root EXTRA pivot_root i:ss pivot_root -- cgit v1.2.3 From 3d0ad5a8dfb7b8dd862108970a62c2c3ce9ddd72 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Tue, 3 Nov 2015 16:03:56 -0200 Subject: posix: Consolidate Linux nanosleep syscall This patch consolidates the nanosleep Linux syscall generation on sysdeps/unix/sysv/linux/nanosleep.c. It basically removes it from architectures auto-generation list. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. * nptl/Makefile (CFLAGS-nanosleep.c): New rule. * posix/Makefile (CFLAGS-nanosleep.c): Likewise. * sysdeps/unix/sysv/linux/nanosleep.c: New file. * sysdeps/unix/sysv/linux/syscalls.list: Remove nanosleep from auto-generated list. --- ChangeLog | 6 ++++++ nptl/Makefile | 1 + posix/Makefile | 1 + sysdeps/unix/sysv/linux/nanosleep.c | 30 ++++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/syscalls.list | 1 - 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/nanosleep.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 98dad73e7b..7bc0ce4cec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2017-05-18 Adhemerval Zanella + * nptl/Makefile (CFLAGS-nanosleep.c): New rule. + * posix/Makefile (CFLAGS-nanosleep.c): Likewise. + * sysdeps/unix/sysv/linux/nanosleep.c: New file. + * sysdeps/unix/sysv/linux/syscalls.list: Remove nanosleep from + auto-generated list. + * sysdeps/unix/sysv/linux/sh/syscalls.list: Remove waitid from auto-generated list. * sysdeps/unix/sysv/linux/m68k/syscalls.list: Likewise. diff --git a/nptl/Makefile b/nptl/Makefile index d39bb50847..cdf69bd033 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -216,6 +216,7 @@ CFLAGS-sendmsg.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-close.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-read.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-write.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-nanosleep.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-pt-system.c = -fexceptions diff --git a/posix/Makefile b/posix/Makefile index a78ca3dd71..52b022cf66 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -231,6 +231,7 @@ CFLAGS-execle.os = -fomit-frame-pointer CFLAGS-execl.os = -fomit-frame-pointer CFLAGS-execvp.os = -fomit-frame-pointer CFLAGS-execlp.os = -fomit-frame-pointer +CFLAGS-nanosleep.c = -fexceptions -fasynchronous-unwind-tables tstgetopt-ARGS = -a -b -cfoobar --required foobar --optional=bazbug \ --none random --col --color --colour diff --git a/sysdeps/unix/sysv/linux/nanosleep.c b/sysdeps/unix/sysv/linux/nanosleep.c new file mode 100644 index 0000000000..b352f84344 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nanosleep.c @@ -0,0 +1,30 @@ +/* Linux high resolution nanosleep implementation. + Copyright (C) 2017 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 + . */ + +#include +#include + +/* Pause execution for a number of nanoseconds. */ +int +__nanosleep (const struct timespec *requested_time, + struct timespec *remaining) +{ + return SYSCALL_CANCEL (nanosleep, requested_time, remaining); +} +libc_hidden_def (__nanosleep) +weak_alias (__nanosleep, nanosleep) diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index eab30dda06..7fca6f827b 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -42,7 +42,6 @@ mount EXTRA mount i:sssip __mount mount mremap EXTRA mremap b:ainip __mremap mremap munlock - munlock i:ai munlock munlockall - munlockall i: munlockall -nanosleep - nanosleep Ci:pp __nanosleep nanosleep nfsservctl EXTRA nfsservctl i:ipp nfsservctl pipe - pipe i:f __pipe pipe pipe2 - pipe2 i:fi __pipe2 pipe2 -- cgit v1.2.3 From 2de15b61e92c76bcb21df1140f20a62dc6d3cc39 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Thu, 24 Nov 2016 09:55:09 -0200 Subject: linux: Consolidate Linux tee implementation This patch consolidates the tee Linux syscall generation on sysdeps/unix/sysv/linux/tee.c. It basically removes it from architectures auto-generation list. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. * sysdeps/unix/sysv/linux/Makefile (sysdeps_routines): Add tee. (CFLAGS-tee.c): New rule. * sysdeps/unix/sysv/linux/syscalls.list: Remove tee from auto-generated list. * sysdeps/unix/sysv/linux/tee.c: New file. --- ChangeLog | 6 ++++++ sysdeps/unix/sysv/linux/Makefile | 3 ++- sysdeps/unix/sysv/linux/syscalls.list | 1 - sysdeps/unix/sysv/linux/tee.c | 26 ++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/tee.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 7bc0ce4cec..0c30af6ccd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2017-05-18 Adhemerval Zanella + * sysdeps/unix/sysv/linux/Makefile (sysdeps_routines): Add tee. + (CFLAGS-tee.c): New rule. + * sysdeps/unix/sysv/linux/syscalls.list: Remove tee from + auto-generated list. + * sysdeps/unix/sysv/linux/tee.c: New file. + * nptl/Makefile (CFLAGS-nanosleep.c): New rule. * posix/Makefile (CFLAGS-nanosleep.c): Likewise. * sysdeps/unix/sysv/linux/nanosleep.c: New file. diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index ad477f543b..9388623345 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -17,9 +17,10 @@ include $(firstword $(wildcard $(sysdirs:=/sysctl.mk))) sysdep_routines += clone umount umount2 readahead \ setfsuid setfsgid epoll_pwait signalfd \ eventfd eventfd_read eventfd_write prlimit \ - personality epoll_wait + personality epoll_wait tee CFLAGS-gethostid.c = -fexceptions +CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-tst-writev.c += "-DARTIFICIAL_LIMIT=(0x80000000-sysconf(_SC_PAGESIZE))" # Note that bits/mman-linux.h is listed here though the file lives in the diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 7fca6f827b..ae99acdea2 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -70,7 +70,6 @@ stime - stime i:p stime sysinfo EXTRA sysinfo i:p __sysinfo sysinfo swapon - swapon i:si __swapon swapon swapoff - swapoff i:s __swapoff swapoff -tee EXTRA tee Ci:iiii tee unshare EXTRA unshare i:i unshare uselib EXTRA uselib i:s __compat_uselib uselib@GLIBC_2.0:GLIBC_2.23 utime - utime i:sP utime diff --git a/sysdeps/unix/sysv/linux/tee.c b/sysdeps/unix/sysv/linux/tee.c new file mode 100644 index 0000000000..3d503fb1c9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tee.c @@ -0,0 +1,26 @@ +/* Linux duplicating pipe content implementation. + Copyright (C) 2017 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 + . */ + +#include +#include + +ssize_t +tee (int src, int dest, size_t len, unsigned int flags) +{ + return SYSCALL_CANCEL (tee, src, dest, len, flags); +} -- cgit v1.2.3 From 51209cbf51192d4a2c337a41ddb6eebc7472c021 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 2 Nov 2015 11:00:39 -0200 Subject: posix: Consolidate Linux fdatasync syscall This patch consolidates the fdatasync Linux syscall generation on sysdeps/unix/sysv/linux/fdatasync.c. It basically removes it from architectures auto-generation list. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. * misc/makefile (CFLAGS-datasync.c): New flag. * nptl/makefile (CFLAGS-datasync.c): Likewise. * sysdeps/unix/sysv/linux/syscalls.list (fdatasync): Remove from auto-generation syscall list. * sysdeps/unix/sysv/linux/fdatasync.c: New file. --- ChangeLog | 6 ++++++ misc/Makefile | 1 + nptl/Makefile | 1 + sysdeps/unix/sysv/linux/fdatasync.c | 29 +++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/syscalls.list | 1 - 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/fdatasync.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index caaf6050ae..6e88eeffea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2017-05-18 Adhemerval Zanella + * misc/Makefile (CFLAGS-fdatasync.c): New rule. + * nptl/Makefile (CFLAGS-fdatasync.c): Likewise. + * sysdeps/unix/syscalls.list: Remove fdatasync from auto-generation + list. + * sysdeps/unix/sysv/linux/fdatasync.c: New file. + * misc/Makefile (CFLAGS-msync.c): New rule. * nptl/Makefile (CFLAGS-msync.c): Likewise. * sysdeps/unix/syscalls.list: Remove msync from auto-generation list. diff --git a/misc/Makefile b/misc/Makefile index 0c1526a592..a777ece4a5 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -109,6 +109,7 @@ CFLAGS-getusershell.c = -fexceptions CFLAGS-err.c = -fexceptions CFLAGS-tst-tsearch.c = $(stack-align-test-flags) CFLAGS-msync.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-fdatasync.c = -fexceptions -fasynchronous-unwind-tables # Called during static library initialization, so turn stack-protection # off for non-shared builds. diff --git a/nptl/Makefile b/nptl/Makefile index 3ade74fa36..90eac7c7f2 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -219,6 +219,7 @@ CFLAGS-write.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-nanosleep.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-sigsuspend.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-msync.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-fdatasync.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-pt-system.c = -fexceptions diff --git a/sysdeps/unix/sysv/linux/fdatasync.c b/sysdeps/unix/sysv/linux/fdatasync.c new file mode 100644 index 0000000000..09a07fbb9e --- /dev/null +++ b/sysdeps/unix/sysv/linux/fdatasync.c @@ -0,0 +1,29 @@ +/* Synchronize a file's in-core state with storage device Linux + implementation. + Copyright (C) 2017 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 + . */ + +#include +#include + +/* Synchronize at least the data part of a file with the underlying + media. */ +int +fdatasync (int fd) +{ + return SYSCALL_CANCEL (fdatasync, fd); +} diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index ae99acdea2..c69eff4432 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -13,7 +13,6 @@ epoll_create1 EXTRA epoll_create1 i:i epoll_create1 epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl eventfd EXTRA eventfd2 i:ii eventfd execve - execve i:spp __execve execve -fdatasync - fdatasync Ci:i fdatasync flock - flock i:ii __flock flock get_kernel_syms EXTRA get_kernel_syms i:p __compat_get_kernel_syms get_kernel_syms@GLIBC_2.0:GLIBC_2.23 getpid - getpid Ei: __getpid getpid -- cgit v1.2.3 From ecade1cb0b9d5139498ccd7a5d4aa4c1cc870231 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 2 Nov 2015 11:13:24 -0200 Subject: linux: Consolidate Linux vmsplice syscall This patch consolidates the vmsplice Linux syscall generation on sysdeps/unix/sysv/linux/vmsplice.c. It basically removes it from architectures auto-generation list. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. * sysdeps/unix/sysv/linux/Makefile (CFLAGS-vmsplice.c): New flag. * sysdeps/unix/sysv/linux/syscalls.list (vmsplice): Remove from auto-generation syscall list. * sysdeps/unix/sysv/linux/vmsplice.c: New file. * misc/Makefile (CFLAGS-vmsplice.c): New rule. --- ChangeLog | 6 ++++++ misc/Makefile | 1 + sysdeps/unix/sysv/linux/Makefile | 2 +- sysdeps/unix/sysv/linux/syscalls.list | 1 - sysdeps/unix/sysv/linux/vmsplice.c | 27 +++++++++++++++++++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/vmsplice.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index b04b779ef7..bc92bfc73d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2017-05-18 Adhemerval Zanella + * sysdeps/unix/sysv/linux/Makefile (CFLAGS-vmsplice.c): New flag. + * sysdeps/unix/sysv/linux/syscalls.list (vmsplice): Remove from + auto-generation syscall list. + * sysdeps/unix/sysv/linux/vmsplice.c: New file. + * misc/Makefile (CFLAGS-vmsplice.c): New rule. + * misc/Makefile (CFLAGS-fsync.c): New flag. * nptl/Makefile (CFLAGS-fsync.c): Likewise. * sysdeps/unix/syscalls.list (fsync): Remove from auto-generation diff --git a/misc/Makefile b/misc/Makefile index 2db1fd8397..c4a75b5908 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -111,6 +111,7 @@ CFLAGS-tst-tsearch.c = $(stack-align-test-flags) CFLAGS-msync.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-fdatasync.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-fsync.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-vmsplice.c = -fexceptions -fasynchronous-unwind-tables # Called during static library initialization, so turn stack-protection # off for non-shared builds. diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 9388623345..7d1f3d3197 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -17,7 +17,7 @@ include $(firstword $(wildcard $(sysdirs:=/sysctl.mk))) sysdep_routines += clone umount umount2 readahead \ setfsuid setfsgid epoll_pwait signalfd \ eventfd eventfd_read eventfd_write prlimit \ - personality epoll_wait tee + personality epoll_wait tee vmsplice CFLAGS-gethostid.c = -fexceptions CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index c69eff4432..9d7bd658af 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -72,7 +72,6 @@ swapoff - swapoff i:s __swapoff swapoff unshare EXTRA unshare i:i unshare uselib EXTRA uselib i:s __compat_uselib uselib@GLIBC_2.0:GLIBC_2.23 utime - utime i:sP utime -vmsplice EXTRA vmsplice Ci:iPii vmsplice wait4 - wait4 i:iWiP __wait4 wait4 chown - chown i:sii __libc_chown __chown chown diff --git a/sysdeps/unix/sysv/linux/vmsplice.c b/sysdeps/unix/sysv/linux/vmsplice.c new file mode 100644 index 0000000000..01dac13a51 --- /dev/null +++ b/sysdeps/unix/sysv/linux/vmsplice.c @@ -0,0 +1,27 @@ +/* Splice user pages into a pipe Linux implementation. + Copyright (C) 2017 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 + . */ + +#include +#include +#include + +ssize_t +vmsplice (int fd, const struct iovec *iov, size_t count, unsigned int flags) +{ + return SYSCALL_CANCEL (vmsplice, fd, iov, count, flags); +} -- cgit v1.2.3 From afbbc18f9e253194cd05252a8d3b93fe97a777c1 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 2 Nov 2015 11:22:30 -0200 Subject: linux: Consolidate Linux splice syscall This patch consolidates the splice Linux syscall generation on sysdeps/unix/sysv/linux/splice.c. It basically removes it from architectures auto-generation list. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add splice. (CFLAGS-splice.c): New flag. * sysdeps/unix/sysv/linux/splice.c: New file. * sysdeps/unix/sysv/linux/syscalls.list (splice): Remove from auto-generation syscall list. * misc/Makefile (CFLAGS-splice.c): New rule. --- ChangeLog | 7 +++++++ misc/Makefile | 1 + sysdeps/unix/sysv/linux/Makefile | 2 +- sysdeps/unix/sysv/linux/splice.c | 27 +++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/syscalls.list | 1 - 5 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/splice.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index bc92bfc73d..0ce006319a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2017-05-18 Adhemerval Zanella + * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add splice. + (CFLAGS-splice.c): New flag. + * sysdeps/unix/sysv/linux/splice.c: New file. + * sysdeps/unix/sysv/linux/syscalls.list (splice): Remove from + auto-generation syscall list. + * misc/Makefile (CFLAGS-splice.c): New rule. + * sysdeps/unix/sysv/linux/Makefile (CFLAGS-vmsplice.c): New flag. * sysdeps/unix/sysv/linux/syscalls.list (vmsplice): Remove from auto-generation syscall list. diff --git a/misc/Makefile b/misc/Makefile index c4a75b5908..e4fe468467 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -112,6 +112,7 @@ CFLAGS-msync.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-fdatasync.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-fsync.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-vmsplice.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-splice.c = -fexceptions -fasynchronous-unwind-tables # Called during static library initialization, so turn stack-protection # off for non-shared builds. diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 7d1f3d3197..c1f6e24775 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -17,7 +17,7 @@ include $(firstword $(wildcard $(sysdirs:=/sysctl.mk))) sysdep_routines += clone umount umount2 readahead \ setfsuid setfsgid epoll_pwait signalfd \ eventfd eventfd_read eventfd_write prlimit \ - personality epoll_wait tee vmsplice + personality epoll_wait tee vmsplice splice CFLAGS-gethostid.c = -fexceptions CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables diff --git a/sysdeps/unix/sysv/linux/splice.c b/sysdeps/unix/sysv/linux/splice.c new file mode 100644 index 0000000000..2aaf878c60 --- /dev/null +++ b/sysdeps/unix/sysv/linux/splice.c @@ -0,0 +1,27 @@ +/* Splice data to/from a pipe Linux implementation. + Copyright (C) 2017 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 + . */ + +#include +#include + +ssize_t +splice (int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, + unsigned int flags) +{ + return SYSCALL_CANCEL (splice, fd_in, off_in, fd_out, off_out, len, flags); +} diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 9d7bd658af..b40825afbd 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -64,7 +64,6 @@ setfsgid EXTRA setfsgid i:i setfsgid setfsuid EXTRA setfsuid i:i setfsuid setpgid - setpgid i:ii __setpgid setpgid sigaltstack - sigaltstack i:PP __sigaltstack sigaltstack -splice EXTRA splice Ci:iPiPii splice stime - stime i:p stime sysinfo EXTRA sysinfo i:p __sysinfo sysinfo swapon - swapon i:si __swapon swapon -- cgit v1.2.3 From a5a34d2eaf717fb95a33553170000fb147ded444 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 2 Nov 2015 11:42:09 -0200 Subject: linux: Consolidate Linux open_by_handle_at syscall This patch consolidates the open_by_handle_at Linux syscall generation on sysdeps/unix/sysv/linux/open_by_handle_at.c. It basically removes it from architectures auto-generation list. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add open_by_handle_at. (CFLAGS-open_by_handle_at.c): New flag. * sysdeps/unix/sysv/linux/open_by_handle_at.c: New file. * sysdeps/unix/sysv/linux/syscalls.list (open_by_handle_at): New file. * misc/Makefile (CFLAGS-open_by_handle_at.c): New rule. --- ChangeLog | 8 +++++++ misc/Makefile | 1 + sysdeps/unix/sysv/linux/Makefile | 3 ++- sysdeps/unix/sysv/linux/open_by_handle_at.c | 37 +++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/syscalls.list | 1 - 5 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/open_by_handle_at.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 0ce006319a..3e846a0506 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2017-05-18 Adhemerval Zanella + * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add + open_by_handle_at. + (CFLAGS-open_by_handle_at.c): New flag. + * sysdeps/unix/sysv/linux/open_by_handle_at.c: New file. + * sysdeps/unix/sysv/linux/syscalls.list (open_by_handle_at): New + file. + * misc/Makefile (CFLAGS-open_by_handle_at.c): New rule. + * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add splice. (CFLAGS-splice.c): New flag. * sysdeps/unix/sysv/linux/splice.c: New file. diff --git a/misc/Makefile b/misc/Makefile index e4fe468467..38beb00d8e 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -113,6 +113,7 @@ CFLAGS-fdatasync.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-fsync.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-vmsplice.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-splice.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-open_by_handle_at.c = -fexceptions -fasynchronous-unwind-tables # Called during static library initialization, so turn stack-protection # off for non-shared builds. diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index c1f6e24775..45c05f1029 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -17,7 +17,8 @@ include $(firstword $(wildcard $(sysdirs:=/sysctl.mk))) sysdep_routines += clone umount umount2 readahead \ setfsuid setfsgid epoll_pwait signalfd \ eventfd eventfd_read eventfd_write prlimit \ - personality epoll_wait tee vmsplice splice + personality epoll_wait tee vmsplice splice \ + open_by_handle_at CFLAGS-gethostid.c = -fexceptions CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables diff --git a/sysdeps/unix/sysv/linux/open_by_handle_at.c b/sysdeps/unix/sysv/linux/open_by_handle_at.c new file mode 100644 index 0000000000..e69f041280 --- /dev/null +++ b/sysdeps/unix/sysv/linux/open_by_handle_at.c @@ -0,0 +1,37 @@ +/* Obtain handle for an open file via a handle. Linux implementation. + Copyright (C) 2017 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 + . */ + +#include +#include +#include +#include + +int +open_by_handle_at (int mount_fd, struct file_handle *handle, int flags) +{ +#ifdef __NR_open_by_handle_at + return SYSCALL_CANCEL (open_by_handle_at, mount_fd, handle, flags); +#else + __set_errno (ENOSYS); + return -1; +#endif +} + +#ifndef __NR_open_by_handle_at +stub_warning (open_by_handle_at) +#endif diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index b40825afbd..a8d1299939 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -106,7 +106,6 @@ timerfd_gettime EXTRA timerfd_gettime i:ip timerfd_gettime fanotify_init EXTRA fanotify_init i:ii fanotify_init name_to_handle_at EXTRA name_to_handle_at i:isppi name_to_handle_at -open_by_handle_at EXTRA open_by_handle_at Ci:ipi open_by_handle_at setns EXTRA setns i:ii setns -- cgit v1.2.3 From a5fdd305970adc9b245f97dd18ff813efea36484 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Wed, 4 Nov 2015 10:32:58 -0200 Subject: posix: Consolidate Linux mq_timedreceive syscall This patch consolidates the mq_timedreceive Linux syscall generation on sysdeps/unix/sysv/linux/mq_timedreceive.c. It basically removes it from architecture auto-generation list. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. * rt/Makefile (CFLAGS-mq_timedreceive.c): New flag. * sysdeps/unix/sysv/linux/mq_timedreceive.c: New file. * sysdeps/unix/sysv/linux/syscalls.list (mq_timedreceive): Remove from auto-generation list. --- ChangeLog | 5 +++++ rt/Makefile | 1 + sysdeps/unix/sysv/linux/mq_timedreceive.c | 34 +++++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/syscalls.list | 1 - 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/mq_timedreceive.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 3e846a0506..65784a9061 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2017-05-18 Adhemerval Zanella + * rt/Makefile (CFLAGS-mq_timedreceive.c): New flag. + * sysdeps/unix/sysv/linux/mq_timedreceive.c: New file. + * sysdeps/unix/sysv/linux/syscalls.list (mq_timedreceive): Remove + from auto-generation list. + * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add open_by_handle_at. (CFLAGS-open_by_handle_at.c): New flag. diff --git a/rt/Makefile b/rt/Makefile index 52838391d7..0ffa12db4c 100644 --- a/rt/Makefile +++ b/rt/Makefile @@ -61,6 +61,7 @@ extra-libs-others := $(extra-libs) include ../Rules CFLAGS-aio_suspend.c = -fexceptions +CFLAGS-mq_timedreceive.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-clock_nanosleep.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-librt-cancellation.c = -fasynchronous-unwind-tables diff --git a/sysdeps/unix/sysv/linux/mq_timedreceive.c b/sysdeps/unix/sysv/linux/mq_timedreceive.c new file mode 100644 index 0000000000..6d1c145c24 --- /dev/null +++ b/sysdeps/unix/sysv/linux/mq_timedreceive.c @@ -0,0 +1,34 @@ +/* Receive a message from a message queue with a timeout. Linux version. + Copyright (C) 2017 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 + . */ + +#include +#include + +/* Receive the oldest from highest priority messages in message queue + MQDES, stop waiting if ABS_TIMEOUT expires. */ +ssize_t +__mq_timedreceive (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len, + unsigned int *__restrict msg_prio, + const struct timespec *__restrict abs_timeout) +{ + return SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, msg_len, msg_prio, + abs_timeout); +} +hidden_def (__mq_timedreceive) +weak_alias (__mq_timedreceive, mq_timedreceive) +hidden_weak (mq_timedreceive) diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index a8d1299939..63914bcc82 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -96,7 +96,6 @@ lremovexattr - lremovexattr i:ss lremovexattr fremovexattr - fremovexattr i:is fremovexattr mq_timedsend - mq_timedsend Ci:ipiip __mq_timedsend mq_timedsend -mq_timedreceive - mq_timedreceive Ci:ipipp __mq_timedreceive mq_timedreceive mq_setattr - mq_getsetattr i:ipp mq_setattr timerfd_create EXTRA timerfd_create i:ii timerfd_create -- cgit v1.2.3 From 332e01c6276e05ece5953007c98aa84725c4fda4 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Wed, 4 Nov 2015 10:40:20 -0200 Subject: posix: Consolidate Linux mq_timedsend syscall This patch consolidates the mq_timedsend Linux syscall generation on sysdeps/unix/sysv/linux/mq_timedsend.c. It basically removes it from architecture auto-generation list. Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, arch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. * rt/Makefile (CFLAGS-mq_timedsend.c): New flag. * sysdeps/unix/sysv/linux/mq_timedsend.c: New file. * sysdeps/unix/sysv/linux/syscalls.list (mq_timedsend): Remove from auto-generation list. --- ChangeLog | 5 +++++ rt/Makefile | 1 + sysdeps/unix/sysv/linux/mq_timedsend.c | 33 +++++++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/syscalls.list | 1 - 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/mq_timedsend.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 65784a9061..527e4e4776 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2017-05-18 Adhemerval Zanella + * rt/Makefile (CFLAGS-mq_timedsend.c): New flag. + * sysdeps/unix/sysv/linux/mq_timedsend.c: New file. + * sysdeps/unix/sysv/linux/syscalls.list (mq_timedsend): Remove from + auto-generation list. + * rt/Makefile (CFLAGS-mq_timedreceive.c): New flag. * sysdeps/unix/sysv/linux/mq_timedreceive.c: New file. * sysdeps/unix/sysv/linux/syscalls.list (mq_timedreceive): Remove diff --git a/rt/Makefile b/rt/Makefile index 0ffa12db4c..9740dc2ad8 100644 --- a/rt/Makefile +++ b/rt/Makefile @@ -62,6 +62,7 @@ include ../Rules CFLAGS-aio_suspend.c = -fexceptions CFLAGS-mq_timedreceive.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-mq_timedsend.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-clock_nanosleep.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-librt-cancellation.c = -fasynchronous-unwind-tables diff --git a/sysdeps/unix/sysv/linux/mq_timedsend.c b/sysdeps/unix/sysv/linux/mq_timedsend.c new file mode 100644 index 0000000000..799555440e --- /dev/null +++ b/sysdeps/unix/sysv/linux/mq_timedsend.c @@ -0,0 +1,33 @@ +/* Send a message to a message queue with a timeout. Linux version. + Copyright (C) 2017 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 + . */ + +#include +#include + +/* Add message pointed by MSG_PTR to message queue MQDES, stop blocking + on full message queue if ABS_TIMEOUT expires. */ +int +__mq_timedsend (mqd_t mqdes, const char *msg_ptr, size_t msg_len, + unsigned int msg_prio, const struct timespec *abs_timeout) +{ + return SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, msg_len, msg_prio, + abs_timeout); +} +hidden_def (__mq_timedsend) +weak_alias (__mq_timedsend, mq_timedsend) +hidden_weak (mq_timedsend) diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 63914bcc82..8bfb080d80 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -95,7 +95,6 @@ removexattr - removexattr i:ss removexattr lremovexattr - lremovexattr i:ss lremovexattr fremovexattr - fremovexattr i:is fremovexattr -mq_timedsend - mq_timedsend Ci:ipiip __mq_timedsend mq_timedsend mq_setattr - mq_getsetattr i:ipp mq_setattr timerfd_create EXTRA timerfd_create i:ii timerfd_create -- cgit v1.2.3 From 59d2cbb1fe4b8601d5cbd359c3806973eab6c62d Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Thu, 23 Nov 2017 10:00:40 +0100 Subject: Linux: Add memfd_create system call wrapper The system call is somewhat obscure because it is closely related to file descriptor sealing. However, it is also the recommended way to create alias mappings, which is why it has more general use. No emulation is provided. Except for the name of the /proc/self/fd links, it would be possible to implement an approximation using O_TMPFILE and tmpfs, but this does not appear to be worth the added complexity. Reviewed-by: Adhemerval Zanella Reviewed-by: Christian Brauner --- ChangeLog | 14 +++ NEWS | 2 + manual/llio.texi | 63 +++++++++++ sysdeps/unix/sysv/linux/Makefile | 2 +- sysdeps/unix/sysv/linux/Versions | 3 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/libc.abilist | 1 + sysdeps/unix/sysv/linux/bits/mman-linux.h | 16 +++ sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist | 1 + sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + sysdeps/unix/sysv/linux/microblaze/libc.abilist | 1 + .../unix/sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../unix/sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../unix/sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../linux/powerpc/powerpc32/nofpu/libc.abilist | 1 + .../sysv/linux/powerpc/powerpc64/libc-le.abilist | 1 + .../unix/sysv/linux/powerpc/powerpc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist | 1 + sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/libc.abilist | 1 + sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist | 1 + sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/syscalls.list | 1 + .../sysv/linux/tile/tilegx/tilegx32/libc.abilist | 1 + .../sysv/linux/tile/tilegx/tilegx64/libc.abilist | 1 + sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist | 1 + sysdeps/unix/sysv/linux/tst-memfd_create.c | 121 +++++++++++++++++++++ sysdeps/unix/sysv/linux/x86_64/64/libc.abilist | 1 + sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 36 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/tst-memfd_create.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index a84f970761..04fac09f2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2017-11-23 Florian Weimer + + Linux: Add memfd_create system call wrapper + * sysdeps/unix/sysv/linux/Makefile [misc] (tests): Add + tst-memfd_create. + * sysdeps/unix/sysv/linux/bits/mman-linux.h [__USE_GNU] + (MFD_CLOEXEC, MFD_ALLOW_SEALING): Define. + [__USE_GNU] (memfd_create): Declare. + * sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add memfd_create. + * sysdeps/unix/sysv/linux/syscalls.list (memfd_create): Add. + * sysdeps/unix/sysv/linux/tst-memfd_create.c: New file. + * sysdeps/unix/sysv/linux/**.abilist: Update. + * manual/llio.texi (Memory-mapped I/O): Document memfd_create. + 2017-11-22 Joseph Myers * localedata/gen-locale.sh: Fix typo in variable name. diff --git a/NEWS b/NEWS index 30ff04ea62..ab14d1eb1b 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,8 @@ Major new features: are the same interfaces added in version 2.26 for some platforms where this format is supported but is not the format of long double. +* glibc now implements the memfd_create function on Linux. + Deprecated and removed features, and other changes affecting compatibility: * On GNU/Linux, the obsolete Linux constant PTRACE_SEIZE_DEVEL is no longer diff --git a/manual/llio.texi b/manual/llio.texi index 41c3e068d1..8b2f599c79 100644 --- a/manual/llio.texi +++ b/manual/llio.texi @@ -1801,6 +1801,69 @@ the given @var{name} previously created by @code{shm_open}. On failure @code{errno} is set. @end deftypefn +@deftypefun int memfd_create (const char *@var{name}, unsigned int @var{flags}) +@standards{Linux, sys/mman.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} +The @code{memfd_create} function returns a file descriptor which can be +used to create memory mappings using the @code{mmap} function. It is +similar to the @code{shm_open} function in the sense that these mappings +are not backed by actual files. However, the descriptor returned by +@code{memfd_create} does not correspond to a named object; the +@var{name} argument is used for debugging purposes only (e.g., will +appear in @file{/proc}), and separate invocations of @code{memfd_create} +with the same @var{name} will not return descriptors for the same region +of memory. The descriptor can also be used to create alias mappings +within the same process. + +The descriptor initially refers to a zero-length file. Before mappings +can be created which are backed by memory, the file size needs to be +increased with the @code{ftruncate} function. @xref{File Size}. + +The @var{flags} argument can be a combination of the following flags: + +@vtable @code +@item MFD_CLOEXEC +@standards{Linux, sys/mman.h} +The descriptor is created with the @code{O_CLOEXEC} flag. + +@item MFD_ALLOW_SEALING +@standards{Linux, sys/mman.h} +The descriptor supports the addition of seals using the @code{fcntl} +function. + +@item MFD_HUGETLB +@standards{Linux, sys/mman.h} +This requests that mappings created using the returned file descriptor +use a larger page size. See @code{MAP_HUGETLB} above for details. + +This flag is incompatible with @code{MFD_ALLOW_SEALING}. +@end vtable + +@code{memfd_create} returns a file descriptor on success, and @math{-1} +on failure. + +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EINVAL +An invalid combination is specified in @var{flags}, or @var{name} is +too long. + +@item EFAULT +The @var{name} argument does not point to a string. + +@item EMFILE +The operation would exceed the file descriptor limit for this process. + +@item ENFILE +The operation would exceed the system-wide file descriptor limit. + +@item ENOMEM +There is not enough memory for the operation. +@end table +@end deftypefun + @node Waiting for I/O @section Waiting for Input or Output @cindex waiting for input or output diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index c6675b3aa5..c484d2688a 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -44,7 +44,7 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ - test-errno-linux + test-errno-linux tst-memfd_create # Generate the list of SYS_* macros for the system calls (__NR_* # macros). The file syscall-names.list contains all possible system diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index d3dbcde8c9..6f2fe516d7 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -166,6 +166,9 @@ libc { GLIBC_2.15 { process_vm_readv; process_vm_writev; } + GLIBC_2.27 { + memfd_create; + } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index ed598aedac..140ca28abc 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2106,6 +2106,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.27 strfromf128 F GLIBC_2.27 strtof128 F GLIBC_2.27 strtof128_l F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 4e57f36bcf..f698e1b2f4 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2017,6 +2017,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.27 strfromf128 F GLIBC_2.27 strtof128 F GLIBC_2.27 strtof128_l F diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist index 5b70e1bfc9..8a8af3e3e4 100644 --- a/sysdeps/unix/sysv/linux/arm/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist @@ -107,6 +107,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.4 GLIBC_2.4 A GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/bits/mman-linux.h b/sysdeps/unix/sysv/linux/bits/mman-linux.h index 78c07c890a..1ffa5490af 100644 --- a/sysdeps/unix/sysv/linux/bits/mman-linux.h +++ b/sysdeps/unix/sysv/linux/bits/mman-linux.h @@ -111,3 +111,19 @@ # define MCL_ONFAULT 4 /* Lock all pages that are faulted in. */ #endif + +#ifdef __USE_GNU +/* Flags for memfd_create. */ +# define MFD_CLOEXEC 1U +# define MFD_ALLOW_SEALING 2U +# define MFD_HUGETLB 4U + +__BEGIN_DECLS + +/* Create a new memory file descriptor. NAME is a name for debugging. + FLAGS is a combination of the MFD_* constants. */ +int memfd_create (const char *__name, unsigned int __flags) __THROW; + +__END_DECLS + +#endif /* __USE_GNU */ diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 6a2500a8b3..5b81a6cd7d 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -1871,6 +1871,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 9ab4e3642a..51ead9e867 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2036,6 +2036,7 @@ GLIBC_2.26 wcstof128_l F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 81bb623fe8..78b4ee8d40 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -1900,6 +1900,7 @@ GLIBC_2.26 wcstof128_l F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 5a33b57390..d9c97779e4 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.4 GLIBC_2.4 A GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 50a86e74fa..4acbf7eeed 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -1985,6 +1985,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist index 250ef305c3..93f02f08ce 100644 --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist @@ -2106,3 +2106,4 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 87a1dc4ad7..795e85de70 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -1960,6 +1960,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index f2b35f250e..dc714057b7 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -1958,6 +1958,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index ade654dbea..ce7bc9b175 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -1956,6 +1956,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.27 strfromf128 F GLIBC_2.27 strtof128 F GLIBC_2.27 strtof128_l F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 56032c3f82..3fdd85eace 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -1951,6 +1951,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.27 strfromf128 F GLIBC_2.27 strtof128 F GLIBC_2.27 strtof128_l F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index c599dd9212..3e0bcb2a5c 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2147,3 +2147,4 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 385409aa6e..375c69d9d1 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index e99cb454b5..a88172a906 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -1994,6 +1994,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist index 173672ab5e..fa026a332c 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist @@ -2201,3 +2201,4 @@ GLIBC_2.26 wcstof128_l F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist index 8a654436ab..838f395d78 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist @@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 _Exit F GLIBC_2.3 _IO_2_1_stderr_ D 0xe0 diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index dbd411ceb1..41b79c496a 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.27 strfromf128 F GLIBC_2.27 strtof128 F GLIBC_2.27 strtof128_l F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 5617784ca0..68251a0e69 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -1890,6 +1890,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.27 strfromf128 F GLIBC_2.27 strtof128 F GLIBC_2.27 strtof128_l F diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist index 0f840e6e88..bc1aae275e 100644 --- a/sysdeps/unix/sysv/linux/sh/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist @@ -1875,6 +1875,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index bb7e1042c7..93e6d092ac 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -1982,6 +1982,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.27 strfromf128 F GLIBC_2.27 strtof128 F GLIBC_2.27 strtof128_l F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 4053b0a51c..b11d6764d4 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -1919,6 +1919,7 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.27 strfromf128 F GLIBC_2.27 strtof128 F GLIBC_2.27 strtof128_l F diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 8bfb080d80..40c4fbb9ea 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -109,3 +109,4 @@ setns EXTRA setns i:ii setns process_vm_readv EXTRA process_vm_readv i:ipipii process_vm_readv process_vm_writev EXTRA process_vm_writev i:ipipii process_vm_writev +memfd_create EXTRA memfd_create i:si memfd_create diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist index 38a96d3a02..e9eb4ff7bd 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist index 572b917d7d..8f08e909cd 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist index 38a96d3a02..e9eb4ff7bd 100644 --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F diff --git a/sysdeps/unix/sysv/linux/tst-memfd_create.c b/sysdeps/unix/sysv/linux/tst-memfd_create.c new file mode 100644 index 0000000000..fd173ff71d --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-memfd_create.c @@ -0,0 +1,121 @@ +/* Test for the memfd_create system call. + Copyright (C) 2017 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Return true if the descriptor has the FD_CLOEXEC flag set. */ +static bool +is_cloexec (int fd) +{ + int flags = fcntl (fd, F_GETFD); + TEST_VERIFY (flags >= 0); + return flags & FD_CLOEXEC; +} + +/* Return the seals set on FD. */ +static int +get_seals (int fd) +{ + int flags = fcntl (fd, F_GET_SEALS); + TEST_VERIFY (flags >= 0); + return flags; +} + +/* Return true if the F_SEAL_SEAL flag is set on the descriptor. */ +static bool +is_sealed (int fd) +{ + return get_seals (fd) & F_SEAL_SEAL; +} + +static int +do_test (void) +{ + /* Initialized by the first call to memfd_create to 0 (memfd_create + unsupported) or 1 (memfd_create is implemented in the kernel). + Subsequent iterations check that the success/failure state is + consistent. */ + int supported = -1; + + for (int do_cloexec = 0; do_cloexec < 2; ++do_cloexec) + for (int do_sealing = 0; do_sealing < 2; ++do_sealing) + { + int flags = 0; + if (do_cloexec) + flags |= MFD_CLOEXEC; + if (do_sealing) + flags |= MFD_ALLOW_SEALING; + if (test_verbose > 0) + printf ("info: memfd_create with flags=0x%x\n", flags); + int fd = memfd_create ("tst-memfd_create", flags); + if (fd < 0) + { + if (errno == ENOSYS) + { + if (supported < 0) + { + printf ("warning: memfd_create is unsupported\n"); + supported = 0; + continue; + } + TEST_VERIFY (supported == 0); + continue; + } + else + FAIL_EXIT1 ("memfd_create: %m"); + } + if (supported < 0) + supported = 1; + TEST_VERIFY (supported > 0); + + char *fd_path = xasprintf ("/proc/self/fd/%d", fd); + char *link = xreadlink (fd_path); + if (test_verbose > 0) + printf ("info: memfd link: %s\n", link); + TEST_VERIFY (strcmp (link, "memfd:tst-memfd_create (deleted)")); + TEST_VERIFY (is_cloexec (fd) == do_cloexec); + TEST_VERIFY (is_sealed (fd) == !do_sealing); + if (do_sealing) + { + TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_WRITE) == 0); + TEST_VERIFY (!is_sealed (fd)); + TEST_VERIFY (get_seals (fd) & F_SEAL_WRITE); + TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_SEAL) == 0); + TEST_VERIFY (is_sealed (fd)); + } + xclose (fd); + free (fd_path); + free (link); + } + + if (supported == 0) + return EXIT_UNSUPPORTED; + return 0; +} + +#include diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index b83d25c2e3..0a4f7797ac 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -1877,6 +1877,7 @@ GLIBC_2.26 wcstof128_l F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index cba1d59057..23f6a91429 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2120,3 +2120,4 @@ GLIBC_2.26 wcstof128_l F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 glob F GLIBC_2.27 glob64 F +GLIBC_2.27 memfd_create F -- cgit v1.2.3 From 446d22e91d3113be57a4b0d1151cf337458c3bec Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Tue, 5 Dec 2017 15:20:30 +0100 Subject: Linux: Implement interfaces for memory protection keys This adds system call wrappers for pkey_alloc, pkey_free, pkey_mprotect, and x86-64 implementations of pkey_get and pkey_set, which abstract over the PKRU CPU register and hide the actual number of memory protection keys supported by the CPU. pkey_mprotect with a -1 key is implemented using mprotect, so it will work even if the kernel does not support the pkey_mprotect system call. The system call wrapers use unsigned int instead of unsigned long for parameters, so that no special treatment for x32 is needed. The flags argument is currently unused, and the access rights bit mask is limited to two bits by the current PKRU register layout anyway. Reviewed-by: Adhemerval Zanella --- ChangeLog | 34 ++ NEWS | 4 + manual/memory.texi | 232 ++++++++++++ support/Makefile | 6 +- support/xraise.c | 27 ++ support/xsigaction.c | 27 ++ support/xsignal.c | 29 ++ support/xsignal.h | 8 + support/xsysconf.c | 36 ++ support/xunistd.h | 1 + sysdeps/unix/sysv/linux/Makefile | 6 +- sysdeps/unix/sysv/linux/Versions | 1 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 5 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 5 + sysdeps/unix/sysv/linux/arm/libc.abilist | 5 + sysdeps/unix/sysv/linux/bits/mman-shared.h | 28 ++ sysdeps/unix/sysv/linux/bits/siginfo-consts.h | 6 +- sysdeps/unix/sysv/linux/hppa/libc.abilist | 5 + sysdeps/unix/sysv/linux/i386/libc.abilist | 5 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 5 + sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist | 5 + sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist | 5 + sysdeps/unix/sysv/linux/microblaze/libc.abilist | 5 + .../unix/sysv/linux/mips/mips32/fpu/libc.abilist | 5 + .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist | 5 + .../unix/sysv/linux/mips/mips64/n32/libc.abilist | 5 + .../unix/sysv/linux/mips/mips64/n64/libc.abilist | 5 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 5 + sysdeps/unix/sysv/linux/pkey_get.c | 26 ++ sysdeps/unix/sysv/linux/pkey_mprotect.c | 37 ++ sysdeps/unix/sysv/linux/pkey_set.c | 26 ++ .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist | 5 + .../linux/powerpc/powerpc32/nofpu/libc.abilist | 5 + .../sysv/linux/powerpc/powerpc64/libc-le.abilist | 5 + .../unix/sysv/linux/powerpc/powerpc64/libc.abilist | 5 + sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist | 5 + sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist | 5 + sysdeps/unix/sysv/linux/sh/libc.abilist | 5 + sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist | 5 + sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist | 5 + sysdeps/unix/sysv/linux/syscalls.list | 2 + .../sysv/linux/tile/tilegx/tilegx32/libc.abilist | 5 + .../sysv/linux/tile/tilegx/tilegx64/libc.abilist | 5 + sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist | 5 + sysdeps/unix/sysv/linux/tst-pkey.c | 399 +++++++++++++++++++++ sysdeps/unix/sysv/linux/x86/arch-pkey.h | 40 +++ sysdeps/unix/sysv/linux/x86/pkey_get.c | 33 ++ sysdeps/unix/sysv/linux/x86/pkey_set.c | 35 ++ sysdeps/unix/sysv/linux/x86_64/64/libc.abilist | 5 + sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist | 5 + 50 files changed, 1179 insertions(+), 4 deletions(-) create mode 100644 support/xraise.c create mode 100644 support/xsigaction.c create mode 100644 support/xsignal.c create mode 100644 support/xsysconf.c create mode 100644 sysdeps/unix/sysv/linux/pkey_get.c create mode 100644 sysdeps/unix/sysv/linux/pkey_mprotect.c create mode 100644 sysdeps/unix/sysv/linux/pkey_set.c create mode 100644 sysdeps/unix/sysv/linux/tst-pkey.c create mode 100644 sysdeps/unix/sysv/linux/x86/arch-pkey.h create mode 100644 sysdeps/unix/sysv/linux/x86/pkey_get.c create mode 100644 sysdeps/unix/sysv/linux/x86/pkey_set.c (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 50ae82ba1d..333012ba81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,37 @@ +2017-12-05 Florian Weimer + + Linux: Implement interfaces for memory protection keys + * support/Makefile (libsupport-routines): Add xraise, xsigaction, + xsignal, xsysconf. + * support/xsignal.h (xraise, xsignal, xsigaction): Declare. + * support/xunistd.h (xsysconf): Declare. + * support/xraise.c: New file. + * support/xsigaction.c: Likewise. + * support/xsignal.c: Likewise. + * support/xsysconf.c: Likewise. + * sysdeps/unix/sysv/linux/Makefile [misc] (routines): Add + pkey_set, pkey_get, pkey_mprotect. + [misc] (tests): Add tst-pkey. + (tst-pkey): Link with -lpthread. + * sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add pkey_alloc, + pkey_free, pkey_set, pkey_get, pkey_mprotect. + * sysdeps/unix/sysv/linux/bits/mman-linux.h (PKEY_DISABLE_ACCESS) + (PKEY_DISABLE_WRITE): Define. + (pkey_alloc, pkey_free, pkey_set, pkey_get, pkey_mprotect): + Declare. + * sysdeps/unix/sysv/linux/bits/siginfo-consts.h (SEGV_BNDERR) + (SEGV_PKUERR): Add. + * sysdeps/unix/sysv/linux/pkey_get.c: New file. + * sysdeps/unix/sysv/linux/pkey_set.c: Likewise. + * sysdeps/unix/sysv/linux/pkey_mprotect.c: Likewise. + * sysdeps/unix/sysv/linux/syscalls.list (pkey_alloc, pkey_free): + Add. + * sysdeps/unix/sysv/linux/tst-pkey.c: New file. + * sysdeps/unix/sysv/linux/x86/arch-pkey.h: Likewise. + * sysdeps/unix/sysv/linux/x86/pkey_get.c: Likewise. + * sysdeps/unix/sysv/linux/x86/pkey_set.c: Likewise. + * sysdeps/unix/sysv/linux/**.abilist: Update. + 2017-12-05 Florian Weimer * support/tst-test_compare.c (subprocess): Use long long instead diff --git a/NEWS b/NEWS index 10f695aab1..6b1a2f92f7 100644 --- a/NEWS +++ b/NEWS @@ -43,6 +43,10 @@ Major new features: * glibc now implements the memfd_create and mlock2 functions on Linux. +* Support for memory protection keys was added. The header now + declares the functions pkey_alloc, pkey_free, pkey_mprotect, pkey_set, + pkey_get. + Deprecated and removed features, and other changes affecting compatibility: * On GNU/Linux, the obsolete Linux constant PTRACE_SEIZE_DEVEL is no longer diff --git a/manual/memory.texi b/manual/memory.texi index 1b431bf5da..b95f6aa1b9 100644 --- a/manual/memory.texi +++ b/manual/memory.texi @@ -3171,6 +3171,238 @@ process memory, no matter how it was allocated. However, portable use of the function requires that it is only used with memory regions returned by @code{mmap} or @code{mmap64}. +@subsection Memory Protection Keys + +@cindex memory protection key +@cindex protection key +@cindex MPK +On some systems, further restrictions can be added to specific pages +using @dfn{memory protection keys}. These restrictions work as follows: + +@itemize @bullet +@item +All memory pages are associated with a protection key. The default +protection key does not cause any additional protections to be applied +during memory accesses. New keys can be allocated with the +@code{pkey_alloc} function, and applied to pages using +@code{pkey_mprotect}. + +@item +Each thread has a set of separate access right restriction for each +protection key. These access rights can be manipulated using the +@code{pkey_set} and @code{pkey_get} functions. + +@item +During a memory access, the system obtains the protection key for the +accessed page and uses that to determine the applicable access rights, +as configured for the current thread. If the access is restricted, a +segmentation fault is the result ((@pxref{Program Error Signals}). +These checks happen in addition to the @code{PROT_}* protection flags +set by @code{mprotect} or @code{pkey_mprotect}. +@end itemize + +New threads and subprocesses inherit the access rights of the current +thread. If a protection key is allocated subsequently, existing threads +(except the current) will use an unspecified system default for the +access rights associated with newly allocated keys. + +Upon entering a signal handler, the system resets the access rights of +the current thread so that pages with the default key can be accessed, +but the access rights for other protection keys are unspecified. + +Applications are expected to allocate a key once using +@code{pkey_alloc}, and apply the key to memory regions which need +special protection with @code{pkey_mprotect}: + +@smallexample + int key = pkey_alloc (0, PKEY_DISABLE_ACCESS); + if (key < 0) + /* Perform error checking, including fallback for lack of support. */ + ...; + + /* Apply the key to a special memory region used to store critical + data. */ + if (pkey_mprotect (region, region_length, + PROT_READ | PROT_WRITE, key) < 0) + ...; /* Perform error checking (generally fatal). */ +@end smallexample + +If the key allocation fails due to lack of support for memory protection +keys, the @code{pkey_mprotect} call can usually be skipped. In this +case, the region will not be protected by default. It is also possible +to call @code{pkey_mprotect} with a key value of @math{-1}, in which +case it will behave in the same way as @code{mprotect}. + +After key allocation assignment to memory pages, @code{pkey_set} can be +used to temporarily acquire access to the memory region and relinquish +it again: + +@smallexample + if (key >= 0 && pkey_set (key, 0) < 0) + ...; /* Perform error checking (generally fatal). */ + /* At this point, the current thread has read-write access to the + memory region. */ + ... + /* Revoke access again. */ + if (key >= 0 && pkey_set (key, PKEY_DISABLE_ACCESS) < 0) + ...; /* Perform error checking (generally fatal). */ +@end smallexample + +In this example, a negative key value indicates that no key had been +allocated, which means that the system lacks support for memory +protection keys and it is not necessary to change the the access rights +of the current thread (because it always has access). + +Compared to using @code{mprotect} to change the page protection flags, +this approach has two advantages: It is thread-safe in the sense that +the access rights are only changed for the current thread, so another +thread which changes its own access rights concurrently to gain access +to the mapping will not suddenly see its access rights revoked. And +@code{pkey_set} typically does not involve a call into the kernel and a +context switch, so it is more efficient. + +@deftypefun int pkey_alloc (unsigned int @var{flags}, unsigned int @var{restrictions}) +@standards{Linux, sys/mman.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} +Allocate a new protection key. The @var{flags} argument is reserved and +must be zero. The @var{restrictions} argument specifies access rights +which are applied to the current thread (as if with @code{pkey_set} +below). Access rights of other threads are not changed. + +The function returns the new protection key, a non-negative number, or +@math{-1} on error. + +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item ENOSYS +The system does not implement memory protection keys. + +@item EINVAL +The @var{flags} argument is not zero. + +The @var{restrictions} argument is invalid. + +The system does not implement memory protection keys or runs in a mode +in which memory protection keys are disabled. + +@item ENOSPC +All available protection keys already have been allocated. +@end table +@end deftypefun + +@deftypefun int pkey_free (int @var{key}) +@standards{Linux, sys/mman.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +Deallocate the protection key, so that it can be reused by +@code{pkey_alloc}. + +Calling this function does not change the access rights of the freed +protection key. The calling thread and other threads may retain access +to it, even if it is subsequently allocated again. For this reason, it +is not recommended to call the @code{pkey_free} function. + +@table @code +@item ENOSYS +The system does not implement memory protection keys. + +@item EINVAL +The @var{key} argument is not a valid protection key. +@end table +@end deftypefun + +@deftypefun int pkey_mprotect (void *@var{address}, size_t @var{length}, int @var{protection}, int @var{key}) +@standards{Linux, sys/mman.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +Similar to @code{mprotect}, but also set the memory protection key for +the memory region to @code{key}. + +Some systems use memory protection keys to emulate certain combinations +of @var{protection} flags. Under such circumstances, specifying an +explicit protection key may behave as if additional flags have been +specified in @var{protection}, even though this does not happen with the +default protection key. For example, some systems can support +@code{PROT_EXEC}-only mappings only with a default protection key, and +memory with a key which was allocated using @code{pkey_alloc} will still +be readable if @code{PROT_EXEC} is specified without @code{PROT_READ}. + +If @var{key} is @math{-1}, the default protection key is applied to the +mapping, just as if @code{mprotect} had been called. + +The @code{pkey_mprotect} function returns @math{0} on success and +@math{-1} on failure. The same @code{errno} error conditions as for +@code{mprotect} are defined for this function, with the following +addition: + +@table @code +@item EINVAL +The @var{key} argument is not @math{-1} or a valid memory protection +key allocated using @code{pkey_alloc}. + +@item ENOSYS +The system does not implement memory protection keys, and @var{key} is +not @math{-1}. +@end table +@end deftypefun + +@deftypefun int pkey_set (int @var{key}, unsigned int @var{rights}) +@standards{Linux, sys/mman.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +Change the access rights of the current thread for memory pages with the +protection key @var{key} to @var{rights}. If @var{rights} is zero, no +additional access restrictions on top of the page protection flags are +applied. Otherwise, @var{rights} is a combination of the following +flags: + +@vtable @code +@item PKEY_DISABLE_WRITE +@standards{Linux, sys/mman.h} +Subsequent attempts to write to memory with the specified protection +key will fault. + +@item PKEY_DISABLE_ACCESS +@standards{Linux, sys/mman.h} +Subsequent attempts to write to or read from memory with the specified +protection key will fault. +@end vtable + +Operations not specified as flags are not restricted. In particular, +this means that the memory region will remain executable if it was +mapped with the @code{PROT_EXEC} protection flag and +@code{PKEY_DISABLE_ACCESS} has been specified. + +Calling the @code{pkey_set} function with a protection key which was not +allocated by @code{pkey_alloc} results in undefined behavior. This +means that calling this function on systems which do not support memory +protection keys is undefined. + +The @code{pkey_set} function returns @math{0} on success and @math{-1} +on failure. + +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EINVAL +The system does not support the access rights restrictions expressed in +the @var{rights} argument. +@end table +@end deftypefun + +@deftypefun int pkey_get (int @var{key}) +@standards{Linux, sys/mman.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +Return the access rights of the current thread for memory pages with +protection key @var{key}. The return value is zero or a combination of +the @code{PKEY_DISABLE_}* flags; see the @code{pkey_set} function. + +Calling the @code{pkey_get} function with a protection key which was not +allocated by @code{pkey_alloc} results in undefined behavior. This +means that calling this function on systems which do not support memory +protection keys is undefined. +@end deftypefun + @node Locking Pages @section Locking Pages @cindex locking pages diff --git a/support/Makefile b/support/Makefile index bb81825fc2..bfde79333e 100644 --- a/support/Makefile +++ b/support/Makefile @@ -87,8 +87,8 @@ libsupport-routines = \ xpthread_attr_destroy \ xpthread_attr_init \ xpthread_attr_setdetachstate \ - xpthread_attr_setstacksize \ xpthread_attr_setguardsize \ + xpthread_attr_setstacksize \ xpthread_barrier_destroy \ xpthread_barrier_init \ xpthread_barrier_wait \ @@ -119,14 +119,18 @@ libsupport-routines = \ xpthread_sigmask \ xpthread_spin_lock \ xpthread_spin_unlock \ + xraise \ xreadlink \ xrealloc \ xrecvfrom \ xsendto \ xsetsockopt \ + xsigaction \ + xsignal \ xsocket \ xstrdup \ xstrndup \ + xsysconf \ xunlink \ xwaitpid \ xwrite \ diff --git a/support/xraise.c b/support/xraise.c new file mode 100644 index 0000000000..9126c6c3ea --- /dev/null +++ b/support/xraise.c @@ -0,0 +1,27 @@ +/* Error-checking wrapper for raise. + Copyright (C) 2017 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 + . */ + +#include +#include + +void +xraise (int sig) +{ + if (raise (sig) != 0) + FAIL_EXIT1 ("raise (%d): %m" , sig); +} diff --git a/support/xsigaction.c b/support/xsigaction.c new file mode 100644 index 0000000000..b74c69afae --- /dev/null +++ b/support/xsigaction.c @@ -0,0 +1,27 @@ +/* Error-checking wrapper for sigaction. + Copyright (C) 2017 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 + . */ + +#include +#include + +void +xsigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) +{ + if (sigaction (sig, newact, oldact)) + FAIL_EXIT1 ("sigaction (%d): %m" , sig); +} diff --git a/support/xsignal.c b/support/xsignal.c new file mode 100644 index 0000000000..22a1dd74a7 --- /dev/null +++ b/support/xsignal.c @@ -0,0 +1,29 @@ +/* Error-checking wrapper for signal. + Copyright (C) 2017 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 + . */ + +#include +#include + +sighandler_t +xsignal (int sig, sighandler_t handler) +{ + sighandler_t result = signal (sig, handler); + if (result == SIG_ERR) + FAIL_EXIT1 ("signal (%d, %p): %m", sig, handler); + return result; +} diff --git a/support/xsignal.h b/support/xsignal.h index 3dc0d9d5ce..3087ed0082 100644 --- a/support/xsignal.h +++ b/support/xsignal.h @@ -24,6 +24,14 @@ __BEGIN_DECLS +/* The following functions call the corresponding libc functions and + terminate the process on error. */ + +void xraise (int sig); +sighandler_t xsignal (int sig, sighandler_t handler); +void xsigaction (int sig, const struct sigaction *newact, + struct sigaction *oldact); + /* The following functions call the corresponding libpthread functions and terminate the process on error. */ diff --git a/support/xsysconf.c b/support/xsysconf.c new file mode 100644 index 0000000000..15ab1e26c4 --- /dev/null +++ b/support/xsysconf.c @@ -0,0 +1,36 @@ +/* Error-checking wrapper for sysconf. + Copyright (C) 2017 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 + . */ + +#include +#include +#include + +long +xsysconf (int name) +{ + /* Detect errors by a changed errno value, in case -1 is a valid + value. Make sure that the caller does not see the zero value for + errno. */ + int old_errno = errno; + errno = 0; + long result = sysconf (name); + if (errno != 0) + FAIL_EXIT1 ("sysconf (%d): %m", name); + errno = old_errno; + return result; +} diff --git a/support/xunistd.h b/support/xunistd.h index 05c2626a7b..00376f7aae 100644 --- a/support/xunistd.h +++ b/support/xunistd.h @@ -39,6 +39,7 @@ void xstat (const char *path, struct stat64 *); void xmkdir (const char *path, mode_t); void xchroot (const char *path); void xunlink (const char *path); +long xsysconf (int name); /* Read the link at PATH. The caller should free the returned string with free. */ diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 478f7e3d4d..8a17828d9d 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -18,7 +18,7 @@ sysdep_routines += clone umount umount2 readahead \ setfsuid setfsgid epoll_pwait signalfd \ eventfd eventfd_read eventfd_write prlimit \ personality epoll_wait tee vmsplice splice \ - open_by_handle_at mlock2 + open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get CFLAGS-gethostid.c = -fexceptions CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables @@ -44,7 +44,7 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ - test-errno-linux tst-memfd_create tst-mlock2 + test-errno-linux tst-memfd_create tst-mlock2 tst-pkey # Generate the list of SYS_* macros for the system calls (__NR_* # macros). The file syscall-names.list contains all possible system @@ -92,6 +92,8 @@ $(objpfx)tst-syscall-list.out: \ # Separate object file for access to the constant from the UAPI header. $(objpfx)tst-sysconf-iov_max: $(objpfx)tst-sysconf-iov_max-uapi.o +$(objpfx)tst-pkey: $(shared-thread-library) + endif # $(subdir) == misc ifeq ($(subdir),time) diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index e799b62285..336c13b57d 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -169,6 +169,7 @@ libc { GLIBC_2.27 { memfd_create; mlock2; + pkey_alloc; pkey_free; pkey_set; pkey_get; pkey_mprotect; } GLIBC_PRIVATE { # functions used in other libraries diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 3448d62cee..bae2ebc087 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2108,6 +2108,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf128 F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof128 F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index d064f5445e..16c3c905cb 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2019,6 +2019,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf128 F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof128 F diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist index a5ce7964d0..27ccdabc0c 100644 --- a/sysdeps/unix/sysv/linux/arm/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist @@ -109,6 +109,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.4 GLIBC_2.4 A GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/bits/mman-shared.h b/sysdeps/unix/sysv/linux/bits/mman-shared.h index bee99c2384..9e532adb23 100644 --- a/sysdeps/unix/sysv/linux/bits/mman-shared.h +++ b/sysdeps/unix/sysv/linux/bits/mman-shared.h @@ -33,6 +33,12 @@ # define MLOCK_ONFAULT 1U # endif +/* Access rights for pkey_alloc. */ +# ifndef PKEY_DISABLE_ACCESS +# define PKEY_DISABLE_ACCESS 0x1 +# define PKEY_DISABLE_WRITE 0x2 +# endif + __BEGIN_DECLS /* Create a new memory file descriptor. NAME is a name for debugging. @@ -43,6 +49,28 @@ int memfd_create (const char *__name, unsigned int __flags) __THROW; memory. FLAGS is a combination of the MLOCK_* flags above. */ int mlock2 (const void *__addr, size_t __length, unsigned int __flags) __THROW; +/* Allocate a new protection key, with the PKEY_DISABLE_* bits + specified in ACCESS_RIGHTS. The protection key mask for the + current thread is updated to match the access privilege for the new + key. */ +int pkey_alloc (unsigned int __flags, unsigned int __access_rights) __THROW; + +/* Update the access rights for the current thread for KEY, which must + have been allocated using pkey_alloc. */ +int pkey_set (int __key, unsigned int __access_rights) __THROW; + +/* Return the access rights for the current thread for KEY, which must + have been allocated using pkey_alloc. */ +int pkey_get (int _key) __THROW; + +/* Free an allocated protection key, which must have been allocated + using pkey_alloc. */ +int pkey_free (int __key) __THROW; + +/* Apply memory protection flags for KEY to the specified address + range. */ +int pkey_mprotect (void *__addr, size_t __len, int __prot, int __pkey) __THROW; + __END_DECLS #endif /* __USE_GNU */ diff --git a/sysdeps/unix/sysv/linux/bits/siginfo-consts.h b/sysdeps/unix/sysv/linux/bits/siginfo-consts.h index 525840cea1..e86b933040 100644 --- a/sysdeps/unix/sysv/linux/bits/siginfo-consts.h +++ b/sysdeps/unix/sysv/linux/bits/siginfo-consts.h @@ -111,8 +111,12 @@ enum { SEGV_MAPERR = 1, /* Address not mapped to object. */ # define SEGV_MAPERR SEGV_MAPERR - SEGV_ACCERR /* Invalid permissions for mapped object. */ + SEGV_ACCERR, /* Invalid permissions for mapped object. */ # define SEGV_ACCERR SEGV_ACCERR + SEGV_BNDERR, /* Bounds checking failure. */ +# define SEGV_BNDERR SEGV_BNDERR + SEGV_PKUERR /* Protection key checking failure. */ +# define SEGV_PKUERR SEGV_PKUERR }; /* `si_code' values for SIGBUS signal. */ diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 69ddf15361..d7e656b13b 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -1873,6 +1873,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index a140edd4a3..8e10641162 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2038,6 +2038,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof64x F GLIBC_2.27 strtof64x_l F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 178c0a45ec..81ec4d6761 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -1902,6 +1902,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof64x F GLIBC_2.27 strtof64x_l F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 01d10d907c..9655afe395 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -110,6 +110,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.4 GLIBC_2.4 A GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 3ad08c20bf..2d9cd557ad 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -1987,6 +1987,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist index 6bd7be1929..256117b3a0 100644 --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist @@ -2108,3 +2108,8 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 9b1e890eda..42e4770341 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -1962,6 +1962,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 3eb5b66f8b..a28a21f842 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -1960,6 +1960,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 543a725114..b725205f4f 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -1958,6 +1958,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf128 F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof128 F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index a9198a3936..373801d4f3 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -1953,6 +1953,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf128 F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof128 F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index afacf1ff2d..7ff042045f 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2149,3 +2149,8 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F diff --git a/sysdeps/unix/sysv/linux/pkey_get.c b/sysdeps/unix/sysv/linux/pkey_get.c new file mode 100644 index 0000000000..fc3204c82f --- /dev/null +++ b/sysdeps/unix/sysv/linux/pkey_get.c @@ -0,0 +1,26 @@ +/* Obtaining the thread memory protection key, generic stub. + Copyright (C) 2017 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 + . */ + +#include + +int +pkey_get (int key) +{ + __set_errno (ENOSYS); + return -1; +} diff --git a/sysdeps/unix/sysv/linux/pkey_mprotect.c b/sysdeps/unix/sysv/linux/pkey_mprotect.c new file mode 100644 index 0000000000..a78fe293b2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/pkey_mprotect.c @@ -0,0 +1,37 @@ +/* mprotect with a memory protection key. + Copyright (C) 2017 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 + . */ + +#include +#include +#include +#include + +int +pkey_mprotect (void *addr, size_t len, int prot, int pkey) +{ + if (pkey == -1) + /* If the key is -1, the system call is precisely equivalent to + mprotect. */ + return __mprotect (addr, len, prot); +#ifdef __NR_pkey_mprotect + return INLINE_SYSCALL_CALL (pkey_mprotect, addr, len, prot, pkey); +#else + __set_errno (ENOSYS); + return -1; +#endif +} diff --git a/sysdeps/unix/sysv/linux/pkey_set.c b/sysdeps/unix/sysv/linux/pkey_set.c new file mode 100644 index 0000000000..f686c4373c --- /dev/null +++ b/sysdeps/unix/sysv/linux/pkey_set.c @@ -0,0 +1,26 @@ +/* Changing the thread memory protection key, generic stub. + Copyright (C) 2017 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 + . */ + +#include + +int +pkey_set (int key, unsigned int access_rights) +{ + __set_errno (ENOSYS); + return -1; +} diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 48af097b6a..a074a05005 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -1991,6 +1991,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index e30535dac9..5271f6dab3 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -1996,6 +1996,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist index f522700890..96cc6cdb1d 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist @@ -2203,6 +2203,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof64x F GLIBC_2.27 strtof64x_l F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist index d3092afd25..3665895b76 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist @@ -110,6 +110,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 _Exit F GLIBC_2.3 _IO_2_1_stderr_ D 0xe0 diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 752176108e..1aa0994c0a 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -1991,6 +1991,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf128 F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof128 F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index b6d4c73635..538f7cca8c 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -1892,6 +1892,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf128 F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof128 F diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist index 1ee21fe8e8..17d5c0c7eb 100644 --- a/sysdeps/unix/sysv/linux/sh/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist @@ -1877,6 +1877,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index e652191c60..e635f380b7 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -1984,6 +1984,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf128 F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof128 F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 37cf8713a5..8cea2c0a8d 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -1921,6 +1921,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf128 F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof128 F diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 40c4fbb9ea..e3dfd0c8db 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -110,3 +110,5 @@ setns EXTRA setns i:ii setns process_vm_readv EXTRA process_vm_readv i:ipipii process_vm_readv process_vm_writev EXTRA process_vm_writev i:ipipii process_vm_writev memfd_create EXTRA memfd_create i:si memfd_create +pkey_alloc EXTRA pkey_alloc i:ii pkey_alloc +pkey_free EXTRA pkey_free i:i pkey_free diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist index 57427eb3ee..d7b49335ab 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist @@ -2115,3 +2115,8 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist index 321f65c600..e96a45818c 100644 --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist @@ -2115,3 +2115,8 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist index 57427eb3ee..d7b49335ab 100644 --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist @@ -2115,3 +2115,8 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F diff --git a/sysdeps/unix/sysv/linux/tst-pkey.c b/sysdeps/unix/sysv/linux/tst-pkey.c new file mode 100644 index 0000000000..e7205dba1f --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-pkey.c @@ -0,0 +1,399 @@ +/* Tests for memory protection keys. + Copyright (C) 2017 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Used to force threads to wait until the main thread has set up the + keys as intended. */ +static pthread_barrier_t barrier; + +/* The keys used for testing. These have been allocated with access + rights set based on their array index. */ +enum { key_count = 4 }; +static int keys[key_count]; +static volatile int *pages[key_count]; + +/* Used to report results from the signal handler. */ +static volatile void *sigsegv_addr; +static volatile int sigsegv_code; +static volatile int sigsegv_pkey; +static sigjmp_buf sigsegv_jmp; + +/* Used to handle expected read or write faults. */ +static void +sigsegv_handler (int signum, siginfo_t *info, void *context) +{ + sigsegv_addr = info->si_addr; + sigsegv_code = info->si_code; + sigsegv_pkey = info->si_pkey; + siglongjmp (sigsegv_jmp, 2); +} + +static const struct sigaction sigsegv_sigaction = + { + .sa_flags = SA_RESETHAND | SA_SIGINFO, + .sa_sigaction = &sigsegv_handler, + }; + +/* Check if PAGE is readable (if !WRITE) or writable (if WRITE). */ +static bool +check_page_access (int page, bool write) +{ + /* This is needed to work around bug 22396: On x86-64, siglongjmp + does not restore the protection key access rights for the current + thread. We restore only the access rights for the keys under + test. (This is not a general solution to this problem, but it + allows testing to proceed after a fault.) */ + unsigned saved_rights[key_count]; + for (int i = 0; i < key_count; ++i) + saved_rights[i] = pkey_get (keys[i]); + + volatile int *addr = pages[page]; + if (test_verbose > 0) + { + printf ("info: checking access at %p (page %d) for %s\n", + addr, page, write ? "writing" : "reading"); + } + int result = sigsetjmp (sigsegv_jmp, 1); + if (result == 0) + { + xsigaction (SIGSEGV, &sigsegv_sigaction, NULL); + if (write) + *addr = 3; + else + (void) *addr; + xsignal (SIGSEGV, SIG_DFL); + if (test_verbose > 0) + puts (" --> access allowed"); + return true; + } + else + { + xsignal (SIGSEGV, SIG_DFL); + if (test_verbose > 0) + puts (" --> access denied"); + TEST_COMPARE (result, 2); + TEST_COMPARE ((uintptr_t) sigsegv_addr, (uintptr_t) addr); + TEST_COMPARE (sigsegv_code, SEGV_PKUERR); + TEST_COMPARE (sigsegv_pkey, keys[page]); + for (int i = 0; i < key_count; ++i) + TEST_COMPARE (pkey_set (keys[i], saved_rights[i]), 0); + return false; + } +} + +static volatile sig_atomic_t sigusr1_handler_ran; + +/* Used to check that access is revoked in signal handlers. */ +static void +sigusr1_handler (int signum) +{ + TEST_COMPARE (signum, SIGUSR1); + for (int i = 0; i < key_count; ++i) + TEST_COMPARE (pkey_get (keys[i]), PKEY_DISABLE_ACCESS); + sigusr1_handler_ran = 1; +} + +/* Used to report results from other threads. */ +struct thread_result +{ + int access_rights[key_count]; + pthread_t next_thread; +}; + +/* Return the thread's access rights for the keys under test. */ +static void * +get_thread_func (void *closure) +{ + struct thread_result *result = xmalloc (sizeof (*result)); + for (int i = 0; i < key_count; ++i) + result->access_rights[i] = pkey_get (keys[i]); + memset (&result->next_thread, 0, sizeof (result->next_thread)); + return result; +} + +/* Wait for initialization and then check that the current thread does + not have access through the keys under test. */ +static void * +delayed_thread_func (void *closure) +{ + bool check_access = *(bool *) closure; + pthread_barrier_wait (&barrier); + struct thread_result *result = get_thread_func (NULL); + + if (check_access) + { + /* Also check directly. This code should not run with other + threads in parallel because of the SIGSEGV handler which is + installed by check_page_access. */ + for (int i = 0; i < key_count; ++i) + { + TEST_VERIFY (!check_page_access (i, false)); + TEST_VERIFY (!check_page_access (i, true)); + } + } + + result->next_thread = xpthread_create (NULL, get_thread_func, NULL); + return result; +} + +static int +do_test (void) +{ + long pagesize = xsysconf (_SC_PAGESIZE); + + /* pkey_mprotect with key -1 should work even when there is no + protection key support. */ + { + int *page = xmmap (NULL, pagesize, PROT_NONE, + MAP_ANONYMOUS | MAP_PRIVATE, -1); + TEST_COMPARE (pkey_mprotect (page, pagesize, PROT_READ | PROT_WRITE, -1), + 0); + volatile int *vpage = page; + *vpage = 5; + TEST_COMPARE (*vpage, 5); + xmunmap (page, pagesize); + } + + xpthread_barrier_init (&barrier, NULL, 2); + bool delayed_thread_check_access = true; + pthread_t delayed_thread = xpthread_create + (NULL, &delayed_thread_func, &delayed_thread_check_access); + + keys[0] = pkey_alloc (0, 0); + if (keys[0] < 0) + { + if (errno == ENOSYS) + FAIL_UNSUPPORTED + ("kernel does not support memory protection keys"); + if (errno == EINVAL) + FAIL_UNSUPPORTED + ("CPU does not support memory protection keys: %m"); + FAIL_EXIT1 ("pkey_alloc: %m"); + } + TEST_COMPARE (pkey_get (keys[0]), 0); + for (int i = 1; i < key_count; ++i) + { + keys[i] = pkey_alloc (0, i); + if (keys[i] < 0) + FAIL_EXIT1 ("pkey_alloc (0, %d): %m", i); + /* pkey_alloc is supposed to change the current thread's access + rights for the new key. */ + TEST_COMPARE (pkey_get (keys[i]), i); + } + /* Check that all the keys have the expected access rights for the + current thread. */ + for (int i = 0; i < key_count; ++i) + TEST_COMPARE (pkey_get (keys[i]), i); + + /* Allocate a test page for each key. */ + for (int i = 0; i < key_count; ++i) + { + pages[i] = xmmap (NULL, pagesize, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1); + TEST_COMPARE (pkey_mprotect ((void *) pages[i], pagesize, + PROT_READ | PROT_WRITE, keys[i]), 0); + } + + /* Check that the initial thread does not have access to the new + keys. */ + { + pthread_barrier_wait (&barrier); + struct thread_result *result = xpthread_join (delayed_thread); + for (int i = 0; i < key_count; ++i) + TEST_COMPARE (result->access_rights[i], + PKEY_DISABLE_ACCESS); + struct thread_result *result2 = xpthread_join (result->next_thread); + for (int i = 0; i < key_count; ++i) + TEST_COMPARE (result->access_rights[i], + PKEY_DISABLE_ACCESS); + free (result); + free (result2); + } + + /* Check that the current thread access rights are inherited by new + threads. */ + { + pthread_t get_thread = xpthread_create (NULL, get_thread_func, NULL); + struct thread_result *result = xpthread_join (get_thread); + for (int i = 0; i < key_count; ++i) + TEST_COMPARE (result->access_rights[i], i); + free (result); + } + + for (int i = 0; i < key_count; ++i) + TEST_COMPARE (pkey_get (keys[i]), i); + + /* Check that in a signal handler, there is no access. */ + xsignal (SIGUSR1, &sigusr1_handler); + xraise (SIGUSR1); + xsignal (SIGUSR1, SIG_DFL); + TEST_COMPARE (sigusr1_handler_ran, 1); + + /* The first key results in a writable page. */ + TEST_VERIFY (check_page_access (0, false)); + TEST_VERIFY (check_page_access (0, true)); + + /* The other keys do not. */ + for (int i = 1; i < key_count; ++i) + { + if (test_verbose) + printf ("info: checking access for key %d, bits 0x%x\n", + i, pkey_get (keys[i])); + for (int j = 0; j < key_count; ++j) + TEST_COMPARE (pkey_get (keys[j]), j); + if (i & PKEY_DISABLE_ACCESS) + { + TEST_VERIFY (!check_page_access (i, false)); + TEST_VERIFY (!check_page_access (i, true)); + } + else + { + TEST_VERIFY (i & PKEY_DISABLE_WRITE); + TEST_VERIFY (check_page_access (i, false)); + TEST_VERIFY (!check_page_access (i, true)); + } + } + + /* But if we set the current thread's access rights, we gain + access. */ + for (int do_write = 0; do_write < 2; ++do_write) + for (int allowed_key = 0; allowed_key < key_count; ++allowed_key) + { + for (int i = 0; i < key_count; ++i) + if (i == allowed_key) + { + if (do_write) + TEST_COMPARE (pkey_set (keys[i], 0), 0); + else + TEST_COMPARE (pkey_set (keys[i], PKEY_DISABLE_WRITE), 0); + } + else + TEST_COMPARE (pkey_set (keys[i], PKEY_DISABLE_ACCESS), 0); + + if (test_verbose) + printf ("info: key %d is allowed access for %s\n", + allowed_key, do_write ? "writing" : "reading"); + for (int i = 0; i < key_count; ++i) + if (i == allowed_key) + { + TEST_VERIFY (check_page_access (i, false)); + TEST_VERIFY (check_page_access (i, true) == do_write); + } + else + { + TEST_VERIFY (!check_page_access (i, false)); + TEST_VERIFY (!check_page_access (i, true)); + } + } + + /* Restore access to all keys, and launch a thread which should + inherit that access. */ + for (int i = 0; i < key_count; ++i) + { + TEST_COMPARE (pkey_set (keys[i], 0), 0); + TEST_VERIFY (check_page_access (i, false)); + TEST_VERIFY (check_page_access (i, true)); + } + delayed_thread_check_access = false; + delayed_thread = xpthread_create + (NULL, delayed_thread_func, &delayed_thread_check_access); + + TEST_COMPARE (pkey_free (keys[0]), 0); + /* Second pkey_free will fail because the key has already been + freed. */ + TEST_COMPARE (pkey_free (keys[0]),-1); + TEST_COMPARE (errno, EINVAL); + for (int i = 1; i < key_count; ++i) + TEST_COMPARE (pkey_free (keys[i]), 0); + + /* Check what happens to running threads which have access to + previously allocated protection keys. The implemented behavior + is somewhat dubious: Ideally, pkey_free should revoke access to + that key and pkey_alloc of the same (numeric) key should not + implicitly confer access to already-running threads, but this is + not what happens in practice. */ + { + /* The limit is in place to avoid running indefinitely in case + there many keys available. */ + int *keys_array = xcalloc (100000, sizeof (*keys_array)); + int keys_allocated = 0; + while (keys_allocated < 100000) + { + int new_key = pkey_alloc (0, PKEY_DISABLE_WRITE); + if (new_key < 0) + { + /* No key reuse observed before running out of keys. */ + TEST_COMPARE (errno, ENOSPC); + break; + } + for (int i = 0; i < key_count; ++i) + if (new_key == keys[i]) + { + /* We allocated the key with disabled write access. + This should affect the protection state of the + existing page. */ + TEST_VERIFY (check_page_access (i, false)); + TEST_VERIFY (!check_page_access (i, true)); + + xpthread_barrier_wait (&barrier); + struct thread_result *result = xpthread_join (delayed_thread); + /* The thread which was launched before should still have + access to the key. */ + TEST_COMPARE (result->access_rights[i], 0); + struct thread_result *result2 + = xpthread_join (result->next_thread); + /* Same for a thread which is launched afterwards from + the old thread. */ + TEST_COMPARE (result2->access_rights[i], 0); + free (result); + free (result2); + keys_array[keys_allocated++] = new_key; + goto after_key_search; + } + /* Save key for later deallocation. */ + keys_array[keys_allocated++] = new_key; + } + after_key_search: + /* Deallocate the keys allocated for testing purposes. */ + for (int j = 0; j < keys_allocated; ++j) + TEST_COMPARE (pkey_free (keys_array[j]), 0); + free (keys_array); + } + + for (int i = 0; i < key_count; ++i) + xmunmap ((void *) pages[i], pagesize); + + xpthread_barrier_destroy (&barrier); + return 0; +} + +#include 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..8e9bfdae96 --- /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 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 + . */ + +#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/pkey_get.c b/sysdeps/unix/sysv/linux/x86/pkey_get.c new file mode 100644 index 0000000000..3a9bfbe676 --- /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 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 + . */ + +#include +#include + +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..91dffd22c3 --- /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 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 + . */ + +#include +#include + +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_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index f26c8b99d5..7317d17e7b 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -1879,6 +1879,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof64x F GLIBC_2.27 strtof64x_l F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 2a6057154b..0a9334f822 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2122,6 +2122,11 @@ GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F GLIBC_2.27 mlock2 F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F GLIBC_2.27 strfromf64x F GLIBC_2.27 strtof64x F GLIBC_2.27 strtof64x_l F -- cgit v1.2.3 From ebc129fd17e8110eb76fb5ebdbb2dc395507ceeb Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Fri, 18 May 2018 16:50:44 +0000 Subject: Obsolete nfsservctl. The Linux nfsservctl syscall was removed in Linux 3.1. Since the minimum kernel version for use with glibc is 3.2, the glibc wrapper for this syscall can no longer usefully be called. This patch makes it into a compat symbol, not provided at all for static linking or new ports. (It was already the case that there was no header declaration of this function.) Tested for x86_64. * sysdeps/unix/sysv/linux/syscalls.list (nfsservctl): Make into a compat symbol, disabled for minimum symbol version GLIBC_2.28 and later. --- ChangeLog | 4 ++++ NEWS | 5 +++++ sysdeps/unix/sysv/linux/syscalls.list | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'sysdeps/unix/sysv/linux/syscalls.list') diff --git a/ChangeLog b/ChangeLog index 4a2d9787c4..62308b5aee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2018-05-18 Joseph Myers + * sysdeps/unix/sysv/linux/syscalls.list (nfsservctl): Make into a + compat symbol, disabled for minimum symbol version GLIBC_2.28 and + later. + [BZ #22639] * time/tzset.c (SECSPERDAY): Cast to time_t. * time/tst-y2039.c: New file. diff --git a/NEWS b/NEWS index 4899a0acab..bade9e4765 100644 --- a/NEWS +++ b/NEWS @@ -69,6 +69,11 @@ Deprecated and removed features, and other changes affecting compatibility: binaries; the headers and have been removed. This function has been deprecated in favor of fstatfs and statfs. +* The obsolete function nfsservctl is no longer available to newly linked + binaries. This function was specific to systems using the Linux kernel + and could not usefully be used with the GNU C Library on systems with + version 3.1 or later of the Linux kernel. + Changes to build and runtime requirements: [Add changes to build and runtime requirements here] diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index e3dfd0c8db..e24ea29e35 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -41,7 +41,7 @@ mount EXTRA mount i:sssip __mount mount mremap EXTRA mremap b:ainip __mremap mremap munlock - munlock i:ai munlock munlockall - munlockall i: munlockall -nfsservctl EXTRA nfsservctl i:ipp nfsservctl +nfsservctl EXTRA nfsservctl i:ipp __compat_nfsservctl nfsservctl@GLIBC_2.0:GLIBC_2.28 pipe - pipe i:f __pipe pipe pipe2 - pipe2 i:fi __pipe2 pipe2 pivot_root EXTRA pivot_root i:ss pivot_root -- cgit v1.2.3