From d612165c6705379aa50144afc35aa40c16793728 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 25 Sep 2013 22:43:36 -0700 Subject: [PATCH] Make it easier to add syscalls for another architecture. Much of the per-architecture duplication can be removed, so let's do so before we add the 64-bit architectures. Change-Id: Ieb796503c8e5353ea38c3bab768bb9a690c9a767 --- libc/SYSCALLS.TXT | 2 +- libc/arch-arm/syscalls.mk | 4 +- libc/arch-mips/syscalls.mk | 4 +- libc/arch-x86/syscalls.mk | 4 +- libc/tools/bionic_utils.py | 58 +++++++++--------------- libc/tools/gensyscalls.py | 91 ++++++++++++++------------------------ 6 files changed, 59 insertions(+), 104 deletions(-) diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 17b6141ca..86b164ad4 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -2,7 +2,7 @@ # # Each non-blank, non-comment line has the following format: # -# return_type func_name[:syscall_name[:call_id]]([parameter_list]) arch_list +# return_type func_name[:syscall_name[:socketcall_id]]([parameter_list]) arch_list # # where: # arch_list ::= "all" | "custom" | arch+ diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk index 33e520f07..e1d02b3c4 100644 --- a/libc/arch-arm/syscalls.mk +++ b/libc/arch-arm/syscalls.mk @@ -1,5 +1,5 @@ -# auto-generated by gensyscalls.py, do not touch -syscall_src := +# Auto-generated by gensyscalls.py. Do not edit. +syscall_src := syscall_src += arch-arm/syscalls/_exit.S syscall_src += arch-arm/syscalls/_exit_thread.S syscall_src += arch-arm/syscalls/__fork.S diff --git a/libc/arch-mips/syscalls.mk b/libc/arch-mips/syscalls.mk index b34b0a9d6..9a1038c01 100644 --- a/libc/arch-mips/syscalls.mk +++ b/libc/arch-mips/syscalls.mk @@ -1,5 +1,5 @@ -# auto-generated by gensyscalls.py, do not touch -syscall_src := +# Auto-generated by gensyscalls.py. Do not edit. +syscall_src := syscall_src += arch-mips/syscalls/_exit.S syscall_src += arch-mips/syscalls/_exit_thread.S syscall_src += arch-mips/syscalls/__fork.S diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk index 7180cf2f2..424bd1ec0 100644 --- a/libc/arch-x86/syscalls.mk +++ b/libc/arch-x86/syscalls.mk @@ -1,5 +1,5 @@ -# auto-generated by gensyscalls.py, do not touch -syscall_src := +# Auto-generated by gensyscalls.py. Do not edit. +syscall_src := syscall_src += arch-x86/syscalls/_exit.S syscall_src += arch-x86/syscalls/_exit_thread.S syscall_src += arch-x86/syscalls/__fork.S diff --git a/libc/tools/bionic_utils.py b/libc/tools/bionic_utils.py index baa41bebf..eed9001fc 100644 --- a/libc/tools/bionic_utils.py +++ b/libc/tools/bionic_utils.py @@ -2,9 +2,7 @@ import sys, os, commands, string -# support Bionic architectures, add new ones as appropriate -# -bionic_archs = [ "arm", "x86", "mips" ] +all_arches = [ "arm", "mips", "x86" ] # basic debugging trace support # call D_setlevel to set the verbosity level @@ -51,7 +49,7 @@ class SysCallsTxtParser: """ parse a syscall spec line. line processing, format is - return type func_name[:syscall_name[:call_id]] ( [paramlist] ) architecture_list + return type func_name[:syscall_name[:socketcall_id]] ( [paramlist] ) architecture_list """ pos_lparen = line.find('(') E = self.E @@ -71,7 +69,7 @@ class SysCallsTxtParser: syscall_func = return_type[-1] return_type = string.join(return_type[:-1],' ') - call_id = -1 + socketcall_id = -1 pos_colon = syscall_func.find(':') if pos_colon < 0: @@ -81,7 +79,7 @@ class SysCallsTxtParser: E("misplaced colon in '%s'" % line) return - # now find if there is a call_id for a dispatch-type syscall + # 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: @@ -92,7 +90,7 @@ class SysCallsTxtParser: E("misplaced colon2 in '%s'" % line) return syscall_name = syscall_func[(pos_colon+1):pos_colon2] - call_id = int(syscall_func[pos_colon2+1:]) + socketcall_id = int(syscall_func[pos_colon2+1:]) syscall_func = syscall_func[:pos_colon] if pos_rparen > pos_lparen+1: @@ -102,51 +100,35 @@ class SysCallsTxtParser: syscall_params = [] params = "void" + t = { + "name" : syscall_name, + "func" : syscall_func, + "params" : syscall_params, + "decl" : "%-15s %s (%s);" % (return_type, syscall_func, params), + "socketcall_id" : socketcall_id + } + # Parse the architecture list. - syscall_common = -1 - syscall_arm = -1 - syscall_x86 = -1 - syscall_mips = -1 arch_list = line[pos_rparen+1:].strip() if arch_list == "custom": pass elif arch_list == "all": - syscall_common = 1 + for arch in all_arches: + t[arch] = True else: for arch in string.split(arch_list, ','): - if arch == "arm": - syscall_arm = 1 - elif arch == "x86": - syscall_x86 = 1 - elif arch == "mips": - syscall_mips = 1 + if arch in all_arches: + t[arch] = True else: E("invalid syscall architecture list in '%s'" % line) return + self.syscalls.append(t) + global verbose if verbose >= 2: - if call_id == -1: - if syscall_common == -1: - print "%s: %d,%d,%d" % (syscall_name, syscall_arm, syscall_x86, syscall_mips) - else: - print "%s: %d" % (syscall_name, syscall_common) - else: - if syscall_common == -1: - print "%s(%d): %d,%d,%d" % (syscall_name, call_id, syscall_arm, syscall_x86, syscall_mips) - else: - print "%s(%d): %d" % (syscall_name, call_id, syscall_common) + print t - t = { "armid" : syscall_arm, - "x86id" : syscall_x86, - "mipsid" : syscall_mips, - "common" : syscall_common, - "cid" : call_id, - "name" : syscall_name, - "func" : syscall_func, - "params" : syscall_params, - "decl" : "%-15s %s (%s);" % (return_type, syscall_func, params) } - self.syscalls.append(t) def parse_file(self, file_path): D2("parse_file: %s" % file_path) diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py index 4894f2da6..ea60eec25 100755 --- a/libc/tools/gensyscalls.py +++ b/libc/tools/gensyscalls.py @@ -15,9 +15,6 @@ bionic_libc_root = os.environ["ANDROID_BUILD_TOP"] + "/bionic/libc/" # 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): @@ -217,10 +214,7 @@ class State: 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: + def x86_genstub_socketcall(self, fname, idname, socketcall_id): # %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 @@ -238,7 +232,7 @@ class State: stack_bias += 4 # set the call id (%ebx) - result += " mov $%d, %%ebx" % (cid) + "\n" + result += " mov $%d, %%ebx" % (socketcall_id) + "\n" # set the pointer to the rest of the args into %ecx result += " mov %esp, %ecx" + "\n" @@ -281,23 +275,23 @@ class State: syscall_func = t["func"] syscall_params = t["params"] syscall_name = t["name"] + __NR_name = make__NR_name(t["name"]) - if t["common"] >= 0 or t["armid"] >= 0: + if t.has_key("arm"): num_regs = count_arm_param_registers(syscall_params) - t["asm-arm"] = self.arm_eabi_genstub(syscall_func, num_regs, make__NR_name(syscall_name)) + t["asm-arm"] = self.arm_eabi_genstub(syscall_func, num_regs, __NR_name) - if t["common"] >= 0 or t["x86id"] >= 0: + if t.has_key("x86"): 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"]) + if t["socketcall_id"] >= 0: + t["asm-x86"] = self.x86_genstub_socketcall(syscall_func, __NR_name, t["socketcall_id"]) 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) + t["asm-x86"] = self.x86_genstub(syscall_func, num_regs, __NR_name) + elif t["socketcall_id"] >= 0: + E("socketcall_id for dispatch syscalls is only supported for x86 in '%s'" % t) return - if t["common"] >= 0 or t["mipsid"] >= 0: + if t.has_key("mips"): t["asm-mips"] = self.mips_genstub(syscall_func, make__NR_name(syscall_name)) @@ -336,60 +330,39 @@ class State: self.other_files.append(glibc_syscalls_h_path) - # now dump the contents of syscalls.mk + # Write 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") - } - + D("generating " + path) + fp = create_file(path) + fp.write("# Auto-generated by gensyscalls.py. Do not edit.\n") + fp.write("syscall_src :=\n") for sc in self.syscalls: - if arch_test[arch](sc): - fp.write("syscall_src += arch-%s/syscalls/%s.S\n" % - (arch, sc["func"])) + if sc.has_key("asm-%s" % arch): + fp.write("syscall_src += arch-%s/syscalls/%s.S\n" % (arch, sc["func"])) fp.close() - self.other_files.append( path ) + self.other_files.append(path) - # now generate each syscall stub + # Write 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 ) + for arch in all_arches: + if sc.has_key("asm-%s" % arch): + filename = "arch-%s/syscalls/%s.S" % (arch, sc["func"]) + D2(">>> generating " + filename) + fp = create_file(filename) + fp.write(sc["asm-%s" % arch]) + fp.close() + self.new_stubs.append(filename) - 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): + def regenerate(self): D( "scanning for existing architecture-specific stub files" ) bionic_libc_root_len = len(bionic_libc_root) - for arch in all_archs: + for arch in all_arches: arch_path = bionic_libc_root + "arch-" + arch D( "scanning " + arch_path ) files = glob.glob( arch_path + "/syscalls/*.S" ) @@ -405,7 +378,7 @@ class State: D( "re-generating stubs and support files" ) self.gen_glibc_syscalls_h() - for arch in all_archs: + for arch in all_arches: self.gen_arch_syscalls_mk(arch) self.gen_syscall_stubs()