summaryrefslogtreecommitdiffhomepage
path: root/cmd/parse-syscall-annotations
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/parse-syscall-annotations')
-rw-r--r--cmd/parse-syscall-annotations/.gitignore1
-rw-r--r--cmd/parse-syscall-annotations/main.go346
-rw-r--r--cmd/parse-syscall-annotations/syscall.go359
3 files changed, 0 insertions, 706 deletions
diff --git a/cmd/parse-syscall-annotations/.gitignore b/cmd/parse-syscall-annotations/.gitignore
deleted file mode 100644
index ecfe5c996..000000000
--- a/cmd/parse-syscall-annotations/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-parse-syscall-annotations
diff --git a/cmd/parse-syscall-annotations/main.go b/cmd/parse-syscall-annotations/main.go
deleted file mode 100644
index 3f8a85ae5..000000000
--- a/cmd/parse-syscall-annotations/main.go
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This program will take a single golang source file, or a directory containing
-// many source files and produce a JSON output which represent any comments
-// containing compatibility metadata.
-
-// Command parse-syscall-annotations parses syscall annotations from Godoc and
-// generates a JSON file with the parsed syscall info.
-//
-// Annotations take the form:
-// @Syscall(<name>, <arg>:<value>, ...)
-//
-// Supported args and values are:
-// - arg: A syscall option. This entry only applies to the syscall when given this option.
-// - support: Indicates support level
-// - FULL: Full support
-// - PARTIAL: Partial support. Details should be provided in note.
-// - UNIMPLEMENTED: Unimplemented
-// - returns: Indicates a known return value. Implies PARTIAL support. Values are syscall errors.
-// This is treated as a string so you can use something like "returns:EPERM or ENOSYS".
-// - issue: A GitHub issue number.
-// - note: A note
-
-package main
-
-import (
- "encoding/json"
- "flag"
- "fmt"
- "go/ast"
- "go/parser"
- "go/token"
- "log"
- "os"
- "path/filepath"
- "regexp"
- "sort"
- "strings"
- "text/template"
-)
-
-var (
- srcDir = flag.String("dir", "./", "The source directory")
- jsonOut = flag.Bool("json", false, "Output info as json")
-
- r *regexp.Regexp
- r2 *regexp.Regexp
-
- mdTemplate = template.Must(template.New("name").Parse(`+++
-title = "AMD64"
-description = "Syscall Compatibility Reference Documentation for AMD64"
-weight = 10
-+++
-
-This table is a reference of Linux syscalls for the AMD64 architecture and
-their compatibility status in gVisor. gVisor does not support all syscalls and
-some syscalls may have a partial implementation.
-
-Of {{ .Total }} syscalls, {{ .Implemented }} syscalls have a full or partial
-implementation. There are currently {{ .Unimplemented }} unimplemented
-syscalls. {{ .Unknown }} syscalls are not yet documented.
-
-<table>
- <thead>
- <tr>
- <th>#</th>
- <th>Name</th>
- <th>Support</th>
- <th>GitHub Issue</th>
- <th>Notes</th>
- </tr>
- </thead>
- <tbody>{{ range .Syscalls }}{{ if ne .Support "Unknown" }}
- <tr>
- <td><a class="doc-table-anchor" id="{{ .Name }}{{ if index .Metadata "arg" }}({{ index .Metadata "arg" }}){{ end }}"></a>{{ .Number }}</td>
- <td><a href="http://man7.org/linux/man-pages/man2/{{ .Name }}.2.html" target="_blank" rel="noopener">{{ .Name }}{{ if index .Metadata "arg" }}({{ index .Metadata "arg" }}){{ end }}</a></td>
- <td>{{ .Support }}</td>
- <td>{{ if index .Metadata "issue" }}<a href="https://github.com/google/gvisor/issues/{{ index .Metadata "issue" }}">#{{ index .Metadata "issue" }}</a>{{ end }}</td>
- <td>{{ .Note }}</td>
- </tr>{{ end }}{{ end }}
- </tbody>
-</table>
-`))
-)
-
-// Syscall represents a function implementation of a syscall.
-type Syscall struct {
- File string
- Line int
-
- Number int
- Name string
-
- Metadata map[string]string
-}
-
-const (
- UNKNOWN = iota
- UNIMPLEMENTED
- PARTIAL_SUPPORT
- FULL_SUPPORT
-)
-
-func (s *Syscall) SupportLevel() int {
- supportLevel := UNKNOWN
- switch strings.ToUpper(s.Metadata["support"]) {
- case "FULL":
- supportLevel = FULL_SUPPORT
- case "PARTIAL":
- supportLevel = PARTIAL_SUPPORT
- case "UNIMPLEMENTED":
- supportLevel = UNIMPLEMENTED
- }
-
- // If an arg or returns is specifed treat that as a partial implementation even if
- // there is full support for the argument.
- if s.Metadata["arg"] != "" {
- supportLevel = PARTIAL_SUPPORT
- }
- if s.Metadata["returns"] != "" && supportLevel == UNKNOWN {
- returns := strings.ToUpper(s.Metadata["returns"])
- // Default to PARTIAL support if only returns is specified
- supportLevel = PARTIAL_SUPPORT
-
- // If ENOSYS is returned unequivically, treat it as unimplemented.
- if returns == "ENOSYS" {
- supportLevel = UNIMPLEMENTED
- }
- }
-
- return supportLevel
-}
-
-func (s *Syscall) Support() string {
- l := s.SupportLevel()
- switch l {
- case FULL_SUPPORT:
- return "Full"
- case PARTIAL_SUPPORT:
- return "Partial"
- case UNIMPLEMENTED:
- return "Unimplemented"
- default:
- return "Unknown"
- }
-}
-
-func (s *Syscall) Note() string {
- note := s.Metadata["note"]
- returns := s.Metadata["returns"]
- // Add "Returns ENOSYS" note by default if support:UNIMPLEMENTED
- if returns == "" && s.SupportLevel() == UNIMPLEMENTED {
- returns = "ENOSYS"
- }
- if returns != "" {
- return_note := fmt.Sprintf("Returns %s", returns)
- if note != "" {
- note = return_note + "; " + note
- } else {
- note = return_note
- }
- }
- if note == "" && s.SupportLevel() == FULL_SUPPORT {
- note = "Full Support"
- }
- return note
-}
-
-type Report struct {
- Implemented int
- Unimplemented int
- Unknown int
- Total int
- Syscalls []*Syscall
-}
-
-func init() {
- // Build a regex that will attempt to match all fields in tokens.
-
- // Regexp for matching syscall definitions
- s := "@Syscall\\(([^\\),]+)([^\\)]+)\\)"
- r = regexp.MustCompile(s)
-
- // Regexp for matching metadata
- s2 := "([^\\ ),]+):([^\\),]+)"
- r2 = regexp.MustCompile(s2)
-
- ReverseSyscallMap = make(map[string]int)
- for no, name := range SyscallMap {
- ReverseSyscallMap[name] = no
- }
-}
-
-// parseDoc parses all comments in a file and returns the parsed syscall
-// information.
-func parseDoc(fs *token.FileSet, f *ast.File) []*Syscall {
- syscalls := []*Syscall{}
- for _, cg := range f.Comments {
- for _, line := range strings.Split(cg.Text(), "\n") {
- if syscall := parseLine(fs, line); syscall != nil {
- pos := fs.Position(cg.Pos())
- syscall.File = pos.Filename
- syscall.Line = pos.Line
-
- syscalls = append(syscalls, syscall)
- }
- }
- }
- return syscalls
-}
-
-// parseLine parses a single line of Godoc and returns the parsed syscall
-// information. If no information is found, nil is returned.
-// Syscall declarations take the form:
-// @Syscall(<name>, <verb>:<value>, ...)
-func parseLine(fs *token.FileSet, line string) *Syscall {
- s := r.FindAllStringSubmatch(line, -1)
- if len(s) > 0 {
- name := strings.ToLower(s[0][1])
- if n, ok := ReverseSyscallMap[name]; ok {
- syscall := Syscall{}
- syscall.Name = name
- syscall.Number = n
- syscall.Metadata = make(map[string]string)
- s2 := r2.FindAllStringSubmatch(s[0][2], -1)
- for _, match := range s2 {
- syscall.Metadata[match[1]] = match[2]
- }
- return &syscall
- } else {
- log.Printf("Warning: unknown syscall %q", name)
- }
- }
- return nil
-}
-
-func main() {
- flag.Parse()
-
- var syscalls []*Syscall
-
- err := filepath.Walk(*srcDir, func(path string, info os.FileInfo, err error) error {
- if info != nil && info.IsDir() {
- fs := token.NewFileSet()
- d, err := parser.ParseDir(fs, path, nil, parser.ParseComments)
- if err != nil {
- return err
- }
-
- for _, p := range d {
- for _, f := range p.Files {
- s := parseDoc(fs, f)
- syscalls = append(syscalls, s...)
- }
- }
- }
-
- return nil
- })
-
- if err != nil {
- fmt.Printf("failed to walk dir %s: %v", *srcDir, err)
- os.Exit(1)
- }
-
- var fullList []*Syscall
- for no, name := range SyscallMap {
- found := false
- for _, s := range syscalls {
- if s.Number == no {
- fullList = append(fullList, s)
- found = true
- }
- }
- if !found {
- fullList = append(fullList, &Syscall{
- Name: name,
- Number: no,
- })
- }
- }
-
- // Sort the syscalls by number.
- sort.Slice(fullList, func(i, j int) bool {
- return fullList[i].Number < fullList[j].Number
- })
-
- if *jsonOut {
- j, err := json.Marshal(fullList)
- if err != nil {
- fmt.Printf("failed to marshal JSON: %v", err)
- os.Exit(1)
- }
- os.Stdout.Write(j)
- return
- }
-
- // Count syscalls and group by syscall number and support level
- supportMap := map[int]int{}
- for _, s := range fullList {
- supportLevel := s.SupportLevel()
-
- // If we already have set a higher level of support
- // keep the current value
- if current, ok := supportMap[s.Number]; ok && supportLevel < current {
- continue
- }
-
- supportMap[s.Number] = supportLevel
- }
- report := Report{
- Syscalls: fullList,
- }
- for _, s := range supportMap {
- switch s {
- case FULL_SUPPORT:
- report.Implemented += 1
- case PARTIAL_SUPPORT:
- report.Implemented += 1
- case UNIMPLEMENTED:
- report.Unimplemented += 1
- case UNKNOWN:
- report.Unknown += 1
- }
- report.Total += 1
- }
-
- err = mdTemplate.Execute(os.Stdout, report)
- if err != nil {
- fmt.Printf("failed to execute template: %v", err)
- os.Exit(1)
- return
- }
-}
diff --git a/cmd/parse-syscall-annotations/syscall.go b/cmd/parse-syscall-annotations/syscall.go
deleted file mode 100644
index b4a756440..000000000
--- a/cmd/parse-syscall-annotations/syscall.go
+++ /dev/null
@@ -1,359 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This program will take a single golang source file, or a directory containing
-// many source files and produce a JSON output which represent any comments
-// containing compatibility metadata.
-
-// Command parse-syscall-annotations parses syscall annotations from Godoc and
-// generates a JSON file with the parsed syscall info.
-
-package main
-
-// ReverseSyscallMap is a map of syscall name (lowercase) to number
-var ReverseSyscallMap map[string]int
-
-// SyscallMap is a map of syscall number to syscall name (lowercase)
-var SyscallMap = map[int]string{
- 0: "read",
- 1: "write",
- 2: "open",
- 3: "close",
- 4: "stat",
- 5: "fstat",
- 6: "lstat",
- 7: "poll",
- 8: "lseek",
- 9: "mmap",
- 10: "mprotect",
- 11: "munmap",
- 12: "brk",
- 13: "rtsigaction",
- 14: "rtsigprocmask",
- 15: "rtsigreturn",
- 16: "ioctl",
- 17: "pread64",
- 18: "pwrite64",
- 19: "readv",
- 20: "writev",
- 21: "access",
- 22: "pipe",
- 23: "select",
- 24: "schedyield",
- 25: "mremap",
- 26: "msync",
- 27: "mincore",
- 28: "madvise",
- 29: "shmget",
- 30: "shmat",
- 31: "shmctl",
- 32: "dup",
- 33: "dup2",
- 34: "pause",
- 35: "nanosleep",
- 36: "getitimer",
- 37: "alarm",
- 38: "setitimer",
- 39: "getpid",
- 40: "sendfile",
- 41: "socket",
- 42: "connect",
- 43: "accept",
- 44: "sendto",
- 45: "recvfrom",
- 46: "sendmsg",
- 47: "recvmsg",
- 48: "shutdown",
- 49: "bind",
- 50: "listen",
- 51: "getsockname",
- 52: "getpeername",
- 53: "socketpair",
- 54: "setsockopt",
- 55: "getsockopt",
- 56: "clone",
- 57: "fork",
- 58: "vfork",
- 59: "execve",
- 60: "exit",
- 61: "wait4",
- 62: "kill",
- 63: "uname",
- 64: "semget",
- 65: "semop",
- 66: "semctl",
- 67: "shmdt",
- 68: "msgget",
- 69: "msgsnd",
- 70: "msgrcv",
- 71: "msgctl",
- 72: "fcntl",
- 73: "flock",
- 74: "fsync",
- 75: "fdatasync",
- 76: "truncate",
- 77: "ftruncate",
- 78: "getdents",
- 79: "getcwd",
- 80: "chdir",
- 81: "fchdir",
- 82: "rename",
- 83: "mkdir",
- 84: "rmdir",
- 85: "creat",
- 86: "link",
- 87: "unlink",
- 88: "symlink",
- 89: "readlink",
- 90: "chmod",
- 91: "fchmod",
- 92: "chown",
- 93: "fchown",
- 94: "lchown",
- 95: "umask",
- 96: "gettimeofday",
- 97: "getrlimit",
- 98: "getrusage",
- 99: "sysinfo",
- 100: "times",
- 101: "ptrace",
- 102: "getuid",
- 103: "syslog",
- 104: "getgid",
- 105: "setuid",
- 106: "setgid",
- 107: "geteuid",
- 108: "getegid",
- 109: "setpgid",
- 110: "getppid",
- 111: "getpgrp",
- 112: "setsid",
- 113: "setreuid",
- 114: "setregid",
- 115: "getgroups",
- 116: "setgroups",
- 117: "setresuid",
- 118: "getresuid",
- 119: "setresgid",
- 120: "getresgid",
- 121: "getpgid",
- 122: "setfsuid",
- 123: "setfsgid",
- 124: "getsid",
- 125: "capget",
- 126: "capset",
- 127: "rtsigpending",
- 128: "rtsigtimedwait",
- 129: "rtsigqueueinfo",
- 130: "rtsigsuspend",
- 131: "sigaltstack",
- 132: "utime",
- 133: "mknod",
- 134: "uselib",
- 135: "setpersonality",
- 136: "ustat",
- 137: "statfs",
- 138: "fstatfs",
- 139: "sysfs",
- 140: "getpriority",
- 141: "setpriority",
- 142: "schedsetparam",
- 143: "schedgetparam",
- 144: "schedsetscheduler",
- 145: "schedgetscheduler",
- 146: "schedgetprioritymax",
- 147: "schedgetprioritymin",
- 148: "schedrrgetinterval",
- 149: "mlock",
- 150: "munlock",
- 151: "mlockall",
- 152: "munlockall",
- 153: "vhangup",
- 154: "modifyldt",
- 155: "pivotroot",
- 156: "sysctl",
- 157: "prctl",
- 158: "archprctl",
- 159: "adjtimex",
- 160: "setrlimit",
- 161: "chroot",
- 162: "sync",
- 163: "acct",
- 164: "settimeofday",
- 165: "mount",
- 166: "umount2",
- 167: "swapon",
- 168: "swapoff",
- 169: "reboot",
- 170: "sethostname",
- 171: "setdomainname",
- 172: "iopl",
- 173: "ioperm",
- 174: "createmodule",
- 175: "initmodule",
- 176: "deletemodule",
- 177: "getkernelsyms",
- 178: "querymodule",
- 179: "quotactl",
- 180: "nfsservctl",
- 181: "getpmsg",
- 182: "putpmsg",
- 183: "afssyscall",
- 184: "tuxcall",
- 185: "security",
- 186: "gettid",
- 187: "readahead",
- 188: "setxattr",
- 189: "lsetxattr",
- 190: "fsetxattr",
- 191: "getxattr",
- 192: "lgetxattr",
- 193: "fgetxattr",
- 194: "listxattr",
- 195: "llistxattr",
- 196: "flistxattr",
- 197: "removexattr",
- 198: "lremovexattr",
- 199: "fremovexattr",
- 200: "tkill",
- 201: "time",
- 202: "futex",
- 203: "schedsetaffinity",
- 204: "schedgetaffinity",
- 205: "setthreadarea",
- 206: "iosetup",
- 207: "iodestroy",
- 208: "iogetevents",
- 209: "iosubmit",
- 210: "iocancel",
- 211: "getthreadarea",
- 212: "lookupdcookie",
- 213: "epollcreate",
- 214: "epollctlold",
- 215: "epollwaitold",
- 216: "remapfilepages",
- 217: "getdents64",
- 218: "settidaddress",
- 219: "restartsyscall",
- 220: "semtimedop",
- 221: "fadvise64",
- 222: "timercreate",
- 223: "timersettime",
- 224: "timergettime",
- 225: "timergetoverrun",
- 226: "timerdelete",
- 227: "clocksettime",
- 228: "clockgettime",
- 229: "clockgetres",
- 230: "clocknanosleep",
- 231: "exitgroup",
- 232: "epollwait",
- 233: "epollctl",
- 234: "tgkill",
- 235: "utimes",
- 236: "vserver",
- 237: "mbind",
- 238: "setmempolicy",
- 239: "getmempolicy",
- 240: "mqopen",
- 241: "mqunlink",
- 242: "mqtimedsend",
- 243: "mqtimedreceive",
- 244: "mqnotify",
- 245: "mqgetsetattr",
- 246: "kexec_load",
- 247: "waitid",
- 248: "addkey",
- 249: "requestkey",
- 250: "keyctl",
- 251: "ioprioset",
- 252: "ioprioget",
- 253: "inotifyinit",
- 254: "inotifyaddwatch",
- 255: "inotifyrmwatch",
- 256: "migratepages",
- 257: "openat",
- 258: "mkdirat",
- 259: "mknodat",
- 260: "fchownat",
- 261: "futimesat",
- 262: "fstatat",
- 263: "unlinkat",
- 264: "renameat",
- 265: "linkat",
- 266: "symlinkat",
- 267: "readlinkat",
- 268: "fchmodat",
- 269: "faccessat",
- 270: "pselect",
- 271: "ppoll",
- 272: "unshare",
- 273: "setrobustlist",
- 274: "getrobustlist",
- 275: "splice",
- 276: "tee",
- 277: "syncfilerange",
- 278: "vmsplice",
- 279: "movepages",
- 280: "utimensat",
- 281: "epollpwait",
- 282: "signalfd",
- 283: "timerfdcreate",
- 284: "eventfd",
- 285: "fallocate",
- 286: "timerfdsettime",
- 287: "timerfdgettime",
- 288: "accept4",
- 289: "signalfd4",
- 290: "eventfd2",
- 291: "epollcreate1",
- 292: "dup3",
- 293: "pipe2",
- 294: "inotifyinit1",
- 295: "preadv",
- 296: "pwritev",
- 297: "rttgsigqueueinfo",
- 298: "perfeventopen",
- 299: "recvmmsg",
- 300: "fanotifyinit",
- 301: "fanotifymark",
- 302: "prlimit64",
- 303: "nametohandleat",
- 304: "openbyhandleat",
- 305: "clockadjtime",
- 306: "syncfs",
- 307: "sendmmsg",
- 308: "setns",
- 309: "getcpu",
- 310: "processvmreadv",
- 311: "processvmwritev",
- 312: "kcmp",
- 313: "finitmodule",
- 314: "schedsetattr",
- 315: "schedgetattr",
- 316: "renameat2",
- 317: "seccomp",
- 318: "getrandom",
- 319: "memfdcreate",
- 320: "kexecfileload",
- 321: "bpf",
- 322: "execveat",
- 323: "userfaultfd",
- 324: "membarrier",
- 325: "mlock2",
- // syscalls after 325 are "backports" from versions of linux after 4.4.
- 326: "copyfilerange",
- 327: "preadv2",
- 328: "pwritev2",
-}