aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/csource/csource.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-12-15 11:25:19 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-12-17 11:39:14 +0100
commit431d3c90b1a4a31a6156ad1cd5fc692af3b1a314 (patch)
treefbea978cb14e1daac37e8c9625a18ea18d6c2355 /pkg/csource/csource.go
parent9004acd9cc20a77e5227326a1ad4a0bcbc03316d (diff)
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.
Diffstat (limited to 'pkg/csource/csource.go')
-rw-r--r--pkg/csource/csource.go181
1 files changed, 2 insertions, 179 deletions
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,
-}`