From 431d3c90b1a4a31a6156ad1cd5fc692af3b1a314 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 15 Dec 2017 11:25:19 +0100 Subject: pkg/csource: refactor csource.go is too large and messy. Move Build/Format into buid.go. Move generation of common header into common.go. Split generation of common header into smaller managable functions. --- pkg/csource/csource.go | 181 +------------------------------------------------ 1 file changed, 2 insertions(+), 179 deletions(-) (limited to 'pkg/csource/csource.go') diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index d8a4a5a01..d99a0168d 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -6,16 +6,11 @@ package csource import ( "bytes" - "errors" "fmt" - "io/ioutil" - "os" - "os/exec" "regexp" "strings" "unsafe" - "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/prog" "github.com/google/syzkaller/sys/targets" ) @@ -24,19 +19,6 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { if err := opts.Check(); err != nil { return nil, fmt.Errorf("csource: invalid opts: %v", err) } - commonHeader := "" - switch p.Target.OS { - case "linux": - commonHeader = commonHeaderLinux - case "akaros": - commonHeader = commonHeaderAkaros - case "freebsd": - commonHeader = commonHeaderFreebsd - case "netbsd": - commonHeader = commonHeaderNetbsd - default: - return nil, fmt.Errorf("unsupported OS: %v", p.Target.OS) - } ctx := &context{ p: p, opts: opts, @@ -51,11 +33,11 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.print("// autogenerated by syzkaller (http://github.com/google/syzkaller)\n\n") - hdr, err := ctx.preprocessCommonHeader(commonHeader) + hdr, err := createCommonHeader(p, opts) if err != nil { return nil, err } - ctx.print(hdr) + ctx.w.Write(hdr) ctx.print("\n") ctx.generateSyscallDefines() @@ -424,162 +406,3 @@ loop: newCall() return calls, n } - -func (ctx *context) preprocessCommonHeader(commonHeader string) (string, error) { - var defines []string - if prog.RequiresBitmasks(ctx.p) { - defines = append(defines, "SYZ_USE_BITMASKS") - } - if prog.RequiresChecksums(ctx.p) { - defines = append(defines, "SYZ_USE_CHECKSUMS") - } - opts := ctx.opts - switch opts.Sandbox { - case "": - // No sandbox, do nothing. - case "none": - defines = append(defines, "SYZ_SANDBOX_NONE") - case "setuid": - defines = append(defines, "SYZ_SANDBOX_SETUID") - case "namespace": - defines = append(defines, "SYZ_SANDBOX_NAMESPACE") - default: - return "", fmt.Errorf("unknown sandbox mode: %v", opts.Sandbox) - } - if opts.Threaded { - defines = append(defines, "SYZ_THREADED") - } - if opts.Collide { - defines = append(defines, "SYZ_COLLIDE") - } - if opts.Repeat { - defines = append(defines, "SYZ_REPEAT") - } - if opts.Fault { - defines = append(defines, "SYZ_FAULT_INJECTION") - } - if opts.EnableTun { - defines = append(defines, "SYZ_TUN_ENABLE") - } - if opts.UseTmpDir { - defines = append(defines, "SYZ_USE_TMP_DIR") - } - if opts.HandleSegv { - defines = append(defines, "SYZ_HANDLE_SEGV") - } - if opts.WaitRepeat { - defines = append(defines, "SYZ_WAIT_REPEAT") - } - if opts.Debug { - defines = append(defines, "SYZ_DEBUG") - } - for name, _ := range ctx.calls { - defines = append(defines, "__NR_"+name) - } - defines = append(defines, ctx.sysTarget.CArch...) - - cmd := osutil.Command("cpp", "-nostdinc", "-undef", "-fdirectives-only", "-dDI", "-E", "-P", "-") - for _, def := range defines { - cmd.Args = append(cmd.Args, "-D"+def) - } - cmd.Stdin = strings.NewReader(commonHeader) - stderr := new(bytes.Buffer) - stdout := new(bytes.Buffer) - cmd.Stderr = stderr - cmd.Stdout = stdout - if err := cmd.Run(); len(stdout.Bytes()) == 0 { - return "", fmt.Errorf("cpp failed: %v\n%v\n%v\n", err, stdout.String(), stderr.String()) - } - remove := append(defines, []string{ - "__STDC__", - "__STDC_HOSTED__", - "__STDC_UTF_16__", - "__STDC_UTF_32__", - }...) - out := stdout.String() - for _, def := range remove { - out = strings.Replace(out, "#define "+def+" 1\n", "", -1) - } - // strip: #define __STDC_VERSION__ 201112L - for _, def := range []string{"__STDC_VERSION__"} { - pos := strings.Index(out, "#define "+def) - if pos == -1 { - continue - } - end := strings.IndexByte(out[pos:], '\n') - if end == -1 { - continue - } - out = strings.Replace(out, out[pos:end+1], "", -1) - } - return out, nil -} - -// Build builds a C/C++ program from source src and returns name of the resulting binary. -// lang can be "c" or "c++". -func Build(target *prog.Target, lang, src string) (string, error) { - bin, err := ioutil.TempFile("", "syzkaller") - if err != nil { - return "", fmt.Errorf("failed to create temp file: %v", err) - } - bin.Close() - sysTarget := targets.List[target.OS][target.Arch] - compiler := sysTarget.CCompilerPrefix + "gcc" - if _, err := exec.LookPath(compiler); err != nil { - return "", NoCompilerErr - } - flags := []string{ - "-x", lang, "-Wall", "-Werror", "-O1", "-g", "-o", bin.Name(), - src, "-pthread", - } - flags = append(flags, sysTarget.CrossCFlags...) - if sysTarget.PtrSize == 4 { - // We do generate uint64's for syscall arguments that overflow longs on 32-bit archs. - flags = append(flags, "-Wno-overflow") - } - out, err := osutil.Command(compiler, append(flags, "-static")...).CombinedOutput() - if err != nil { - // Some distributions don't have static libraries. - out, err = osutil.Command(compiler, flags...).CombinedOutput() - } - if err != nil { - os.Remove(bin.Name()) - data, _ := ioutil.ReadFile(src) - return "", fmt.Errorf("failed to build program:\n%s\n%s\ncompiler invocation: %v %v\n", - data, out, compiler, flags) - } - return bin.Name(), nil -} - -var NoCompilerErr = errors.New("no target compiler") - -// Format reformats C source using clang-format. -func Format(src []byte) ([]byte, error) { - stdout, stderr := new(bytes.Buffer), new(bytes.Buffer) - cmd := osutil.Command("clang-format", "-assume-filename=/src.c", "-style", style) - cmd.Stdin = bytes.NewReader(src) - cmd.Stdout = stdout - cmd.Stderr = stderr - if err := cmd.Run(); err != nil { - return src, fmt.Errorf("failed to format source: %v\n%v", err, stderr.String()) - } - return stdout.Bytes(), nil -} - -// Something acceptable for kernel developers and email-friendly. -var style = `{ -BasedOnStyle: LLVM, -IndentWidth: 2, -UseTab: Never, -BreakBeforeBraces: Linux, -IndentCaseLabels: false, -DerivePointerAlignment: false, -PointerAlignment: Left, -AlignTrailingComments: true, -AllowShortBlocksOnASingleLine: false, -AllowShortCaseLabelsOnASingleLine: false, -AllowShortFunctionsOnASingleLine: false, -AllowShortIfStatementsOnASingleLine: false, -AllowShortLoopsOnASingleLine: false, -ColumnLimit: 72, -}` -- cgit mrf-deployment