diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/update-syscall-lists.py')
-rw-r--r-- | sysdeps/unix/sysv/linux/update-syscall-lists.py | 93 |
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() |