github.com/giovannyortegon/go@v0.0.0-20220115155912-8890063f5bdd/src/pkg/mod/golang.org/x/sys@v0.0.0-20210927094055-39ccf1dd6fa6/unix/linux/mksysnum.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build ignore 6 7 package main 8 9 import ( 10 "bufio" 11 "fmt" 12 "os" 13 "os/exec" 14 "regexp" 15 "strconv" 16 "strings" 17 ) 18 19 var ( 20 goos, goarch string 21 ) 22 23 // cmdLine returns this programs's commandline arguments 24 func cmdLine() string { 25 return "go run linux/mksysnum.go " + strings.Join(os.Args[1:], " ") 26 } 27 28 // goBuildTags returns build tags in the go:build format. 29 func goBuildTags() string { 30 return fmt.Sprintf("%s && %s", goarch, goos) 31 } 32 33 // plusBuildTags returns build tags in the +build format. 34 func plusBuildTags() string { 35 return fmt.Sprintf("%s,%s", goarch, goos) 36 } 37 38 func format(name string, num int, offset int) string { 39 if num > 999 { 40 // ignore deprecated syscalls that are no longer implemented 41 // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/unistd.h?id=refs/heads/master#n716 42 return "" 43 } 44 name = strings.ToUpper(name) 45 num = num + offset 46 return fmt.Sprintf(" SYS_%s = %d;\n", name, num) 47 } 48 49 func checkErr(err error) { 50 if err != nil { 51 fmt.Fprintf(os.Stderr, "%v\n", err) 52 os.Exit(1) 53 } 54 } 55 56 // source string and substring slice for regexp 57 type re struct { 58 str string // source string 59 sub []string // matched sub-string 60 } 61 62 // Match performs regular expression match 63 func (r *re) Match(exp string) bool { 64 r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str) 65 if r.sub != nil { 66 return true 67 } 68 return false 69 } 70 71 func main() { 72 // Get the OS and architecture (using GOARCH_TARGET if it exists) 73 goos = os.Getenv("GOOS") 74 goarch = os.Getenv("GOARCH_TARGET") 75 if goarch == "" { 76 goarch = os.Getenv("GOARCH") 77 } 78 // Check if GOOS and GOARCH environment variables are defined 79 if goarch == "" || goos == "" { 80 fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n") 81 os.Exit(1) 82 } 83 // Check that we are using the new build system if we should 84 if os.Getenv("GOLANG_SYS_BUILD") != "docker" { 85 fmt.Fprintf(os.Stderr, "In the new build system, mksysnum should not be called directly.\n") 86 fmt.Fprintf(os.Stderr, "See README.md\n") 87 os.Exit(1) 88 } 89 90 cc := os.Getenv("CC") 91 if cc == "" { 92 fmt.Fprintf(os.Stderr, "CC is not defined in environment\n") 93 os.Exit(1) 94 } 95 args := os.Args[1:] 96 args = append([]string{"-E", "-dD"}, args...) 97 cmd, err := exec.Command(cc, args...).Output() // execute command and capture output 98 if err != nil { 99 fmt.Fprintf(os.Stderr, "can't run %s", cc) 100 os.Exit(1) 101 } 102 text := "" 103 s := bufio.NewScanner(strings.NewReader(string(cmd))) 104 var offset, prev int 105 for s.Scan() { 106 t := re{str: s.Text()} 107 if t.Match(`^#define __NR_Linux\s+([0-9]+)`) { 108 // mips/mips64: extract offset 109 offset, _ = strconv.Atoi(t.sub[1]) // Make offset=0 if empty or non-numeric 110 } else if t.Match(`^#define __NR(\w*)_SYSCALL_BASE\s+([0-9]+)`) { 111 // arm: extract offset 112 offset, _ = strconv.Atoi(t.sub[1]) // Make offset=0 if empty or non-numeric 113 } else if t.Match(`^#define __NR_syscalls\s+`) { 114 // ignore redefinitions of __NR_syscalls 115 } else if t.Match(`^#define __NR_(\w*)Linux_syscalls\s+`) { 116 // mips/mips64: ignore definitions about the number of syscalls 117 } else if t.Match(`^#define __NR_(\w+)\s+([0-9]+)`) { 118 prev, err = strconv.Atoi(t.sub[2]) 119 checkErr(err) 120 text += format(t.sub[1], prev, offset) 121 } else if t.Match(`^#define __NR3264_(\w+)\s+([0-9]+)`) { 122 prev, err = strconv.Atoi(t.sub[2]) 123 checkErr(err) 124 text += format(t.sub[1], prev, offset) 125 } else if t.Match(`^#define __NR_(\w+)\s+\(\w+\+\s*([0-9]+)\)`) { 126 r2, err := strconv.Atoi(t.sub[2]) 127 checkErr(err) 128 text += format(t.sub[1], prev+r2, offset) 129 } else if t.Match(`^#define __NR_(\w+)\s+\(__NR_(?:SYSCALL_BASE|Linux) \+ ([0-9]+)`) { 130 r2, err := strconv.Atoi(t.sub[2]) 131 checkErr(err) 132 text += format(t.sub[1], r2, offset) 133 } 134 } 135 err = s.Err() 136 checkErr(err) 137 fmt.Printf(template, cmdLine(), goBuildTags(), plusBuildTags(), text) 138 } 139 140 const template = `// %s 141 // Code generated by the command above; see README.md. DO NOT EDIT. 142 143 //go:build %s 144 // +build %s 145 146 package unix 147 148 const( 149 %s)`