1#!/usr/bin/env python3
2
3import argparse
4import logging
5import os
6import re
7
8from gensyscalls import SupportedArchitectures, SysCallsTxtParser
9from genseccomp import parse_syscall_NRs
10
11
12def load_syscall_names_from_file(file_path, architecture):
13    parser = SysCallsTxtParser()
14    parser.parse_open_file(open(file_path))
15    arch_map = {}
16    for syscall in parser.syscalls:
17        if syscall.get(architecture):
18            arch_map[syscall["func"]] = syscall["name"]
19
20    return arch_map
21
22
23def gen_syscall_nrs(out_file, base_syscall_file, syscall_NRs):
24    for arch in SupportedArchitectures:
25        base_names = load_syscall_names_from_file(base_syscall_file, arch)
26
27        for func, syscall in base_names.items():
28            out_file.write("#define __" + arch + "_" + func + " " +
29                           str(syscall_NRs[arch][syscall]) + ";\n")
30
31
32def main():
33    parser = argparse.ArgumentParser(
34        description=
35        "Generates a mapping of bionic functions to system call numbers per architecture."
36    )
37    parser.add_argument("--verbose", "-v", help="Enables verbose logging.")
38    parser.add_argument("--out-dir",
39                        help="The output directory for the output files")
40    parser.add_argument(
41        "base_file",
42        metavar="base-file",
43        type=str,
44        help="The path of the base syscall list (SYSCALLS.TXT).")
45    parser.add_argument(
46        "files",
47        metavar="FILE",
48        type=str,
49        nargs="+",
50        help=("A syscall name-number mapping file for an architecture.\n"))
51    args = parser.parse_args()
52
53    if args.verbose:
54        logging.basicConfig(level=logging.DEBUG)
55    else:
56        logging.basicConfig(level=logging.INFO)
57
58    syscall_NRs = {}
59    for filename in args.files:
60        m = re.search(r"libseccomp_gen_syscall_nrs_([^/]+)", filename)
61        syscall_NRs[m.group(1)] = parse_syscall_NRs(filename)
62
63    output_path = os.path.join(args.out_dir, "func_to_syscall_nrs.h")
64    with open(output_path, "w") as output_file:
65        gen_syscall_nrs(out_file=output_file,
66                        syscall_NRs=syscall_NRs,
67                        base_syscall_file=args.base_file)
68
69
70if __name__ == "__main__":
71    main()
72