#!/usr/bin/env python

# This tool is used to generate the assembler system call stubs,
# the header files listing all available system calls, and the
# makefiles used to build all the stubs.

import atexit
import commands
import filecmp
import glob
import logging
import os.path
import re
import shutil
import stat
import string
import sys
import tempfile


all_arches = [ "arm", "arm64", "mips", "mips64", "x86", "x86_64" ]


# temp directory where we store all intermediate files
bionic_temp = tempfile.mkdtemp(prefix="bionic_gensyscalls");
# Make sure the directory is deleted when the script exits.
atexit.register(shutil.rmtree, bionic_temp)

bionic_libc_root = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                "..")

warning = "Generated by gensyscalls.py. Do not edit."

DRY_RUN = False

def make_dir(path):
    path = os.path.abspath(path)
    if not os.path.exists(path):
        parent = os.path.dirname(path)
        if parent:
            make_dir(parent)
        os.mkdir(path)


def create_file(relpath):
    full_path = os.path.join(bionic_temp, relpath)
    dir = os.path.dirname(full_path)
    make_dir(dir)
    return open(full_path, "w")


syscall_stub_header = "/* " + warning + " */\n" + \
"""
#include <private/bionic_asm.h>

ENTRY(%(func)s)
"""


#
# ARM assembler templates for each syscall stub
#

arm_eabi_call_default = syscall_stub_header + """\
    mov     ip, r7
    .cfi_register r7, ip
    ldr     r7, =%(__NR_name)s
    swi     #0
    mov     r7, ip
    .cfi_restore r7
    cmn     r0, #(MAX_ERRNO + 1)
    bxls    lr
    neg     r0, r0
    b       __set_errno_internal
END(%(func)s)
"""

arm_eabi_call_long = syscall_stub_header + """\
    mov     ip, sp
    stmfd   sp!, {r4, r5, r6, r7}
    .cfi_def_cfa_offset 16
    .cfi_rel_offset r4, 0
    .cfi_rel_offset r5, 4
    .cfi_rel_offset r6, 8
    .cfi_rel_offset r7, 12
    ldmfd   ip, {r4, r5, r6}
    ldr     r7, =%(__NR_name)s
    swi     #0
    ldmfd   sp!, {r4, r5, r6, r7}
    .cfi_def_cfa_offset 0
    cmn     r0, #(MAX_ERRNO + 1)
    bxls    lr
    neg     r0, r0
    b       __set_errno_internal
END(%(func)s)
"""


#
# Arm64 assembler templates for each syscall stub
#

arm64_call = syscall_stub_header + """\
    mov     x8, %(__NR_name)s
    svc     #0

    cmn     x0, #(MAX_ERRNO + 1)
    cneg    x0, x0, hi
    b.hi    __set_errno_internal

    ret
END(%(func)s)
"""


#
# MIPS assembler templates for each syscall stub
#

mips_call = syscall_stub_header + """\
    .set noreorder
    .cpload $t9
    li $v0, %(__NR_name)s
    syscall
    bnez $a3, 1f
    move $a0, $v0
    j $ra
    nop
1:
    la $t9,__set_errno_internal
    j $t9
    nop
    .set reorder
END(%(func)s)
"""


#
# MIPS64 assembler templates for each syscall stub
#

mips64_call = syscall_stub_header + """\
    .set push
    .set noreorder
    li $v0, %(__NR_name)s
    syscall
    bnez $a3, 1f
    move $a0, $v0
    j $ra
    nop
1:
    move $t0, $ra
    bal 2f
    nop
2:
    .cpsetup $ra, $t1, 2b
    LA $t9, __set_errno_internal
    .cpreturn
    j $t9
    move $ra, $t0
    .set pop
END(%(func)s)
"""


#
# x86 assembler templates for each syscall stub
#

x86_registers = [ "ebx", "ecx", "edx", "esi", "edi", "ebp" ]

x86_call_prepare = """\

    call    __kernel_syscall
    pushl   %eax
    .cfi_adjust_cfa_offset 4
    .cfi_rel_offset eax, 0

"""

x86_call = """\
    movl    $%(__NR_name)s, %%eax
    call    *(%%esp)
    addl    $4, %%esp

    cmpl    $-MAX_ERRNO, %%eax
    jb      1f
    negl    %%eax
    pushl   %%eax
    call    __set_errno_internal
    addl    $4, %%esp
1:
"""

x86_return = """\
    ret
END(%(func)s)
"""


#
# x86_64 assembler templates for each syscall stub
#

x86_64_call = """\
    movl    $%(__NR_name)s, %%eax
    syscall
    cmpq    $-MAX_ERRNO, %%rax
    jb      1f
    negl    %%eax
    movl    %%eax, %%edi
    call    __set_errno_internal
1:
    ret
END(%(func)s)
"""


def param_uses_64bits(param):
    """Returns True iff a syscall parameter description corresponds
       to a 64-bit type."""
    param = param.strip()
    # First, check that the param type begins with one of the known
    # 64-bit types.
    if not ( \
       param.startswith("int64_t") or param.startswith("uint64_t") or \
       param.startswith("loff_t") or param.startswith("off64_t") or \
       param.startswith("long long") or param.startswith("unsigned long long") or
       param.startswith("signed long long") ):
           return False

    # Second, check that there is no pointer type here
    if param.find("*") >= 0:
            return False

    # Ok
    return True


def count_arm_param_registers(params):
    """This function is used to count the number of register used
       to pass parameters when invoking an ARM system call.
       This is because the ARM EABI mandates that 64-bit quantities
       must be passed in an even+odd register pair. So, for example,
       something like:

             foo(int fd, off64_t pos)

       would actually need 4 registers:
             r0 -> int
             r1 -> unused
             r2-r3 -> pos
   """
    count = 0
    for param in params:
        if param_uses_64bits(param):
            if (count & 1) != 0:
                count += 1
            count += 2
        else:
            count += 1
    return count


def count_generic_param_registers(params):
    count = 0
    for param in params:
        if param_uses_64bits(param):
            count += 2
        else:
            count += 1
    return count


def count_generic_param_registers64(params):
    count = 0
    for param in params:
        count += 1
    return count


# This lets us support regular system calls like __NR_write and also weird
# ones like __ARM_NR_cacheflush, where the NR doesn't come at the start.
def make__NR_name(name):
    if name.startswith("__ARM_NR_"):
        return name
    else:
        return "__NR_%s" % (name)


def add_footer(pointer_length, stub, syscall):
    # Add any aliases for this syscall.
    aliases = syscall["aliases"]
    for alias in aliases:
        stub += "\nALIAS_SYMBOL(%s, %s)\n" % (alias, syscall["func"])

    # Use hidden visibility on LP64 for any functions beginning with underscores.
    # Force hidden visibility for any functions which begin with 3 underscores
    if (pointer_length == 64 and syscall["func"].startswith("__")) or syscall["func"].startswith("___"):
        stub += '.hidden ' + syscall["func"] + '\n'

    return stub


def arm_eabi_genstub(syscall):
    num_regs = count_arm_param_registers(syscall["params"])
    if num_regs > 4:
        return arm_eabi_call_long % syscall
    return arm_eabi_call_default % syscall


def arm64_genstub(syscall):
    return arm64_call % syscall


def mips_genstub(syscall):
    return mips_call % syscall


def mips64_genstub(syscall):
    return mips64_call % syscall


def x86_genstub(syscall):
    result     = syscall_stub_header % syscall

    numparams = count_generic_param_registers(syscall["params"])
    stack_bias = numparams*4 + 8
    offset = 0
    mov_result = ""
    first_push = True
    for register in x86_registers[:numparams]:
        result     += "    pushl   %%%s\n" % register
        if first_push:
          result   += "    .cfi_def_cfa_offset 8\n"
          result   += "    .cfi_rel_offset %s, 0\n" % register
          first_push = False
        else:
          result   += "    .cfi_adjust_cfa_offset 4\n"
          result   += "    .cfi_rel_offset %s, 0\n" % register
        mov_result += "    mov     %d(%%esp), %%%s\n" % (stack_bias+offset, register)
        offset += 4

    result += x86_call_prepare
    result += mov_result
    result += x86_call % syscall

    for register in reversed(x86_registers[:numparams]):
        result += "    popl    %%%s\n" % register

    result += x86_return % syscall
    return result


def x86_genstub_socketcall(syscall):
    #   %ebx <--- Argument 1 - The call id of the needed vectored
    #                          syscall (socket, bind, recv, etc)
    #   %ecx <--- Argument 2 - Pointer to the rest of the arguments
    #                          from the original function called (socket())

    result = syscall_stub_header % syscall

    # save the regs we need
    result += "    pushl   %ebx\n"
    result += "    .cfi_def_cfa_offset 8\n"
    result += "    .cfi_rel_offset ebx, 0\n"
    result += "    pushl   %ecx\n"
    result += "    .cfi_adjust_cfa_offset 4\n"
    result += "    .cfi_rel_offset ecx, 0\n"
    stack_bias = 16

    result += x86_call_prepare

    # set the call id (%ebx)
    result += "    mov     $%d, %%ebx\n" % syscall["socketcall_id"]

    # set the pointer to the rest of the args into %ecx
    result += "    mov     %esp, %ecx\n"
    result += "    addl    $%d, %%ecx\n" % (stack_bias)

    # now do the syscall code itself
    result += x86_call % syscall

    # now restore the saved regs
    result += "    popl    %ecx\n"
    result += "    popl    %ebx\n"

    # epilog
    result += x86_return % syscall
    return result


def x86_64_genstub(syscall):
    result = syscall_stub_header % syscall
    num_regs = count_generic_param_registers64(syscall["params"])
    if (num_regs > 3):
        # rcx is used as 4th argument. Kernel wants it at r10.
        result += "    movq    %rcx, %r10\n"

    result += x86_64_call % syscall
    return result


class SysCallsTxtParser:
    def __init__(self):
        self.syscalls = []
        self.lineno   = 0

    def E(self, msg):
        print "%d: %s" % (self.lineno, msg)

    def parse_line(self, line):
        """ parse a syscall spec line.

        line processing, format is
           return type    func_name[|alias_list][:syscall_name[:socketcall_id]] ( [paramlist] ) architecture_list
        """
        pos_lparen = line.find('(')
        E          = self.E
        if pos_lparen < 0:
            E("missing left parenthesis in '%s'" % line)
            return

        pos_rparen = line.rfind(')')
        if pos_rparen < 0 or pos_rparen <= pos_lparen:
            E("missing or misplaced right parenthesis in '%s'" % line)
            return

        return_type = line[:pos_lparen].strip().split()
        if len(return_type) < 2:
            E("missing return type in '%s'" % line)
            return

        syscall_func = return_type[-1]
        return_type  = string.join(return_type[:-1],' ')
        socketcall_id = -1

        pos_colon = syscall_func.find(':')
        if pos_colon < 0:
            syscall_name = syscall_func
        else:
            if pos_colon == 0 or pos_colon+1 >= len(syscall_func):
                E("misplaced colon in '%s'" % line)
                return

            # now find if there is a socketcall_id for a dispatch-type syscall
            # after the optional 2nd colon
            pos_colon2 = syscall_func.find(':', pos_colon + 1)
            if pos_colon2 < 0:
                syscall_name = syscall_func[pos_colon+1:]
                syscall_func = syscall_func[:pos_colon]
            else:
                if pos_colon2+1 >= len(syscall_func):
                    E("misplaced colon2 in '%s'" % line)
                    return
                syscall_name = syscall_func[(pos_colon+1):pos_colon2]
                socketcall_id = int(syscall_func[pos_colon2+1:])
                syscall_func = syscall_func[:pos_colon]

        alias_delim = syscall_func.find('|')
        if alias_delim > 0:
            alias_list = syscall_func[alias_delim+1:].strip()
            syscall_func = syscall_func[:alias_delim]
            alias_delim = syscall_name.find('|')
            if alias_delim > 0:
                syscall_name = syscall_name[:alias_delim]
            syscall_aliases = string.split(alias_list, ',')
        else:
            syscall_aliases = []

        if pos_rparen > pos_lparen+1:
            syscall_params = line[pos_lparen+1:pos_rparen].split(',')
            params         = string.join(syscall_params,',')
        else:
            syscall_params = []
            params         = "void"

        t = {
              "name"    : syscall_name,
              "func"    : syscall_func,
              "aliases" : syscall_aliases,
              "params"  : syscall_params,
              "decl"    : "%-15s  %s (%s);" % (return_type, syscall_func, params),
              "socketcall_id" : socketcall_id
        }

        # Parse the architecture list.
        arch_list = line[pos_rparen+1:].strip()
        if arch_list == "all":
            for arch in all_arches:
                t[arch] = True
        else:
            for arch in string.split(arch_list, ','):
                if arch in all_arches:
                    t[arch] = True
                else:
                    E("invalid syscall architecture '%s' in '%s'" % (arch, line))
                    return

        self.syscalls.append(t)

        logging.debug(t)

    def parse_open_file(self, fp):
        for line in fp:
            self.lineno += 1
            line = line.strip()
            if not line: continue
            if line[0] == '#': continue
            self.parse_line(line)

    def parse_file(self, file_path):
        logging.debug("parse_file: %s" % file_path)
        with open(file_path) as fp:
            self.parse_open_file(fp)


class State:
    def __init__(self):
        self.old_stubs = []
        self.new_stubs = []
        self.other_files = []
        self.syscalls = []


    def process_file(self, input):
        parser = SysCallsTxtParser()
        parser.parse_file(input)
        self.syscalls = parser.syscalls
        parser = None

        for syscall in self.syscalls:
            syscall["__NR_name"] = make__NR_name(syscall["name"])

            if syscall.has_key("arm"):
                syscall["asm-arm"] = add_footer(32, arm_eabi_genstub(syscall), syscall)

            if syscall.has_key("arm64"):
                syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall)

            if syscall.has_key("x86"):
                if syscall["socketcall_id"] >= 0:
                    syscall["asm-x86"] = add_footer(32, x86_genstub_socketcall(syscall), syscall)
                else:
                    syscall["asm-x86"] = add_footer(32, x86_genstub(syscall), syscall)
            elif syscall["socketcall_id"] >= 0:
                E("socketcall_id for dispatch syscalls is only supported for x86 in '%s'" % t)
                return

            if syscall.has_key("mips"):
                syscall["asm-mips"] = add_footer(32, mips_genstub(syscall), syscall)

            if syscall.has_key("mips64"):
                syscall["asm-mips64"] = add_footer(64, mips64_genstub(syscall), syscall)

            if syscall.has_key("x86_64"):
                syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall)


    # Scan Linux kernel asm/unistd.h files containing __NR_* constants
    # and write out equivalent SYS_* constants for glibc source compatibility.
    def gen_glibc_syscalls_h(self):
        glibc_syscalls_h_path = "include/bits/glibc-syscalls.h"
        logging.info("generating " + glibc_syscalls_h_path)
        glibc_fp = create_file(glibc_syscalls_h_path)
        glibc_fp.write("/* %s */\n" % warning)
        glibc_fp.write("#ifndef _BIONIC_BITS_GLIBC_SYSCALLS_H_\n")
        glibc_fp.write("#define _BIONIC_BITS_GLIBC_SYSCALLS_H_\n")

        # Collect the set of all syscalls for all architectures.
        syscalls = set()
        pattern = re.compile(r'^\s*#\s*define\s*__NR_([a-z_]\S+)')
        for unistd_h in ["kernel/uapi/asm-generic/unistd.h",
                         "kernel/uapi/asm-arm/asm/unistd.h",
                         "kernel/uapi/asm-arm/asm/unistd-common.h",
                         "kernel/uapi/asm-arm/asm/unistd-eabi.h",
                         "kernel/uapi/asm-arm/asm/unistd-oabi.h",
                         "kernel/uapi/asm-mips/asm/unistd.h",
                         "kernel/uapi/asm-x86/asm/unistd_32.h",
                         "kernel/uapi/asm-x86/asm/unistd_64.h"]:
          for line in open(os.path.join(bionic_libc_root, unistd_h)):
            m = re.search(pattern, line)
            if m:
              nr_name = m.group(1)
              if 'reserved' not in nr_name and 'unused' not in nr_name:
                syscalls.add(nr_name)

        # Write out a single file listing them all. Note that the input
        # files include #if trickery, so even for a single architecture
        # we don't know exactly which ones are available.
        # https://code.google.com/p/android/issues/detail?id=215853
        for syscall in sorted(syscalls):
          nr_name = make__NR_name(syscall)
          glibc_fp.write("#if defined(%s)\n" % nr_name)
          glibc_fp.write("  #define SYS_%s %s\n" % (syscall, nr_name))
          glibc_fp.write("#endif\n")

        glibc_fp.write("#endif /* _BIONIC_BITS_GLIBC_SYSCALLS_H_ */\n")
        glibc_fp.close()
        self.other_files.append(glibc_syscalls_h_path)


    # Write each syscall stub.
    def gen_syscall_stubs(self):
        for syscall in self.syscalls:
            for arch in all_arches:
                if syscall.has_key("asm-%s" % arch):
                    filename = "arch-%s/syscalls/%s.S" % (arch, syscall["func"])
                    logging.info(">>> generating " + filename)
                    fp = create_file(filename)
                    fp.write(syscall["asm-%s" % arch])
                    fp.close()
                    self.new_stubs.append(filename)


    def regenerate(self):
        logging.info("scanning for existing architecture-specific stub files...")

        for arch in all_arches:
            arch_dir = "arch-" + arch
            logging.info("scanning " + os.path.join(bionic_libc_root, arch_dir))
            rel_path = os.path.join(arch_dir, "syscalls")
            for file in os.listdir(os.path.join(bionic_libc_root, rel_path)):
                if file.endswith(".S"):
                  self.old_stubs.append(os.path.join(rel_path, file))

        logging.info("found %d stub files" % len(self.old_stubs))

        if not os.path.exists(bionic_temp):
            logging.info("creating %s..." % bionic_temp)
            make_dir(bionic_temp)

        logging.info("re-generating stubs and support files...")

        self.gen_glibc_syscalls_h()
        self.gen_syscall_stubs()

        logging.info("comparing files...")
        adds    = []
        edits   = []

        for stub in self.new_stubs + self.other_files:
            tmp_file = os.path.join(bionic_temp, stub)
            libc_file = os.path.join(bionic_libc_root, stub)
            if not os.path.exists(libc_file):
                # new file, git add it
                logging.info("new file:     " + stub)
                adds.append(libc_file)
                shutil.copyfile(tmp_file, libc_file)

            elif not filecmp.cmp(tmp_file, libc_file):
                logging.info("changed file: " + stub)
                edits.append(stub)

        deletes = []
        for stub in self.old_stubs:
            if not stub in self.new_stubs:
                logging.info("deleted file: " + stub)
                deletes.append(os.path.join(bionic_libc_root, stub))

        if not DRY_RUN:
            if adds:
                commands.getoutput("git add " + " ".join(adds))
            if deletes:
                commands.getoutput("git rm " + " ".join(deletes))
            if edits:
                for file in edits:
                    shutil.copyfile(os.path.join(bionic_temp, file),
                                    os.path.join(bionic_libc_root, file))
                commands.getoutput("git add " + " ".join((os.path.join(bionic_libc_root, file)) for file in edits))

            commands.getoutput("git add %s" % (os.path.join(bionic_libc_root, "SYSCALLS.TXT")))

        if (not adds) and (not deletes) and (not edits):
            logging.info("no changes detected!")
        else:
            logging.info("ready to go!!")

logging.basicConfig(level=logging.INFO)

if __name__ == "__main__":
    state = State()
    state.process_file(os.path.join(bionic_libc_root, "SYSCALLS.TXT"))
    state.regenerate()
