elf/Makefile: Split and sort PIE tests
[glibc.git] / sysdeps / unix / sysv / linux / update-syscall-lists.py
blob2393e9c40accdc5176d94d761279f992912f616f
1 #!/usr/bin/python3
2 # Regenerate <arch-syscall.h> and update syscall-names.list.
3 # Copyright (C) 2020-2024 Free Software Foundation, Inc.
4 # This file is part of the GNU C Library.
6 # The GNU C Library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # The GNU C Library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with the GNU C Library; if not, see
18 # <http://www.gnu.org/licenses/>.
20 import argparse
21 import io
22 import os
23 import sys
25 import glibcextract
26 import glibcsyscalls
28 def atomic_replace(path, contents):
29 """Atomically replace PATH with CONTENTS, via a temporary file.
31 The name of the temporary file is predictable, so locking is
32 required to avoid corruption.
34 """
35 path_tmp = path + 'T'
36 with open(path_tmp, 'w') as tmp:
37 tmp.write(contents)
38 ok = False
39 try:
40 os.rename(path_tmp, path)
41 ok = True
42 finally:
43 # On error, try to delete the temporary file.
44 if not ok:
45 try:
46 os.unlink(path_tmp)
47 except:
48 pass
50 def main():
51 """The main entry point."""
52 parser = argparse.ArgumentParser(
53 description='System call list consistency checks')
54 parser.add_argument('--cc', metavar='CC', required=True,
55 help='C compiler (including options) to use')
56 parser.add_argument('--lock', metavar='PATH', required=True,
57 help='file to lock during the updates')
58 parser.add_argument('arch_syscall', metavar='ARCH-SYSCALL-H',
59 help='The <arch-syscall.h> file to update')
60 parser.add_argument('names_list', metavar='SYSCALL-NAMES-LIST',
61 help='The syscall name list to update ')
63 args = parser.parse_args()
65 kernel_constants = glibcsyscalls.kernel_constants(args.cc)
67 with open(args.lock, 'r+') as lockfile:
68 os.lockf(lockfile.fileno(), os.F_LOCK, 0)
70 # Replace <arch-syscall.h> with data derived from kernel headers.
71 # No merging is necessary here. Arch-specific changes should go
72 # into <fixup-unistd-asm.h>.
73 out = io.StringIO()
74 out.write('/* AUTOGENERATED by update-syscall-lists.py. */\n')
75 for name, value in sorted(kernel_constants.items()):
76 out.write('#define __NR_{} {}\n'.format(name, value))
77 atomic_replace(args.arch_syscall, out.getvalue())
79 # Merge the architecture-specific system call names into the
80 # global names list, syscall-names.list. This file contains names
81 # from other architectures (and comments), so it is necessary to
82 # merge the existing files with the names obtained from the
83 # kernel.
84 with open(args.names_list, 'r') as list_file:
85 names_list = glibcsyscalls.SyscallNamesList(list_file)
86 merged = names_list.merge(kernel_constants.keys())
87 out = io.StringIO()
88 for line in merged:
89 out.write(line)
90 atomic_replace(args.names_list, out.getvalue())
92 if __name__ == '__main__':
93 main()