diff --git a/libc/tools/genseccomp.py b/libc/tools/genseccomp.py
index fa6e7e3..7d2b1da 100755
--- a/libc/tools/genseccomp.py
+++ b/libc/tools/genseccomp.py
@@ -5,7 +5,8 @@
 from gensyscalls import SysCallsTxtParser
 
 
-syscall_file = "SYSCALLS.TXT"
+BPF_JGE = "BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, {0}, {1}, {2})"
+BPF_ALLOW = "BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW)"
 
 
 class SyscallRange(object):
@@ -14,6 +15,9 @@
     self.begin = value
     self.end = self.begin + 1
 
+  def __str__(self):
+    return "(%s, %s, %s)" % (self.begin, self.end, self.names)
+
   def add(self, name, value):
     if value != self.end:
       raise ValueError
@@ -21,39 +25,21 @@
     self.names.append(name)
 
 
-def generate_bpf_jge(value, ge_target, less_target):
-  return "BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, {0}, {1}, {2})".format(value, ge_target, less_target)
-
-
-# Converts the sorted ranges of allowed syscalls to a binary tree bpf
-# For a single range, output a simple jump to {fail} or {allow}. We can't set
-# the jump ranges yet, since we don't know the size of the filter, so use a
-# placeholder
-# For multiple ranges, split into two, convert the two halves and output a jump
-# to the correct half
-def convert_to_bpf(ranges):
-  if len(ranges) == 1:
-    # We will replace {fail} and {allow} with appropriate range jumps later
-    return [generate_bpf_jge(ranges[0].end, "{fail}", "{allow}") +
-            ", //" + "|".join(ranges[0].names)]
-  else:
-    half = (len(ranges) + 1) / 2
-    first = convert_to_bpf(ranges[:half])
-    second = convert_to_bpf(ranges[half:])
-    return [generate_bpf_jge(ranges[half].begin, len(first), 0) + ","] + first + second
-
-
-def construct_bpf(architecture, header_dir, output_path):
-  parser = SysCallsTxtParser()
-  parser.parse_file(syscall_file)
-  syscalls = parser.syscalls
+def get_names(syscall_files, architecture):
+  syscalls = []
+  for syscall_file in syscall_files:
+    parser = SysCallsTxtParser()
+    parser.parse_open_file(syscall_file)
+    syscalls += parser.syscalls
 
   # Select only elements matching required architecture
   syscalls = [x for x in syscalls if architecture in x and x[architecture]]
 
   # We only want the name
-  names = [x["name"] for x in syscalls]
+  return [x["name"] for x in syscalls]
 
+
+def convert_names_to_NRs(names, header_dir):
   # Run preprocessor over the __NR_syscall symbols, including unistd.h,
   # to get the actual numbers
   prefix = "__SECCOMP_"  # prefix to ensure no name collisions
@@ -89,6 +75,10 @@
     value = eval(value)
     syscalls.append((name, value))
 
+  return syscalls
+
+
+def convert_NRs_to_ranges(syscalls):
   # Sort the values so we convert to ranges and binary chop
   syscalls = sorted(syscalls, lambda x, y: cmp(x[1], y[1]))
 
@@ -104,8 +94,30 @@
       last_range.add(name, value)
     else:
       ranges.append(SyscallRange(name, value))
+  return ranges
 
-  bpf = convert_to_bpf(ranges)
+
+# Converts the sorted ranges of allowed syscalls to a binary tree bpf
+# For a single range, output a simple jump to {fail} or {allow}. We can't set
+# the jump ranges yet, since we don't know the size of the filter, so use a
+# placeholder
+# For multiple ranges, split into two, convert the two halves and output a jump
+# to the correct half
+def convert_to_intermediate_bpf(ranges):
+  if len(ranges) == 1:
+    # We will replace {fail} and {allow} with appropriate range jumps later
+    return [BPF_JGE.format(ranges[0].end, "{fail}", "{allow}") +
+            ", //" + "|".join(ranges[0].names)]
+  else:
+    half = (len(ranges) + 1) / 2
+    first = convert_to_intermediate_bpf(ranges[:half])
+    second = convert_to_intermediate_bpf(ranges[half:])
+    jump = [BPF_JGE.format(ranges[half].begin, len(first), 0) + ","]
+    return jump + first + second
+
+
+def convert_ranges_to_bpf(ranges):
+  bpf = convert_to_intermediate_bpf(ranges)
 
   # Now we know the size of the tree, we can substitute the {fail} and {allow}
   # placeholders
@@ -121,16 +133,16 @@
                                 allow=str(len(bpf) - i - 1))
 
   # Add check that we aren't off the bottom of the syscalls
-  bpf.insert(0,
-             "BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, " + str(ranges[0].begin) +
-             ", 0, " + str(len(bpf)) + "),")
+  bpf.insert(0, BPF_JGE.format(ranges[0].begin, 0, str(len(bpf))) + ',')
 
   # Add the allow calls at the end. If the syscall is not matched, we will
   # continue. This allows the user to choose to match further syscalls, and
   # also to choose the action when we want to block
-  bpf.append("BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),")
+  bpf.append(BPF_ALLOW + ",")
+  return bpf
 
-  # And output policy
+
+def convert_bpf_to_output(bpf, architecture):
   header = textwrap.dedent("""\
     // Autogenerated file - edit at your peril!!
 
@@ -147,25 +159,52 @@
 
     const size_t {architecture}_filter_size = sizeof({architecture}_filter) / sizeof(struct sock_filter);
     """).format(architecture=architecture)
-  output = header + "\n".join(bpf) + footer
+  return header + "\n".join(bpf) + footer
 
-  existing = ""
-  if os.path.isfile(output_path):
-    existing = open(output_path).read()
-  if output == existing:
-    print "File " + output_path + " not changed."
-  else:
-    with open(output_path, "w") as output_file:
-      output_file.write(output)
 
-    print "Generated file " + output_path
+def construct_bpf(syscall_files, architecture, header_dir):
+  names = get_names(syscall_files, architecture)
+  syscalls = convert_names_to_NRs(names, header_dir)
+  ranges = convert_NRs_to_ranges(syscalls)
+  bpf = convert_ranges_to_bpf(ranges)
+  return convert_bpf_to_output(bpf, architecture)
+
+
+android_syscall_files = ["SYSCALLS.TXT", "SECCOMP_WHITELIST.TXT"]
+arm_headers = "kernel/uapi/asm-arm"
+arm64_headers = "kernel/uapi/asm-arm64"
+arm_architecture = "arm"
+arm64_architecture = "arm64"
+
+
+ANDROID_SYSCALL_FILES = ["SYSCALLS.TXT", "SECCOMP_WHITELIST.TXT"]
+
+POLICY_CONFIGS = [("arm", "kernel/uapi/asm-arm"),
+                  ("arm64", "kernel/uapi/asm-arm64")]
+
+
+def set_dir():
+  # Set working directory for predictable results
+  os.chdir(os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc"))
 
 
 def main():
-  # Set working directory for predictable results
-  os.chdir(os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc"))
-  construct_bpf("arm", "kernel/uapi/asm-arm", "seccomp/arm_policy.c")
-  construct_bpf("arm64", "kernel/uapi/asm-arm64", "seccomp/arm64_policy.c")
+  set_dir()
+  for arch, header_path in POLICY_CONFIGS:
+    files = [open(filename) for filename in ANDROID_SYSCALL_FILES]
+    output = construct_bpf(files, arch, header_path)
+
+    # And output policy
+    existing = ""
+    output_path = "seccomp/{}_policy.c".format(arch)
+    if os.path.isfile(output_path):
+      existing = open(output_path).read()
+    if output == existing:
+      print "File " + output_path + " not changed."
+    else:
+      with open(output_path, "w") as output_file:
+        output_file.write(output)
+      print "Generated file " + output_path
 
 
 if __name__ == "__main__":
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 329184f..f50445c 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -500,18 +500,18 @@
 
         logging.debug(t)
 
-
-    def parse_file(self, file_path):
-        logging.debug("parse_file: %s" % file_path)
-        fp = open(file_path)
-        for line in fp.xreadlines():
+    def parse_open_file(self, fp):
+        for line in fp:
             self.lineno += 1
             line = line.strip()
             if not line: continue
             if line[0] == '#': continue
             self.parse_line(line)
 
-        fp.close()
+    def parse_file(self, file_path):
+        logging.debug("parse_file: %s" % file_path)
+        with open(file_path) as fp:
+            parse_open_file(fp)
 
 
 class State:
diff --git a/libc/tools/test_genseccomp.py b/libc/tools/test_genseccomp.py
new file mode 100755
index 0000000..de1e5fe
--- /dev/null
+++ b/libc/tools/test_genseccomp.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+# Unit tests for genseccomp.py
+
+import cStringIO
+import textwrap
+import unittest
+
+import genseccomp
+
+class TestGenseccomp(unittest.TestCase):
+  def setUp(self):
+    genseccomp.set_dir()
+
+  def get_config(self, arch):
+    for i in genseccomp.POLICY_CONFIGS:
+      if i[0] == arch:
+        return i
+    self.fail("No such architecture")
+
+  def get_headers(self, arch):
+    return self.get_config(arch)[1]
+
+  def test_get_names(self):
+    syscalls = cStringIO.StringIO(textwrap.dedent("""\
+int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,mips,x86
+int         fchown:fchown(int, uid_t, gid_t)    arm64,mips,mips64,x86_64
+    """))
+
+    whitelist = cStringIO.StringIO(textwrap.dedent("""\
+ssize_t     read(int, void*, size_t)        all
+    """))
+
+    syscall_files = [syscalls, whitelist]
+    names = genseccomp.get_names(syscall_files, "arm")
+    for f in syscall_files:
+      f.seek(0)
+    names64 = genseccomp.get_names(syscall_files, "arm64")
+
+    self.assertIn("fchown", names64)
+    self.assertNotIn("fchown", names)
+    self.assertIn("_llseek", names)
+    self.assertNotIn("_llseek", names64)
+    self.assertIn("read", names)
+    self.assertIn("read", names64)
+
+  def test_convert_names_to_NRs(self):
+    self.assertEquals(genseccomp.convert_names_to_NRs(["open"],
+                                                      self.get_headers("arm")),
+                      [("open", 5)])
+
+    self.assertEquals(genseccomp.convert_names_to_NRs(["__ARM_NR_set_tls"],
+                                                      self.get_headers("arm")),
+                      [('__ARM_NR_set_tls', 983045)])
+
+    self.assertEquals(genseccomp.convert_names_to_NRs(["openat"],
+                                                      self.get_headers("arm64")),
+                      [("openat", 56)])
+
+
+  def test_convert_NRs_to_ranges(self):
+    ranges = genseccomp.convert_NRs_to_ranges([("b", 2), ("a", 1)])
+    self.assertEquals(len(ranges), 1)
+    self.assertEquals(ranges[0].begin, 1)
+    self.assertEquals(ranges[0].end, 3)
+    self.assertItemsEqual(ranges[0].names, ["a", "b"])
+
+    ranges = genseccomp.convert_NRs_to_ranges([("b", 3), ("a", 1)])
+    self.assertEquals(len(ranges), 2)
+    self.assertEquals(ranges[0].begin, 1)
+    self.assertEquals(ranges[0].end, 2)
+    self.assertItemsEqual(ranges[0].names, ["a"])
+    self.assertEquals(ranges[1].begin, 3)
+    self.assertEquals(ranges[1].end, 4)
+    self.assertItemsEqual(ranges[1].names, ["b"])
+
+  def test_convert_to_intermediate_bpf(self):
+    ranges = genseccomp.convert_NRs_to_ranges([("b", 2), ("a", 1)])
+    bpf = genseccomp.convert_to_intermediate_bpf(ranges)
+    self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, {fail}, {allow}), //a|b'])
+
+    ranges = genseccomp.convert_NRs_to_ranges([("b", 3), ("a", 1)])
+    bpf = genseccomp.convert_to_intermediate_bpf(ranges)
+    self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),',
+                            'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, {fail}, {allow}), //a',
+                            'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, {fail}, {allow}), //b'])
+
+  def test_convert_ranges_to_bpf(self):
+    ranges = genseccomp.convert_NRs_to_ranges([("b", 2), ("a", 1)])
+    bpf = genseccomp.convert_ranges_to_bpf(ranges)
+    self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 1, 0, 1),',
+                            'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0), //a|b',
+                            'BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),'])
+
+    ranges = genseccomp.convert_NRs_to_ranges([("b", 3), ("a", 1)])
+    bpf = genseccomp.convert_ranges_to_bpf(ranges)
+    self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 1, 0, 3),',
+                            'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),',
+                            'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 2, 1), //a',
+                            'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 1, 0), //b',
+                            'BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),'])
+
+  def test_convert_bpf_to_output(self):
+    output = genseccomp.convert_bpf_to_output(["line1", "line2"], "arm")
+    expected_output = textwrap.dedent("""\
+    // Autogenerated file - edit at your peril!!
+
+    #include <linux/filter.h>
+    #include <errno.h>
+
+    #include "seccomp_policy.h"
+    const struct sock_filter arm_filter[] = {
+    line1
+    line2
+    };
+
+    const size_t arm_filter_size = sizeof(arm_filter) / sizeof(struct sock_filter);
+    """)
+    self.assertEquals(output, expected_output)
+
+  def test_construct_bpf(self):
+    syscalls = cStringIO.StringIO(textwrap.dedent("""\
+    int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,mips,x86
+    int         fchown:fchown(int, uid_t, gid_t)    arm64,mips,mips64,x86_64
+    """))
+
+    whitelist = cStringIO.StringIO(textwrap.dedent("""\
+    ssize_t     read(int, void*, size_t)        all
+    """))
+
+    syscall_files = [syscalls, whitelist]
+    output = genseccomp.construct_bpf(syscall_files, "arm", self.get_headers("arm"))
+
+    expected_output = textwrap.dedent("""\
+    // Autogenerated file - edit at your peril!!
+
+    #include <linux/filter.h>
+    #include <errno.h>
+
+    #include "seccomp_policy.h"
+    const struct sock_filter arm_filter[] = {
+    BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 0, 3),
+    BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 1, 0),
+    BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 2, 1), //read
+    BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 141, 1, 0), //_llseek
+    BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+    };
+
+    const size_t arm_filter_size = sizeof(arm_filter) / sizeof(struct sock_filter);
+    """)
+    self.assertEquals(output, expected_output)
+
+
+if __name__ == '__main__':
+  unittest.main()
