aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/update-syscall-lists.py')
-rw-r--r--sysdeps/unix/sysv/linux/update-syscall-lists.py93
1 files changed, 93 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/update-syscall-lists.py b/sysdeps/unix/sysv/linux/update-syscall-lists.py
new file mode 100644
index 0000000000..aa2dda1bd1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/update-syscall-lists.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python3
+# Regenerate <arch-syscall.h> and update syscall-names.list.
+# Copyright (C) 2020 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/>.
+
+import argparse
+import io
+import os
+import sys
+
+import glibcextract
+import glibcsyscalls
+
+def atomic_replace(path, contents):
+ """Atomically replace PATH with CONTENTS, via a temporary file.
+
+ The name of the temporary file is predictable, so locking is
+ required to avoid corruption.
+
+ """
+ path_tmp = path + 'T'
+ with open(path_tmp, 'w') as tmp:
+ tmp.write(contents)
+ ok = False
+ try:
+ os.rename(path_tmp, path)
+ ok = True
+ finally:
+ # On error, try to delete the temporary file.
+ if not ok:
+ try:
+ os.unlink(path_tmp)
+ except:
+ pass
+
+def main():
+ """The main entry point."""
+ parser = argparse.ArgumentParser(
+ description='System call list consistency checks')
+ parser.add_argument('--cc', metavar='CC', required=True,
+ help='C compiler (including options) to use')
+ parser.add_argument('--lock', metavar='PATH', required=True,
+ help='file to lock during the updates')
+ parser.add_argument('arch_syscall', metavar='ARCH-SYSCALL-H',
+ help='The <arch-syscall.h> file to update')
+ parser.add_argument('names_list', metavar='SYSCALL-NAMES-LIST',
+ help='The syscall name list to update ')
+
+ args = parser.parse_args()
+
+ kernel_constants = glibcsyscalls.kernel_constants(args.cc)
+
+ with open(args.lock, 'r+') as lockfile:
+ os.lockf(lockfile.fileno(), os.F_LOCK, 0)
+
+ # Replace <arch-syscall.h> with data derived from kernel headers.
+ # No merging is necessary here. Arch-specific changes should go
+ # into <fixup-unistd-asm.h>.
+ out = io.StringIO()
+ out.write('/* AUTOGENERATED by update-syscall-lists.py. */\n')
+ for name, value in sorted(kernel_constants.items()):
+ out.write('#define __NR_{} {}\n'.format(name, value))
+ atomic_replace(args.arch_syscall, out.getvalue())
+
+ # Merge the architecture-specific system call names into the
+ # global names list, syscall-names.list. This file contains names
+ # from other architectures (and comments), so it is necessary to
+ # merge the existing files with the names obtained from the
+ # kernel.
+ with open(args.names_list, 'r') as list_file:
+ names_list = glibcsyscalls.SyscallNamesList(list_file)
+ merged = names_list.merge(kernel_constants.keys())
+ out = io.StringIO()
+ for line in merged:
+ out.write(line)
+ atomic_replace(args.names_list, out.getvalue())
+
+if __name__ == '__main__':
+ main()