summaryrefslogtreecommitdiffstats
path: root/libc/tools/gensyscalls.py
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:13 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:13 -0800
commit1767f908af327fa388b1c66883760ad851267013 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /libc/tools/gensyscalls.py
parenta799b53f10e5a6fd51fef4436cfb7ec99836a516 (diff)
downloadbionic-1767f908af327fa388b1c66883760ad851267013.zip
bionic-1767f908af327fa388b1c66883760ad851267013.tar.gz
bionic-1767f908af327fa388b1c66883760ad851267013.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libc/tools/gensyscalls.py')
-rwxr-xr-xlibc/tools/gensyscalls.py506
1 files changed, 0 insertions, 506 deletions
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
deleted file mode 100755
index 530e565..0000000
--- a/libc/tools/gensyscalls.py
+++ /dev/null
@@ -1,506 +0,0 @@
-#!/usr/bin/python
-#
-# this tool is used to generate the syscall assmbler templates
-# to be placed into arch-x86/syscalls, as well as the content
-# of arch-x86/linux/_syscalls.h
-#
-
-import sys, os.path, glob, re, commands, filecmp, shutil
-
-from bionic_utils import *
-
-# set this to 1 if you want to generate thumb stubs
-gen_thumb_stubs = 0
-
-# set this to 1 if you want to generate ARM EABI stubs
-gen_eabi_stubs = 1
-
-# 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", "x86" ]
-
-def make_dir( 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 <sys/linux-syscalls.h>
-
- .text
- .type %(fname)s, @function
- .globl %(fname)s
- .align 4
-
-%(fname)s:
-"""
-
-x86_registers = [ "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp" ]
-
-x86_call = """ movl $%(idname)s, %%eax
- int $0x80
- cmpl $-129, %%eax
- jb 1f
- negl %%eax
- pushl %%eax
- call __set_errno
- addl $4, %%esp
- orl $-1, %%eax
-1:
-"""
-
-x86_return = """ ret
-"""
-
-# ARM assembler templates for each syscall stub
-#
-arm_header = """/* autogenerated by gensyscalls.py */
-#include <sys/linux-syscalls.h>
-
- .text
- .type %(fname)s, #function
- .globl %(fname)s
- .align 4
- .fnstart
-
-%(fname)s:
-"""
-
-arm_call_default = arm_header + """\
- swi #%(idname)s
- movs r0, r0
- bxpl lr
- b __set_syscall_errno
- .fnend
-"""
-
-arm_call_long = arm_header + """\
- .save {r4, r5, lr}
- stmfd sp!, {r4, r5, lr}
- ldr r4, [sp, #12]
- ldr r5, [sp, #16]
- swi # %(idname)s
- ldmfd sp!, {r4, r5, lr}
- movs r0, r0
- bxpl lr
- b __set_syscall_errno
- .fnend
-"""
-
-arm_eabi_call_default = arm_header + """\
- .save {r4, r7}
- stmfd sp!, {r4, r7}
- ldr r7, =%(idname)s
- swi #0
- ldmfd sp!, {r4, r7}
- movs r0, r0
- bxpl lr
- b __set_syscall_errno
- .fnend
-"""
-
-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}
- movs r0, r0
- bxpl lr
- b __set_syscall_errno
- .fnend
-"""
-
-# ARM thumb assembler templates for each syscall stub
-#
-thumb_header = """/* autogenerated by gensyscalls.py */
- .text
- .type %(fname)s, #function
- .globl %(fname)s
- .align 4
- .thumb_func
- .fnstart
-
-#define __thumb__
-#include <sys/linux-syscalls.h>
-
-
-%(fname)s:
-"""
-
-thumb_call_default = thumb_header + """\
- .save {r7,lr}
- push {r7,lr}
- ldr r7, =%(idname)s
- swi #0
- tst r0, r0
- bmi 1f
- pop {r7,pc}
-1:
- neg r0, r0
- ldr r1, =__set_errno
- blx r1
- pop {r7,pc}
- .fnend
-"""
-
-thumb_call_long = thumb_header + """\
- .save {r4,r5,r7,lr}
- push {r4,r5,r7,lr}
- ldr r4, [sp,#16]
- ldr r5, [sp,#20]
- ldr r7, =%(idname)s
- swi #0
- tst r0, r0
- bmi 1f
- pop {r4,r5,r7,pc}
-1:
- neg r0, r0
- ldr r1, =__set_errno
- blx r1
- pop {r4,r5,r7,pc}
- .fnend
-"""
-
-
-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
- 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
- return result
-
- def arm_genstub(self,fname, flags, idname):
- t = { "fname" : fname,
- "idname" : idname }
- if flags:
- numargs = int(flags)
- if numargs > 4:
- return arm_call_long % t
- return arm_call_default % t
-
-
- 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 thumb_genstub(self,fname, flags, idname):
- t = { "fname" : fname,
- "idname" : idname }
- if flags:
- numargs = int(flags)
- if numargs > 4:
- return thumb_call_long % t
- return thumb_call_default % 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["id"] >= 0:
- if gen_thumb_stubs:
- t["asm-thumb"] = self.thumb_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
- else:
- if gen_eabi_stubs:
- t["asm-arm"] = self.arm_eabi_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
- else:
- t["asm-arm"] = self.arm_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
-
- if t["id2"] >= 0:
- if t["cid"] >= 0:
- t["asm-x86"] = self.x86_genstub_cid(syscall_func, len(syscall_params), "__NR_"+syscall_name, t["cid"])
- else:
- t["asm-x86"] = self.x86_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
- elif t["cid"] >= 0:
- E("cid for dispatch syscalls is only supported for x86 in "
- "'%s'" % syscall_name)
- return
-
-
- def gen_NR_syscall(self,fp,name,id):
- fp.write( "#define __NR_%-25s (__NR_SYSCALL_BASE + %d)\n" % (name,id) )
-
- # now dump the content of linux/_syscalls.h
- def gen_linux_syscalls_h(self):
- path = "include/sys/linux-syscalls.h"
- D( "generating "+path )
- fp = create_file( path )
- fp.write( "/* auto-generated by gensyscalls.py, do not touch */\n" )
- fp.write( "#ifndef _BIONIC_LINUX_SYSCALLS_H_\n\n" )
- fp.write( "#if !defined __ASM_ARM_UNISTD_H && !defined __ASM_I386_UNISTD_H\n" )
- fp.write( "#if defined __arm__ && !defined __ARM_EABI__ && !defined __thumb__\n" )
- fp.write( " # define __NR_SYSCALL_BASE 0x900000\n" )
- fp.write( " #else\n" )
- fp.write( " # define __NR_SYSCALL_BASE 0\n" )
- fp.write( " #endif\n\n" )
-
- # first, all common syscalls
- for sc in self.syscalls:
- sc_id = sc["id"]
- sc_id2 = sc["id2"]
- sc_name = sc["name"]
- if sc_id == sc_id2 and sc_id >= 0:
- self.gen_NR_syscall( fp, sc_name, sc_id )
-
- # now, all arm-specific syscalls
- fp.write( "\n#ifdef __arm__\n" );
- for sc in self.syscalls:
- sc_id = sc["id"]
- sc_id2 = sc["id2"]
- sc_name = sc["name"]
- if sc_id != sc_id2 and sc_id >= 0:
- self.gen_NR_syscall( fp, sc_name, sc_id )
- fp.write( "#endif\n" );
-
- gen_syscalls = {}
- # finally, all i386-specific syscalls
- fp.write( "\n#ifdef __i386__\n" );
- for sc in self.syscalls:
- sc_id = sc["id"]
- sc_id2 = sc["id2"]
- sc_name = sc["name"]
- if sc_id != sc_id2 and sc_id2 >= 0 and sc_name not in gen_syscalls:
- self.gen_NR_syscall( fp, sc_name, sc_id2 )
- gen_syscalls[sc_name] = True
- fp.write( "#endif\n" );
-
- fp.write( "\n#endif\n" )
- fp.write( "\n#endif /* _BIONIC_LINUX_SYSCALLS_H_ */\n" );
- fp.close()
- self.other_files.append( path )
-
-
- # now dump the content of linux/_syscalls.h
- def gen_linux_unistd_h(self):
- path = "include/sys/linux-unistd.h"
- D( "generating "+path )
- fp = create_file( path )
- fp.write( "/* auto-generated by gensyscalls.py, do not touch */\n" )
- fp.write( "#ifndef _BIONIC_LINUX_UNISTD_H_\n\n" );
- fp.write( "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n" )
-
- for sc in self.syscalls:
- fp.write( sc["decl"]+"\n" )
-
- fp.write( "#ifdef __cplusplus\n}\n#endif\n" )
- fp.write( "\n#endif /* _BIONIC_LINUX_UNISTD_H_ */\n" );
- fp.close()
- self.other_files.append( 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") or x.has_key("asm-thumb"),
- "x86": lambda x: x.has_key("asm-x86")
- }
-
- 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"]
- D( ">>> generating "+fname )
- fp = create_file( fname )
- fp.write(sc["asm-arm"])
- fp.close()
- self.new_stubs.append( fname )
-
- if sc.has_key("asm-thumb") and 'arm' in all_archs:
- fname = "arch-arm/syscalls/%s.S" % sc["func"]
- D( ">>> generating "+fname )
- fp = create_file( fname )
- fp.write(sc["asm-thumb"])
- 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"]
- D( ">>> generating "+fname )
- fp = create_file( fname )
- fp.write(sc["asm-x86"])
- 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 )
- os.mkdir( bionic_temp )
-
-# D( "p4 editing source files" )
-# for arch in all_archs:
-# commands.getoutput( "p4 edit " + arch + "/syscalls/*.S " )
-# commands.getoutput( "p4 edit " + arch + "/syscalls.mk" )
-# commands.getoutput( "p4 edit " + bionic_root + "include/sys/linux-syscalls.h" )
-
- D( "re-generating stubs and support files" )
-
- self.gen_linux_syscalls_h()
- for arch in all_archs:
- self.gen_arch_syscalls_mk(arch)
- self.gen_linux_unistd_h()
- 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, P4 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("p4 add " + " ".join(adds))
- if deletes:
- commands.getoutput("p4 delete " + " ".join(deletes))
- if edits:
- commands.getoutput("p4 edit " +
- " ".join((bionic_root + file) for file in edits))
- for file in edits:
- shutil.copyfile( bionic_temp + file, bionic_root + file )
-
- D("ready to go !!")
-
-D_setlevel(1)
-
-state = State()
-state.process_file(bionic_root+"SYSCALLS.TXT")
-state.regenerate()