#!/usr/bin/env python ''' Generate syscall tables from the Linux source. Used to generate manticore/platforms/linux_syscalls.py. This fetches the tables from kernel.org. Usage: ./extract_syscalls.py [--linux_version linux_version] linux_syscalls.py ''' import os import sys import urllib import argparse base_url = 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/{}?id=refs/tags/v{}' arch_tables = { 'armv7': 'arch/arm/tools/syscall.tbl', 'i386': 'arch/x86/entry/syscalls/syscall_32.tbl', 'amd64': 'arch/x86/entry/syscalls/syscall_64.tbl', } __ARM_NR_BASE = 0xf0000 additional_syscalls = { 'armv7': [ ('sys_ARM_NR_breakpoint', __ARM_NR_BASE + 1), ('sys_ARM_NR_cacheflush', __ARM_NR_BASE + 2), ('sys_ARM_NR_usr26', __ARM_NR_BASE + 3), ('sys_ARM_NR_usr32', __ARM_NR_BASE + 4), ('sys_ARM_NR_set_tls', __ARM_NR_BASE + 5), ] } if __name__=='__main__': parser = argparse.ArgumentParser(description='Generate syscall tables') parser.add_argument('output', help='Python output to generate tables') parser.add_argument('--linux_version', help='Major version of the Linux kernel to use', default='4.11') args = parser.parse_args() output = open(args.output, 'w+') output.write('#\n#\n# AUTOGENERATED, DO NOT EDIT\n#\n') output.write('# From version: {}\n#\n\n'.format(args.linux_version)) for arch, path in arch_tables.items(): url = base_url.format(path, args.linux_version) tbl = urllib.urlopen(url) if tbl.code // 100 != 2: sys.stderr.write("Failed retrieving table; check version and connection.\n") sys.stderr.write("Url: {}\n".format(url)) sys.exit(1) output.write('{} = {{\n'.format(arch)) for line in tbl.readlines(): line = line.strip() if line.startswith('#'): continue columns = line.split() if len(columns) < 4: continue num, abi, name, entry = columns[:4] output.write(' {}: "{}",\n'.format(num, entry)) for entry, num in additional_syscalls.get(arch, {}): output.write(' {}: "{}",\n'.format(num, entry)) output.write('}\n')