diff options
Diffstat (limited to 'libc/tools/gensyscalls.py')
-rwxr-xr-x | libc/tools/gensyscalls.py | 239 |
1 files changed, 36 insertions, 203 deletions
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py index 9a3b95e58..b307486d5 100755 --- a/libc/tools/gensyscalls.py +++ b/libc/tools/gensyscalls.py @@ -8,7 +8,6 @@ import atexit import commands import filecmp import glob -import logging import os.path import re import shutil @@ -20,39 +19,10 @@ import tempfile all_arches = [ "arm", "arm64", "mips", "mips64", "x86", "x86_64" ] +bionic_libc = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") -# 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" + \ +syscall_stub_header = \ """ -#include <private/bionic_asm.h> - ENTRY(%(func)s) """ @@ -97,7 +67,7 @@ END(%(func)s) # -# Arm64 assembler templates for each syscall stub +# Arm64 assembler template for each syscall stub # arm64_call = syscall_stub_header + """\ @@ -114,7 +84,7 @@ END(%(func)s) # -# MIPS assembler templates for each syscall stub +# MIPS assembler template for each syscall stub # mips_call = syscall_stub_header + """\ @@ -136,7 +106,7 @@ END(%(func)s) # -# MIPS64 assembler templates for each syscall stub +# MIPS64 assembler template for each syscall stub # mips64_call = syscall_stub_header + """\ @@ -199,7 +169,7 @@ END(%(func)s) # -# x86_64 assembler templates for each syscall stub +# x86_64 assembler template for each syscall stub # x86_64_call = """\ @@ -507,8 +477,6 @@ class SysCallsTxtParser: self.syscalls.append(t) - logging.debug(t) - def parse_open_file(self, fp): for line in fp: self.lineno += 1 @@ -518,182 +486,47 @@ class SysCallsTxtParser: 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 main(arch): + parser = SysCallsTxtParser() + parser.parse_file(os.path.join(bionic_libc, "SYSCALLS.TXT")) + for syscall in parser.syscalls: + syscall["__NR_name"] = make__NR_name(syscall["name"]) - def process_file(self, input): - parser = SysCallsTxtParser() - parser.parse_file(input) - self.syscalls = parser.syscalls - parser = None + if syscall.has_key("arm"): + syscall["asm-arm"] = add_footer(32, arm_eabi_genstub(syscall), syscall) - for syscall in self.syscalls: - syscall["__NR_name"] = make__NR_name(syscall["name"]) + if syscall.has_key("arm64"): + syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall) - if syscall.has_key("arm"): - syscall["asm-arm"] = add_footer(32, arm_eabi_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("arm64"): - syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall) + if syscall.has_key("mips"): + syscall["asm-mips"] = add_footer(32, mips_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("mips64"): + syscall["asm-mips64"] = add_footer(64, mips64_genstub(syscall), syscall) - 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-mips/asm/unistd_n32.h", - "kernel/uapi/asm-mips/asm/unistd_n64.h", - "kernel/uapi/asm-mips/asm/unistd_nr_n32.h", - "kernel/uapi/asm-mips/asm/unistd_nr_n64.h", - "kernel/uapi/asm-mips/asm/unistd_nr_o32.h", - "kernel/uapi/asm-mips/asm/unistd_o32.h", - "kernel/uapi/asm-x86/asm/unistd_32.h", - "kernel/uapi/asm-x86/asm/unistd_64.h", - "kernel/uapi/asm-x86/asm/unistd_x32.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!!") + if syscall.has_key("x86_64"): + syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall) + + print("/* Generated by gensyscalls.py. Do not edit. */\n") + print("#include <private/bionic_asm.h>\n") + for syscall in parser.syscalls: + if syscall.has_key("asm-%s" % arch): + print(syscall["asm-%s" % arch]) -logging.basicConfig(level=logging.INFO) if __name__ == "__main__": - state = State() - state.process_file(os.path.join(bionic_libc_root, "SYSCALLS.TXT")) - state.regenerate() + main(sys.argv[1]) |