#!/usr/bin/env python3
#
# This script generates syscall name to number mapping for supported
# architectures.  To update the output, runs:
#
#  $ app/gen_blacklist.py --allowed app/assets/syscalls_allowed.json \
#      --blocked app/assets/syscalls_blocked.json
#
# Note that these are just syscalls that explicitly allowed and blocked in CTS
# currently.
#
# TODO: Consider generating it in Android.mk/bp.

import argparse
import glob
import json
import os
import subprocess

_SUPPORTED_ARCHS = ['arm', 'arm64', 'x86', 'x86_64', 'mips', 'mips64']

# Syscalls that are currently explicitly allowed in CTS
_SYSCALLS_ALLOWED_IN_CTS = {
    'openat': 'all',

    # b/35034743 - do not remove test without reading bug.
    'syncfs': 'arm64',

    # b/35906875 - do not remove test without reading bug
    'inotify_init': 'arm',
}

# Syscalls that are currently explicitly blocked in CTS
_SYSCALLS_BLOCKED_IN_CTS = {
    'acct': 'all',
    'add_key': 'all',
    'adjtimex': 'all',
    'chroot': 'all',
    'clock_adjtime': 'all',
    'clock_settime': 'all',
    'delete_module': 'all',
    'init_module': 'all',
    'keyctl': 'all',
    'mount': 'all',
    'reboot': 'all',
    'setdomainname': 'all',
    'sethostname': 'all',
    'settimeofday': 'all',
    'setfsgid': 'all',
    'setfsuid': 'all',
    'setgid': 'all',
    'setgid32': 'x86,arm',
    'setgroups': 'all',
    'setgroups32': 'x86,arm',
    'setregid': 'all',
    'setregid32': 'x86,arm',
    'setresgid': 'all',
    'setresgid32': 'x86,arm',
    'setreuid': 'all',
    'setreuid32': 'x86,arm',
    'setuid': 'all',
    'setuid32': 'x86,arm',
    'swapoff': 'all',
    'swapoff': 'all',
    'swapon': 'all',
    'swapon': 'all',
    'syslog': 'all',
    'umount2': 'all',
}

def create_syscall_name_to_number_map(arch, names):
  arch_config = {
      'arm': {
          'uapi_class': 'asm-arm',
          'extra_cflags': [],
      },
      'arm64': {
          'uapi_class': 'asm-arm64',
          'extra_cflags': [],
      },
      'x86': {
          'uapi_class': 'asm-x86',
          'extra_cflags': ['-D__i386__'],
      },
      'x86_64': {
          'uapi_class': 'asm-x86',
          'extra_cflags': [],
      },
      'mips': {
          'uapi_class': 'asm-mips',
          'extra_cflags': ['-D_MIPS_SIM=_MIPS_SIM_ABI32'],
      },
      'mips64': {
          'uapi_class': 'asm-mips',
          'extra_cflags': ['-D_MIPS_SIM=_MIPS_SIM_ABI64'],
      }
  }

  # Run preprocessor over the __NR_syscall symbols, including unistd.h,
  # to get the actual numbers
  # TODO: The following code is forked from bionic/libc/tools/genseccomp.py.
  # Figure out if we can de-duplicate them crossing cts project boundary.
  prefix = '__SECCOMP_'  # prefix to ensure no name collisions
  kernel_uapi_path = os.path.join(os.getenv('ANDROID_BUILD_TOP'),
                                  'bionic/libc/kernel/uapi')
  cpp = subprocess.Popen(
      [get_latest_clang_path(),
       '-E', '-nostdinc',
       '-I' + os.path.join(kernel_uapi_path,
                           arch_config[arch]['uapi_class']),
       '-I' + os.path.join(kernel_uapi_path)
       ]
      + arch_config[arch]['extra_cflags']
      + ['-'],
      universal_newlines=True,
      stdin=subprocess.PIPE, stdout=subprocess.PIPE)
  cpp.stdin.write('#include <asm/unistd.h>\n')
  for name in names:
    # In SYSCALLS.TXT, there are two arm-specific syscalls whose names start
    # with __ARM__NR_. These we must simply write out as is.
    if not name.startswith('__ARM_NR_'):
      cpp.stdin.write(prefix + name + ', __NR_' + name + '\n')
    else:
      cpp.stdin.write(prefix + name + ', ' + name + '\n')
  content = cpp.communicate()[0].split('\n')

  # The input is now the preprocessed source file. This will contain a lot
  # of junk from the preprocessor, but our lines will be in the format:
  #
  #     __SECCOMP_${NAME}, (0 + value)
  syscalls = {}
  for line in content:
    if not line.startswith(prefix):
      continue
    # We might pick up extra whitespace during preprocessing, so best to strip.
    name, value = [w.strip() for w in line.split(',')]
    name = name[len(prefix):]
    # Note that some of the numbers were expressed as base + offset, so we
    # need to eval, not just int
    value = eval(value)
    if name in syscalls:
      raise Exception('syscall %s is re-defined' % name)
    syscalls[name] = value
  return syscalls

def get_latest_clang_path():
  candidates = sorted(glob.glob(os.path.join(os.getenv('ANDROID_BUILD_TOP'),
      'prebuilts/clang/host/linux-x86/clang-*')), reverse=True)
  for clang_dir in candidates:
    clang_exe = os.path.join(clang_dir, 'bin/clang')
    if os.path.exists(clang_exe):
      return clang_exe
  raise FileNotFoundError('Cannot locate clang executable')

def collect_syscall_names_for_arch(syscall_map, arch):
  syscall_names = []
  for syscall in syscall_map.keys():
    if (arch in syscall_map[syscall] or
        'all' == syscall_map[syscall]):
      syscall_names.append(syscall)
  return syscall_names

def main():
  parser = argparse.ArgumentParser('syscall name to number generator')
  parser.add_argument('--allowed', metavar='path/to/json', type=str)
  parser.add_argument('--blocked', metavar='path/to/json', type=str)
  args = parser.parse_args()

  allowed = {}
  blocked = {}
  for arch in _SUPPORTED_ARCHS:
    blocked[arch] = create_syscall_name_to_number_map(
        arch,
        collect_syscall_names_for_arch(_SYSCALLS_BLOCKED_IN_CTS, arch))
    allowed[arch] = create_syscall_name_to_number_map(
        arch,
        collect_syscall_names_for_arch(_SYSCALLS_ALLOWED_IN_CTS, arch))

  msg_do_not_modify = '# DO NOT MODIFY.  CHANGE gen_blacklist.py INSTEAD.'
  with open(args.allowed, 'w') as f:
    print(msg_do_not_modify, file=f)
    json.dump(allowed, f, sort_keys=True, indent=2)

  with open(args.blocked, 'w') as f:
    print(msg_do_not_modify, file=f)
    json.dump(blocked, f, sort_keys=True, indent=2)

if __name__ == '__main__':
  main()
