summaryrefslogtreecommitdiff
path: root/libc/tools/gensyscalls.py
diff options
context:
space:
mode:
Diffstat (limited to 'libc/tools/gensyscalls.py')
-rwxr-xr-xlibc/tools/gensyscalls.py239
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])