diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:13 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:13 -0800 |
commit | 1767f908af327fa388b1c66883760ad851267013 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /libc/tools/gensyscalls.py | |
parent | a799b53f10e5a6fd51fef4436cfb7ec99836a516 (diff) | |
download | bionic-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-x | libc/tools/gensyscalls.py | 506 |
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() |