aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/declextract/serialization.go
blob: 2906ce6c24e8e6298bdbf62b853476504a63bbe6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright 2024 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package declextract

import (
	"bytes"
	"fmt"
	"strings"
)

func (ctx *context) serialize() {
	ctx.descriptions = new(bytes.Buffer)
	ctx.fmt(header)
	ctx.serializeIncludes()
	ctx.serializeEnums()
	ctx.serializeSyscalls()
	ctx.serializeFileOps()
	ctx.serializeNetlink()
	ctx.serializeStructs()
	ctx.serializeDefines()
}

const header = `# Code generated by syz-declextract. DO NOT EDIT.

meta automatic

type auto_todo intptr

`

func (ctx *context) fmt(msg string, args ...any) {
	fmt.Fprintf(ctx.descriptions, msg, args...)
}

func (ctx *context) serializeIncludes() {
	for _, inc := range ctx.Includes {
		ctx.fmt("include <%s>\n", inc)
	}
	ctx.fmt("\n")
}

func (ctx *context) serializeDefines() {
	for _, def := range ctx.Defines {
		ctx.fmt("define %v %v\n", def.Name, def.Value)
	}
	ctx.fmt("\n")
}

func (ctx *context) serializeSyscalls() {
	for _, call := range ctx.Syscalls {
		ctx.fmt("%v(", call.Func)
		for i, arg := range call.Args {
			ctx.fmt("%v%v %v", comma(i), arg.Name, arg.syzType)
		}
		ctx.fmt(")\n")
	}
	ctx.fmt("\n")
}

func (ctx *context) serializeEnums() {
	for _, enum := range ctx.Enums {
		ctx.fmt("%v = ", enum.Name)
		for i, val := range enum.Values {
			ctx.fmt("%v %v", comma(i), val)
		}
		ctx.fmt("\n")
	}
	ctx.fmt("\n")
}

func (ctx *context) serializeStructs() {
	for _, str := range ctx.Structs {
		delims := "{}"
		if str.IsUnion {
			delims = "[]"
		}
		ctx.fmt("%v %c\n", str.Name, delims[0])
		for _, f := range str.Fields {
			ctx.fmt("%v %v\n", f.Name, f.syzType)
		}
		ctx.fmt("%c", delims[1])
		var attrs []string
		if str.IsPacked {
			attrs = append(attrs, "packed")
		}
		if str.Align != 0 {
			attrs = append(attrs, fmt.Sprintf("align[%v]", str.Align))
		}
		if len(attrs) != 0 {
			ctx.fmt(" [%v]", strings.Join(attrs, ", "))
		}
		ctx.fmt("\n\n")
	}
}