about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/update-syscall-lists.py
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()