diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-01-10 16:13:34 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-01-13 12:52:09 +0100 |
| commit | 6b52293f4defa6b45b564d037fd641be5d6d0e0e (patch) | |
| tree | 53c7f28df3fd2666ca165ce7231d470c9d1e2dc5 /sys | |
| parent | 9dc808a65eb3f44d64e078b79bcac0f0510629f6 (diff) | |
pkg/compiler: support type templates
Netlink descriptions contain tons of code duplication,
and need much more for proper descriptions. Introduce
type templates to simplify writing such descriptions
and remove code duplication.
Note: type templates are experimental, have poor error handling
and are subject to change.
Type templates can be declared as follows:
```
type buffer[DIR] ptr[DIR, array[int8]]
type fileoff[BASE] BASE
type nlattr[TYPE, PAYLOAD] {
nla_len len[parent, int16]
nla_type const[TYPE, int16]
payload PAYLOAD
} [align_4]
```
and later used as follows:
```
syscall(a buffer[in], b fileoff[int64], c ptr[in, nlattr[FOO, int32]])
```
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/syz-extract/extract.go | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/sys/syz-extract/extract.go b/sys/syz-extract/extract.go index 81067615a..5e5e95144 100644 --- a/sys/syz-extract/extract.go +++ b/sys/syz-extract/extract.go @@ -42,6 +42,7 @@ type File struct { arch *Arch name string undeclared map[string]bool + info *compiler.ConstInfo err error } @@ -160,15 +161,17 @@ func main() { for job := range jobC { switch j := job.(type) { case *Arch: - j.err = OS.prepareArch(j) + infos, err := processArch(OS, j) + j.err = err if j.err == nil { for _, f := range j.files { + f.info = infos[f.name] wg.Add(1) jobC <- f } } case *File: - j.undeclared, j.err = processFile(OS, j.arch, j.name) + j.undeclared, j.err = processFile(OS, j.arch, j) } wg.Done() } @@ -205,29 +208,33 @@ func main() { } } -func processFile(OS OS, arch *Arch, inname string) (map[string]bool, error) { - inname = filepath.Join("sys", arch.target.OS, inname) - outname := strings.TrimSuffix(inname, ".txt") + "_" + arch.target.Arch + ".const" - indata, err := ioutil.ReadFile(inname) - if err != nil { - return nil, fmt.Errorf("failed to read input file: %v", err) - } +func processArch(OS OS, arch *Arch) (map[string]*compiler.ConstInfo, error) { errBuf := new(bytes.Buffer) eh := func(pos ast.Pos, msg string) { fmt.Fprintf(errBuf, "%v: %v\n", pos, msg) } - desc := ast.Parse(indata, filepath.Base(inname), eh) - if desc == nil { + top := ast.ParseGlob(filepath.Join("sys", arch.target.OS, "*.txt"), eh) + if top == nil { return nil, fmt.Errorf("%v", errBuf.String()) } - info := compiler.ExtractConsts(desc, arch.target, eh) - if info == nil { + infos := compiler.ExtractConsts(top, arch.target, eh) + if infos == nil { return nil, fmt.Errorf("%v", errBuf.String()) } - if len(info.Consts) == 0 { + if err := OS.prepareArch(arch); err != nil { + return nil, err + } + return infos, nil +} + +func processFile(OS OS, arch *Arch, file *File) (map[string]bool, error) { + inname := filepath.Join("sys", arch.target.OS, file.name) + outname := strings.TrimSuffix(inname, ".txt") + "_" + arch.target.Arch + ".const" + if len(file.info.Consts) == 0 { + os.Remove(outname) return nil, nil } - consts, undeclared, err := OS.processFile(arch, info) + consts, undeclared, err := OS.processFile(arch, file.info) if err != nil { return nil, err } |
