summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--sysdeps/unix/sysv/linux/Makefile111
-rw-r--r--sysdeps/unix/sysv/linux/filter-nr-syscalls.awk35
-rw-r--r--sysdeps/unix/sysv/linux/gen-syscall-h.awk81
-rw-r--r--sysdeps/unix/sysv/linux/syscall-names.list601
-rw-r--r--sysdeps/unix/sysv/linux/tst-syscall-list.sh99
6 files changed, 881 insertions, 68 deletions
diff --git a/ChangeLog b/ChangeLog
index 6dbf10cd8f..5677c5eb46 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2017-08-28  Florian Weimer  <fweimer@redhat.com>
+
+	Store supported list of SYS_* system calls in the source tree.
+	* sysdeps/unix/sysv/linux/Makefile [$(subdir) = misc]
+	(bits/syscall.h): Generate from list file.
+	[$(subdir) = misc] (before-compile): Add bits/syscall.h.
+	[$(subdir) = misc] (tests): Add tst-syscall-list.
+	[$(subdir) = misc] (tests-special): Add tst-syscall-list.out
+	[$(subdir) = misc] (tst-syscall-list-macros.list)
+	[$(subdir) = misc] (tst-syscall-list-nr.list)
+	(tst-syscall-list-sys.list): Helper targets for new
+	tst-syscall-list test.
+	[$(subdir) = misc] (tst-syscall-list.out): Run test script
+	tst-syscall-list.sh.
+	[$(subdir) = misc] (bits/syscall%h, bits/syscall%d): Remove
+	target. Do not include bits/syscall.d.
+	[$(subdir) = misc] (generated): Do not update.
+	* sysdeps/unix/sysv/linux/syscall-names.list: New file.
+	* sysdeps/unix/sysv/linux/gen-syscall-h.awk: Likewise.
+	* sysdeps/unix/sysv/linux/filter-nr-syscalls.awk: Likewise.
+	* sysdeps/unix/sysv/linux/tst-syscall-list.sh: Likewise.
+
 2017-08-27  Paul Pluzhnikov  <ppluzhnikov@google.com>
 
 	* stdlib/Makefile (tst-atexit, tst-at_quick_exit): New tests.
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 9d6a2de870..e571fe2efe 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -52,75 +52,50 @@ 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 test-errno-linux
 
-# Generate the list of SYS_* macros for the system calls (__NR_* macros).
-
-# If there is more than one syscall list for different architecture
-# variants, the CPU/Makefile defines abi-variants to be a list of names
-# for those variants (e.g. 32 64), and, for each variant, defines
-# abi-$(variant)-options to be compiler options to cause <asm/unistd.h>
-# to define the desired list of syscalls and abi-$(variant)-condition to
-# be the condition for those options to use in a C #if condition.
-# abi-includes may be defined to a list of headers to include
-# in the generated header, if the default does not suffice.
-#
-# The generated header is compiled with `-ffreestanding' to avoid any
-# circular dependencies against the installed implementation headers.
-# Such a dependency would require the implementation header to be
-# installed before the generated header could be built (See bug 15711).
-# In current practice the generated header dependencies do not include
-# any of the implementation headers removed by the use of `-ffreestanding'.
-
-$(objpfx)bits/syscall%h $(objpfx)bits/syscall%d: ../sysdeps/unix/sysv/linux/sys/syscall.h
+# Generate the list of SYS_* macros for the system calls (__NR_*
+# macros).  The file syscall-names.list contains all possible system
+# call names, and the generated header file produces SYS_* macros for
+# the __NR_* macros which are actually defined.
+
+generated += bits/syscall.h
+$(objpfx)bits/syscall.h: \
+  ../sysdeps/unix/sysv/linux/gen-syscall-h.awk \
+  ../sysdeps/unix/sysv/linux/syscall-names.list
 	$(make-target-directory)
-	{ \
-	 echo '/* Generated at libc build time from kernel syscall list.  */';\
-	 echo ''; \
-	 echo '#ifndef _SYSCALL_H'; \
-	 echo '# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."'; \
-	 echo '#endif'; \
-	 echo ''; \
-	 $(foreach h,$(abi-includes), echo '#include <$(h)>';) \
-	 echo ''; \
-	 $(if $(abi-variants), \
-	 $(foreach v,$(abi-variants),\
-	 $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \
-	       -x c $(sysincludes) $< $(abi-$(v)-options) \
-	       -D_LIBC -dM | \
-	 sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
-	 LC_ALL=C sort > $(@:.d=.h).new$(v); \
-	 $(if $(abi-$(v)-condition),\
-	 echo '#if $(abi-$(v)-condition)';) \
-	 cat $(@:.d=.h).new$(v); \
-	 $(if $(abi-$(v)-condition),echo '#endif';) \
-	 rm -f $(@:.d=.h).new$(v); \
-	 ), \
-	 $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \
-	       -x c $(sysincludes) $< \
-	       -D_LIBC -dM | \
-	 sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
-	 LC_ALL=C sort;) \
-	} > $(@:.d=.h).new
-	mv -f $(@:.d=.h).new $(@:.d=.h)
-ifdef abi-variants
-ifneq (,$(objpfx))
-	sed $(sed-remove-objpfx) \
-	 $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) > $(@:.h=.d)-t3
-else
-	cat $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) \
-	 > $(@:.h=.d)-t3
-endif
-	rm -f $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v))
-	mv -f $(@:.h=.d)-t3 $(@:.h=.d)
-else
-	mv -f $(@:.h=.d)-t $(@:.h=.d)
-endif
-
-ifndef no_deps
-# Get the generated list of dependencies (probably /usr/include/asm/unistd.h).
--include $(objpfx)bits/syscall.d
-endif
-generated += bits/syscall.h bits/syscall.d
-endif
+	LC_ALL=C $(AWK) -f $^ > $@-tmp
+	$(move-if-change) $@-tmp $@
+before-compile += $(objpfx)bits/syscall.h
+
+# All macros defined by <sys/syscall.h>.  Include <bits/syscall.h>
+# explicitly because <sys/sycall.h> skips it if _LIBC is defined.
+$(objpfx)tst-syscall-list-macros.list: \
+  $(objpfx)bits/syscall.h ../sysdeps/unix/sysv/linux/sys/syscall.h
+	printf '#include <linux/version.h>\n\
+#include <sys/syscall.h>\n#include <bits/syscall.h>\n' | \
+	  $(CC) -E -o $@-tmp $(CFLAGS) $(CPPFLAGS) -x c - -dM
+	$(move-if-change) $@-tmp $@
+
+# __NR_* system call names.  Used by the test below.
+$(objpfx)tst-syscall-list-nr.list: \
+  ../sysdeps/unix/sysv/linux/filter-nr-syscalls.awk \
+  $(objpfx)tst-syscall-list-macros.list
+	LC_ALL=C $(AWK) -f $^ > $@-tmp
+	$(move-if-change) $@-tmp $@
+
+# SYS_* system call names.  Used by the test below.
+$(objpfx)tst-syscall-list-sys.list: $(objpfx)tst-syscall-list-macros.list
+	LC_ALL=C $(AWK) '/^#define SYS_/ { print substr($$2, 5) }' $< > $@-tmp
+	$(move-if-change) $@-tmp $@
+
+tests-special += $(objpfx)tst-syscall-list.out
+$(objpfx)tst-syscall-list.out: \
+  ../sysdeps/unix/sysv/linux/tst-syscall-list.sh \
+  $(objpfx)tst-syscall-list-macros.list \
+  $(objpfx)tst-syscall-list-nr.list \
+  $(objpfx)tst-syscall-list-sys.list
+	$(BASH) $^ $(AWK) > $@; $(evaluate-test)
+
+endif # $(subdir) == misc
 
 ifeq ($(subdir),time)
 sysdep_headers += sys/timex.h bits/timex.h
diff --git a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
new file mode 100644
index 0000000000..15b052a9c9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
@@ -0,0 +1,35 @@
+# Filter preprocessor __NR_* macros and extract system call names.
+# 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
+# <http://www.gnu.org/licenses/>.
+
+# Skip reserved system calls.
+/^#define __NR_(unused|reserved)[0-9]+ / {
+    next;
+}
+
+# Skip pseudo-system calls which describe ranges.
+/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) / {
+    next;
+}
+/^#define __NR_(|64_|[NO]32_)Linux(_syscalls)? / {
+    next;
+}
+
+# Print the remaining _NR_* macros as system call names.
+/^#define __NR_/ {
+    print substr($2, 6);
+}
diff --git a/sysdeps/unix/sysv/linux/gen-syscall-h.awk b/sysdeps/unix/sysv/linux/gen-syscall-h.awk
new file mode 100644
index 0000000000..ef8eb6be52
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/gen-syscall-h.awk
@@ -0,0 +1,81 @@
+# Generate SYS_* macros from a list in a text file.
+# 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
+# <http://www.gnu.org/licenses/>.
+
+# Emit a conditional definition for SYS_NAME.
+function emit(name) {
+    print "#ifdef __NR_" name;
+    print "# define SYS_" name " __NR_" name;
+    print "#endif";
+    print "";
+}
+
+# Bail out with an error.
+function fatal(message) {
+    print FILENAME ":" FNR ": " message > "/dev/stderr";
+    exit 1;
+}
+
+BEGIN {
+    name = "";
+    kernel = "";
+}
+
+# Skip empty lines and comments.
+/^\s*(|#.*)$/ {
+    next;
+}
+
+# Kernel version.  Used for documentation purposes only.
+/^kernel [0-9.]+$/ {
+    if (kernel != "") {
+        fatal("duplicate kernel directive");
+    }
+    kernel = $2;
+    print "/* Generated at libc build time from syscall list.  */";
+    print "/* The system call list corresponds to kernel " kernel ".  */";
+    print "";
+    print "#ifndef _SYSCALL_H"
+    print "# error \"Never use <bits/syscall.h> directly; include <sys/syscall.h> instead.\"";
+    print "#endif";
+    print "";
+    split($2, kernel_version, ".");
+    kernel_major = kernel_version[1];
+    kernel_minor = kernel_version[2];
+    kernel_version_code = kernel_major * 65536 + kernel_minor * 256;
+    print "#define __GLIBC_LINUX_VERSION_CODE " kernel_version_code;
+    print "";
+    next;
+}
+
+# If there is just one word, it is a system call.
+/^[a-zA-Z_][a-zA-Z0-9_]+$/ {
+    if (kernel == "") {
+        fatal("expected kernel directive before this line");
+    }
+    if ($1 <= name) {
+        fatal("name " name " violates ordering");
+    }
+    emit($1);
+    name = $1;
+    next;
+}
+
+# The rest has to be syntax errors.
+// {
+    fatal("unrecognized syntax");
+}
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
new file mode 100644
index 0000000000..2e5cc77fe0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -0,0 +1,601 @@
+# List of all known Linux system calls.
+# 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
+# <http://www.gnu.org/licenses/>.
+
+# This file contains the list of system call names names.  It has to
+# remain in alphabetica order.  Lines which start with # are treated
+# as comments.  This file can list all potential system calls.  The
+# names are only used if the installed kernel headers also provide
+# them.
+
+# The list of system calls is current as of Linux 4.12.
+kernel 4.12
+
+FAST_atomic_update
+FAST_cmpxchg
+FAST_cmpxchg64
+_llseek
+_newselect
+_sysctl
+accept
+accept4
+access
+acct
+acl_get
+acl_set
+add_key
+adjtimex
+afs_syscall
+alarm
+alloc_hugepages
+arch_prctl
+arm_fadvise64_64
+arm_sync_file_range
+atomic_barrier
+atomic_cmpxchg_32
+attrctl
+bdflush
+bind
+bpf
+break
+brk
+cachectl
+cacheflush
+capget
+capset
+chdir
+chmod
+chown
+chown32
+chroot
+clock_adjtime
+clock_getres
+clock_gettime
+clock_nanosleep
+clock_settime
+clone
+clone2
+close
+cmpxchg_badaddr
+connect
+copy_file_range
+creat
+create_module
+delete_module
+dipc
+dup
+dup2
+dup3
+epoll_create
+epoll_create1
+epoll_ctl
+epoll_ctl_old
+epoll_pwait
+epoll_wait
+epoll_wait_old
+eventfd
+eventfd2
+exec_with_loader
+execv
+execve
+execveat
+exit
+exit_group
+faccessat
+fadvise64
+fadvise64_64
+fallocate
+fanotify_init
+fanotify_mark
+fchdir
+fchmod
+fchmodat
+fchown
+fchown32
+fchownat
+fcntl
+fcntl64
+fdatasync
+fgetxattr
+finit_module
+flistxattr
+flock
+fork
+free_hugepages
+fremovexattr
+fsetxattr
+fstat
+fstat64
+fstatat64
+fstatfs
+fstatfs64
+fsync
+ftime
+ftruncate
+ftruncate64
+futex
+futimesat
+get_kernel_syms
+get_mempolicy
+get_robust_list
+get_thread_area
+getcpu
+getcwd
+getdents
+getdents64
+getdomainname
+getdtablesize
+getegid
+getegid32
+geteuid
+geteuid32
+getgid
+getgid32
+getgroups
+getgroups32
+gethostname
+getitimer
+getpagesize
+getpeername
+getpgid
+getpgrp
+getpid
+getpmsg
+getppid
+getpriority
+getrandom
+getresgid
+getresgid32
+getresuid
+getresuid32
+getrlimit
+getrusage
+getsid
+getsockname
+getsockopt
+gettid
+gettimeofday
+getuid
+getuid32
+getunwind
+getxattr
+getxgid
+getxpid
+getxuid
+gtty
+idle
+init_module
+inotify_add_watch
+inotify_init
+inotify_init1
+inotify_rm_watch
+io_cancel
+io_destroy
+io_getevents
+io_setup
+io_submit
+ioctl
+ioperm
+iopl
+ioprio_get
+ioprio_set
+ipc
+kcmp
+kern_features
+kexec_file_load
+kexec_load
+keyctl
+kill
+lchown
+lchown32
+lgetxattr
+link
+linkat
+listen
+listxattr
+llistxattr
+llseek
+lock
+lookup_dcookie
+lremovexattr
+lseek
+lsetxattr
+lstat
+lstat64
+madvise
+mbind
+membarrier
+memfd_create
+memory_ordering
+migrate_pages
+mincore
+mkdir
+mkdirat
+mknod
+mknodat
+mlock
+mlock2
+mlockall
+mmap
+mmap2
+modify_ldt
+mount
+move_pages
+mprotect
+mpx
+mq_getsetattr
+mq_notify
+mq_open
+mq_timedreceive
+mq_timedsend
+mq_unlink
+mremap
+msgctl
+msgget
+msgrcv
+msgsnd
+msync
+multiplexer
+munlock
+munlockall
+munmap
+name_to_handle_at
+nanosleep
+newfstatat
+nfsservctl
+ni_syscall
+nice
+old_adjtimex
+oldfstat
+oldlstat
+oldolduname
+oldstat
+oldumount
+olduname
+open
+open_by_handle_at
+openat
+osf_adjtime
+osf_afs_syscall
+osf_alt_plock
+osf_alt_setsid
+osf_alt_sigpending
+osf_asynch_daemon
+osf_audcntl
+osf_audgen
+osf_chflags
+osf_execve
+osf_exportfs
+osf_fchflags
+osf_fdatasync
+osf_fpathconf
+osf_fstat
+osf_fstatfs
+osf_fstatfs64
+osf_fuser
+osf_getaddressconf
+osf_getdirentries
+osf_getdomainname
+osf_getfh
+osf_getfsstat
+osf_gethostid
+osf_getitimer
+osf_getlogin
+osf_getmnt
+osf_getrusage
+osf_getsysinfo
+osf_gettimeofday
+osf_kloadcall
+osf_kmodcall
+osf_lstat
+osf_memcntl
+osf_mincore
+osf_mount
+osf_mremap
+osf_msfs_syscall
+osf_msleep
+osf_mvalid
+osf_mwakeup
+osf_naccept
+osf_nfssvc
+osf_ngetpeername
+osf_ngetsockname
+osf_nrecvfrom
+osf_nrecvmsg
+osf_nsendmsg
+osf_ntp_adjtime
+osf_ntp_gettime
+osf_old_creat
+osf_old_fstat
+osf_old_getpgrp
+osf_old_killpg
+osf_old_lstat
+osf_old_open
+osf_old_sigaction
+osf_old_sigblock
+osf_old_sigreturn
+osf_old_sigsetmask
+osf_old_sigvec
+osf_old_stat
+osf_old_vadvise
+osf_old_vtrace
+osf_old_wait
+osf_oldquota
+osf_pathconf
+osf_pid_block
+osf_pid_unblock
+osf_plock
+osf_priocntlset
+osf_profil
+osf_proplist_syscall
+osf_reboot
+osf_revoke
+osf_sbrk
+osf_security
+osf_select
+osf_set_program_attributes
+osf_set_speculative
+osf_sethostid
+osf_setitimer
+osf_setlogin
+osf_setsysinfo
+osf_settimeofday
+osf_shmat
+osf_signal
+osf_sigprocmask
+osf_sigsendset
+osf_sigstack
+osf_sigwaitprim
+osf_sstk
+osf_stat
+osf_statfs
+osf_statfs64
+osf_subsys_info
+osf_swapctl
+osf_swapon
+osf_syscall
+osf_sysinfo
+osf_table
+osf_uadmin
+osf_usleep_thread
+osf_uswitch
+osf_utc_adjtime
+osf_utc_gettime
+osf_utimes
+osf_utsname
+osf_wait4
+osf_waitid
+pause
+pciconfig_iobase
+pciconfig_read
+pciconfig_write
+perf_event_open
+perfctr
+perfmonctl
+personality
+pipe
+pipe2
+pivot_root
+pkey_alloc
+pkey_free
+pkey_mprotect
+poll
+ppoll
+prctl
+pread64
+preadv
+preadv2
+prlimit64
+process_vm_readv
+process_vm_writev
+prof
+profil
+pselect6
+ptrace
+putpmsg
+pwrite64
+pwritev
+pwritev2
+query_module
+quotactl
+read
+readahead
+readdir
+readlink
+readlinkat
+readv
+reboot
+recv
+recvfrom
+recvmmsg
+recvmsg
+remap_file_pages
+removexattr
+rename
+renameat
+renameat2
+request_key
+restart_syscall
+rmdir
+rt_sigaction
+rt_sigpending
+rt_sigprocmask
+rt_sigqueueinfo
+rt_sigreturn
+rt_sigsuspend
+rt_sigtimedwait
+rt_tgsigqueueinfo
+rtas
+s390_guarded_storage
+s390_pci_mmio_read
+s390_pci_mmio_write
+s390_runtime_instr
+sched_get_affinity
+sched_get_priority_max
+sched_get_priority_min
+sched_getaffinity
+sched_getattr
+sched_getparam
+sched_getscheduler
+sched_rr_get_interval
+sched_set_affinity
+sched_setaffinity
+sched_setattr
+sched_setparam
+sched_setscheduler
+sched_yield
+seccomp
+security
+select
+semctl
+semget
+semop
+semtimedop
+send
+sendfile
+sendfile64
+sendmmsg
+sendmsg
+sendto
+set_mempolicy
+set_robust_list
+set_thread_area
+set_tid_address
+setdomainname
+setfsgid
+setfsgid32
+setfsuid
+setfsuid32
+setgid
+setgid32
+setgroups
+setgroups32
+sethae
+sethostname
+setitimer
+setns
+setpgid
+setpgrp
+setpriority
+setregid
+setregid32
+setresgid
+setresgid32
+setresuid
+setresuid32
+setreuid
+setreuid32
+setrlimit
+setsid
+setsockopt
+settimeofday
+setuid
+setuid32
+setxattr
+sgetmask
+shmat
+shmctl
+shmdt
+shmget
+shutdown
+sigaction
+sigaltstack
+signal
+signalfd
+signalfd4
+sigpending
+sigprocmask
+sigreturn
+sigsuspend
+socket
+socketcall
+socketpair
+splice
+spu_create
+spu_run
+ssetmask
+stat
+stat64
+statfs
+statfs64
+statx
+stime
+stty
+subpage_prot
+swapcontext
+swapoff
+swapon
+switch_endian
+symlink
+symlinkat
+sync
+sync_file_range
+sync_file_range2
+syncfs
+sys_debug_setcontext
+sys_epoll_create
+sys_epoll_ctl
+sys_epoll_wait
+syscall
+sysfs
+sysinfo
+syslog
+sysmips
+tee
+tgkill
+time
+timer_create
+timer_delete
+timer_getoverrun
+timer_gettime
+timer_settime
+timerfd
+timerfd_create
+timerfd_gettime
+timerfd_settime
+times
+tkill
+truncate
+truncate64
+tuxcall
+ugetrlimit
+ulimit
+umask
+umount
+umount2
+uname
+unlink
+unlinkat
+unshare
+uselib
+userfaultfd
+ustat
+utime
+utimensat
+utimes
+utrap_install
+vfork
+vhangup
+vm86
+vm86old
+vmsplice
+vserver
+wait4
+waitid
+waitpid
+write
+writev
diff --git a/sysdeps/unix/sysv/linux/tst-syscall-list.sh b/sysdeps/unix/sysv/linux/tst-syscall-list.sh
new file mode 100644
index 0000000000..8474cf888f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-syscall-list.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+# Consistency checks for the system call list
+# 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
+# <http://www.gnu.org/licenses/>.
+
+export LC_ALL=C
+set -e
+set -o pipefail
+
+if test $# != 4; then
+    echo "error: wrong number of arguments: $#"
+    exit 1
+fi
+
+macros="$1"
+list_nr="$2"
+list_sys="$3"
+GAWK="$4"
+
+linux_version="$("$GAWK" \
+  '/#define LINUX_VERSION_CODE / {print $3}' < "$macros")"
+glibc_linux_version="$("$GAWK" \
+  '/#define __GLIBC_LINUX_VERSION_CODE / {print $3}' < "$macros")"
+
+echo "info: LINUX_VERSION_CODE: $linux_version"
+echo "info: __GLIBC_LINUX_VERSION_CODE: $glibc_linux_version"
+# Ignore the subrelease in the comparison.
+if test $(expr "$glibc_linux_version" / 256) \
+        -lt $(expr "$linux_version" / 256); then
+    echo "info: The kernel major/minor version is newer than the glibc version"
+    kernel_newer=true
+else
+    kernel_newer=false
+fi
+echo
+
+errors=0
+
+# Use getpid as a system call which is expected to be always defined.
+# alpha uses getxpid instead, so it is permitted as an alternative.
+if ! grep -E -q '^getx?pid$' -- "$list_nr"; then
+    echo "error: __NR_getpid not defined"
+    errors=1
+fi
+if ! grep -E -q '^getx?pid$' -- "$list_sys"; then
+    echo "error: SYS_getpid not defined"
+    errors=1
+fi
+
+comm_1="$(mktemp)"
+comm_2="$(mktemp)"
+comm_result="$(mktemp)"
+cleanup () {
+    rm -f -- "$comm_1" "$comm_2" "$comm_result"
+}
+trap cleanup 0
+
+sort -o "$comm_1" -- "$list_nr"
+sort -o "$comm_2" -- "$list_sys"
+
+# Check for missing SYS_* macros.
+comm --check-order -2 -3 -- "$comm_1" "$comm_2" > "$comm_result"
+if test -s "$comm_result"; then
+    echo "error: These system calls need to be added to syscall-names.list:"
+    cat -- "$comm_result"
+    # This is only an error if our version is older than the kernel
+    # version because we cannot predict future kernel development.
+    if $kernel_newer; then
+        echo
+        echo "warning: This error has been ignored because the glibc"
+        echo "warning: system call list is older than the kernel version."
+    else
+        errors=1
+    fi
+fi
+
+# Check for additional SYS_* macros.
+comm --check-order -1 -3 -- "$comm_1" "$comm_2" > "$comm_result"
+if test -s "$comm_result"; then
+    echo "error: The following system calls have unexpected SYS_* macros:"
+    cat -- "$comm_result"
+    errors=1
+fi
+
+exit "$errors"