aboutsummaryrefslogtreecommitdiffstats
path: root/executor/embed.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-05-08 12:24:46 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-05-08 12:26:59 +0000
commit4dbd403fd0978b91ffe3bb2f2a749511591644dd (patch)
treea43a92648849d5127c4165b744e05e38c90bf9ee /executor/embed.go
parentdc488c459880e3f3af557dc336697138ecb8228b (diff)
pkg/csource: replace go:generate with go:embed
go:embed is a more modern way to do this and it does not require a special Makefile step. Since go:embed cannot use paths that contains "..", the actual embeding is moved to executor package.
Diffstat (limited to 'executor/embed.go')
-rw-r--r--executor/embed.go73
1 files changed, 73 insertions, 0 deletions
diff --git a/executor/embed.go b/executor/embed.go
new file mode 100644
index 000000000..a02413a12
--- /dev/null
+++ b/executor/embed.go
@@ -0,0 +1,73 @@
+// 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 executor
+
+import (
+ "bytes"
+ "embed"
+ "fmt"
+ "io/fs"
+ "path"
+ "regexp"
+)
+
+//go:embed common*.h kvm*.h android/*.h
+var src embed.FS
+
+// CommonHeader contains all executor common headers used by pkg/csource to generate C reproducers.
+// All includes in common.h are transitively replaced with their contents so that it's just a single blob.
+var CommonHeader = func() []byte {
+ data, err := src.ReadFile("common.h")
+ if err != nil {
+ panic(err)
+ }
+ headers := make(map[string]bool)
+ for _, glob := range []string{"*.h", "android/*.h"} {
+ files, err := fs.Glob(src, glob)
+ if err != nil {
+ panic(err)
+ }
+ for _, file := range files {
+ if file == "common.h" || file == "common_ext_example.h" {
+ continue
+ }
+ headers[file] = true
+ }
+ }
+ // To not hardcode concrete order in which headers need to be replaced
+ // we just iteratively try to replace whatever headers can be replaced
+ // on the current step.
+ for len(headers) != 0 {
+ relacedSomething := false
+ for file := range headers {
+ replace := []byte("#include \"" + path.Base(file) + "\"")
+ if !bytes.Contains(data, replace) {
+ replace = []byte("#include \"android/" + path.Base(file) + "\"")
+ if !bytes.Contains(data, replace) {
+ continue
+ }
+ }
+ contents, err := src.ReadFile(file)
+ if err != nil {
+ panic(err)
+ }
+ data = bytes.ReplaceAll(data, replace, contents)
+ delete(headers, file)
+ relacedSomething = true
+ }
+ if !relacedSomething {
+ panic(fmt.Sprintf("can't find includes for %v", headers))
+ }
+ }
+ // Remove `//` comments, but keep lines which start with `//%`.
+ for _, remove := range []string{
+ "(\n|^)\\s*//$",
+ "(\n|^)\\s*//[^%].*",
+ "\\s*//$",
+ "\\s*//[^%].*",
+ } {
+ data = regexp.MustCompile(remove).ReplaceAll(data, nil)
+ }
+ return data
+}()