Skip to content

Commit 900c1a4

Browse files
committed
tools/syz-declextract: allow to run on subset of arches
This may be useful for downstream kernels that only build and are supposed to be used with a subset of arches. Some esoteric arches may be broken on such kernels. Allow to ignore them.
1 parent 996a961 commit 900c1a4

File tree

5 files changed

+86
-24
lines changed

5 files changed

+86
-24
lines changed

pkg/tool/flags.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import (
99
"errors"
1010
"flag"
1111
"fmt"
12+
"sort"
1213
"strings"
1314

1415
"github.com/google/syzkaller/pkg/log"
16+
"github.com/google/syzkaller/sys/targets"
1517
)
1618

1719
type Flag struct {
@@ -50,6 +52,30 @@ func ParseFlags(set *flag.FlagSet, args []string) error {
5052
return nil
5153
}
5254

55+
func ParseArchList(OS, archList string) ([]string, error) {
56+
allArches := targets.List[OS]
57+
if allArches == nil {
58+
return nil, fmt.Errorf("bad OS %q", OS)
59+
}
60+
archMap := make(map[string]bool)
61+
if archList != "" {
62+
for _, arch := range strings.Split(archList, ",") {
63+
if allArches[arch] == nil {
64+
return nil, fmt.Errorf("bad arch %q for OS %q in arches flag", arch, OS)
65+
}
66+
archMap[arch] = true
67+
}
68+
}
69+
var arches []string
70+
for arch := range allArches {
71+
if len(archMap) == 0 || archMap[arch] {
72+
arches = append(arches, arch)
73+
}
74+
}
75+
sort.Strings(arches)
76+
return arches, nil
77+
}
78+
5379
const optionalFlag = "optional"
5480

5581
func serializeFlags(flags []Flag) string {

pkg/tool/flags_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
package tool
55

66
import (
7+
"errors"
78
"flag"
89
"fmt"
910
"io"
1011
"strings"
1112
"testing"
1213

1314
"github.com/google/go-cmp/cmp"
15+
"github.com/stretchr/testify/assert"
1416
)
1517

1618
func TestParseFlags(t *testing.T) {
@@ -84,3 +86,40 @@ func TestCfgsFlagAlreadySet(t *testing.T) {
8486
t.Errorf("cfgs.Set got: nil, want: error")
8587
}
8688
}
89+
90+
func TestParseArchList(t *testing.T) {
91+
type Test struct {
92+
OS string
93+
In string
94+
Out []string
95+
Err error
96+
}
97+
tests := []Test{
98+
{
99+
OS: "foo",
100+
Err: errors.New(`bad OS "foo"`),
101+
},
102+
{
103+
OS: "linux",
104+
In: "amd64,bar",
105+
Err: errors.New(`bad arch "bar" for OS "linux" in arches flag`),
106+
},
107+
{
108+
OS: "linux",
109+
In: "",
110+
Out: []string{"386", "amd64", "arm", "arm64", "mips64le", "ppc64le", "riscv64", "s390x"},
111+
},
112+
{
113+
OS: "linux",
114+
In: "ppc64le,386",
115+
Out: []string{"386", "ppc64le"},
116+
},
117+
}
118+
for i, test := range tests {
119+
t.Run(fmt.Sprint(i), func(t *testing.T) {
120+
got, err := ParseArchList(test.OS, test.In)
121+
assert.Equal(t, err, test.Err)
122+
assert.Equal(t, got, test.Out)
123+
})
124+
}
125+
}

sys/syz-extract/extract.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"path/filepath"
1212
"runtime"
1313
"sort"
14-
"strings"
1514

1615
"github.com/google/syzkaller/pkg/ast"
1716
"github.com/google/syzkaller/pkg/compiler"
@@ -80,7 +79,11 @@ func main() {
8079
if extractor == nil {
8180
tool.Failf("unknown os: %v", OS)
8281
}
83-
arches, nfiles, err := createArches(OS, archList(OS, *flagArch), flag.Args())
82+
archList, err := tool.ParseArchList(OS, *flagArch)
83+
if err != nil {
84+
tool.Failf("failed to parse arch flag: %v", err)
85+
}
86+
arches, nfiles, err := createArches(OS, archList, flag.Args())
8487
if err != nil {
8588
tool.Fail(err)
8689
}
@@ -242,18 +245,6 @@ func createArches(OS string, archArray, files []string) ([]*Arch, int, error) {
242245
return arches, nfiles, nil
243246
}
244247

245-
func archList(OS, arches string) []string {
246-
if arches != "" {
247-
return strings.Split(arches, ",")
248-
}
249-
var archArray []string
250-
for arch := range targets.List[OS] {
251-
archArray = append(archArray, arch)
252-
}
253-
sort.Strings(archArray)
254-
return archArray
255-
}
256-
257248
func checkUnsupportedCalls(arches []*Arch) bool {
258249
supported := make(map[string]bool)
259250
unsupported := make(map[string]string)

tools/syz-declextract/declextract.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func main() {
3737
var (
3838
flagConfig = flag.String("config", "", "manager config file")
3939
flagBinary = flag.String("binary", "syz-declextract", "path to syz-declextract binary")
40+
flagArches = flag.String("arches", "", "comma-separated list of arches to extract (all if empty)")
4041
)
4142
defer tool.Init()()
4243
cfg, err := mgrconfig.LoadFile(*flagConfig)
@@ -46,7 +47,7 @@ func main() {
4647
loadProbeInfo := func() (*ifaceprobe.Info, error) {
4748
return probe(cfg, *flagConfig)
4849
}
49-
if _, err := run(filepath.FromSlash("sys/linux/auto.txt"), loadProbeInfo, &clangtool.Config{
50+
if _, err := run(filepath.FromSlash("sys/linux/auto.txt"), loadProbeInfo, *flagArches, &clangtool.Config{
5051
ToolBin: *flagBinary,
5152
KernelSrc: cfg.KernelSrc,
5253
KernelObj: cfg.KernelObj,
@@ -57,9 +58,13 @@ func main() {
5758
}
5859
}
5960

60-
func run(autoFile string, loadProbeInfo func() (*ifaceprobe.Info, error), cfg *clangtool.Config) (
61+
func run(autoFile string, loadProbeInfo func() (*ifaceprobe.Info, error), archList string, cfg *clangtool.Config) (
6162
*declextract.Result, error) {
62-
out, probeInfo, syscallRename, err := prepare(loadProbeInfo, cfg)
63+
arches, err := tool.ParseArchList(target.OS, archList)
64+
if err != nil {
65+
return nil, fmt.Errorf("failed to parse arches flag: %v", err)
66+
}
67+
out, probeInfo, syscallRename, err := prepare(loadProbeInfo, arches, cfg)
6368
if err != nil {
6469
return nil, err
6570
}
@@ -123,7 +128,7 @@ func removeUnused(desc *ast.Description, autoFile string, unusedNodes []ast.Node
123128
})
124129
}
125130

126-
func prepare(loadProbeInfo func() (*ifaceprobe.Info, error), cfg *clangtool.Config) (
131+
func prepare(loadProbeInfo func() (*ifaceprobe.Info, error), arches []string, cfg *clangtool.Config) (
127132
*declextract.Output, *ifaceprobe.Info, map[string][]string, error) {
128133
var eg errgroup.Group
129134
var out *declextract.Output
@@ -147,7 +152,7 @@ func prepare(loadProbeInfo func() (*ifaceprobe.Info, error), cfg *clangtool.Conf
147152
var syscallRename map[string][]string
148153
eg.Go(func() error {
149154
var err error
150-
syscallRename, err = buildSyscallRenameMap(cfg.KernelSrc)
155+
syscallRename, err = buildSyscallRenameMap(cfg.KernelSrc, arches)
151156
if err != nil {
152157
return fmt.Errorf("failed to build syscall rename map: %w", err)
153158
}
@@ -234,7 +239,7 @@ func finishInterfaces(interfaces []*declextract.Interface, consts map[string]*co
234239
}
235240
}
236241

237-
func buildSyscallRenameMap(sourceDir string) (map[string][]string, error) {
242+
func buildSyscallRenameMap(sourceDir string, arches []string) (map[string][]string, error) {
238243
// Some syscalls have different names and entry points and thus need to be renamed.
239244
// e.g. SYSCALL_DEFINE1(setuid16, old_uid_t, uid) is referred to in the .tbl file with setuid.
240245
// Parse *.tbl files that map functions defined with SYSCALL_DEFINE macros to actual syscall names.
@@ -244,7 +249,7 @@ func buildSyscallRenameMap(sourceDir string) (map[string][]string, error) {
244249
// and then just order arches by name to have deterministic result.
245250
// Note: some syscalls may have no record in the tables for the architectures we support.
246251
syscalls := make(map[string][]tblSyscall)
247-
tblFiles, err := findTblFiles(sourceDir)
252+
tblFiles, err := findTblFiles(sourceDir, arches)
248253
if err != nil {
249254
return nil, err
250255
}
@@ -320,9 +325,10 @@ func parseTblFile(data []byte, arch string, syscalls map[string][]tblSyscall) {
320325
}
321326
}
322327

323-
func findTblFiles(sourceDir string) (map[string][]string, error) {
328+
func findTblFiles(sourceDir string, arches []string) (map[string][]string, error) {
324329
files := make(map[string][]string)
325-
for _, arch := range targets.List[target.OS] {
330+
for _, name := range arches {
331+
arch := targets.List[target.OS][name]
326332
err := filepath.WalkDir(filepath.Join(sourceDir, "arch", arch.KernelHeaderArch),
327333
func(file string, d fs.DirEntry, err error) error {
328334
if err == nil && strings.HasSuffix(file, ".tbl") {

tools/syz-declextract/declextract_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func TestDeclextract(t *testing.T) {
6868
return probeInfo, nil
6969
}
7070
autoFile := filepath.Join(cfg.KernelObj, filepath.Base(file)+".txt")
71-
res, err := run(autoFile, loadProbeInfo, cfg)
71+
res, err := run(autoFile, loadProbeInfo, "", cfg)
7272
if err != nil {
7373
if *flagUpdate {
7474
osutil.CopyFile(autoFile, file+".txt")

0 commit comments

Comments
 (0)