]>
Commit | Line | Data |
---|---|---|
1 | // Copyright 2016 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 | // mkpost processes the output of cgo -godefs to | |
8 | // modify the generated types. It is used to clean up | |
9 | // the sys API in an architecture specific manner. | |
10 | // | |
11 | // mkpost is run after cgo -godefs; see README.md. | |
12 | package main | |
13 | ||
14 | import ( | |
15 | "bytes" | |
16 | "fmt" | |
17 | "go/format" | |
18 | "io/ioutil" | |
19 | "log" | |
20 | "os" | |
21 | "regexp" | |
22 | ) | |
23 | ||
24 | func main() { | |
25 | // Get the OS and architecture (using GOARCH_TARGET if it exists) | |
26 | goos := os.Getenv("GOOS") | |
27 | goarch := os.Getenv("GOARCH_TARGET") | |
28 | if goarch == "" { | |
29 | goarch = os.Getenv("GOARCH") | |
30 | } | |
31 | // Check that we are using the Docker-based build system if we should be. | |
32 | if goos == "linux" { | |
33 | if os.Getenv("GOLANG_SYS_BUILD") != "docker" { | |
34 | os.Stderr.WriteString("In the Docker-based build system, mkpost should not be called directly.\n") | |
35 | os.Stderr.WriteString("See README.md\n") | |
36 | os.Exit(1) | |
37 | } | |
38 | } | |
39 | ||
40 | b, err := ioutil.ReadAll(os.Stdin) | |
41 | if err != nil { | |
42 | log.Fatal(err) | |
43 | } | |
44 | ||
45 | // Intentionally export __val fields in Fsid and Sigset_t | |
46 | valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__val(\s+\S+\s+)}`) | |
47 | b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$3}")) | |
48 | ||
49 | // Intentionally export __fds_bits field in FdSet | |
50 | fdSetRegex := regexp.MustCompile(`type (FdSet) struct {(\s+)X__fds_bits(\s+\S+\s+)}`) | |
51 | b = fdSetRegex.ReplaceAll(b, []byte("type $1 struct {${2}Bits$3}")) | |
52 | ||
53 | // If we have empty Ptrace structs, we should delete them. Only s390x emits | |
54 | // nonempty Ptrace structs. | |
55 | ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`) | |
56 | b = ptraceRexexp.ReplaceAll(b, nil) | |
57 | ||
58 | // Replace the control_regs union with a blank identifier for now. | |
59 | controlRegsRegex := regexp.MustCompile(`(Control_regs)\s+\[0\]uint64`) | |
60 | b = controlRegsRegex.ReplaceAll(b, []byte("_ [0]uint64")) | |
61 | ||
62 | // Remove fields that are added by glibc | |
63 | // Note that this is unstable as the identifers are private. | |
64 | removeFieldsRegex := regexp.MustCompile(`X__glibc\S*`) | |
65 | b = removeFieldsRegex.ReplaceAll(b, []byte("_")) | |
66 | ||
67 | // Convert [65]int8 to [65]byte in Utsname members to simplify | |
68 | // conversion to string; see golang.org/issue/20753 | |
69 | convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`) | |
70 | b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte")) | |
71 | ||
72 | // Convert [1024]int8 to [1024]byte in Ptmget members | |
73 | convertPtmget := regexp.MustCompile(`([SC]n)(\s+)\[(\d+)\]u?int8`) | |
74 | b = convertPtmget.ReplaceAll(b, []byte("$1[$3]byte")) | |
75 | ||
76 | // Remove spare fields (e.g. in Statx_t) | |
77 | spareFieldsRegex := regexp.MustCompile(`X__spare\S*`) | |
78 | b = spareFieldsRegex.ReplaceAll(b, []byte("_")) | |
79 | ||
80 | // Remove cgo padding fields | |
81 | removePaddingFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`) | |
82 | b = removePaddingFieldsRegex.ReplaceAll(b, []byte("_")) | |
83 | ||
84 | // Remove padding, hidden, or unused fields | |
85 | removeFieldsRegex = regexp.MustCompile(`\b(X_\S+|Padding)`) | |
86 | b = removeFieldsRegex.ReplaceAll(b, []byte("_")) | |
87 | ||
88 | // Remove the first line of warning from cgo | |
89 | b = b[bytes.IndexByte(b, '\n')+1:] | |
90 | // Modify the command in the header to include: | |
91 | // mkpost, our own warning, and a build tag. | |
92 | replacement := fmt.Sprintf(`$1 | go run mkpost.go | |
93 | // Code generated by the command above; see README.md. DO NOT EDIT. | |
94 | ||
95 | // +build %s,%s`, goarch, goos) | |
96 | cgoCommandRegex := regexp.MustCompile(`(cgo -godefs .*)`) | |
97 | b = cgoCommandRegex.ReplaceAll(b, []byte(replacement)) | |
98 | ||
99 | // gofmt | |
100 | b, err = format.Source(b) | |
101 | if err != nil { | |
102 | log.Fatal(err) | |
103 | } | |
104 | ||
105 | os.Stdout.Write(b) | |
106 | } |