]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/missing_syscalls.py
Merge pull request #18007 from fw-strlen/ipv6_masq_and_dnat
[thirdparty/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 'getrandom',
13 'memfd_create',
14 'name_to_handle_at',
15 'pidfd_open',
16 'pidfd_send_signal',
17 'pkey_mprotect',
18 'renameat2',
19 'setns',
20 'statx']
21
22 def dictify(f):
23 def wrap(*args, **kwargs):
24 return dict(f(*args, **kwargs))
25 return functools.update_wrapper(wrap, f)
26
27 @dictify
28 def parse_syscall_table(filename):
29 print(f'Reading {filename}…')
30 for line in open(filename):
31 items = line.split()
32 if len(items) >= 2:
33 yield items[0], int(items[1])
34
35 def parse_syscall_tables(filenames):
36 return {filename.split('-')[-1][:-4]: parse_syscall_table(filename)
37 for filename in filenames}
38
39 DEF_TEMPLATE = '''\
40 #ifndef __IGNORE_{syscall}
41 # if defined(__aarch64__)
42 # define systemd_NR_{syscall} {nr_arm64}
43 # elif defined(__alpha__)
44 # define systemd_NR_{syscall} {nr_alpha}
45 # elif defined(__arc__) || defined(__tilegx__)
46 # define systemd_NR_{syscall} {nr_arc}
47 # elif defined(__arm__)
48 # define systemd_NR_{syscall} {nr_arm}
49 # elif defined(__i386__)
50 # define systemd_NR_{syscall} {nr_i386}
51 # elif defined(__ia64__)
52 # define systemd_NR_{syscall} {nr_ia64}
53 # elif defined(__m68k__)
54 # define systemd_NR_{syscall} {nr_m68k}
55 # elif defined(_MIPS_SIM)
56 # if _MIPS_SIM == _MIPS_SIM_ABI32
57 # define systemd_NR_{syscall} {nr_mipso32}
58 # elif _MIPS_SIM == _MIPS_SIM_NABI32
59 # define systemd_NR_{syscall} {nr_mips64n32}
60 # elif _MIPS_SIM == _MIPS_SIM_ABI64
61 # define systemd_NR_{syscall} {nr_mips64}
62 # else
63 # error "Unknown MIPS ABI"
64 # endif
65 # elif defined(__powerpc__)
66 # define systemd_NR_{syscall} {nr_powerpc}
67 # elif defined(__s390__)
68 # define systemd_NR_{syscall} {nr_s390}
69 # elif defined(__sparc__)
70 # define systemd_NR_{syscall} {nr_sparc}
71 # elif defined(__x86_64__)
72 # if defined(__ILP32__)
73 # define systemd_NR_{syscall} ({nr_x86_64} | /* __X32_SYSCALL_BIT */ 0x40000000)
74 # else
75 # define systemd_NR_{syscall} {nr_x86_64}
76 # endif
77 # else
78 # warning "{syscall}() syscall number is unknown for your architecture"
79 # endif
80
81 /* may be an (invalid) negative number due to libseccomp, see PR 13319 */
82 # if defined __NR_{syscall} && __NR_{syscall} >= 0
83 # if defined systemd_NR_{syscall}
84 assert_cc(__NR_{syscall} == systemd_NR_{syscall});
85 # endif
86 # else
87 # if defined __NR_{syscall}
88 # undef __NR_{syscall}
89 # endif
90 # if defined systemd_NR_{syscall} && systemd_NR_{syscall} >= 0
91 # define __NR_{syscall} systemd_NR_{syscall}
92 # endif
93 # endif
94 #endif
95 '''
96
97 def print_syscall_def(syscall, tables, out):
98 mappings = {f'nr_{arch}':t.get(syscall, -1)
99 for arch, t in tables.items()}
100 print(DEF_TEMPLATE.format(syscall=syscall, **mappings),
101 file=out)
102
103 def print_syscall_defs(syscalls, tables, out):
104 print('''\
105 /* SPDX-License-Identifier: LGPL-2.1-or-later
106 * This file is generated. Do not edit! */
107 ''' , file=out)
108 for syscall in syscalls:
109 print_syscall_def(syscall, tables, out)
110
111 if __name__ == '__main__':
112 output_file = sys.argv[1]
113 arch_files = sys.argv[2:]
114 out = open(output_file, 'wt')
115
116 tables = parse_syscall_tables(arch_files)
117 print_syscall_defs(SYSCALLS, tables, out)
118
119 print(f'Wrote {output_file}')