#!/usr/bin/python
#
# this tool is used to generate the syscall assembler templates
# to be placed into arch-{arm,x86,mips}/syscalls, as well as the content
# of arch-{arm,x86,mips}/linux/_syscalls.h
#

import sys, os.path, glob, re, commands, filecmp, shutil
import getpass

from bionic_utils import *

# get the root Bionic directory, simply this script's dirname
#
bionic_root = find_bionic_root()
if not bionic_root:
    print "could not find the Bionic root directory. aborting"
    sys.exit(1)

if bionic_root[-1] != '/':
    bionic_root += "/"

print "bionic_root is %s" % bionic_root

# temp directory where we store all intermediate files
bionic_temp = "/tmp/bionic_gensyscalls/"

# all architectures, update as you see fit
all_archs = [ "arm", "mips", "x86" ]

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 ):
    dir = os.path.dirname( bionic_temp + relpath )
    make_dir(dir)
    return open( bionic_temp + relpath, "w" )

#
# x86 assembler templates for each syscall stub
#

x86_header = """/* autogenerated by gensyscalls.py */
#include <linux/err.h>
#include <machine/asm.h>
#include <asm/unistd.h>

ENTRY(%(fname)s)
"""

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

x86_call = """    movl    $%(idname)s, %%eax
    int     $0x80
    cmpl    $-MAX_ERRNO, %%eax
    jb      1f
    negl    %%eax
    pushl   %%eax
    call    __set_errno
    addl    $4, %%esp
    orl     $-1, %%eax
1:
"""

x86_return = """    ret
END(%(fname)s)
"""

#
# ARM assembler templates for each syscall stub
#

arm_header = """/* autogenerated by gensyscalls.py */
#include <asm/unistd.h>
#include <linux/err.h>
#include <machine/asm.h>

ENTRY(%(fname)s)
"""

arm_eabi_call_default = arm_header + """\
    mov     ip, r7
    ldr     r7, =%(idname)s
    swi     #0
    mov     r7, ip
    cmn     r0, #(MAX_ERRNO + 1)
    bxls    lr
    neg     r0, r0
    b       __set_errno
END(%(fname)s)
"""

arm_eabi_call_long = arm_header + """\
    mov     ip, sp
    .save   {r4, r5, r6, r7}
    stmfd   sp!, {r4, r5, r6, r7}
    ldmfd   ip, {r4, r5, r6}
    ldr     r7, =%(idname)s
    swi     #0
    ldmfd   sp!, {r4, r5, r6, r7}
    cmn     r0, #(MAX_ERRNO + 1)
    bxls    lr
    neg     r0, r0
    b       __set_errno
END(%(fname)s)
"""

#
# mips assembler templates for each syscall stub
#

mips_call = """/* autogenerated by gensyscalls.py */
#include <asm/unistd.h>
    .text
    .globl %(fname)s
    .align 4
    .ent %(fname)s

%(fname)s:
    .set noreorder
    .cpload $t9
    li $v0, %(idname)s
    syscall
    bnez $a3, 1f
    move $a0, $v0
    j $ra
    nop
1:
    la $t9,__set_errno
    j $t9
    nop
    .set reorder
    .end %(fname)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

# 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("__"):
        return name
    else:
        return "__NR_%s" % (name)

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

    def x86_genstub(self, fname, numparams, idname):
        t = { "fname"  : fname,
              "idname" : idname }

        result     = x86_header % t
        stack_bias = 4
        for r in range(numparams):
            result     += "    pushl   " + x86_registers[r] + "\n"
            stack_bias += 4

        for r in range(numparams):
            result += "    mov     %d(%%esp), %s" % (stack_bias+r*4, x86_registers[r]) + "\n"

        result += x86_call % t

        for r in range(numparams):
            result += "    popl    " + x86_registers[numparams-r-1] + "\n"

        result += x86_return % t
        return result

    def x86_genstub_cid(self, fname, numparams, idname, cid):
        # We'll ignore numparams here because in reality, if there is a
        # dispatch call (like a socketcall syscall) there are actually
        # only 2 arguments to the syscall and 2 regs we have to save:
        #   %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())
        t = { "fname"  : fname,
              "idname" : idname }

        result = x86_header % t
        stack_bias = 4

        # save the regs we need
        result += "    pushl   %ebx" + "\n"
        stack_bias += 4
        result += "    pushl   %ecx" + "\n"
        stack_bias += 4

        # set the call id (%ebx)
        result += "    mov     $%d, %%ebx" % (cid) + "\n"

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

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

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

        # epilog
        result += x86_return % t
        return result


    def arm_eabi_genstub(self,fname, flags, idname):
        t = { "fname"  : fname,
              "idname" : idname }
        if flags:
            numargs = int(flags)
            if numargs > 4:
                return arm_eabi_call_long % t
        return arm_eabi_call_default % t


    def mips_genstub(self,fname, idname):
        t = { "fname"  : fname,
              "idname" : idname }
        return mips_call % t

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

        for t in self.syscalls:
            syscall_func   = t["func"]
            syscall_params = t["params"]
            syscall_name   = t["name"]

            if t["common"] >= 0 or t["armid"] >= 0:
                num_regs = count_arm_param_registers(syscall_params)
                t["asm-arm"] = self.arm_eabi_genstub(syscall_func, num_regs, make__NR_name(syscall_name))

            if t["common"] >= 0 or t["x86id"] >= 0:
                num_regs = count_generic_param_registers(syscall_params)
                if t["cid"] >= 0:
                    t["asm-x86"] = self.x86_genstub_cid(syscall_func, num_regs, make__NR_name(syscall_name), t["cid"])
                else:
                    t["asm-x86"] = self.x86_genstub(syscall_func, num_regs, make__NR_name(syscall_name))
            elif t["cid"] >= 0:
                E("cid for dispatch syscalls is only supported for x86 in "
                  "'%s'" % syscall_name)
                return

            if t["common"] >= 0 or t["mipsid"] >= 0:
                t["asm-mips"] = self.mips_genstub(syscall_func, make__NR_name(syscall_name))


    # Scan a Linux kernel asm/unistd.h file containing __NR_* constants
    # and write out equivalent SYS_* constants for glibc source compatibility.
    def scan_linux_unistd_h(self, fp, path):
        pattern = re.compile(r'^#define __NR_([a-z]\S+) .*')
        syscalls = set() # MIPS defines everything three times; work around that.
        for line in open(path):
            m = re.search(pattern, line)
            if m:
                syscalls.add(m.group(1))
        for syscall in sorted(syscalls):
            fp.write("#define SYS_%s %s\n" % (syscall, make__NR_name(syscall)))


    def gen_glibc_syscalls_h(self):
        # TODO: generate a separate file for each architecture, like glibc's bits/syscall.h.
        glibc_syscalls_h_path = "include/sys/glibc-syscalls.h"
        D("generating " + glibc_syscalls_h_path)
        glibc_fp = create_file(glibc_syscalls_h_path)
        glibc_fp.write("/* Auto-generated by gensyscalls.py; do not edit. */\n")
        glibc_fp.write("#ifndef _BIONIC_GLIBC_SYSCALLS_H_\n")
        glibc_fp.write("#define _BIONIC_GLIBC_SYSCALLS_H_\n")

        glibc_fp.write("#if defined(__arm__)\n")
        self.scan_linux_unistd_h(glibc_fp, "libc/kernel/arch-arm/asm/unistd.h")
        glibc_fp.write("#elif defined(__mips__)\n")
        self.scan_linux_unistd_h(glibc_fp, "libc/kernel/arch-mips/asm/unistd.h")
        glibc_fp.write("#elif defined(__i386__)\n")
        self.scan_linux_unistd_h(glibc_fp, "libc/kernel/arch-x86/asm/unistd_32.h")
        glibc_fp.write("#endif\n")

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


    # now dump the contents of syscalls.mk
    def gen_arch_syscalls_mk(self, arch):
        path = "arch-%s/syscalls.mk" % arch
        D( "generating "+path )
        fp = create_file( path )
        fp.write( "# auto-generated by gensyscalls.py, do not touch\n" )
        fp.write( "syscall_src := \n" )
        arch_test = {
            "arm": lambda x: x.has_key("asm-arm"),
            "x86": lambda x: x.has_key("asm-x86"),
            "mips": lambda x: x.has_key("asm-mips")
        }

        for sc in self.syscalls:
            if arch_test[arch](sc):
                fp.write("syscall_src += arch-%s/syscalls/%s.S\n" %
                         (arch, sc["func"]))
        fp.close()
        self.other_files.append( path )


    # now generate each syscall stub
    def gen_syscall_stubs(self):
        for sc in self.syscalls:
            if sc.has_key("asm-arm") and 'arm' in all_archs:
                fname = "arch-arm/syscalls/%s.S" % sc["func"]
                D2( ">>> generating "+fname )
                fp = create_file( fname )
                fp.write(sc["asm-arm"])
                fp.close()
                self.new_stubs.append( fname )

            if sc.has_key("asm-x86") and 'x86' in all_archs:
                fname = "arch-x86/syscalls/%s.S" % sc["func"]
                D2( ">>> generating "+fname )
                fp = create_file( fname )
                fp.write(sc["asm-x86"])
                fp.close()
                self.new_stubs.append( fname )

            if sc.has_key("asm-mips") and 'mips' in all_archs:
                fname = "arch-mips/syscalls/%s.S" % sc["func"]
                D2( ">>> generating "+fname )
                fp = create_file( fname )
                fp.write(sc["asm-mips"])
                fp.close()
                self.new_stubs.append( fname )

    def  regenerate(self):
        D( "scanning for existing architecture-specific stub files" )

        bionic_root_len = len(bionic_root)

        for arch in all_archs:
            arch_path = bionic_root + "arch-" + arch
            D( "scanning " + arch_path )
            files = glob.glob( arch_path + "/syscalls/*.S" )
            for f in files:
                self.old_stubs.append( f[bionic_root_len:] )

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

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

        D( "re-generating stubs and support files" )

        self.gen_glibc_syscalls_h()
        for arch in all_archs:
            self.gen_arch_syscalls_mk(arch)
        self.gen_syscall_stubs()

        D( "comparing files" )
        adds    = []
        edits   = []

        for stub in self.new_stubs + self.other_files:
            if not os.path.exists( bionic_root + stub ):
                # new file, git add it
                D( "new file:     " + stub)
                adds.append( bionic_root + stub )
                shutil.copyfile( bionic_temp + stub, bionic_root + stub )

            elif not filecmp.cmp( bionic_temp + stub, bionic_root + stub ):
                D( "changed file: " + stub)
                edits.append( stub )

        deletes = []
        for stub in self.old_stubs:
            if not stub in self.new_stubs:
                D( "deleted file: " + stub)
                deletes.append( bionic_root + stub )


        if adds:
            commands.getoutput("git add " + " ".join(adds))
        if deletes:
            commands.getoutput("git rm " + " ".join(deletes))
        if edits:
            for file in edits:
                shutil.copyfile( bionic_temp + file, bionic_root + file )
            commands.getoutput("git add " +
                               " ".join((bionic_root + file) for file in edits))

        commands.getoutput("git add %s%s" % (bionic_root,"SYSCALLS.TXT"))

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

D_setlevel(1)

state = State()
state.process_file(bionic_root+"SYSCALLS.TXT")
state.regenerate()
