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