]>
Commit | Line | Data |
---|---|---|
4cf0d223 FW |
1 | #!/usr/bin/python3 |
2 | # Consistency checks for glibc system call lists. | |
2b778ceb | 3 | # Copyright (C) 2020-2021 Free Software Foundation, Inc. |
4cf0d223 FW |
4 | # This file is part of the GNU C Library. |
5 | # | |
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. | |
10 | # | |
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. | |
15 | # | |
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/>. | |
19 | ||
20 | import argparse | |
21 | import sys | |
22 | ||
23 | import glibcextract | |
24 | import glibcsyscalls | |
25 | ||
26 | def main(): | |
27 | """The main entry point.""" | |
28 | parser = argparse.ArgumentParser( | |
29 | description="System call list consistency checks") | |
30 | parser.add_argument('--cc', metavar='CC', required=True, | |
31 | help='C compiler (including options) to use') | |
32 | parser.add_argument('syscall_numbers_list', metavar='PATH', | |
33 | help='Path to the list of system call numbers') | |
34 | parser.add_argument('syscall_names_list', metavar='PATH', | |
35 | help='Path to the list of system call names') | |
36 | ||
37 | args = parser.parse_args() | |
38 | ||
39 | glibc_constants = glibcsyscalls.load_arch_syscall_header( | |
40 | args.syscall_numbers_list) | |
41 | with open(args.syscall_names_list) as inp: | |
42 | glibc_names = glibcsyscalls.SyscallNamesList(inp) | |
43 | kernel_constants = glibcsyscalls.kernel_constants(args.cc) | |
44 | kernel_version = glibcsyscalls.linux_kernel_version(args.cc) | |
45 | ||
46 | errors = 0 | |
47 | warnings = False | |
48 | for name in glibc_constants.keys() & kernel_constants.keys(): | |
49 | if glibc_constants[name] != kernel_constants[name]: | |
50 | print("error: syscall {!r} number mismatch: glibc={!r} kernel={!r}" | |
51 | .format(name, glibc_constants[name], kernel_constants[name])) | |
52 | errors = 1 | |
53 | ||
54 | # The architecture-specific list in the glibc tree must be a | |
55 | # subset of the global list of system call names. | |
56 | for name in glibc_constants.keys() - set(glibc_names.syscalls): | |
57 | print("error: architecture syscall {!r} missing from global names list" | |
58 | .format(name)) | |
59 | errors = 1 | |
60 | ||
61 | for name in glibc_constants.keys() - kernel_constants.keys(): | |
62 | print("info: glibc syscall {!r} not known to kernel".format(name)) | |
63 | warnings = True | |
64 | ||
65 | # If the glibc-recorded kernel version is not older than the | |
66 | # installed kernel headers, the glibc system call set must be a | |
67 | # superset of the kernel system call set. | |
68 | if glibc_names.kernel_version >= kernel_version: | |
69 | for name in kernel_constants.keys() - glibc_constants.keys(): | |
70 | print("error: kernel syscall {!r} ({}) not known to glibc" | |
71 | .format(name, kernel_constants[name])) | |
72 | errors = 1 | |
73 | else: | |
74 | for name in kernel_constants.keys() - glibc_constants.keys(): | |
75 | print("warning: kernel syscall {!r} ({}) not known to glibc" | |
76 | .format(name, kernel_constants[name])) | |
77 | warnings = True | |
78 | ||
79 | if errors > 0 or warnings: | |
80 | print("info: glibc tables are based on kernel version {}".format( | |
81 | ".".join(map(str, glibc_names.kernel_version)))) | |
82 | print("info: installed kernel headers are version {}".format( | |
83 | ".".join(map(str, kernel_version)))) | |
84 | ||
85 | sys.exit(errors) | |
86 | ||
87 | if __name__ == '__main__': | |
88 | main() |