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