go-seccomp: Go support for compiling and installing Seccomp-BPF policy files.

BUG=chromium:489765
TEST=Ran 'go test -cpu=10 -test_install -test_endian' on host.
TEST=Cross compiled test with 'x86_64-cros-linux-gnu-go' and ran on a panther device.
TEST=Cross compiled test with 'i686-pc-linux-gnu-go' and ran on a x86-zgb device.
TEST=Cross compiled test with 'armv7a-cros-linux-gnueabi-go' and ran on a daisy device.

Change-Id: I7aa5d7aed0b8f67a2da8c899d35cc2a2a28591b0
Reviewed-on: https://chromium-review.googlesource.com/272832
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Reviewed-by: Matthew Dempsky <mdempsky@chromium.org>
Commit-Queue: Rahul Chaudhry <rahulchaudhry@chromium.org>
Tested-by: Rahul Chaudhry <rahulchaudhry@chromium.org>
diff --git a/src/chromiumos/seccomp/audit_386.go b/src/chromiumos/seccomp/audit_386.go
new file mode 100644
index 0000000..ac1fc54
--- /dev/null
+++ b/src/chromiumos/seccomp/audit_386.go
@@ -0,0 +1,13 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+// #include <linux/audit.h>
+import "C"
+
+const (
+	auditArch = C.AUDIT_ARCH_I386
+	nbits     = 32
+)
diff --git a/src/chromiumos/seccomp/audit_amd64.go b/src/chromiumos/seccomp/audit_amd64.go
new file mode 100644
index 0000000..90b5e6c
--- /dev/null
+++ b/src/chromiumos/seccomp/audit_amd64.go
@@ -0,0 +1,13 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+// #include <linux/audit.h>
+import "C"
+
+const (
+	auditArch = C.AUDIT_ARCH_X86_64
+	nbits     = 64
+)
diff --git a/src/chromiumos/seccomp/audit_arm.go b/src/chromiumos/seccomp/audit_arm.go
new file mode 100644
index 0000000..d720ec4
--- /dev/null
+++ b/src/chromiumos/seccomp/audit_arm.go
@@ -0,0 +1,13 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+// #include <linux/audit.h>
+import "C"
+
+const (
+	auditArch = C.AUDIT_ARCH_ARM
+	nbits     = 32
+)
diff --git a/src/chromiumos/seccomp/bpf.go b/src/chromiumos/seccomp/bpf.go
new file mode 100644
index 0000000..ebd6f23
--- /dev/null
+++ b/src/chromiumos/seccomp/bpf.go
@@ -0,0 +1,107 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+import (
+	"fmt"
+)
+
+// #include <linux/filter.h>
+import "C"
+
+// BPF machine opcodes. These are the only ones we use.
+const (
+	opLOAD = C.BPF_LD + C.BPF_W + C.BPF_ABS
+	opJEQ  = C.BPF_JMP + C.BPF_JEQ + C.BPF_K
+	opJSET = C.BPF_JMP + C.BPF_JSET + C.BPF_K
+	opJUMP = C.BPF_JMP + C.BPF_JA
+	opRET  = C.BPF_RET + C.BPF_K
+)
+
+// SockFilter encodes one BPF machine instruction.
+// This struct mirrors struct sock_filter from <linux/filter.h>.
+type SockFilter struct {
+	Code uint16 // Actual filter code.
+	JT   uint8  // Jump true.
+	JF   uint8  // Jump false.
+	K    uint32 // Generic multiuse field.
+}
+
+// SockFprog encodes a BPF machine program.
+// This struct mirrors struct sock_fprog from <linux/filter.h>.
+type SockFprog struct {
+	Len    uint16      // Number of BPF machine instructions.
+	Filter *SockFilter // Pointer to the first instruction.
+}
+
+// C versions of the structs used for sanity checking.
+type sock_filter C.struct_sock_filter
+type sock_fprog C.struct_sock_fprog
+
+// bpfInsn constructs one BPF machine instruction.
+func bpfInsn(code uint16, k uint32, jt, jf uint8) SockFilter {
+	return SockFilter{code, jt, jf, k}
+}
+
+// bpfStmt constructs one BPF machine statement.
+func bpfStmt(code uint16, k uint32) SockFilter {
+	return bpfInsn(code, k, 0, 0)
+}
+
+// bpfLoad returns the instruction to load the word at the given offset.
+func bpfLoad(offset uintptr) SockFilter {
+	return bpfStmt(opLOAD, uint32(offset))
+}
+
+// bpfJeq returns an instruction encoding "jump-if-equal".
+// Register A is compared with val.
+// Both jt and jf are relative offsets. Offset 0 means fallthrough.
+func bpfJeq(val uint32, jt, jf uint8) SockFilter {
+	return bpfInsn(opJEQ, val, jt, jf)
+}
+
+// bpfJset returns an instruction encoding "jump-if-set".
+// Register A is bitwise anded with val and result compared with zero.
+// Both jt and jf are relative offsets. Offset 0 means fallthrough.
+func bpfJset(val uint32, jt, jf uint8) SockFilter {
+	return bpfInsn(opJSET, val, jt, jf)
+}
+
+// bpfJump returns an instruction encoding an unconditional jump to a relative offset.
+// Offset 0 means fallthrough (NOP).
+func bpfJump(offset int) SockFilter {
+	return bpfStmt(opJUMP, uint32(offset))
+}
+
+// bpfRet returns the instruction to return the value val.
+func bpfRet(val uint32) SockFilter {
+	return bpfStmt(opRET, val)
+}
+
+// String returns a readable representation of a BPF machine instruction.
+func (f SockFilter) String() string {
+	var code string
+	switch f.Code {
+	case opLOAD:
+		code = "Load"
+	case opJEQ:
+		code = "Jeq"
+	case opJSET:
+		code = "Jset"
+	case opJUMP:
+		code = "Jump"
+	case opRET:
+		code = "Return"
+	default:
+		code = fmt.Sprintf("%04x", f.Code)
+	}
+	return fmt.Sprintf("%8s %08x, %02x, %02x\n", code, f.K, f.JT, f.JF)
+}
+
+// ptr returns a pointer to a copy of the argument, useful in cases
+// where the & syntax isn't allowed. e.g. ptr(bpfInsn(...)).
+func ptr(f SockFilter) *SockFilter {
+	return &f
+}
diff --git a/src/chromiumos/seccomp/sanity_test.go b/src/chromiumos/seccomp/sanity_test.go
new file mode 100644
index 0000000..5f5741e
--- /dev/null
+++ b/src/chromiumos/seccomp/sanity_test.go
@@ -0,0 +1,175 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+import (
+	"testing"
+	"unsafe"
+)
+
+func TestSockFilter(t *testing.T) {
+	var f SockFilter
+	var cf sock_filter
+	tests := []struct {
+		desc string
+		g, c uintptr
+	}{
+		{
+			"Sizeof(SockFilter)",
+			unsafe.Sizeof(f),
+			unsafe.Sizeof(cf),
+		},
+		{
+			"Sizeof(SockFilter.Code)",
+			unsafe.Sizeof(f.Code),
+			unsafe.Sizeof(cf.code),
+		},
+		{
+			"Offsetof(SockFilter.Code)",
+			unsafe.Offsetof(f.Code),
+			unsafe.Offsetof(cf.code),
+		},
+		{
+			"Sizeof(SockFilter.Jt)",
+			unsafe.Sizeof(f.JT),
+			unsafe.Sizeof(cf.jt),
+		},
+		{
+			"Offsetof(SockFilter.Jt)",
+			unsafe.Offsetof(f.JT),
+			unsafe.Offsetof(cf.jt),
+		},
+		{
+			"Sizeof(SockFilter.Jf)",
+			unsafe.Sizeof(f.JF),
+			unsafe.Sizeof(cf.jf),
+		},
+		{
+			"Offsetof(SockFilter.Jf)",
+			unsafe.Offsetof(f.JF),
+			unsafe.Offsetof(cf.jf),
+		},
+		{
+			"Sizeof(SockFilter.K)",
+			unsafe.Sizeof(f.K),
+			unsafe.Sizeof(cf.k),
+		},
+		{
+			"Offsetof(SockFilter.K)",
+			unsafe.Offsetof(f.K),
+			unsafe.Offsetof(cf.k),
+		},
+	}
+	for _, test := range tests {
+		if test.g != test.c {
+			t.Errorf("%s = %v; want %v", test.desc, test.g, test.c)
+		}
+	}
+}
+
+func TestSockFprog(t *testing.T) {
+	var p SockFprog
+	var cp sock_fprog
+	tests := []struct {
+		desc string
+		g, c uintptr
+	}{
+		{
+			"Sizeof(SockFprog)",
+			unsafe.Sizeof(p),
+			unsafe.Sizeof(cp),
+		},
+		{
+			"Sizeof(SockFprog.Len)",
+			unsafe.Sizeof(p.Len),
+			unsafe.Sizeof(cp.len),
+		},
+		{
+			"Offsetof(SockFprog.Len)",
+			unsafe.Offsetof(p.Len),
+			unsafe.Offsetof(cp.len),
+		},
+		{
+			"Sizeof(SockFprog.Filter)",
+			unsafe.Sizeof(p.Filter),
+			unsafe.Sizeof(cp.filter),
+		},
+		{
+			"Offsetof(SockFprog.Filter)",
+			unsafe.Offsetof(p.Filter),
+			unsafe.Offsetof(cp.filter),
+		},
+	}
+	for _, test := range tests {
+		if test.g != test.c {
+			t.Errorf("%s = %v; want %v", test.desc, test.g, test.c)
+		}
+	}
+}
+
+func TestSeccompData(t *testing.T) {
+	var d SeccompData
+	var cd seccomp_data
+	tests := []struct {
+		desc string
+		g, c uintptr
+	}{
+		{
+			"Sizeof(SeccompData)",
+			unsafe.Sizeof(d),
+			unsafe.Sizeof(cd),
+		},
+		{
+			"Sizeof(SeccompData.NR)",
+			unsafe.Sizeof(d.NR),
+			unsafe.Sizeof(cd.nr),
+		},
+		{
+			"Offsetof(SeccompData.NR)",
+			unsafe.Offsetof(d.NR),
+			unsafe.Offsetof(cd.nr),
+		},
+		{
+			"Sizeof(SeccompData.Arch)",
+			unsafe.Sizeof(d.Arch),
+			unsafe.Sizeof(cd.arch),
+		},
+		{
+			"Offsetof(SeccompData.Arch)",
+			unsafe.Offsetof(d.Arch),
+			unsafe.Offsetof(cd.arch),
+		},
+		{
+			"Sizeof(SeccompData.InstructionPointer)",
+			unsafe.Sizeof(d.InstructionPointer),
+			unsafe.Sizeof(cd.instruction_pointer),
+		},
+		{
+			"Offsetof(SeccompData.InstructionPointer)",
+			unsafe.Offsetof(d.InstructionPointer),
+			unsafe.Offsetof(cd.instruction_pointer),
+		},
+		{
+			"Sizeof(SeccompData.Args)",
+			unsafe.Sizeof(d.Args),
+			unsafe.Sizeof(cd.args),
+		},
+		{
+			"Offsetof(SeccompData.Args)",
+			unsafe.Offsetof(d.Args),
+			unsafe.Offsetof(cd.args),
+		},
+		{
+			"Sizeof(SeccompData.Args[0])",
+			unsafe.Sizeof(d.Args[0]),
+			unsafe.Sizeof(cd.args[0]),
+		},
+	}
+	for _, test := range tests {
+		if test.g != test.c {
+			t.Errorf("%s = %v; want %v", test.desc, test.g, test.c)
+		}
+	}
+}
diff --git a/src/chromiumos/seccomp/seccomp.go b/src/chromiumos/seccomp/seccomp.go
new file mode 100644
index 0000000..922f42d
--- /dev/null
+++ b/src/chromiumos/seccomp/seccomp.go
@@ -0,0 +1,495 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Package seccomp implements support for compiling and installing Seccomp-BPF policy files.
+//   - http://www.chromium.org/chromium-os/developer-guide/chromium-os-sandboxing
+//
+// Typical usage:
+//	// Check for the required kernel support for seccomp.
+//	if err := seccomp.CheckSupport(); err != nil {
+//		log.Fatal(err)
+//	}
+//
+//	// Compile BPF program from a Chromium-OS policy file.
+//	bpf, err := seccomp.Compile(path)
+//	if err != nil {
+//		log.Fatal(err)
+//	}
+//
+//	// Install Seccomp-BPF filter program with the kernel.
+//	if err := seccomp.Install(bpf); err != nil {
+//		log.Fatal(err)
+//	}
+//
+// For background and more information:
+//   - http://www.tcpdump.org/papers/bpf-usenix93.pdf
+//   - http://en.wikipedia.org/wiki/Seccomp
+//   - http://lwn.net/Articles/475043/
+//   - http://outflux.net/teach-seccomp/
+//   - http://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
+//   - http://github.com/torvalds/linux/blob/master/kernel/seccomp.c
+//
+// TODO:
+//   - Exit the program if any thread is killed because of seccomp violation.
+//   - Provide a debug mode to log system calls used during normal operation.
+package seccomp
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"syscall"
+	"unsafe"
+)
+
+// #include <sys/prctl.h>
+// #include <asm/unistd.h>
+// #include <linux/seccomp.h>
+import "C"
+
+// SeccompData is the format the BPF program executes over.
+// This struct mirrors struct seccomp_data from <linux/seccomp.h>.
+type SeccompData struct {
+	NR                 int32     // The system call number.
+	Arch               uint32    // System call convention as an AUDIT_ARCH_* value.
+	InstructionPointer uint64    // At the time of the system call.
+	Args               [6]uint64 // System call arguments (always stored as 64-bit values).
+}
+
+// C version of the struct used for sanity checking.
+type seccomp_data C.struct_seccomp_data
+
+// bpfLoadNR returns the instruction to load the NR field in SeccompData.
+func bpfLoadNR() SockFilter {
+	return bpfLoad(unsafe.Offsetof(SeccompData{}.NR))
+}
+
+// bpfLoadArch returns the instruction to load the Arch field in SeccompData.
+func bpfLoadArch() SockFilter {
+	return bpfLoad(unsafe.Offsetof(SeccompData{}.Arch))
+}
+
+// bpfLoadArg returns the instruction to load one word of an argument in SeccompData.
+func bpfLoadArg(arg, word int) SockFilter {
+	return bpfLoad(unsafe.Offsetof(SeccompData{}.Args) + uintptr(((2*arg)+word)*4))
+}
+
+// retKill returns the code for seccomp kill action.
+func retKill() uint32 {
+	return C.SECCOMP_RET_KILL
+}
+
+// retTrap returns the code for seccomp trap action.
+func retTrap() uint32 {
+	return C.SECCOMP_RET_TRAP
+}
+
+// retErrno returns the code for seccomp errno action with the specified errno embedded.
+func retErrno(errno syscall.Errno) uint32 {
+	return C.SECCOMP_RET_ERRNO | (uint32(errno) & C.SECCOMP_RET_DATA)
+}
+
+// retAllow returns the code for seccomp allow action.
+func retAllow() uint32 {
+	return C.SECCOMP_RET_ALLOW
+}
+
+// policy represents the seccomp policy for a single syscall.
+type policy struct {
+	// name of the syscall.
+	name string
+
+	// expr is evaluated on the syscall arguments.
+	// nil expr evaluates to false.
+	expr orExpr
+
+	// then is executed if the expr evaluates to true.
+	// (cannot be specified in policy file, used in tests only).
+	then SockFilter
+
+	// default action (else) if the expr evaluates to false.
+	// nil means jump to end of program for the overall default.
+	def *SockFilter
+}
+
+// orExpr is a list of and expressions.
+type orExpr []andExpr
+
+// andExpr is a list of arg comparisons.
+type andExpr []argComp
+
+// argComp represents a basic argument comparison in the policy.
+type argComp struct {
+	idx  int    // 0..5 for indexing into SeccompData.Args.
+	oper string // comparison operator: "==", "!=", or "&".
+	val  uint64 // upper 32 bits compared only if nbits>32.
+}
+
+// String converts the internal policy representation back to policy file syntax.
+func (p policy) String() string {
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "%s: ", p.name)
+
+	for i, and := range p.expr {
+		if i > 0 {
+			fmt.Fprintf(&buf, " || ")
+		}
+		for j, arg := range and {
+			if j > 0 {
+				fmt.Fprintf(&buf, " && ")
+			}
+			fmt.Fprintf(&buf, "arg%d %s %#x", arg.idx, arg.oper, arg.val)
+		}
+	}
+
+	pret := func(f SockFilter) {
+		if f.Code == opRET {
+			switch f.K & C.SECCOMP_RET_ACTION {
+			case C.SECCOMP_RET_ALLOW:
+				fmt.Fprintf(&buf, "1")
+				return
+			case C.SECCOMP_RET_ERRNO:
+				fmt.Fprintf(&buf, "return %d", f.K&C.SECCOMP_RET_DATA)
+				return
+			}
+		}
+		fmt.Fprintf(&buf, "%s", f)
+	}
+	if p.then != bpfRet(retAllow()) {
+		fmt.Fprintf(&buf, " ? ")
+		pret(p.then)
+	}
+	if p.def != nil {
+		if p.expr != nil {
+			fmt.Fprintf(&buf, "; ")
+		}
+		pret(*p.def)
+	}
+
+	return buf.String()
+}
+
+// Syntax of policy line for a single syscall.
+var (
+	allowRE      = regexp.MustCompile(`^([[:word:]]+) *: *1$`)
+	returnRE     = regexp.MustCompile(`^([[:word:]]+) *: *return *([[:word:]]+)$`)
+	exprRE       = regexp.MustCompile(`^([[:word:]]+) *:([^;]+)$`)
+	exprReturnRE = regexp.MustCompile(`^([[:word:]]+) *:([^;]+); *return *([[:word:]]+)$`)
+
+	argRE = regexp.MustCompile(`^arg([0-5]) *(==|!=|&) *([[:word:]]+)$`)
+)
+
+// parseLine parses the policy line for a single syscall.
+func parseLine(line string) (policy, error) {
+	var name, expr, ret string
+	var then SockFilter
+	var def *SockFilter
+
+	line = strings.TrimSpace(line)
+	if match := allowRE.FindStringSubmatch(line); match != nil {
+		name = match[1]
+		def = ptr(bpfRet(retAllow()))
+	} else if match = returnRE.FindStringSubmatch(line); match != nil {
+		name = match[1]
+		ret = match[2]
+	} else if match = exprRE.FindStringSubmatch(line); match != nil {
+		name = match[1]
+		expr = match[2]
+	} else if match = exprReturnRE.FindStringSubmatch(line); match != nil {
+		name = match[1]
+		expr = match[2]
+		ret = match[3]
+	} else {
+		return policy{}, fmt.Errorf("invalid syntax")
+	}
+
+	if _, ok := syscallNum[name]; !ok {
+		return policy{}, fmt.Errorf("unknown syscall: %s", name)
+	}
+
+	var or orExpr
+	if expr != "" {
+		for _, sub := range strings.Split(expr, "||") {
+			var and andExpr
+			for _, arg := range strings.Split(sub, "&&") {
+				arg = strings.TrimSpace(arg)
+				match := argRE.FindStringSubmatch(arg)
+				if match == nil {
+					return policy{}, fmt.Errorf("invalid expression: %s", arg)
+				}
+				idx, err := strconv.Atoi(match[1])
+				if err != nil {
+					return policy{}, fmt.Errorf("invalid arg: %s", arg)
+				}
+				oper := match[2]
+				val, err := strconv.ParseUint(match[3], 0, 64)
+				if err != nil {
+					return policy{}, fmt.Errorf("invalid value: %s", arg)
+				}
+				and = append(and, argComp{idx, oper, val})
+			}
+			or = append(or, and)
+		}
+	}
+
+	then = bpfRet(retAllow())
+
+	if ret != "" {
+		errno, err := strconv.ParseUint(ret, 0, 16)
+		if err != nil {
+			return policy{}, fmt.Errorf("invalid errno: %s", ret)
+		}
+		def = ptr(bpfRet(retErrno(syscall.Errno(errno))))
+	}
+
+	return policy{name, or, then, def}, nil
+}
+
+// parseLines parses multiple policy lines, each one for a single syscall.
+// Empty lines and lines beginning with "#" are ignored.
+// Multiple policies for a syscall are detected and reported as error.
+func parseLines(lines []string) ([]policy, error) {
+	var ps []policy
+	seen := make(map[string]int)
+	for i, line := range lines {
+		lineno := i + 1
+		if line == "" || strings.HasPrefix(line, "#") {
+			continue
+		}
+		p, err := parseLine(line)
+		if err != nil {
+			return nil, fmt.Errorf("line %d: %v", lineno, err)
+		}
+		if seen[p.name] > 0 {
+			return nil, fmt.Errorf("lines %d,%d: multiple policies for %s",
+				seen[p.name], lineno, p.name)
+		}
+		seen[p.name] = lineno
+		ps = append(ps, p)
+	}
+	return ps, nil
+}
+
+// parseFile reads a Chromium-OS Seccomp-BPF policy file and parses its contents.
+func parseFile(path string) ([]policy, error) {
+	file, err := ioutil.ReadFile(path)
+	if err != nil {
+		return nil, err
+	}
+	return parseLines(strings.Split(string(file), "\n"))
+}
+
+// compile compiles a Seccomp-BPF program implementing the syscall policies.
+// long specifies whether to generate 32-bit or 64-bit argument comparisons.
+// def is the overall default action to take when the syscall does not match
+// any policy in the filter.
+func compile(ps []policy, long bool, def SockFilter) ([]SockFilter, error) {
+	var bpf []SockFilter
+	do := func(insn SockFilter) {
+		bpf = append(bpf, insn)
+	}
+
+	// ref maps a label to addresses of all the instructions that jump to it.
+	ref := make(map[string][]int)
+	jump := func(name string) {
+		// jump to a label with unresolved address: insert a placeholder instruction.
+		ref[name] = append(ref[name], len(bpf))
+		do(SockFilter{})
+	}
+	label := func(name string) {
+		// label address resolved: replace placeholder instructions with actual jumps.
+		for _, i := range ref[name] {
+			bpf[i] = bpfJump(len(bpf) - (i + 1))
+		}
+		delete(ref, name)
+	}
+
+	// Conditional jumps: jump if condition is true, fall through otherwise.
+	jeq := func(val uint32, target string) {
+		// if A == val { goto target }
+		do(bpfJeq(val, 0, 1))
+		jump(target)
+	}
+	jne := func(val uint32, target string) {
+		// if A != val { goto target }
+		do(bpfJeq(val, 1, 0))
+		jump(target)
+	}
+	jset := func(val uint32, target string) {
+		// if A&val != 0 { goto target }
+		do(bpfJset(val, 0, 1))
+		jump(target)
+	}
+	jnset := func(val uint32, target string) {
+		// if A&val == 0 { goto target }
+		do(bpfJset(val, 1, 0))
+		jump(target)
+	}
+
+	do(bpfLoadArch())
+	do(bpfJeq(auditArch, 1, 0))
+	do(bpfRet(retKill()))
+
+	do(bpfLoadNR())
+	for _, p := range ps {
+		nr, ok := syscallNum[p.name]
+		if !ok {
+			return nil, fmt.Errorf("unknown syscall: %s", p.name)
+		}
+		jne(uint32(nr), "nextcall")
+
+		for _, and := range p.expr {
+			for _, arg := range and {
+				val := struct{ high, low uint32 }{uint32(arg.val >> 32), uint32(arg.val)}
+				switch arg.oper {
+				case "==":
+					if long {
+						do(bpfLoadArg(arg.idx, 1))
+						jne(val.high, "nextor")
+					}
+					do(bpfLoadArg(arg.idx, 0))
+					jne(val.low, "nextor")
+				case "!=":
+					if long {
+						do(bpfLoadArg(arg.idx, 1))
+						jne(val.high, "nextand")
+					}
+					do(bpfLoadArg(arg.idx, 0))
+					jeq(val.low, "nextor")
+				case "&":
+					if long {
+						do(bpfLoadArg(arg.idx, 1))
+						jset(val.high, "nextand")
+					}
+					do(bpfLoadArg(arg.idx, 0))
+					jnset(val.low, "nextor")
+				default:
+					return nil, fmt.Errorf("unknown operator: %q", arg.oper)
+				}
+
+				// Comparison was satisfied. Move on to the next comparison in &&.
+				label("nextand")
+			}
+
+			// All comparisons in && were satisfied.
+			do(p.then)
+
+			// Some comparison in && was false. Move on to the next expression in ||.
+			label("nextor")
+		}
+
+		// All expressions in || evaluated to false (or expr was nil).
+		if p.def != nil {
+			do(*p.def)
+		} else {
+			jump("default")
+		}
+
+		label("nextcall")
+	}
+
+	label("default")
+	do(def)
+
+	if len(ref) > 0 {
+		return nil, fmt.Errorf("unresolved labels: %v\n%v", ref, bpf)
+	}
+	return bpf, nil
+}
+
+// Compile reads a Chromium-OS policy file and compiles a
+// Seccomp-BPF filter program implementing the policies.
+func Compile(path string) ([]SockFilter, error) {
+	ps, err := parseFile(path)
+	if err != nil {
+		return nil, err
+	}
+	return compile(ps, nbits > 32, bpfRet(retKill()))
+}
+
+// prctl is a wrapper for the 'prctl' system call.
+// See 'man prctl' for details.
+func prctl(option uintptr, args ...uintptr) error {
+	if len(args) > 4 {
+		return syscall.E2BIG
+	}
+	var arg [4]uintptr
+	copy(arg[:], args)
+	_, _, e := syscall.Syscall6(C.__NR_prctl, option, arg[0], arg[1], arg[2], arg[3], 0)
+	if e != 0 {
+		return e
+	}
+	return nil
+}
+
+// seccomp is a wrapper for the 'seccomp' system call.
+// See <linux/seccomp.h> for valid op and flag values.
+// uargs is typically a pointer to struct sock_fprog.
+func seccomp(op, flags uintptr, uargs unsafe.Pointer) error {
+	_, _, e := syscall.Syscall(C.__NR_seccomp, op, flags, uintptr(uargs))
+	if e != 0 {
+		return e
+	}
+	return nil
+}
+
+// CheckSupport checks for the required seccomp support in the kernel.
+func CheckSupport() error {
+	// This is based on http://outflux.net/teach-seccomp/autodetect.html.
+	if err := prctl(C.PR_GET_SECCOMP); err != nil {
+		return fmt.Errorf("seccomp not available: %v", err)
+	}
+	if err := prctl(C.PR_SET_SECCOMP, C.SECCOMP_MODE_FILTER, 0); err != syscall.EFAULT {
+		return fmt.Errorf("seccomp filter not available: %v", err)
+	}
+	if err := seccomp(C.SECCOMP_SET_MODE_FILTER, 0, nil); err != syscall.EFAULT {
+		return fmt.Errorf("seccomp syscall not available: %v", err)
+	}
+	if err := seccomp(C.SECCOMP_SET_MODE_FILTER, C.SECCOMP_FILTER_FLAG_TSYNC, nil); err != syscall.EFAULT {
+		return fmt.Errorf("seccomp tsync not available: %v", err)
+	}
+	return nil
+}
+
+// Load makes the seccomp system call to install the bpf filter for
+// all threads (with tsync). prctl(set_no_new_privs, 1) must have
+// been called (from the same thread) before calling Load for the
+// first time.
+//   Most users of this library should use Install instead of calling
+//   Load directly. There are a couple of situations where it may be
+//   necessary to use Load instead of Install:
+//   - If a previous call to Install has disabled the 'prctl' system
+//     call, Install cannot be called again. In that case, it is safe
+//     to add additional filters directly with Load.
+//   - If the process is running as a priviledged user, and you want
+//     to load the seccomp filter without setting no_new_privs.
+func Load(bpf []SockFilter) error {
+	if size, limit := len(bpf), 0xffff; size > limit {
+		return fmt.Errorf("filter program too big: %d bpf instructions (limit = %d)", size, limit)
+	}
+	prog := &SockFprog{
+		Filter: &bpf[0],
+		Len:    uint16(len(bpf)),
+	}
+	return seccomp(C.SECCOMP_SET_MODE_FILTER, C.SECCOMP_FILTER_FLAG_TSYNC, unsafe.Pointer(prog))
+}
+
+// Install makes the necessary system calls to install the Seccomp-BPF
+// filter for the current process (all threads). Install can be called
+// multiple times to install additional filters.
+func Install(bpf []SockFilter) error {
+	// prctl(set_no_new_privs, 1) must be called (from the same thread)
+	// before a seccomp filter can be installed by an unprivileged user:
+	// - http://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt.
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+	if err := prctl(C.PR_SET_NO_NEW_PRIVS, 1); err != nil {
+		return err
+	}
+	return Load(bpf)
+}
diff --git a/src/chromiumos/seccomp/seccomp_test.go b/src/chromiumos/seccomp/seccomp_test.go
new file mode 100644
index 0000000..a5b90ab
--- /dev/null
+++ b/src/chromiumos/seccomp/seccomp_test.go
@@ -0,0 +1,529 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+import (
+	"flag"
+	"os"
+	"runtime"
+	"syscall"
+	"testing"
+	"unsafe"
+)
+
+var (
+	parseFilePath = flag.String("parse_file", "", "path for TestParseFile")
+	testInstall   = flag.Bool("test_install", false, "enable TestInstall (use with -cpu=N)")
+	testEndian    = flag.Bool("test_endian", false, "enable TestEndian")
+)
+
+func TestParseLine(t *testing.T) {
+	tests := []struct {
+		policy string
+		want   string
+		err    string
+	}{
+		{policy: "read: 1"},
+		{policy: "open: return 1"},
+		{policy: "prctl: arg0 == 0xf"},
+		{policy: "prctl: arg0 != 0xf"},
+		{policy: "ioctl: arg1 & 0x5401"},
+		{policy: "ioctl: arg1 == 0x4024700a || arg1 == 0x541b"},
+		{policy: "ioctl: arg1 == 0x4024700a && arg1 == 0x541b"},
+		{policy: "ioctl: arg1 == 0x5401 || arg1 == 0x700a || arg2 & 0x541b"},
+		{policy: "ioctl: arg1 == 0x5401 && arg1 == 0x700a && arg3 & 0x541b"},
+		{policy: "ioctl: arg1 == 0x5401 || arg1 == 0x700a && arg4 & 0x541b"},
+		{policy: "ioctl: arg1 == 0x5401 && arg1 == 0x700a || arg5 & 0x541b"},
+		{policy: "ioctl: arg1 == 0x5401 && arg1 == 0x700a || arg5 & 0x541b; return 1"},
+		{
+			// different spacing around colon.
+			policy: "read :1",
+			want:   "read: 1",
+		},
+		{
+			// leading and trailing whitespace.
+			policy: " open :  return 1  ",
+			want:   "open: return 1",
+		},
+		{
+			// return hexadecimal errno.
+			policy: "open: return 0x10",
+			want:   "open: return 16",
+		},
+		{
+			// return octal errno.
+			policy: "open: return 010",
+			want:   "open: return 8",
+		},
+		{
+			// return highest errno.
+			policy: "open: return 0xffff",
+			want:   "open: return 65535",
+		},
+		{
+			// expression with no spaces.
+			policy: "ioctl:arg1==0x5401&&arg1==0x700a||arg2&0x541b",
+			want:   "ioctl: arg1 == 0x5401 && arg1 == 0x700a || arg2 & 0x541b",
+		},
+		{
+			// compare with decimal value.
+			policy: "ioctl: arg1 == 5401 && arg1 == 0x700a || arg2 & 0x541b",
+			want:   "ioctl: arg1 == 0x1519 && arg1 == 0x700a || arg2 & 0x541b",
+		},
+		{
+			// compare with octal value.
+			policy: "ioctl: arg1 == 05401 && arg1 == 0x700a || arg2 & 0x541b",
+			want:   "ioctl: arg1 == 0xb01 && arg1 == 0x700a || arg2 & 0x541b",
+		},
+		{
+			// all decimal comparisons.
+			policy: "clone: arg0 == 1 || arg0 == 2 || arg0 == 16",
+			want:   "clone: arg0 == 0x1 || arg0 == 0x2 || arg0 == 0x10",
+		},
+		{
+			// missing syscall name.
+			policy: ": 1",
+			err:    "invalid syntax",
+		},
+		{
+			// malformed syscall name.
+			policy: "two words: 1",
+			err:    "invalid syntax",
+		},
+		{
+			// missing colon.
+			policy: "read = 1",
+			err:    "invalid syntax",
+		},
+		{
+			// trailing semicolon after return.
+			policy: "open: return 1;",
+			err:    "invalid syntax",
+		},
+		{
+			// trailing semicolon after expression.
+			policy: "prctl: arg0 == 0xf;",
+			err:    "invalid syntax",
+		},
+		{
+			// missing return after semicolon.
+			policy: "prctl: arg0 == 0xf; 1",
+			err:    "invalid syntax",
+		},
+		{
+			// bad syscall name.
+			policy: "bad: 1",
+			err:    "unknown syscall: bad",
+		},
+		{
+			// symbolic errno is not supported.
+			policy: "open: return EPERM",
+			err:    "invalid errno: EPERM",
+		},
+		{
+			// errno must fit in 16 bits.
+			policy: "open: return 0x10000",
+			err:    "invalid errno: 0x10000",
+		},
+		{
+			// missing argument index.
+			policy: "prctl: arg == 0xf",
+			err:    "invalid expression: arg == 0xf",
+		},
+		{
+			// arg index out of range.
+			policy: "prctl: arg6 == 0xf",
+			err:    "invalid expression: arg6 == 0xf",
+		},
+		{
+			// bitwise and with argument not supported.
+			policy: "prctl: arg0 & 0xf == 0xf",
+			err:    "invalid expression: arg0 & 0xf == 0xf",
+		},
+		{
+			// unknown operator.
+			policy: "prctl: arg0 !== 0xf",
+			err:    "invalid expression: arg0 !== 0xf",
+		},
+		{
+			// invalid hexadecimal value.
+			policy: "prctl: arg0 == 0xfdx",
+			err:    "invalid value: arg0 == 0xfdx",
+		},
+		{
+			// invalid decimal value.
+			policy: "prctl: arg0 == 123a",
+			err:    "invalid value: arg0 == 123a",
+		},
+		{
+			// invalid octal value.
+			policy: "prctl: arg0 == 0129",
+			err:    "invalid value: arg0 == 0129",
+		},
+		{
+			// invalid subexpression.
+			policy: "prctl: arg0 == 0x100 && arg1 = 0x101 || arg2 == 0x102",
+			err:    "invalid expression: arg1 = 0x101",
+		},
+	}
+	for _, test := range tests {
+		var err string
+		p, e := parseLine(test.policy)
+		if e != nil {
+			err = e.Error()
+		}
+		if err != "" || test.err != "" {
+			if err != test.err {
+				t.Errorf("parseLine(%q): error = %q; want %q", test.policy, err, test.err)
+			}
+			continue
+		}
+		want := test.want
+		if want == "" {
+			want = test.policy
+		}
+		if got := p.String(); got != want {
+			t.Errorf("parseLine(%q) = %q; want %q", test.policy, got, test.want)
+		}
+	}
+}
+
+func TestParseLines(t *testing.T) {
+	tests := []struct {
+		file []string
+		err  string
+	}{
+		{
+			// simple policy file.
+			file: []string{
+				"read: 1",
+				"write: 1",
+				"open: return 1",
+			},
+		},
+		{
+			// comment lines are ignored.
+			file: []string{
+				"read: 1",
+				"write: 1",
+				"# open: return EPERM",
+				"open: return 1",
+			},
+		},
+		{
+			// blank lines are ignored.
+			file: []string{
+				"read: 1",
+				"write: 1",
+				"",
+				"open: return 1",
+			},
+		},
+		{
+			// leading space on comment line.
+			file: []string{
+				"read: 1",
+				"write: 1",
+				" # open: return EPERM",
+				"open: return 1",
+			},
+			err: "line 3: invalid syntax",
+		},
+		{
+			// line consisting of whitespace only.
+			file: []string{
+				"read: 1",
+				"write: 1",
+				" ",
+				"open: return 1",
+			},
+			err: "line 3: invalid syntax",
+		},
+		{
+			// parse error on one line.
+			file: []string{
+				"read: 1",
+				"write: return 019",
+				"open: return 1",
+			},
+			err: "line 2: invalid errno: 019",
+		},
+		{
+			// multiple policies for a syscall.
+			file: []string{
+				"read: 1",
+				"write: 1",
+				"read: return 1",
+				"open: return 1",
+			},
+			err: "lines 1,3: multiple policies for read",
+		},
+	}
+	for _, test := range tests {
+		var err string
+		_, e := parseLines(test.file)
+		if e != nil {
+			err = e.Error()
+		}
+		if err != "" || test.err != "" {
+			if err != test.err {
+				t.Errorf("parseLines(%q): error = %q; want %q", test.file, err, test.err)
+			}
+		}
+	}
+}
+
+func TestParseFile(t *testing.T) {
+	if *parseFilePath == "" {
+		t.Skip("use -parse_file to enable.")
+	}
+
+	if _, err := parseFile(*parseFilePath); err != nil {
+		t.Errorf("parseFile(%q): %v", *parseFilePath, err)
+	}
+}
+
+func TestCompile(t *testing.T) {
+	syscallName := make(map[int32]string)
+	for name, nr := range syscallNum {
+		syscallName[int32(nr)] = name
+	}
+
+	call := func(name string, args ...uint64) SeccompData {
+		nr, ok := syscallNum[name]
+		if !ok {
+			t.Fatalf("unknown syscall: %s", name)
+		}
+		data := SeccompData{
+			NR:   int32(nr),
+			Arch: auditArch,
+		}
+		copy(data.Args[:], args)
+		return data
+	}
+
+	eval := func(bpf []SockFilter, data SeccompData) uint32 {
+		var A uint32
+		IP := 0
+		for {
+			Insn := bpf[IP]
+			IP++
+			switch Insn.Code {
+			case opLOAD:
+				A = *(*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(&data)) + uintptr(Insn.K)))
+			case opJEQ:
+				if A == Insn.K {
+					IP += int(Insn.JT)
+				} else {
+					IP += int(Insn.JF)
+				}
+			case opJSET:
+				if A&Insn.K != 0 {
+					IP += int(Insn.JT)
+				} else {
+					IP += int(Insn.JF)
+				}
+			case opJUMP:
+				IP += int(Insn.K)
+			case opRET:
+				return Insn.K
+			default:
+				t.Fatalf("unsupported instruction: %v", Insn)
+			}
+		}
+	}
+
+	file := []string{
+		"read: 1",
+		"open: return 1",
+		"write: arg0 == 1",
+		"close: arg0 == 2; return 9",
+		"dup: arg0 == 1 || arg0 == 2",
+		"pipe: arg0 == 1 && arg1 == 2",
+		"link: arg0 != 1 && arg1 != 2 || arg2 == 3",
+		"unlink: arg0 != 1 || arg1 != 2 && arg2 == 3",
+		"creat: arg0 & 0xf00 && arg1 & 0x0f0 && arg2 & 0x00f",
+		"lseek: arg0 & 0x0f000f000f000f00 && arg1 & 0x00f000f000f000f0 && arg2 & 0x000f000f000f000f",
+		"stat: arg0 != 0x0123456789abcdef && arg1 != 0x123456789abcdef0 || arg2 == 0x00f000f000000000",
+		"fstat: arg0 != 0x0123456789abcdef || arg1 != 0x123456789abcdef0 && arg2 == 0x00f000f000000000",
+	}
+	tests := []struct {
+		data SeccompData
+		want uint32
+	}{
+		{call("fork"), retKill()},
+		{call("read"), retAllow()},
+		{call("open"), retErrno(1)},
+		{call("write", 0), retKill()},
+		{call("write", 1), retAllow()},
+		{call("close", 1), retErrno(9)},
+		{call("close", 2), retAllow()},
+		{call("dup", 0), retKill()},
+		{call("dup", 1), retAllow()},
+		{call("dup", 2), retAllow()},
+		{call("dup", 3), retKill()},
+		{call("pipe", 1, 1), retKill()},
+		{call("pipe", 1, 2), retAllow()},
+		{call("pipe", 2, 1), retKill()},
+		{call("pipe", 2, 2), retKill()},
+		{call("link", 1, 2, 3), retAllow()},
+		{call("link", 1, 2, 2), retKill()},
+		{call("link", 2, 2, 2), retKill()},
+		{call("link", 2, 1, 2), retAllow()},
+		{call("unlink", 2, 1, 2), retAllow()},
+		{call("unlink", 1, 1, 2), retKill()},
+		{call("unlink", 1, 1, 3), retAllow()},
+		{call("unlink", 1, 2, 3), retKill()},
+		{call("creat", 0x100, 0x100, 0x101), retKill()},
+		{call("creat", 0x200, 0x110, 0x101), retAllow()},
+		{call("creat", 0x400, 0x110, 0x110), retKill()},
+		{call("creat", 0x800, 0x110, 0x007), retAllow()},
+		{call("lseek", 0x0100, 0x0100, 0x0101), retKill()},
+		{call("lseek", 0x0200, 0x0110, 0x0101), retAllow()},
+		{call("lseek", 0x0400, 0x0110, 0x0110), retKill()},
+		{call("lseek", 0x0800, 0x0110, 0x0007), retAllow()},
+		{call("lseek", 0x0100000000000000, 0x0100000000000000, 0x0101000000000000), retKill()},
+		{call("lseek", 0x0200000000000000, 0x0110000000000000, 0x0101000000000000), retAllow()},
+		{call("lseek", 0x0400000000000000, 0x0110000000000000, 0x0110000000000000), retKill()},
+		{call("lseek", 0x0800000000000000, 0x0110000000000000, 0x0007000000000000), retAllow()},
+		{call("stat", 0x0123456789abcdef, 0x123456789abcdef0, 0x00f000f000000000), retAllow()},
+		{call("stat", 0x0123456789abcdef, 0x123456789abcdef0, 0x007000f000000000), retKill()},
+		{call("stat", 0x0133456789abcdef, 0x123457789abcdef0, 0x007000f000000000), retAllow()},
+		{call("stat", 0x0133456789abcdef, 0x123456789abcdef0, 0x007000f000000000), retKill()},
+		{call("fstat", 0x0123456789abcdef, 0x123456789abcdef0, 0x00f000f000000000), retKill()},
+		{call("fstat", 0x0133456789abcdef, 0x123456789abcdef0, 0x00f000f000000000), retAllow()},
+		{call("fstat", 0x0123456789abcdef, 0x123457789abcdef0, 0x00f000f000000000), retAllow()},
+		{call("fstat", 0x0123456789abcdef, 0x123457789abcdef0, 0x007000f000000000), retKill()},
+	}
+
+	ps, err := parseLines(file)
+	if err != nil {
+		t.Fatalf("parse failed: %v", err)
+	}
+	bpf, err := compile(ps, true, bpfRet(retKill()))
+	if err != nil {
+		t.Fatalf("compile failed: %v", err)
+	}
+	t.Logf("len(bpf) = %d", len(bpf))
+	for _, test := range tests {
+		if got := eval(bpf, test.data); got != test.want {
+			t.Errorf("%s%#x = %#08x; want %#08x", syscallName[test.data.NR], test.data.Args, got, test.want)
+		}
+	}
+}
+
+func TestSupport(t *testing.T) {
+	if err := CheckSupport(); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestInstall(t *testing.T) {
+	if !*testInstall {
+		t.Skip("use -test_install (with -cpu=N) to enable.")
+	}
+
+	file := []string{
+		"# open: return EPERM",
+		"open: return 1",
+		"# default: ALLOW",
+	}
+
+	ps, err := parseLines(file)
+	if err != nil {
+		t.Fatalf("parse failed: %v", err)
+	}
+	bpf, err := compile(ps, nbits > 32, bpfRet(retAllow()))
+	if err != nil {
+		t.Fatalf("compile failed: %v", err)
+	}
+	if err = Install(bpf); err != nil {
+		t.Fatalf("install failed: %v", err)
+	}
+
+	N := runtime.GOMAXPROCS(0)
+	opened := make(chan bool)
+	for i := 0; i < N; i++ {
+		go func() {
+			if f, err := os.Open("/dev/null"); err != nil {
+				t.Logf("open() failed: %v", err)
+				opened <- false
+			} else {
+				t.Logf("open() succeeded")
+				f.Close()
+				opened <- true
+			}
+		}()
+	}
+	for i := 0; i < N; i++ {
+		if <-opened {
+			t.Fail()
+		}
+	}
+}
+
+func TestEndian(t *testing.T) {
+	if !*testEndian {
+		t.Skip("use -test_endian to enable.")
+	}
+
+	pass := syscall.EDOM
+	fail := syscall.ERANGE
+	name := map[error]string{
+		pass: "pass",
+		fail: "fail",
+		nil:  "<nil>",
+	}
+
+	type seccomp [3]uintptr
+	ps := []policy{
+		{
+			name: "seccomp",
+			expr: orExpr{
+				andExpr{
+					argComp{0, "==", 0x0123456789abcdef},
+				},
+				andExpr{
+					argComp{1, "!=", 0x01234567},
+					argComp{2, "&", 0x01010101},
+				},
+			},
+			then: bpfRet(retErrno(pass)),
+			def:  ptr(bpfRet(retErrno(fail))),
+		},
+	}
+	tests := []struct {
+		args seccomp
+		want error
+	}{
+		{seccomp{0x01234567, 0, 0}, fail},
+		{seccomp{0x89abcdef, 0, 0}, pass},
+		{seccomp{0, 0x01234567, 0}, fail},
+		{seccomp{0, 0x12345678, 0}, fail},
+		{seccomp{0, 0x01234567, 1}, fail},
+		{seccomp{0, 0x12345678, 1}, pass},
+	}
+	call := func(args seccomp) error {
+		if nr, ok := syscallNum["seccomp"]; ok {
+			if _, _, e := syscall.Syscall(uintptr(nr), args[0], args[1], args[2]); e != 0 {
+				return e
+			}
+		}
+		return nil
+	}
+
+	bpf, err := compile(ps, false, bpfRet(retAllow()))
+	if err != nil {
+		t.Fatalf("compile failed: %v", err)
+	}
+	if err = Install(bpf); err != nil {
+		t.Fatalf("install failed: %v", err)
+	}
+	for _, test := range tests {
+		if got := call(test.args); got != test.want {
+			t.Errorf("seccomp%#x = %v; want %v", test.args, name[got], name[test.want])
+		}
+	}
+}
diff --git a/src/chromiumos/seccomp/syscalls_386.go b/src/chromiumos/seccomp/syscalls_386.go
new file mode 100644
index 0000000..edb3c5d
--- /dev/null
+++ b/src/chromiumos/seccomp/syscalls_386.go
@@ -0,0 +1,365 @@
+// DO NOT EDIT. Autogenerated by syscalls_gen.go
+
+package seccomp
+
+// #include <asm/unistd.h>
+import "C"
+
+// syscallNum maps system call names to numbers.
+var syscallNum = map[string]int{
+	"restart_syscall":        C.__NR_restart_syscall,
+	"exit":                   C.__NR_exit,
+	"fork":                   C.__NR_fork,
+	"read":                   C.__NR_read,
+	"write":                  C.__NR_write,
+	"open":                   C.__NR_open,
+	"close":                  C.__NR_close,
+	"waitpid":                C.__NR_waitpid,
+	"creat":                  C.__NR_creat,
+	"link":                   C.__NR_link,
+	"unlink":                 C.__NR_unlink,
+	"execve":                 C.__NR_execve,
+	"chdir":                  C.__NR_chdir,
+	"time":                   C.__NR_time,
+	"mknod":                  C.__NR_mknod,
+	"chmod":                  C.__NR_chmod,
+	"lchown":                 C.__NR_lchown,
+	"break":                  C.__NR_break,
+	"oldstat":                C.__NR_oldstat,
+	"lseek":                  C.__NR_lseek,
+	"getpid":                 C.__NR_getpid,
+	"mount":                  C.__NR_mount,
+	"umount":                 C.__NR_umount,
+	"setuid":                 C.__NR_setuid,
+	"getuid":                 C.__NR_getuid,
+	"stime":                  C.__NR_stime,
+	"ptrace":                 C.__NR_ptrace,
+	"alarm":                  C.__NR_alarm,
+	"oldfstat":               C.__NR_oldfstat,
+	"pause":                  C.__NR_pause,
+	"utime":                  C.__NR_utime,
+	"stty":                   C.__NR_stty,
+	"gtty":                   C.__NR_gtty,
+	"access":                 C.__NR_access,
+	"nice":                   C.__NR_nice,
+	"ftime":                  C.__NR_ftime,
+	"sync":                   C.__NR_sync,
+	"kill":                   C.__NR_kill,
+	"rename":                 C.__NR_rename,
+	"mkdir":                  C.__NR_mkdir,
+	"rmdir":                  C.__NR_rmdir,
+	"dup":                    C.__NR_dup,
+	"pipe":                   C.__NR_pipe,
+	"times":                  C.__NR_times,
+	"prof":                   C.__NR_prof,
+	"brk":                    C.__NR_brk,
+	"setgid":                 C.__NR_setgid,
+	"getgid":                 C.__NR_getgid,
+	"signal":                 C.__NR_signal,
+	"geteuid":                C.__NR_geteuid,
+	"getegid":                C.__NR_getegid,
+	"acct":                   C.__NR_acct,
+	"umount2":                C.__NR_umount2,
+	"lock":                   C.__NR_lock,
+	"ioctl":                  C.__NR_ioctl,
+	"fcntl":                  C.__NR_fcntl,
+	"mpx":                    C.__NR_mpx,
+	"setpgid":                C.__NR_setpgid,
+	"ulimit":                 C.__NR_ulimit,
+	"oldolduname":            C.__NR_oldolduname,
+	"umask":                  C.__NR_umask,
+	"chroot":                 C.__NR_chroot,
+	"ustat":                  C.__NR_ustat,
+	"dup2":                   C.__NR_dup2,
+	"getppid":                C.__NR_getppid,
+	"getpgrp":                C.__NR_getpgrp,
+	"setsid":                 C.__NR_setsid,
+	"sigaction":              C.__NR_sigaction,
+	"sgetmask":               C.__NR_sgetmask,
+	"ssetmask":               C.__NR_ssetmask,
+	"setreuid":               C.__NR_setreuid,
+	"setregid":               C.__NR_setregid,
+	"sigsuspend":             C.__NR_sigsuspend,
+	"sigpending":             C.__NR_sigpending,
+	"sethostname":            C.__NR_sethostname,
+	"setrlimit":              C.__NR_setrlimit,
+	"getrlimit":              C.__NR_getrlimit,
+	"getrusage":              C.__NR_getrusage,
+	"gettimeofday":           C.__NR_gettimeofday,
+	"settimeofday":           C.__NR_settimeofday,
+	"getgroups":              C.__NR_getgroups,
+	"setgroups":              C.__NR_setgroups,
+	"select":                 C.__NR_select,
+	"symlink":                C.__NR_symlink,
+	"oldlstat":               C.__NR_oldlstat,
+	"readlink":               C.__NR_readlink,
+	"uselib":                 C.__NR_uselib,
+	"swapon":                 C.__NR_swapon,
+	"reboot":                 C.__NR_reboot,
+	"readdir":                C.__NR_readdir,
+	"mmap":                   C.__NR_mmap,
+	"munmap":                 C.__NR_munmap,
+	"truncate":               C.__NR_truncate,
+	"ftruncate":              C.__NR_ftruncate,
+	"fchmod":                 C.__NR_fchmod,
+	"fchown":                 C.__NR_fchown,
+	"getpriority":            C.__NR_getpriority,
+	"setpriority":            C.__NR_setpriority,
+	"profil":                 C.__NR_profil,
+	"statfs":                 C.__NR_statfs,
+	"fstatfs":                C.__NR_fstatfs,
+	"ioperm":                 C.__NR_ioperm,
+	"socketcall":             C.__NR_socketcall,
+	"syslog":                 C.__NR_syslog,
+	"setitimer":              C.__NR_setitimer,
+	"getitimer":              C.__NR_getitimer,
+	"stat":                   C.__NR_stat,
+	"lstat":                  C.__NR_lstat,
+	"fstat":                  C.__NR_fstat,
+	"olduname":               C.__NR_olduname,
+	"iopl":                   C.__NR_iopl,
+	"vhangup":                C.__NR_vhangup,
+	"idle":                   C.__NR_idle,
+	"vm86old":                C.__NR_vm86old,
+	"wait4":                  C.__NR_wait4,
+	"swapoff":                C.__NR_swapoff,
+	"sysinfo":                C.__NR_sysinfo,
+	"ipc":                    C.__NR_ipc,
+	"fsync":                  C.__NR_fsync,
+	"sigreturn":              C.__NR_sigreturn,
+	"clone":                  C.__NR_clone,
+	"setdomainname":          C.__NR_setdomainname,
+	"uname":                  C.__NR_uname,
+	"modify_ldt":             C.__NR_modify_ldt,
+	"adjtimex":               C.__NR_adjtimex,
+	"mprotect":               C.__NR_mprotect,
+	"sigprocmask":            C.__NR_sigprocmask,
+	"create_module":          C.__NR_create_module,
+	"init_module":            C.__NR_init_module,
+	"delete_module":          C.__NR_delete_module,
+	"get_kernel_syms":        C.__NR_get_kernel_syms,
+	"quotactl":               C.__NR_quotactl,
+	"getpgid":                C.__NR_getpgid,
+	"fchdir":                 C.__NR_fchdir,
+	"bdflush":                C.__NR_bdflush,
+	"sysfs":                  C.__NR_sysfs,
+	"personality":            C.__NR_personality,
+	"afs_syscall":            C.__NR_afs_syscall,
+	"setfsuid":               C.__NR_setfsuid,
+	"setfsgid":               C.__NR_setfsgid,
+	"_llseek":                C.__NR__llseek,
+	"getdents":               C.__NR_getdents,
+	"_newselect":             C.__NR__newselect,
+	"flock":                  C.__NR_flock,
+	"msync":                  C.__NR_msync,
+	"readv":                  C.__NR_readv,
+	"writev":                 C.__NR_writev,
+	"getsid":                 C.__NR_getsid,
+	"fdatasync":              C.__NR_fdatasync,
+	"_sysctl":                C.__NR__sysctl,
+	"mlock":                  C.__NR_mlock,
+	"munlock":                C.__NR_munlock,
+	"mlockall":               C.__NR_mlockall,
+	"munlockall":             C.__NR_munlockall,
+	"sched_setparam":         C.__NR_sched_setparam,
+	"sched_getparam":         C.__NR_sched_getparam,
+	"sched_setscheduler":     C.__NR_sched_setscheduler,
+	"sched_getscheduler":     C.__NR_sched_getscheduler,
+	"sched_yield":            C.__NR_sched_yield,
+	"sched_get_priority_max": C.__NR_sched_get_priority_max,
+	"sched_get_priority_min": C.__NR_sched_get_priority_min,
+	"sched_rr_get_interval":  C.__NR_sched_rr_get_interval,
+	"nanosleep":              C.__NR_nanosleep,
+	"mremap":                 C.__NR_mremap,
+	"setresuid":              C.__NR_setresuid,
+	"getresuid":              C.__NR_getresuid,
+	"vm86":                   C.__NR_vm86,
+	"query_module":           C.__NR_query_module,
+	"poll":                   C.__NR_poll,
+	"nfsservctl":             C.__NR_nfsservctl,
+	"setresgid":              C.__NR_setresgid,
+	"getresgid":              C.__NR_getresgid,
+	"prctl":                  C.__NR_prctl,
+	"rt_sigreturn":           C.__NR_rt_sigreturn,
+	"rt_sigaction":           C.__NR_rt_sigaction,
+	"rt_sigprocmask":         C.__NR_rt_sigprocmask,
+	"rt_sigpending":          C.__NR_rt_sigpending,
+	"rt_sigtimedwait":        C.__NR_rt_sigtimedwait,
+	"rt_sigqueueinfo":        C.__NR_rt_sigqueueinfo,
+	"rt_sigsuspend":          C.__NR_rt_sigsuspend,
+	"pread64":                C.__NR_pread64,
+	"pwrite64":               C.__NR_pwrite64,
+	"chown":                  C.__NR_chown,
+	"getcwd":                 C.__NR_getcwd,
+	"capget":                 C.__NR_capget,
+	"capset":                 C.__NR_capset,
+	"sigaltstack":            C.__NR_sigaltstack,
+	"sendfile":               C.__NR_sendfile,
+	"getpmsg":                C.__NR_getpmsg,
+	"putpmsg":                C.__NR_putpmsg,
+	"vfork":                  C.__NR_vfork,
+	"ugetrlimit":             C.__NR_ugetrlimit,
+	"mmap2":                  C.__NR_mmap2,
+	"truncate64":             C.__NR_truncate64,
+	"ftruncate64":            C.__NR_ftruncate64,
+	"stat64":                 C.__NR_stat64,
+	"lstat64":                C.__NR_lstat64,
+	"fstat64":                C.__NR_fstat64,
+	"lchown32":               C.__NR_lchown32,
+	"getuid32":               C.__NR_getuid32,
+	"getgid32":               C.__NR_getgid32,
+	"geteuid32":              C.__NR_geteuid32,
+	"getegid32":              C.__NR_getegid32,
+	"setreuid32":             C.__NR_setreuid32,
+	"setregid32":             C.__NR_setregid32,
+	"getgroups32":            C.__NR_getgroups32,
+	"setgroups32":            C.__NR_setgroups32,
+	"fchown32":               C.__NR_fchown32,
+	"setresuid32":            C.__NR_setresuid32,
+	"getresuid32":            C.__NR_getresuid32,
+	"setresgid32":            C.__NR_setresgid32,
+	"getresgid32":            C.__NR_getresgid32,
+	"chown32":                C.__NR_chown32,
+	"setuid32":               C.__NR_setuid32,
+	"setgid32":               C.__NR_setgid32,
+	"setfsuid32":             C.__NR_setfsuid32,
+	"setfsgid32":             C.__NR_setfsgid32,
+	"pivot_root":             C.__NR_pivot_root,
+	"mincore":                C.__NR_mincore,
+	"madvise":                C.__NR_madvise,
+	"getdents64":             C.__NR_getdents64,
+	"fcntl64":                C.__NR_fcntl64,
+	"gettid":                 C.__NR_gettid,
+	"readahead":              C.__NR_readahead,
+	"setxattr":               C.__NR_setxattr,
+	"lsetxattr":              C.__NR_lsetxattr,
+	"fsetxattr":              C.__NR_fsetxattr,
+	"getxattr":               C.__NR_getxattr,
+	"lgetxattr":              C.__NR_lgetxattr,
+	"fgetxattr":              C.__NR_fgetxattr,
+	"listxattr":              C.__NR_listxattr,
+	"llistxattr":             C.__NR_llistxattr,
+	"flistxattr":             C.__NR_flistxattr,
+	"removexattr":            C.__NR_removexattr,
+	"lremovexattr":           C.__NR_lremovexattr,
+	"fremovexattr":           C.__NR_fremovexattr,
+	"tkill":                  C.__NR_tkill,
+	"sendfile64":             C.__NR_sendfile64,
+	"futex":                  C.__NR_futex,
+	"sched_setaffinity":      C.__NR_sched_setaffinity,
+	"sched_getaffinity":      C.__NR_sched_getaffinity,
+	"set_thread_area":        C.__NR_set_thread_area,
+	"get_thread_area":        C.__NR_get_thread_area,
+	"io_setup":               C.__NR_io_setup,
+	"io_destroy":             C.__NR_io_destroy,
+	"io_getevents":           C.__NR_io_getevents,
+	"io_submit":              C.__NR_io_submit,
+	"io_cancel":              C.__NR_io_cancel,
+	"fadvise64":              C.__NR_fadvise64,
+	"exit_group":             C.__NR_exit_group,
+	"lookup_dcookie":         C.__NR_lookup_dcookie,
+	"epoll_create":           C.__NR_epoll_create,
+	"epoll_ctl":              C.__NR_epoll_ctl,
+	"epoll_wait":             C.__NR_epoll_wait,
+	"remap_file_pages":       C.__NR_remap_file_pages,
+	"set_tid_address":        C.__NR_set_tid_address,
+	"timer_create":           C.__NR_timer_create,
+	"timer_settime":          C.__NR_timer_settime,
+	"timer_gettime":          C.__NR_timer_gettime,
+	"timer_getoverrun":       C.__NR_timer_getoverrun,
+	"timer_delete":           C.__NR_timer_delete,
+	"clock_settime":          C.__NR_clock_settime,
+	"clock_gettime":          C.__NR_clock_gettime,
+	"clock_getres":           C.__NR_clock_getres,
+	"clock_nanosleep":        C.__NR_clock_nanosleep,
+	"statfs64":               C.__NR_statfs64,
+	"fstatfs64":              C.__NR_fstatfs64,
+	"tgkill":                 C.__NR_tgkill,
+	"utimes":                 C.__NR_utimes,
+	"fadvise64_64":           C.__NR_fadvise64_64,
+	"vserver":                C.__NR_vserver,
+	"mbind":                  C.__NR_mbind,
+	"get_mempolicy":          C.__NR_get_mempolicy,
+	"set_mempolicy":          C.__NR_set_mempolicy,
+	"mq_open":                C.__NR_mq_open,
+	"mq_unlink":              C.__NR_mq_unlink,
+	"mq_timedsend":           C.__NR_mq_timedsend,
+	"mq_timedreceive":        C.__NR_mq_timedreceive,
+	"mq_notify":              C.__NR_mq_notify,
+	"mq_getsetattr":          C.__NR_mq_getsetattr,
+	"kexec_load":             C.__NR_kexec_load,
+	"waitid":                 C.__NR_waitid,
+	"add_key":                C.__NR_add_key,
+	"request_key":            C.__NR_request_key,
+	"keyctl":                 C.__NR_keyctl,
+	"ioprio_set":             C.__NR_ioprio_set,
+	"ioprio_get":             C.__NR_ioprio_get,
+	"inotify_init":           C.__NR_inotify_init,
+	"inotify_add_watch":      C.__NR_inotify_add_watch,
+	"inotify_rm_watch":       C.__NR_inotify_rm_watch,
+	"migrate_pages":          C.__NR_migrate_pages,
+	"openat":                 C.__NR_openat,
+	"mkdirat":                C.__NR_mkdirat,
+	"mknodat":                C.__NR_mknodat,
+	"fchownat":               C.__NR_fchownat,
+	"futimesat":              C.__NR_futimesat,
+	"fstatat64":              C.__NR_fstatat64,
+	"unlinkat":               C.__NR_unlinkat,
+	"renameat":               C.__NR_renameat,
+	"linkat":                 C.__NR_linkat,
+	"symlinkat":              C.__NR_symlinkat,
+	"readlinkat":             C.__NR_readlinkat,
+	"fchmodat":               C.__NR_fchmodat,
+	"faccessat":              C.__NR_faccessat,
+	"pselect6":               C.__NR_pselect6,
+	"ppoll":                  C.__NR_ppoll,
+	"unshare":                C.__NR_unshare,
+	"set_robust_list":        C.__NR_set_robust_list,
+	"get_robust_list":        C.__NR_get_robust_list,
+	"splice":                 C.__NR_splice,
+	"sync_file_range":        C.__NR_sync_file_range,
+	"tee":                    C.__NR_tee,
+	"vmsplice":               C.__NR_vmsplice,
+	"move_pages":             C.__NR_move_pages,
+	"getcpu":                 C.__NR_getcpu,
+	"epoll_pwait":            C.__NR_epoll_pwait,
+	"utimensat":              C.__NR_utimensat,
+	"signalfd":               C.__NR_signalfd,
+	"timerfd_create":         C.__NR_timerfd_create,
+	"eventfd":                C.__NR_eventfd,
+	"fallocate":              C.__NR_fallocate,
+	"timerfd_settime":        C.__NR_timerfd_settime,
+	"timerfd_gettime":        C.__NR_timerfd_gettime,
+	"signalfd4":              C.__NR_signalfd4,
+	"eventfd2":               C.__NR_eventfd2,
+	"epoll_create1":          C.__NR_epoll_create1,
+	"dup3":                   C.__NR_dup3,
+	"pipe2":                  C.__NR_pipe2,
+	"inotify_init1":          C.__NR_inotify_init1,
+	"preadv":                 C.__NR_preadv,
+	"pwritev":                C.__NR_pwritev,
+	"rt_tgsigqueueinfo":      C.__NR_rt_tgsigqueueinfo,
+	"perf_event_open":        C.__NR_perf_event_open,
+	"recvmmsg":               C.__NR_recvmmsg,
+	"fanotify_init":          C.__NR_fanotify_init,
+	"fanotify_mark":          C.__NR_fanotify_mark,
+	"prlimit64":              C.__NR_prlimit64,
+	"name_to_handle_at":      C.__NR_name_to_handle_at,
+	"open_by_handle_at":      C.__NR_open_by_handle_at,
+	"clock_adjtime":          C.__NR_clock_adjtime,
+	"syncfs":                 C.__NR_syncfs,
+	"sendmmsg":               C.__NR_sendmmsg,
+	"setns":                  C.__NR_setns,
+	"process_vm_readv":       C.__NR_process_vm_readv,
+	"process_vm_writev":      C.__NR_process_vm_writev,
+	"kcmp":                   C.__NR_kcmp,
+	"finit_module":           C.__NR_finit_module,
+	"sched_setattr":          C.__NR_sched_setattr,
+	"sched_getattr":          C.__NR_sched_getattr,
+	"renameat2":              C.__NR_renameat2,
+	"seccomp":                C.__NR_seccomp,
+	"getrandom":              C.__NR_getrandom,
+	"memfd_create":           C.__NR_memfd_create,
+	"bpf":                    C.__NR_bpf,
+	"execveat":               C.__NR_execveat,
+}
diff --git a/src/chromiumos/seccomp/syscalls_amd64.go b/src/chromiumos/seccomp/syscalls_amd64.go
new file mode 100644
index 0000000..749cfeb
--- /dev/null
+++ b/src/chromiumos/seccomp/syscalls_amd64.go
@@ -0,0 +1,333 @@
+// DO NOT EDIT. Autogenerated by syscalls_gen.go
+
+package seccomp
+
+// #include <asm/unistd.h>
+import "C"
+
+// syscallNum maps system call names to numbers.
+var syscallNum = map[string]int{
+	"read":                   C.__NR_read,
+	"write":                  C.__NR_write,
+	"open":                   C.__NR_open,
+	"close":                  C.__NR_close,
+	"stat":                   C.__NR_stat,
+	"fstat":                  C.__NR_fstat,
+	"lstat":                  C.__NR_lstat,
+	"poll":                   C.__NR_poll,
+	"lseek":                  C.__NR_lseek,
+	"mmap":                   C.__NR_mmap,
+	"mprotect":               C.__NR_mprotect,
+	"munmap":                 C.__NR_munmap,
+	"brk":                    C.__NR_brk,
+	"rt_sigaction":           C.__NR_rt_sigaction,
+	"rt_sigprocmask":         C.__NR_rt_sigprocmask,
+	"rt_sigreturn":           C.__NR_rt_sigreturn,
+	"ioctl":                  C.__NR_ioctl,
+	"pread64":                C.__NR_pread64,
+	"pwrite64":               C.__NR_pwrite64,
+	"readv":                  C.__NR_readv,
+	"writev":                 C.__NR_writev,
+	"access":                 C.__NR_access,
+	"pipe":                   C.__NR_pipe,
+	"select":                 C.__NR_select,
+	"sched_yield":            C.__NR_sched_yield,
+	"mremap":                 C.__NR_mremap,
+	"msync":                  C.__NR_msync,
+	"mincore":                C.__NR_mincore,
+	"madvise":                C.__NR_madvise,
+	"shmget":                 C.__NR_shmget,
+	"shmat":                  C.__NR_shmat,
+	"shmctl":                 C.__NR_shmctl,
+	"dup":                    C.__NR_dup,
+	"dup2":                   C.__NR_dup2,
+	"pause":                  C.__NR_pause,
+	"nanosleep":              C.__NR_nanosleep,
+	"getitimer":              C.__NR_getitimer,
+	"alarm":                  C.__NR_alarm,
+	"setitimer":              C.__NR_setitimer,
+	"getpid":                 C.__NR_getpid,
+	"sendfile":               C.__NR_sendfile,
+	"socket":                 C.__NR_socket,
+	"connect":                C.__NR_connect,
+	"accept":                 C.__NR_accept,
+	"sendto":                 C.__NR_sendto,
+	"recvfrom":               C.__NR_recvfrom,
+	"sendmsg":                C.__NR_sendmsg,
+	"recvmsg":                C.__NR_recvmsg,
+	"shutdown":               C.__NR_shutdown,
+	"bind":                   C.__NR_bind,
+	"listen":                 C.__NR_listen,
+	"getsockname":            C.__NR_getsockname,
+	"getpeername":            C.__NR_getpeername,
+	"socketpair":             C.__NR_socketpair,
+	"setsockopt":             C.__NR_setsockopt,
+	"getsockopt":             C.__NR_getsockopt,
+	"clone":                  C.__NR_clone,
+	"fork":                   C.__NR_fork,
+	"vfork":                  C.__NR_vfork,
+	"execve":                 C.__NR_execve,
+	"exit":                   C.__NR_exit,
+	"wait4":                  C.__NR_wait4,
+	"kill":                   C.__NR_kill,
+	"uname":                  C.__NR_uname,
+	"semget":                 C.__NR_semget,
+	"semop":                  C.__NR_semop,
+	"semctl":                 C.__NR_semctl,
+	"shmdt":                  C.__NR_shmdt,
+	"msgget":                 C.__NR_msgget,
+	"msgsnd":                 C.__NR_msgsnd,
+	"msgrcv":                 C.__NR_msgrcv,
+	"msgctl":                 C.__NR_msgctl,
+	"fcntl":                  C.__NR_fcntl,
+	"flock":                  C.__NR_flock,
+	"fsync":                  C.__NR_fsync,
+	"fdatasync":              C.__NR_fdatasync,
+	"truncate":               C.__NR_truncate,
+	"ftruncate":              C.__NR_ftruncate,
+	"getdents":               C.__NR_getdents,
+	"getcwd":                 C.__NR_getcwd,
+	"chdir":                  C.__NR_chdir,
+	"fchdir":                 C.__NR_fchdir,
+	"rename":                 C.__NR_rename,
+	"mkdir":                  C.__NR_mkdir,
+	"rmdir":                  C.__NR_rmdir,
+	"creat":                  C.__NR_creat,
+	"link":                   C.__NR_link,
+	"unlink":                 C.__NR_unlink,
+	"symlink":                C.__NR_symlink,
+	"readlink":               C.__NR_readlink,
+	"chmod":                  C.__NR_chmod,
+	"fchmod":                 C.__NR_fchmod,
+	"chown":                  C.__NR_chown,
+	"fchown":                 C.__NR_fchown,
+	"lchown":                 C.__NR_lchown,
+	"umask":                  C.__NR_umask,
+	"gettimeofday":           C.__NR_gettimeofday,
+	"getrlimit":              C.__NR_getrlimit,
+	"getrusage":              C.__NR_getrusage,
+	"sysinfo":                C.__NR_sysinfo,
+	"times":                  C.__NR_times,
+	"ptrace":                 C.__NR_ptrace,
+	"getuid":                 C.__NR_getuid,
+	"syslog":                 C.__NR_syslog,
+	"getgid":                 C.__NR_getgid,
+	"setuid":                 C.__NR_setuid,
+	"setgid":                 C.__NR_setgid,
+	"geteuid":                C.__NR_geteuid,
+	"getegid":                C.__NR_getegid,
+	"setpgid":                C.__NR_setpgid,
+	"getppid":                C.__NR_getppid,
+	"getpgrp":                C.__NR_getpgrp,
+	"setsid":                 C.__NR_setsid,
+	"setreuid":               C.__NR_setreuid,
+	"setregid":               C.__NR_setregid,
+	"getgroups":              C.__NR_getgroups,
+	"setgroups":              C.__NR_setgroups,
+	"setresuid":              C.__NR_setresuid,
+	"getresuid":              C.__NR_getresuid,
+	"setresgid":              C.__NR_setresgid,
+	"getresgid":              C.__NR_getresgid,
+	"getpgid":                C.__NR_getpgid,
+	"setfsuid":               C.__NR_setfsuid,
+	"setfsgid":               C.__NR_setfsgid,
+	"getsid":                 C.__NR_getsid,
+	"capget":                 C.__NR_capget,
+	"capset":                 C.__NR_capset,
+	"rt_sigpending":          C.__NR_rt_sigpending,
+	"rt_sigtimedwait":        C.__NR_rt_sigtimedwait,
+	"rt_sigqueueinfo":        C.__NR_rt_sigqueueinfo,
+	"rt_sigsuspend":          C.__NR_rt_sigsuspend,
+	"sigaltstack":            C.__NR_sigaltstack,
+	"utime":                  C.__NR_utime,
+	"mknod":                  C.__NR_mknod,
+	"uselib":                 C.__NR_uselib,
+	"personality":            C.__NR_personality,
+	"ustat":                  C.__NR_ustat,
+	"statfs":                 C.__NR_statfs,
+	"fstatfs":                C.__NR_fstatfs,
+	"sysfs":                  C.__NR_sysfs,
+	"getpriority":            C.__NR_getpriority,
+	"setpriority":            C.__NR_setpriority,
+	"sched_setparam":         C.__NR_sched_setparam,
+	"sched_getparam":         C.__NR_sched_getparam,
+	"sched_setscheduler":     C.__NR_sched_setscheduler,
+	"sched_getscheduler":     C.__NR_sched_getscheduler,
+	"sched_get_priority_max": C.__NR_sched_get_priority_max,
+	"sched_get_priority_min": C.__NR_sched_get_priority_min,
+	"sched_rr_get_interval":  C.__NR_sched_rr_get_interval,
+	"mlock":                  C.__NR_mlock,
+	"munlock":                C.__NR_munlock,
+	"mlockall":               C.__NR_mlockall,
+	"munlockall":             C.__NR_munlockall,
+	"vhangup":                C.__NR_vhangup,
+	"modify_ldt":             C.__NR_modify_ldt,
+	"pivot_root":             C.__NR_pivot_root,
+	"_sysctl":                C.__NR__sysctl,
+	"prctl":                  C.__NR_prctl,
+	"arch_prctl":             C.__NR_arch_prctl,
+	"adjtimex":               C.__NR_adjtimex,
+	"setrlimit":              C.__NR_setrlimit,
+	"chroot":                 C.__NR_chroot,
+	"sync":                   C.__NR_sync,
+	"acct":                   C.__NR_acct,
+	"settimeofday":           C.__NR_settimeofday,
+	"mount":                  C.__NR_mount,
+	"umount2":                C.__NR_umount2,
+	"swapon":                 C.__NR_swapon,
+	"swapoff":                C.__NR_swapoff,
+	"reboot":                 C.__NR_reboot,
+	"sethostname":            C.__NR_sethostname,
+	"setdomainname":          C.__NR_setdomainname,
+	"iopl":                   C.__NR_iopl,
+	"ioperm":                 C.__NR_ioperm,
+	"create_module":          C.__NR_create_module,
+	"init_module":            C.__NR_init_module,
+	"delete_module":          C.__NR_delete_module,
+	"get_kernel_syms":        C.__NR_get_kernel_syms,
+	"query_module":           C.__NR_query_module,
+	"quotactl":               C.__NR_quotactl,
+	"nfsservctl":             C.__NR_nfsservctl,
+	"getpmsg":                C.__NR_getpmsg,
+	"putpmsg":                C.__NR_putpmsg,
+	"afs_syscall":            C.__NR_afs_syscall,
+	"tuxcall":                C.__NR_tuxcall,
+	"security":               C.__NR_security,
+	"gettid":                 C.__NR_gettid,
+	"readahead":              C.__NR_readahead,
+	"setxattr":               C.__NR_setxattr,
+	"lsetxattr":              C.__NR_lsetxattr,
+	"fsetxattr":              C.__NR_fsetxattr,
+	"getxattr":               C.__NR_getxattr,
+	"lgetxattr":              C.__NR_lgetxattr,
+	"fgetxattr":              C.__NR_fgetxattr,
+	"listxattr":              C.__NR_listxattr,
+	"llistxattr":             C.__NR_llistxattr,
+	"flistxattr":             C.__NR_flistxattr,
+	"removexattr":            C.__NR_removexattr,
+	"lremovexattr":           C.__NR_lremovexattr,
+	"fremovexattr":           C.__NR_fremovexattr,
+	"tkill":                  C.__NR_tkill,
+	"time":                   C.__NR_time,
+	"futex":                  C.__NR_futex,
+	"sched_setaffinity":      C.__NR_sched_setaffinity,
+	"sched_getaffinity":      C.__NR_sched_getaffinity,
+	"set_thread_area":        C.__NR_set_thread_area,
+	"io_setup":               C.__NR_io_setup,
+	"io_destroy":             C.__NR_io_destroy,
+	"io_getevents":           C.__NR_io_getevents,
+	"io_submit":              C.__NR_io_submit,
+	"io_cancel":              C.__NR_io_cancel,
+	"get_thread_area":        C.__NR_get_thread_area,
+	"lookup_dcookie":         C.__NR_lookup_dcookie,
+	"epoll_create":           C.__NR_epoll_create,
+	"epoll_ctl_old":          C.__NR_epoll_ctl_old,
+	"epoll_wait_old":         C.__NR_epoll_wait_old,
+	"remap_file_pages":       C.__NR_remap_file_pages,
+	"getdents64":             C.__NR_getdents64,
+	"set_tid_address":        C.__NR_set_tid_address,
+	"restart_syscall":        C.__NR_restart_syscall,
+	"semtimedop":             C.__NR_semtimedop,
+	"fadvise64":              C.__NR_fadvise64,
+	"timer_create":           C.__NR_timer_create,
+	"timer_settime":          C.__NR_timer_settime,
+	"timer_gettime":          C.__NR_timer_gettime,
+	"timer_getoverrun":       C.__NR_timer_getoverrun,
+	"timer_delete":           C.__NR_timer_delete,
+	"clock_settime":          C.__NR_clock_settime,
+	"clock_gettime":          C.__NR_clock_gettime,
+	"clock_getres":           C.__NR_clock_getres,
+	"clock_nanosleep":        C.__NR_clock_nanosleep,
+	"exit_group":             C.__NR_exit_group,
+	"epoll_wait":             C.__NR_epoll_wait,
+	"epoll_ctl":              C.__NR_epoll_ctl,
+	"tgkill":                 C.__NR_tgkill,
+	"utimes":                 C.__NR_utimes,
+	"vserver":                C.__NR_vserver,
+	"mbind":                  C.__NR_mbind,
+	"set_mempolicy":          C.__NR_set_mempolicy,
+	"get_mempolicy":          C.__NR_get_mempolicy,
+	"mq_open":                C.__NR_mq_open,
+	"mq_unlink":              C.__NR_mq_unlink,
+	"mq_timedsend":           C.__NR_mq_timedsend,
+	"mq_timedreceive":        C.__NR_mq_timedreceive,
+	"mq_notify":              C.__NR_mq_notify,
+	"mq_getsetattr":          C.__NR_mq_getsetattr,
+	"kexec_load":             C.__NR_kexec_load,
+	"waitid":                 C.__NR_waitid,
+	"add_key":                C.__NR_add_key,
+	"request_key":            C.__NR_request_key,
+	"keyctl":                 C.__NR_keyctl,
+	"ioprio_set":             C.__NR_ioprio_set,
+	"ioprio_get":             C.__NR_ioprio_get,
+	"inotify_init":           C.__NR_inotify_init,
+	"inotify_add_watch":      C.__NR_inotify_add_watch,
+	"inotify_rm_watch":       C.__NR_inotify_rm_watch,
+	"migrate_pages":          C.__NR_migrate_pages,
+	"openat":                 C.__NR_openat,
+	"mkdirat":                C.__NR_mkdirat,
+	"mknodat":                C.__NR_mknodat,
+	"fchownat":               C.__NR_fchownat,
+	"futimesat":              C.__NR_futimesat,
+	"newfstatat":             C.__NR_newfstatat,
+	"unlinkat":               C.__NR_unlinkat,
+	"renameat":               C.__NR_renameat,
+	"linkat":                 C.__NR_linkat,
+	"symlinkat":              C.__NR_symlinkat,
+	"readlinkat":             C.__NR_readlinkat,
+	"fchmodat":               C.__NR_fchmodat,
+	"faccessat":              C.__NR_faccessat,
+	"pselect6":               C.__NR_pselect6,
+	"ppoll":                  C.__NR_ppoll,
+	"unshare":                C.__NR_unshare,
+	"set_robust_list":        C.__NR_set_robust_list,
+	"get_robust_list":        C.__NR_get_robust_list,
+	"splice":                 C.__NR_splice,
+	"tee":                    C.__NR_tee,
+	"sync_file_range":        C.__NR_sync_file_range,
+	"vmsplice":               C.__NR_vmsplice,
+	"move_pages":             C.__NR_move_pages,
+	"utimensat":              C.__NR_utimensat,
+	"epoll_pwait":            C.__NR_epoll_pwait,
+	"signalfd":               C.__NR_signalfd,
+	"timerfd_create":         C.__NR_timerfd_create,
+	"eventfd":                C.__NR_eventfd,
+	"fallocate":              C.__NR_fallocate,
+	"timerfd_settime":        C.__NR_timerfd_settime,
+	"timerfd_gettime":        C.__NR_timerfd_gettime,
+	"accept4":                C.__NR_accept4,
+	"signalfd4":              C.__NR_signalfd4,
+	"eventfd2":               C.__NR_eventfd2,
+	"epoll_create1":          C.__NR_epoll_create1,
+	"dup3":                   C.__NR_dup3,
+	"pipe2":                  C.__NR_pipe2,
+	"inotify_init1":          C.__NR_inotify_init1,
+	"preadv":                 C.__NR_preadv,
+	"pwritev":                C.__NR_pwritev,
+	"rt_tgsigqueueinfo":      C.__NR_rt_tgsigqueueinfo,
+	"perf_event_open":        C.__NR_perf_event_open,
+	"recvmmsg":               C.__NR_recvmmsg,
+	"fanotify_init":          C.__NR_fanotify_init,
+	"fanotify_mark":          C.__NR_fanotify_mark,
+	"prlimit64":              C.__NR_prlimit64,
+	"name_to_handle_at":      C.__NR_name_to_handle_at,
+	"open_by_handle_at":      C.__NR_open_by_handle_at,
+	"clock_adjtime":          C.__NR_clock_adjtime,
+	"syncfs":                 C.__NR_syncfs,
+	"sendmmsg":               C.__NR_sendmmsg,
+	"setns":                  C.__NR_setns,
+	"getcpu":                 C.__NR_getcpu,
+	"process_vm_readv":       C.__NR_process_vm_readv,
+	"process_vm_writev":      C.__NR_process_vm_writev,
+	"kcmp":                   C.__NR_kcmp,
+	"finit_module":           C.__NR_finit_module,
+	"sched_setattr":          C.__NR_sched_setattr,
+	"sched_getattr":          C.__NR_sched_getattr,
+	"renameat2":              C.__NR_renameat2,
+	"seccomp":                C.__NR_seccomp,
+	"getrandom":              C.__NR_getrandom,
+	"memfd_create":           C.__NR_memfd_create,
+	"kexec_file_load":        C.__NR_kexec_file_load,
+	"bpf":                    C.__NR_bpf,
+	"execveat":               C.__NR_execveat,
+}
diff --git a/src/chromiumos/seccomp/syscalls_arm.go b/src/chromiumos/seccomp/syscalls_arm.go
new file mode 100644
index 0000000..829a0ac
--- /dev/null
+++ b/src/chromiumos/seccomp/syscalls_arm.go
@@ -0,0 +1,359 @@
+// DO NOT EDIT. Autogenerated by syscalls_gen.go
+
+package seccomp
+
+// #include <asm/unistd.h>
+import "C"
+
+// syscallNum maps system call names to numbers.
+var syscallNum = map[string]int{
+	"restart_syscall":        C.__NR_restart_syscall,
+	"exit":                   C.__NR_exit,
+	"fork":                   C.__NR_fork,
+	"read":                   C.__NR_read,
+	"write":                  C.__NR_write,
+	"open":                   C.__NR_open,
+	"close":                  C.__NR_close,
+	"creat":                  C.__NR_creat,
+	"link":                   C.__NR_link,
+	"unlink":                 C.__NR_unlink,
+	"execve":                 C.__NR_execve,
+	"chdir":                  C.__NR_chdir,
+	"mknod":                  C.__NR_mknod,
+	"chmod":                  C.__NR_chmod,
+	"lchown":                 C.__NR_lchown,
+	"lseek":                  C.__NR_lseek,
+	"getpid":                 C.__NR_getpid,
+	"mount":                  C.__NR_mount,
+	"setuid":                 C.__NR_setuid,
+	"getuid":                 C.__NR_getuid,
+	"ptrace":                 C.__NR_ptrace,
+	"pause":                  C.__NR_pause,
+	"access":                 C.__NR_access,
+	"nice":                   C.__NR_nice,
+	"sync":                   C.__NR_sync,
+	"kill":                   C.__NR_kill,
+	"rename":                 C.__NR_rename,
+	"mkdir":                  C.__NR_mkdir,
+	"rmdir":                  C.__NR_rmdir,
+	"dup":                    C.__NR_dup,
+	"pipe":                   C.__NR_pipe,
+	"times":                  C.__NR_times,
+	"brk":                    C.__NR_brk,
+	"setgid":                 C.__NR_setgid,
+	"getgid":                 C.__NR_getgid,
+	"geteuid":                C.__NR_geteuid,
+	"getegid":                C.__NR_getegid,
+	"acct":                   C.__NR_acct,
+	"umount2":                C.__NR_umount2,
+	"ioctl":                  C.__NR_ioctl,
+	"fcntl":                  C.__NR_fcntl,
+	"setpgid":                C.__NR_setpgid,
+	"umask":                  C.__NR_umask,
+	"chroot":                 C.__NR_chroot,
+	"ustat":                  C.__NR_ustat,
+	"dup2":                   C.__NR_dup2,
+	"getppid":                C.__NR_getppid,
+	"getpgrp":                C.__NR_getpgrp,
+	"setsid":                 C.__NR_setsid,
+	"sigaction":              C.__NR_sigaction,
+	"setreuid":               C.__NR_setreuid,
+	"setregid":               C.__NR_setregid,
+	"sigsuspend":             C.__NR_sigsuspend,
+	"sigpending":             C.__NR_sigpending,
+	"sethostname":            C.__NR_sethostname,
+	"setrlimit":              C.__NR_setrlimit,
+	"getrusage":              C.__NR_getrusage,
+	"gettimeofday":           C.__NR_gettimeofday,
+	"settimeofday":           C.__NR_settimeofday,
+	"getgroups":              C.__NR_getgroups,
+	"setgroups":              C.__NR_setgroups,
+	"symlink":                C.__NR_symlink,
+	"readlink":               C.__NR_readlink,
+	"uselib":                 C.__NR_uselib,
+	"swapon":                 C.__NR_swapon,
+	"reboot":                 C.__NR_reboot,
+	"munmap":                 C.__NR_munmap,
+	"truncate":               C.__NR_truncate,
+	"ftruncate":              C.__NR_ftruncate,
+	"fchmod":                 C.__NR_fchmod,
+	"fchown":                 C.__NR_fchown,
+	"getpriority":            C.__NR_getpriority,
+	"setpriority":            C.__NR_setpriority,
+	"statfs":                 C.__NR_statfs,
+	"fstatfs":                C.__NR_fstatfs,
+	"syslog":                 C.__NR_syslog,
+	"setitimer":              C.__NR_setitimer,
+	"getitimer":              C.__NR_getitimer,
+	"stat":                   C.__NR_stat,
+	"lstat":                  C.__NR_lstat,
+	"fstat":                  C.__NR_fstat,
+	"vhangup":                C.__NR_vhangup,
+	"wait4":                  C.__NR_wait4,
+	"swapoff":                C.__NR_swapoff,
+	"sysinfo":                C.__NR_sysinfo,
+	"fsync":                  C.__NR_fsync,
+	"sigreturn":              C.__NR_sigreturn,
+	"clone":                  C.__NR_clone,
+	"setdomainname":          C.__NR_setdomainname,
+	"uname":                  C.__NR_uname,
+	"adjtimex":               C.__NR_adjtimex,
+	"mprotect":               C.__NR_mprotect,
+	"sigprocmask":            C.__NR_sigprocmask,
+	"init_module":            C.__NR_init_module,
+	"delete_module":          C.__NR_delete_module,
+	"quotactl":               C.__NR_quotactl,
+	"getpgid":                C.__NR_getpgid,
+	"fchdir":                 C.__NR_fchdir,
+	"bdflush":                C.__NR_bdflush,
+	"sysfs":                  C.__NR_sysfs,
+	"personality":            C.__NR_personality,
+	"setfsuid":               C.__NR_setfsuid,
+	"setfsgid":               C.__NR_setfsgid,
+	"_llseek":                C.__NR__llseek,
+	"getdents":               C.__NR_getdents,
+	"_newselect":             C.__NR__newselect,
+	"flock":                  C.__NR_flock,
+	"msync":                  C.__NR_msync,
+	"readv":                  C.__NR_readv,
+	"writev":                 C.__NR_writev,
+	"getsid":                 C.__NR_getsid,
+	"fdatasync":              C.__NR_fdatasync,
+	"_sysctl":                C.__NR__sysctl,
+	"mlock":                  C.__NR_mlock,
+	"munlock":                C.__NR_munlock,
+	"mlockall":               C.__NR_mlockall,
+	"munlockall":             C.__NR_munlockall,
+	"sched_setparam":         C.__NR_sched_setparam,
+	"sched_getparam":         C.__NR_sched_getparam,
+	"sched_setscheduler":     C.__NR_sched_setscheduler,
+	"sched_getscheduler":     C.__NR_sched_getscheduler,
+	"sched_yield":            C.__NR_sched_yield,
+	"sched_get_priority_max": C.__NR_sched_get_priority_max,
+	"sched_get_priority_min": C.__NR_sched_get_priority_min,
+	"sched_rr_get_interval":  C.__NR_sched_rr_get_interval,
+	"nanosleep":              C.__NR_nanosleep,
+	"mremap":                 C.__NR_mremap,
+	"setresuid":              C.__NR_setresuid,
+	"getresuid":              C.__NR_getresuid,
+	"poll":                   C.__NR_poll,
+	"nfsservctl":             C.__NR_nfsservctl,
+	"setresgid":              C.__NR_setresgid,
+	"getresgid":              C.__NR_getresgid,
+	"prctl":                  C.__NR_prctl,
+	"rt_sigreturn":           C.__NR_rt_sigreturn,
+	"rt_sigaction":           C.__NR_rt_sigaction,
+	"rt_sigprocmask":         C.__NR_rt_sigprocmask,
+	"rt_sigpending":          C.__NR_rt_sigpending,
+	"rt_sigtimedwait":        C.__NR_rt_sigtimedwait,
+	"rt_sigqueueinfo":        C.__NR_rt_sigqueueinfo,
+	"rt_sigsuspend":          C.__NR_rt_sigsuspend,
+	"pread64":                C.__NR_pread64,
+	"pwrite64":               C.__NR_pwrite64,
+	"chown":                  C.__NR_chown,
+	"getcwd":                 C.__NR_getcwd,
+	"capget":                 C.__NR_capget,
+	"capset":                 C.__NR_capset,
+	"sigaltstack":            C.__NR_sigaltstack,
+	"sendfile":               C.__NR_sendfile,
+	"vfork":                  C.__NR_vfork,
+	"ugetrlimit":             C.__NR_ugetrlimit,
+	"mmap2":                  C.__NR_mmap2,
+	"truncate64":             C.__NR_truncate64,
+	"ftruncate64":            C.__NR_ftruncate64,
+	"stat64":                 C.__NR_stat64,
+	"lstat64":                C.__NR_lstat64,
+	"fstat64":                C.__NR_fstat64,
+	"lchown32":               C.__NR_lchown32,
+	"getuid32":               C.__NR_getuid32,
+	"getgid32":               C.__NR_getgid32,
+	"geteuid32":              C.__NR_geteuid32,
+	"getegid32":              C.__NR_getegid32,
+	"setreuid32":             C.__NR_setreuid32,
+	"setregid32":             C.__NR_setregid32,
+	"getgroups32":            C.__NR_getgroups32,
+	"setgroups32":            C.__NR_setgroups32,
+	"fchown32":               C.__NR_fchown32,
+	"setresuid32":            C.__NR_setresuid32,
+	"getresuid32":            C.__NR_getresuid32,
+	"setresgid32":            C.__NR_setresgid32,
+	"getresgid32":            C.__NR_getresgid32,
+	"chown32":                C.__NR_chown32,
+	"setuid32":               C.__NR_setuid32,
+	"setgid32":               C.__NR_setgid32,
+	"setfsuid32":             C.__NR_setfsuid32,
+	"setfsgid32":             C.__NR_setfsgid32,
+	"getdents64":             C.__NR_getdents64,
+	"pivot_root":             C.__NR_pivot_root,
+	"mincore":                C.__NR_mincore,
+	"madvise":                C.__NR_madvise,
+	"fcntl64":                C.__NR_fcntl64,
+	"gettid":                 C.__NR_gettid,
+	"readahead":              C.__NR_readahead,
+	"setxattr":               C.__NR_setxattr,
+	"lsetxattr":              C.__NR_lsetxattr,
+	"fsetxattr":              C.__NR_fsetxattr,
+	"getxattr":               C.__NR_getxattr,
+	"lgetxattr":              C.__NR_lgetxattr,
+	"fgetxattr":              C.__NR_fgetxattr,
+	"listxattr":              C.__NR_listxattr,
+	"llistxattr":             C.__NR_llistxattr,
+	"flistxattr":             C.__NR_flistxattr,
+	"removexattr":            C.__NR_removexattr,
+	"lremovexattr":           C.__NR_lremovexattr,
+	"fremovexattr":           C.__NR_fremovexattr,
+	"tkill":                  C.__NR_tkill,
+	"sendfile64":             C.__NR_sendfile64,
+	"futex":                  C.__NR_futex,
+	"sched_setaffinity":      C.__NR_sched_setaffinity,
+	"sched_getaffinity":      C.__NR_sched_getaffinity,
+	"io_setup":               C.__NR_io_setup,
+	"io_destroy":             C.__NR_io_destroy,
+	"io_getevents":           C.__NR_io_getevents,
+	"io_submit":              C.__NR_io_submit,
+	"io_cancel":              C.__NR_io_cancel,
+	"exit_group":             C.__NR_exit_group,
+	"lookup_dcookie":         C.__NR_lookup_dcookie,
+	"epoll_create":           C.__NR_epoll_create,
+	"epoll_ctl":              C.__NR_epoll_ctl,
+	"epoll_wait":             C.__NR_epoll_wait,
+	"remap_file_pages":       C.__NR_remap_file_pages,
+	"set_tid_address":        C.__NR_set_tid_address,
+	"timer_create":           C.__NR_timer_create,
+	"timer_settime":          C.__NR_timer_settime,
+	"timer_gettime":          C.__NR_timer_gettime,
+	"timer_getoverrun":       C.__NR_timer_getoverrun,
+	"timer_delete":           C.__NR_timer_delete,
+	"clock_settime":          C.__NR_clock_settime,
+	"clock_gettime":          C.__NR_clock_gettime,
+	"clock_getres":           C.__NR_clock_getres,
+	"clock_nanosleep":        C.__NR_clock_nanosleep,
+	"statfs64":               C.__NR_statfs64,
+	"fstatfs64":              C.__NR_fstatfs64,
+	"tgkill":                 C.__NR_tgkill,
+	"utimes":                 C.__NR_utimes,
+	"arm_fadvise64_64":       C.__NR_arm_fadvise64_64,
+	"pciconfig_iobase":       C.__NR_pciconfig_iobase,
+	"pciconfig_read":         C.__NR_pciconfig_read,
+	"pciconfig_write":        C.__NR_pciconfig_write,
+	"mq_open":                C.__NR_mq_open,
+	"mq_unlink":              C.__NR_mq_unlink,
+	"mq_timedsend":           C.__NR_mq_timedsend,
+	"mq_timedreceive":        C.__NR_mq_timedreceive,
+	"mq_notify":              C.__NR_mq_notify,
+	"mq_getsetattr":          C.__NR_mq_getsetattr,
+	"waitid":                 C.__NR_waitid,
+	"socket":                 C.__NR_socket,
+	"bind":                   C.__NR_bind,
+	"connect":                C.__NR_connect,
+	"listen":                 C.__NR_listen,
+	"accept":                 C.__NR_accept,
+	"getsockname":            C.__NR_getsockname,
+	"getpeername":            C.__NR_getpeername,
+	"socketpair":             C.__NR_socketpair,
+	"send":                   C.__NR_send,
+	"sendto":                 C.__NR_sendto,
+	"recv":                   C.__NR_recv,
+	"recvfrom":               C.__NR_recvfrom,
+	"shutdown":               C.__NR_shutdown,
+	"setsockopt":             C.__NR_setsockopt,
+	"getsockopt":             C.__NR_getsockopt,
+	"sendmsg":                C.__NR_sendmsg,
+	"recvmsg":                C.__NR_recvmsg,
+	"semop":                  C.__NR_semop,
+	"semget":                 C.__NR_semget,
+	"semctl":                 C.__NR_semctl,
+	"msgsnd":                 C.__NR_msgsnd,
+	"msgrcv":                 C.__NR_msgrcv,
+	"msgget":                 C.__NR_msgget,
+	"msgctl":                 C.__NR_msgctl,
+	"shmat":                  C.__NR_shmat,
+	"shmdt":                  C.__NR_shmdt,
+	"shmget":                 C.__NR_shmget,
+	"shmctl":                 C.__NR_shmctl,
+	"add_key":                C.__NR_add_key,
+	"request_key":            C.__NR_request_key,
+	"keyctl":                 C.__NR_keyctl,
+	"semtimedop":             C.__NR_semtimedop,
+	"vserver":                C.__NR_vserver,
+	"ioprio_set":             C.__NR_ioprio_set,
+	"ioprio_get":             C.__NR_ioprio_get,
+	"inotify_init":           C.__NR_inotify_init,
+	"inotify_add_watch":      C.__NR_inotify_add_watch,
+	"inotify_rm_watch":       C.__NR_inotify_rm_watch,
+	"mbind":                  C.__NR_mbind,
+	"get_mempolicy":          C.__NR_get_mempolicy,
+	"set_mempolicy":          C.__NR_set_mempolicy,
+	"openat":                 C.__NR_openat,
+	"mkdirat":                C.__NR_mkdirat,
+	"mknodat":                C.__NR_mknodat,
+	"fchownat":               C.__NR_fchownat,
+	"futimesat":              C.__NR_futimesat,
+	"fstatat64":              C.__NR_fstatat64,
+	"unlinkat":               C.__NR_unlinkat,
+	"renameat":               C.__NR_renameat,
+	"linkat":                 C.__NR_linkat,
+	"symlinkat":              C.__NR_symlinkat,
+	"readlinkat":             C.__NR_readlinkat,
+	"fchmodat":               C.__NR_fchmodat,
+	"faccessat":              C.__NR_faccessat,
+	"pselect6":               C.__NR_pselect6,
+	"ppoll":                  C.__NR_ppoll,
+	"unshare":                C.__NR_unshare,
+	"set_robust_list":        C.__NR_set_robust_list,
+	"get_robust_list":        C.__NR_get_robust_list,
+	"splice":                 C.__NR_splice,
+	"arm_sync_file_range":    C.__NR_arm_sync_file_range,
+	"sync_file_range2":       C.__NR_sync_file_range2,
+	"tee":                    C.__NR_tee,
+	"vmsplice":               C.__NR_vmsplice,
+	"move_pages":             C.__NR_move_pages,
+	"getcpu":                 C.__NR_getcpu,
+	"epoll_pwait":            C.__NR_epoll_pwait,
+	"kexec_load":             C.__NR_kexec_load,
+	"utimensat":              C.__NR_utimensat,
+	"signalfd":               C.__NR_signalfd,
+	"timerfd_create":         C.__NR_timerfd_create,
+	"eventfd":                C.__NR_eventfd,
+	"fallocate":              C.__NR_fallocate,
+	"timerfd_settime":        C.__NR_timerfd_settime,
+	"timerfd_gettime":        C.__NR_timerfd_gettime,
+	"signalfd4":              C.__NR_signalfd4,
+	"eventfd2":               C.__NR_eventfd2,
+	"epoll_create1":          C.__NR_epoll_create1,
+	"dup3":                   C.__NR_dup3,
+	"pipe2":                  C.__NR_pipe2,
+	"inotify_init1":          C.__NR_inotify_init1,
+	"preadv":                 C.__NR_preadv,
+	"pwritev":                C.__NR_pwritev,
+	"rt_tgsigqueueinfo":      C.__NR_rt_tgsigqueueinfo,
+	"perf_event_open":        C.__NR_perf_event_open,
+	"recvmmsg":               C.__NR_recvmmsg,
+	"accept4":                C.__NR_accept4,
+	"fanotify_init":          C.__NR_fanotify_init,
+	"fanotify_mark":          C.__NR_fanotify_mark,
+	"prlimit64":              C.__NR_prlimit64,
+	"name_to_handle_at":      C.__NR_name_to_handle_at,
+	"open_by_handle_at":      C.__NR_open_by_handle_at,
+	"clock_adjtime":          C.__NR_clock_adjtime,
+	"syncfs":                 C.__NR_syncfs,
+	"sendmmsg":               C.__NR_sendmmsg,
+	"setns":                  C.__NR_setns,
+	"process_vm_readv":       C.__NR_process_vm_readv,
+	"process_vm_writev":      C.__NR_process_vm_writev,
+	"kcmp":                   C.__NR_kcmp,
+	"finit_module":           C.__NR_finit_module,
+	"sched_setattr":          C.__NR_sched_setattr,
+	"sched_getattr":          C.__NR_sched_getattr,
+	"renameat2":              C.__NR_renameat2,
+	"seccomp":                C.__NR_seccomp,
+	"getrandom":              C.__NR_getrandom,
+	"memfd_create":           C.__NR_memfd_create,
+	"bpf":                    C.__NR_bpf,
+	"execveat":               C.__NR_execveat,
+	"ARM_breakpoint":         C.__ARM_NR_breakpoint,
+	"ARM_cacheflush":         C.__ARM_NR_cacheflush,
+	"ARM_usr26":              C.__ARM_NR_usr26,
+	"ARM_usr32":              C.__ARM_NR_usr32,
+	"ARM_set_tls":            C.__ARM_NR_set_tls,
+}
diff --git a/src/chromiumos/seccomp/syscalls_gen.go b/src/chromiumos/seccomp/syscalls_gen.go
new file mode 100644
index 0000000..8dc1cbc
--- /dev/null
+++ b/src/chromiumos/seccomp/syscalls_gen.go
@@ -0,0 +1,61 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// +build ignore
+
+// syscalls_gen processes system headers and generates a mapping from system call names to numbers.
+// Usage:
+//   $ echo "#include <asm/unistd.h>" | x86_64-cros-linux-gnu-gcc     -E -dD - | go run syscalls_gen.go | gofmt > syscalls_amd64.go
+//   $ echo "#include <asm/unistd.h>" | i686-pc-linux-gnu-gcc         -E -dD - | go run syscalls_gen.go | gofmt > syscalls_386.go
+//   $ echo "#include <asm/unistd.h>" | armv7a-cros-linux-gnueabi-gcc -E -dD - | go run syscalls_gen.go | gofmt > syscalls_arm.go
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"log"
+	"os"
+	"regexp"
+)
+
+func main() {
+	type syscall struct {
+		prefix string
+		name   string
+	}
+
+	define := regexp.MustCompile(`^#define __([A-Z]+_)?NR_([a-z0-9_]+)`)
+	undef := regexp.MustCompile(`^#undef __([A-Z]+_)?NR_([a-z0-9_]+)`)
+
+	defined := []syscall{}
+	undefed := map[syscall]bool{}
+
+	scanner := bufio.NewScanner(os.Stdin)
+	for scanner.Scan() {
+		line := scanner.Text()
+		if match := define.FindStringSubmatch(line); match != nil {
+			defined = append(defined, syscall{match[1], match[2]})
+		}
+		if match := undef.FindStringSubmatch(line); match != nil {
+			undefed[syscall{match[1], match[2]}] = true
+		}
+	}
+	if err := scanner.Err(); err != nil {
+		log.Fatalf("Error reading standard input: %v", err)
+	}
+
+	fmt.Println("// DO NOT EDIT. Autogenerated by syscalls_gen.go")
+	fmt.Println()
+	fmt.Println("package seccomp")
+	fmt.Println("// #include <asm/unistd.h>")
+	fmt.Println("import \"C\"")
+	fmt.Println("// syscallNum maps system call names to numbers.")
+	fmt.Println("var syscallNum = map[string]int{")
+	for _, call := range defined {
+		if !undefed[call] {
+			fmt.Printf("%q: C.__%sNR_%s,\n", call.prefix+call.name, call.prefix, call.name)
+		}
+	}
+	fmt.Println("}")
+}