]> git.proxmox.com Git - systemd.git/blob - src/basic/missing_syscalls.py
New upstream version 249~rc1
[systemd.git] / src / basic / missing_syscalls.py
1 #!/usr/bin/env python3
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3
4 import sys
5 import functools
6
7 # We only generate numbers for a dozen or so syscalls
8 SYSCALLS = [
9 'bpf',
10 'close_range',
11 'copy_file_range',
12 'epoll_pwait2',
13 'getrandom',
14 'memfd_create',
15 'mount_setattr',
16 'move_mount',
17 'name_to_handle_at',
18 'open_tree',
19 'pidfd_open',
20 'pidfd_send_signal',
21 'pkey_mprotect',
22 'renameat2',
23 'setns',
24 'statx',
25 ]
26
27 def dictify(f):
28 def wrap(*args, **kwargs):
29 return dict(f(*args, **kwargs))
30 return functools.update_wrapper(wrap, f)
31
32 @dictify
33 def parse_syscall_table(filename):
34 print(f'Reading {filename}…')
35 for line in open(filename):
36 items = line.split()
37 if len(items) >= 2:
38 yield items[0], int(items[1])
39
40 def parse_syscall_tables(filenames):
41 return {filename.split('-')[-1][:-4]: parse_syscall_table(filename)
42 for filename in filenames}
43
44 DEF_TEMPLATE_A = '''\
45
46 #ifndef __IGNORE_{syscall}
47 '''
48
49 DEF_TEMPLATE_B = '''\
50 # if defined(__aarch64__)
51 # define systemd_NR_{syscall} {nr_arm64}
52 # elif defined(__alpha__)
53 # define systemd_NR_{syscall} {nr_alpha}
54 # elif defined(__arc__) || defined(__tilegx__)
55 # define systemd_NR_{syscall} {nr_arc}
56 # elif defined(__arm__)
57 # define systemd_NR_{syscall} {nr_arm}
58 # elif defined(__i386__)
59 # define systemd_NR_{syscall} {nr_i386}
60 # elif defined(__ia64__)
61 # define systemd_NR_{syscall} {nr_ia64}
62 # elif defined(__m68k__)
63 # define systemd_NR_{syscall} {nr_m68k}
64 # elif defined(_MIPS_SIM)
65 # if _MIPS_SIM == _MIPS_SIM_ABI32
66 # define systemd_NR_{syscall} {nr_mipso32}
67 # elif _MIPS_SIM == _MIPS_SIM_NABI32
68 # define systemd_NR_{syscall} {nr_mips64n32}
69 # elif _MIPS_SIM == _MIPS_SIM_ABI64
70 # define systemd_NR_{syscall} {nr_mips64}
71 # else
72 # error "Unknown MIPS ABI"
73 # endif
74 # elif defined(__powerpc__)
75 # define systemd_NR_{syscall} {nr_powerpc}
76 # elif defined(__riscv)
77 # if __riscv_xlen == 32
78 # define systemd_NR_{syscall} {nr_riscv32}
79 # elif __riscv_xlen == 64
80 # define systemd_NR_{syscall} {nr_riscv64}
81 # else
82 # error "Unknown RISC-V ABI"
83 # endif
84 # elif defined(__s390__)
85 # define systemd_NR_{syscall} {nr_s390}
86 # elif defined(__sparc__)
87 # define systemd_NR_{syscall} {nr_sparc}
88 # elif defined(__x86_64__)
89 # if defined(__ILP32__)
90 # define systemd_NR_{syscall} ({nr_x86_64} | /* __X32_SYSCALL_BIT */ 0x40000000)
91 # else
92 # define systemd_NR_{syscall} {nr_x86_64}
93 # endif
94 # elif !defined(missing_arch_template)
95 %s
96 # endif
97 '''
98
99 DEF_TEMPLATE_C = '''\
100
101 /* may be an (invalid) negative number due to libseccomp, see PR 13319 */
102 # if defined __NR_{syscall} && __NR_{syscall} >= 0
103 # if defined systemd_NR_{syscall}
104 assert_cc(__NR_{syscall} == systemd_NR_{syscall});
105 # endif
106 # else
107 # if defined __NR_{syscall}
108 # undef __NR_{syscall}
109 # endif
110 # if defined systemd_NR_{syscall} && systemd_NR_{syscall} >= 0
111 # define __NR_{syscall} systemd_NR_{syscall}
112 # endif
113 # endif
114 #endif'''
115
116 DEF_TEMPLATE = (DEF_TEMPLATE_A +
117 DEF_TEMPLATE_B % '# warning "{syscall}() syscall number is unknown for your architecture"' +
118 DEF_TEMPLATE_C)
119
120 ARCH_CHECK = '''\
121 /* Note: if this code looks strange, this is because it is derived from the same
122 * template as the per-syscall blocks below. */
123 ''' + '\n'.join(line for line in DEF_TEMPLATE_B.splitlines()
124 if ' define ' not in line) % '''\
125 # warning "Current architecture is missing from the template"
126 # define missing_arch_template 1'''
127
128 def print_syscall_def(syscall, tables, out):
129 mappings = {f'nr_{arch}':t.get(syscall, -1)
130 for arch, t in tables.items()}
131 print(DEF_TEMPLATE.format(syscall=syscall, **mappings),
132 file=out)
133
134 def print_syscall_defs(syscalls, tables, out):
135 print('''\
136 /* SPDX-License-Identifier: LGPL-2.1-or-later
137 * This file is generated by src/basic/missing_syscalls.py. Do not edit!
138 *
139 * Use 'ninja -C build update-syscall-tables' to download new syscall tables,
140 * and 'ninja -C build update-syscall-header' to regenerate this file.
141 */
142 ''',
143 file=out)
144 print(ARCH_CHECK, file=out)
145 for syscall in syscalls:
146 print_syscall_def(syscall, tables, out)
147
148 if __name__ == '__main__':
149 output_file = sys.argv[1]
150 arch_files = sys.argv[2:]
151 out = open(output_file, 'wt')
152
153 tables = parse_syscall_tables(arch_files)
154 print_syscall_defs(SYSCALLS, tables, out)
155
156 print(f'Wrote {output_file}')