|
|
ce426f |
Posted upstream at:
|
|
|
ce426f |
|
|
|
ce426f |
https://sourceware.org/ml/libc-alpha/2017-04/msg00082.html
|
|
|
ce426f |
|
|
|
51f0aa |
sysdeps/unix/sysv/linux/syscall-names.list is stored as a separate patch
|
|
|
51f0aa |
(glibc-rh1439165-syscall-names.patch) in the source RPM for easier
|
|
|
51f0aa |
updates.
|
|
|
ce426f |
|
|
|
ce426f |
Author: Florian Weimer <fweimer@redhat.com>
|
|
|
ce426f |
|
|
|
ce426f |
<bits/syscall.h>: Use an arch-independent system call list on Linux
|
|
|
51f0aa |
|
|
|
ce426f |
This commit changes the way the list of SYS_* system call macros
|
|
|
ce426f |
is created on Linux. glibc now contains a list of all known system
|
|
|
ce426f |
calls, and the generated <bits/syscall.h> file defines the SYS_
|
|
|
ce426f |
macro only if the correspnding __NR_ macro is defined by the kernel
|
|
|
ce426f |
headers.
|
|
|
51f0aa |
|
|
|
ce426f |
As a result, there glibc does not have to be rebuilt to pick up
|
|
|
ce426f |
system calls if the glibc sources already know about them. This
|
|
|
ce426f |
means that glibc can be built with older kernel headers, and if
|
|
|
ce426f |
the installed kernel headers are upgraded afterwards, additional
|
|
|
ce426f |
SYS_ macros become available as long as glibc has a record for
|
|
|
ce426f |
those system calls.
|
|
|
ce426f |
|
|
|
51f0aa |
The explicit system call list for system call management was not
|
|
|
51f0aa |
accepted upstream.
|
|
|
51f0aa |
|
|
|
51f0aa |
Fedora bug: https://bugzilla.redhat.com/show_bug.cgi?id=1484729
|
|
|
51f0aa |
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
|
|
51f0aa |
index 366b1d7..95cff0e 100644
|
|
|
ce426f |
--- a/sysdeps/unix/sysv/linux/Makefile
|
|
|
ce426f |
+++ b/sysdeps/unix/sysv/linux/Makefile
|
|
|
51f0aa |
@@ -39,75 +39,46 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
|
|
|
ce426f |
|
|
|
ce426f |
tests += tst-clone
|
|
|
ce426f |
|
|
|
ce426f |
-# Generate the list of SYS_* macros for the system calls (__NR_* macros).
|
|
|
51f0aa |
-
|
|
|
ce426f |
-# If there is more than one syscall list for different architecture
|
|
|
ce426f |
-# variants, the CPU/Makefile defines abi-variants to be a list of names
|
|
|
ce426f |
-# for those variants (e.g. 32 64), and, for each variant, defines
|
|
|
ce426f |
-# abi-$(variant)-options to be compiler options to cause <asm/unistd.h>
|
|
|
ce426f |
-# to define the desired list of syscalls and abi-$(variant)-condition to
|
|
|
ce426f |
-# be the condition for those options to use in a C #if condition.
|
|
|
ce426f |
-# abi-includes may be defined to a list of headers to include
|
|
|
ce426f |
-# in the generated header, if the default does not suffice.
|
|
|
ce426f |
-#
|
|
|
ce426f |
-# The generated header is compiled with `-ffreestanding' to avoid any
|
|
|
ce426f |
-# circular dependencies against the installed implementation headers.
|
|
|
ce426f |
-# Such a dependency would require the implementation header to be
|
|
|
ce426f |
-# installed before the generated header could be built (See bug 15711).
|
|
|
ce426f |
-# In current practice the generated header dependencies do not include
|
|
|
ce426f |
-# any of the implementation headers removed by the use of `-ffreestanding'.
|
|
|
51f0aa |
-
|
|
|
ce426f |
-$(objpfx)bits/syscall%h $(objpfx)bits/syscall%d: ../sysdeps/unix/sysv/linux/sys/syscall.h
|
|
|
51f0aa |
+# Generate the list of SYS_* macros for the system calls (__NR_*
|
|
|
51f0aa |
+# macros). The file syscall-names.list contains all possible system
|
|
|
51f0aa |
+# call names, and the generated header file produces SYS_* macros for
|
|
|
51f0aa |
+# the __NR_* macros which are actually defined.
|
|
|
51f0aa |
+
|
|
|
51f0aa |
+generated += bits/syscall.h
|
|
|
51f0aa |
+$(objpfx)bits/syscall.h: \
|
|
|
51f0aa |
+ ../sysdeps/unix/sysv/linux/gen-syscall-h.awk \
|
|
|
51f0aa |
+ ../sysdeps/unix/sysv/linux/syscall-names.list
|
|
|
51f0aa |
$(make-target-directory)
|
|
|
ce426f |
- { \
|
|
|
ce426f |
- echo '/* Generated at libc build time from kernel syscall list. */';\
|
|
|
ce426f |
- echo ''; \
|
|
|
ce426f |
- echo '#ifndef _SYSCALL_H'; \
|
|
|
ce426f |
- echo '# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."'; \
|
|
|
ce426f |
- echo '#endif'; \
|
|
|
ce426f |
- echo ''; \
|
|
|
ce426f |
- $(foreach h,$(abi-includes), echo '#include <$(h)>';) \
|
|
|
ce426f |
- echo ''; \
|
|
|
ce426f |
- $(if $(abi-variants), \
|
|
|
ce426f |
- $(foreach v,$(abi-variants),\
|
|
|
ce426f |
- $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \
|
|
|
ce426f |
- -x c $(sysincludes) $< $(abi-$(v)-options) \
|
|
|
ce426f |
- -D_LIBC -dM | \
|
|
|
ce426f |
- sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
|
|
|
ce426f |
- LC_ALL=C sort > $(@:.d=.h).new$(v); \
|
|
|
ce426f |
- $(if $(abi-$(v)-condition),\
|
|
|
ce426f |
- echo '#if $(abi-$(v)-condition)';) \
|
|
|
ce426f |
- cat $(@:.d=.h).new$(v); \
|
|
|
ce426f |
- $(if $(abi-$(v)-condition),echo '#endif';) \
|
|
|
ce426f |
- rm -f $(@:.d=.h).new$(v); \
|
|
|
ce426f |
- ), \
|
|
|
ce426f |
- $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \
|
|
|
ce426f |
- -x c $(sysincludes) $< \
|
|
|
ce426f |
- -D_LIBC -dM | \
|
|
|
ce426f |
- sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
|
|
|
ce426f |
- LC_ALL=C sort;) \
|
|
|
ce426f |
- } > $(@:.d=.h).new
|
|
|
ce426f |
- mv -f $(@:.d=.h).new $(@:.d=.h)
|
|
|
ce426f |
-ifdef abi-variants
|
|
|
ce426f |
-ifneq (,$(objpfx))
|
|
|
ce426f |
- sed $(sed-remove-objpfx) \
|
|
|
ce426f |
- $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) > $(@:.h=.d)-t3
|
|
|
ce426f |
-else
|
|
|
ce426f |
- cat $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) \
|
|
|
ce426f |
- > $(@:.h=.d)-t3
|
|
|
ce426f |
-endif
|
|
|
ce426f |
- rm -f $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v))
|
|
|
ce426f |
- mv -f $(@:.h=.d)-t3 $(@:.h=.d)
|
|
|
ce426f |
-else
|
|
|
ce426f |
- mv -f $(@:.h=.d)-t $(@:.h=.d)
|
|
|
ce426f |
-endif
|
|
|
ce426f |
-
|
|
|
ce426f |
-ifndef no_deps
|
|
|
ce426f |
-# Get the generated list of dependencies (probably /usr/include/asm/unistd.h).
|
|
|
ce426f |
--include $(objpfx)bits/syscall.d
|
|
|
ce426f |
-endif
|
|
|
ce426f |
-generated += bits/syscall.h bits/syscall.d
|
|
|
ce426f |
-endif
|
|
|
51f0aa |
+ $(AWK) -f $^ > $@-tmp
|
|
|
51f0aa |
+ $(move-if-change) $@-tmp $@
|
|
|
51f0aa |
+
|
|
|
51f0aa |
+# All macros defined by <sys/syscall.h>. Include <bits/syscall.h>
|
|
|
51f0aa |
+# explicitly because <sys/sycall.h> skips it if _LIBC is defined.
|
|
|
51f0aa |
+$(objpfx)tst-syscall-list-macros.list: \
|
|
|
51f0aa |
+ $(objpfx)bits/syscall.h ../sysdeps/unix/sysv/linux/sys/syscall.h
|
|
|
51f0aa |
+ printf '#include <sys/syscall.h>\n#include <bits/syscall.h>\n' | \
|
|
|
51f0aa |
+ $(CC) -E -o $@-tmp $(CFLAGS) $(CPPFLAGS) -x c - -dM
|
|
|
51f0aa |
+ $(move-if-change) $@-tmp $@
|
|
|
51f0aa |
+
|
|
|
51f0aa |
+# __NR_* system call names. Used by the test below.
|
|
|
51f0aa |
+$(objpfx)tst-syscall-list-nr.list: \
|
|
|
51f0aa |
+ ../sysdeps/unix/sysv/linux/filter-nr-syscalls.awk \
|
|
|
51f0aa |
+ $(objpfx)tst-syscall-list-macros.list
|
|
|
51f0aa |
+ $(AWK) -f $^ > $@-tmp
|
|
|
51f0aa |
+ $(move-if-change) $@-tmp $@
|
|
|
51f0aa |
+
|
|
|
51f0aa |
+# SYS_* system call names. Used by the test below.
|
|
|
51f0aa |
+$(objpfx)tst-syscall-list-sys.list: $(objpfx)tst-syscall-list-macros.list
|
|
|
51f0aa |
+ $(AWK) '/^#define SYS_/ { print substr($$2, 5) }' $< > $@-tmp
|
|
|
51f0aa |
+ $(move-if-change) $@-tmp $@
|
|
|
51f0aa |
+
|
|
|
51f0aa |
+tests: $(objpfx)tst-syscall-list.out
|
|
|
51f0aa |
+$(objpfx)tst-syscall-list.out: \
|
|
|
51f0aa |
+ ../sysdeps/unix/sysv/linux/tst-syscall-list.sh \
|
|
|
51f0aa |
+ $(objpfx)tst-syscall-list-nr.list $(objpfx)tst-syscall-list-sys.list
|
|
|
51f0aa |
+ $(BASH) $^ > $@
|
|
|
51f0aa |
+
|
|
|
ce426f |
+endif # $(subdir) == misc
|
|
|
ce426f |
|
|
|
ce426f |
ifeq ($(subdir),time)
|
|
|
ce426f |
sysdep_headers += sys/timex.h bits/timex.h
|
|
|
51f0aa |
diff --git a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
|
|
|
51f0aa |
new file mode 100644
|
|
|
51f0aa |
index 0000000..15b052a
|
|
|
ce426f |
--- /dev/null
|
|
|
ce426f |
+++ b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
|
|
|
ce426f |
@@ -0,0 +1,35 @@
|
|
|
ce426f |
+# Filter preprocessor __NR_* macros and extract system call names.
|
|
|
ce426f |
+# Copyright (C) 2017 Free Software Foundation, Inc.
|
|
|
ce426f |
+# This file is part of the GNU C Library.
|
|
|
ce426f |
+#
|
|
|
ce426f |
+# The GNU C Library is free software; you can redistribute it and/or
|
|
|
ce426f |
+# modify it under the terms of the GNU Lesser General Public
|
|
|
ce426f |
+# License as published by the Free Software Foundation; either
|
|
|
ce426f |
+# version 2.1 of the License, or (at your option) any later version.
|
|
|
ce426f |
+#
|
|
|
ce426f |
+# The GNU C Library is distributed in the hope that it will be useful,
|
|
|
ce426f |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ce426f |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
ce426f |
+# Lesser General Public License for more details.
|
|
|
ce426f |
+#
|
|
|
ce426f |
+# You should have received a copy of the GNU Lesser General Public
|
|
|
ce426f |
+# License along with the GNU C Library; if not, see
|
|
|
ce426f |
+# <http://www.gnu.org/licenses/>.
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Skip reserved system calls.
|
|
|
ce426f |
+/^#define __NR_(unused|reserved)[0-9]+ / {
|
|
|
ce426f |
+ next;
|
|
|
ce426f |
+}
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Skip pseudo-system calls which describe ranges.
|
|
|
ce426f |
+/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) / {
|
|
|
ce426f |
+ next;
|
|
|
ce426f |
+}
|
|
|
ce426f |
+/^#define __NR_(|64_|[NO]32_)Linux(_syscalls)? / {
|
|
|
ce426f |
+ next;
|
|
|
ce426f |
+}
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Print the remaining _NR_* macros as system call names.
|
|
|
ce426f |
+/^#define __NR_/ {
|
|
|
ce426f |
+ print substr($2, 6);
|
|
|
ce426f |
+}
|
|
|
51f0aa |
diff --git a/sysdeps/unix/sysv/linux/gen-syscall-h.awk b/sysdeps/unix/sysv/linux/gen-syscall-h.awk
|
|
|
51f0aa |
new file mode 100644
|
|
|
51f0aa |
index 0000000..0a27b3c
|
|
|
ce426f |
--- /dev/null
|
|
|
ce426f |
+++ b/sysdeps/unix/sysv/linux/gen-syscall-h.awk
|
|
|
ce426f |
@@ -0,0 +1,75 @@
|
|
|
ce426f |
+# Generate SYS_* macros from a list in a text file.
|
|
|
ce426f |
+# Copyright (C) 2017 Free Software Foundation, Inc.
|
|
|
ce426f |
+# This file is part of the GNU C Library.
|
|
|
ce426f |
+#
|
|
|
ce426f |
+# The GNU C Library is free software; you can redistribute it and/or
|
|
|
ce426f |
+# modify it under the terms of the GNU Lesser General Public
|
|
|
ce426f |
+# License as published by the Free Software Foundation; either
|
|
|
ce426f |
+# version 2.1 of the License, or (at your option) any later version.
|
|
|
ce426f |
+#
|
|
|
ce426f |
+# The GNU C Library is distributed in the hope that it will be useful,
|
|
|
ce426f |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ce426f |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
ce426f |
+# Lesser General Public License for more details.
|
|
|
ce426f |
+#
|
|
|
ce426f |
+# You should have received a copy of the GNU Lesser General Public
|
|
|
ce426f |
+# License along with the GNU C Library; if not, see
|
|
|
ce426f |
+# <http://www.gnu.org/licenses/>.
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Emit a conditional definition for SYS_NAME.
|
|
|
ce426f |
+function emit(name) {
|
|
|
ce426f |
+ print "#ifdef __NR_" name;
|
|
|
ce426f |
+ print "# define SYS_" name " __NR_" name;
|
|
|
ce426f |
+ print "#endif";
|
|
|
ce426f |
+ print "";
|
|
|
ce426f |
+}
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Bail out with an error.
|
|
|
ce426f |
+function fatal(message) {
|
|
|
ce426f |
+ print FILENAME ":" FNR ": " message > "/dev/stderr";
|
|
|
ce426f |
+ exit 1;
|
|
|
ce426f |
+}
|
|
|
ce426f |
+
|
|
|
ce426f |
+BEGIN {
|
|
|
ce426f |
+ name = "";
|
|
|
ce426f |
+ kernel = "";
|
|
|
ce426f |
+}
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Skip empty lines and comments.
|
|
|
ce426f |
+/^\s*(|#.*)$/ {
|
|
|
ce426f |
+ next;
|
|
|
ce426f |
+}
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Kernel version. Used for documentation purposes only.
|
|
|
ce426f |
+/^kernel [0-9.]+$/ {
|
|
|
ce426f |
+ if (kernel != "") {
|
|
|
ce426f |
+ fatal("duplicate kernel directive");
|
|
|
ce426f |
+ }
|
|
|
ce426f |
+ kernel = $2;
|
|
|
ce426f |
+ print "/* Generated at libc build time from syscall list. */";
|
|
|
ce426f |
+ print "/* The system call list corresponds to kernel " kernel ". */";
|
|
|
ce426f |
+ print "";
|
|
|
ce426f |
+ print "#ifndef _SYSCALL_H"
|
|
|
ce426f |
+ print "# error \"Never use <bits/syscall.h> directly; include <sys/syscall.h> instead.\"";
|
|
|
ce426f |
+ print "#endif";
|
|
|
ce426f |
+ print "";
|
|
|
ce426f |
+ next;
|
|
|
ce426f |
+}
|
|
|
ce426f |
+
|
|
|
ce426f |
+# If there is just one word, it is a system call.
|
|
|
ce426f |
+/^[a-zA-Z_][a-zA-Z0-9_]+$/ {
|
|
|
ce426f |
+ if (kernel == "") {
|
|
|
ce426f |
+ fatal("expected kernel directive before this line");
|
|
|
ce426f |
+ }
|
|
|
ce426f |
+ if ($1 <= name) {
|
|
|
ce426f |
+ fatal("name " name " violates ordering");
|
|
|
ce426f |
+ }
|
|
|
ce426f |
+ emit($1);
|
|
|
ce426f |
+ name = $1;
|
|
|
ce426f |
+ next;
|
|
|
ce426f |
+}
|
|
|
ce426f |
+
|
|
|
ce426f |
+# The rest has to be syntax errors.
|
|
|
ce426f |
+// {
|
|
|
ce426f |
+ fatal("unrecognized syntax");
|
|
|
ce426f |
+}
|
|
|
51f0aa |
diff --git a/sysdeps/unix/sysv/linux/tst-syscall-list.sh b/sysdeps/unix/sysv/linux/tst-syscall-list.sh
|
|
|
51f0aa |
new file mode 100644
|
|
|
51f0aa |
index 0000000..f48b7cd
|
|
|
ce426f |
--- /dev/null
|
|
|
ce426f |
+++ b/sysdeps/unix/sysv/linux/tst-syscall-list.sh
|
|
|
ce426f |
@@ -0,0 +1,72 @@
|
|
|
ce426f |
+#!/bin/bash
|
|
|
ce426f |
+# Consistency checks for the system call list
|
|
|
ce426f |
+# Copyright (C) 2017 Free Software Foundation, Inc.
|
|
|
ce426f |
+# This file is part of the GNU C Library.
|
|
|
ce426f |
+#
|
|
|
ce426f |
+# The GNU C Library is free software; you can redistribute it and/or
|
|
|
ce426f |
+# modify it under the terms of the GNU Lesser General Public
|
|
|
ce426f |
+# License as published by the Free Software Foundation; either
|
|
|
ce426f |
+# version 2.1 of the License, or (at your option) any later version.
|
|
|
ce426f |
+#
|
|
|
ce426f |
+# The GNU C Library is distributed in the hope that it will be useful,
|
|
|
ce426f |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ce426f |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
ce426f |
+# Lesser General Public License for more details.
|
|
|
ce426f |
+#
|
|
|
ce426f |
+# You should have received a copy of the GNU Lesser General Public
|
|
|
ce426f |
+# License along with the GNU C Library; if not, see
|
|
|
ce426f |
+# <http://www.gnu.org/licenses/>.
|
|
|
ce426f |
+
|
|
|
ce426f |
+export LC_ALL=C
|
|
|
ce426f |
+set -e
|
|
|
ce426f |
+set -o pipefail
|
|
|
ce426f |
+
|
|
|
ce426f |
+if test $# != 2 ; then
|
|
|
ce426f |
+ echo "error: wrong number of arguments: $#"
|
|
|
ce426f |
+ exit 1
|
|
|
ce426f |
+fi
|
|
|
ce426f |
+
|
|
|
ce426f |
+list_nr="$1"
|
|
|
ce426f |
+list_sys="$2"
|
|
|
ce426f |
+
|
|
|
ce426f |
+errors=0
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Use getpid as a system call which is expected to be always defined.
|
|
|
ce426f |
+# alpha uses getxpid instead, so it is permitted as an alternative.
|
|
|
ce426f |
+if ! grep -E -q '^getx?pid$' -- "$list_nr" ; then
|
|
|
ce426f |
+ echo "error: __NR_getpid not defined"
|
|
|
ce426f |
+ errors=1
|
|
|
ce426f |
+fi
|
|
|
ce426f |
+if ! grep -E -q '^getx?pid$' -- "$list_sys" ; then
|
|
|
ce426f |
+ echo "error: SYS_getpid not defined"
|
|
|
ce426f |
+ errors=1
|
|
|
ce426f |
+fi
|
|
|
ce426f |
+
|
|
|
ce426f |
+comm_1="$(mktemp)"
|
|
|
ce426f |
+comm_2="$(mktemp)"
|
|
|
ce426f |
+comm_result="$(mktemp)"
|
|
|
ce426f |
+cleanup () {
|
|
|
ce426f |
+ rm -f -- "$comm_1" "$comm_2" "$comm_result"
|
|
|
ce426f |
+}
|
|
|
ce426f |
+trap cleanup 0
|
|
|
ce426f |
+
|
|
|
ce426f |
+sort -o "$comm_1" -- "$list_nr"
|
|
|
ce426f |
+sort -o "$comm_2" -- "$list_sys"
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Check for missing SYS_* macros.
|
|
|
ce426f |
+comm --check-order -2 -3 -- "$comm_1" "$comm_2" > "$comm_result"
|
|
|
ce426f |
+if test -s "$comm_result"; then
|
|
|
ce426f |
+ echo "error: These system calls need to be added to syscall-names.list:"
|
|
|
ce426f |
+ cat -- "$comm_result"
|
|
|
ce426f |
+ errors=1
|
|
|
ce426f |
+fi
|
|
|
ce426f |
+
|
|
|
ce426f |
+# Check for additional SYS_* macros.
|
|
|
ce426f |
+comm --check-order -1 -3 -- "$comm_1" "$comm_2" > "$comm_result"
|
|
|
ce426f |
+if test -s "$comm_result"; then
|
|
|
ce426f |
+ echo "error: The following system calls have unexpected SYS_* macros:"
|
|
|
ce426f |
+ cat -- "$comm_result"
|
|
|
ce426f |
+ errors=1
|
|
|
ce426f |
+fi
|
|
|
ce426f |
+
|
|
|
ce426f |
+exit "$errors"
|