diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-06-29 10:47:42 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-06-29 10:47:42 +0200 |
| commit | 7b45fa115b57d0a6424c369483b320acfe6a1de7 (patch) | |
| tree | fbc8b30b977926c3345509358bfdc76eaa2ca495 /pkg/csource/csource.go | |
| parent | 1a3c2436df1f7c9c0271aad092558d943a0ee19e (diff) | |
pkg/csource: support fuchsia
Lots of assorted heavylifting to support csource on fuchsia.
Diffstat (limited to 'pkg/csource/csource.go')
| -rw-r--r-- | pkg/csource/csource.go | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index ddb1fbf3f..a3c1b00b7 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -15,7 +15,7 @@ import ( ) func Write(p *prog.Prog, opts Options) ([]byte, error) { - if err := opts.Check(); err != nil { + if err := opts.Check(p.Target.OS); err != nil { return nil, fmt.Errorf("csource: invalid opts: %v", err) } ctx := &context{ @@ -44,7 +44,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.print("// autogenerated by syzkaller (http://github.com/google/syzkaller)\n\n") - hdr, err := createCommonHeader(p, opts) + hdr, err := createCommonHeader(p, mmapProg, opts) if err != nil { return nil, err } @@ -87,17 +87,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { if opts.UseTmpDir { ctx.printf("\tuse_temporary_dir();\n") } - if opts.Sandbox != "" { - ctx.printf("\tint pid = do_sandbox_%v();\n", opts.Sandbox) - ctx.print("\tint status = 0;\n") - ctx.print("\twhile (waitpid(pid, &status, __WALL) != pid) {}\n") - } else { - if opts.EnableTun { - ctx.printf("\tinitialize_tun();\n") - ctx.printf("\tinitialize_netdevices();\n") - } - ctx.print("\tloop();\n") - } + ctx.writeLoopCall() ctx.print("\treturn 0;\n}\n") } else { ctx.generateTestFunc(calls, len(vars) != 0, "execute_one") @@ -118,17 +108,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.print("\t\t\tfail(\"failed to chdir\");\n") ctx.print("\t\tuse_temporary_dir();\n") } - if opts.Sandbox != "" { - ctx.printf("\t\tint pid = do_sandbox_%v();\n", opts.Sandbox) - ctx.print("\t\tint status = 0;\n") - ctx.print("\t\twhile (waitpid(pid, &status, __WALL) != pid) {}\n") - } else { - if opts.EnableTun { - ctx.printf("\t\tinitialize_tun();\n") - ctx.printf("\t\tinitialize_netdevices();\n") - } - ctx.print("\t\tloop();\n") - } + ctx.writeLoopCall() ctx.print("\t}\n}\n") } else { ctx.print("int main()\n{\n") @@ -149,17 +129,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.print("\t\t\t\t\tfail(\"failed to chdir\");\n") ctx.print("\t\t\t\tuse_temporary_dir();\n") } - if opts.Sandbox != "" { - ctx.printf("\t\t\t\tint pid = do_sandbox_%v();\n", opts.Sandbox) - ctx.print("\t\t\t\tint status = 0;\n") - ctx.print("\t\t\t\twhile (waitpid(pid, &status, __WALL) != pid) {}\n") - } else { - if opts.EnableTun { - ctx.printf("\t\t\t\tinitialize_tun();\n") - ctx.printf("\t\t\t\tinitialize_netdevices();\n") - } - ctx.print("\t\t\t\tloop();\n") - } + ctx.writeLoopCall() ctx.print("\t\t\t}\n") ctx.print("\t\t}\n") ctx.print("\t}\n") @@ -175,9 +145,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { result = re.ReplaceAll(result, []byte("$1;\n")) } if !opts.Debug { - re := regexp.MustCompile(`\t*debug\(.*\);\n`) + re := regexp.MustCompile(`\t*debug\((.*\n)*?.*\);\n`) result = re.ReplaceAll(result, nil) - re = regexp.MustCompile(`\t*debug_dump_data\(.*\);\n`) + re = regexp.MustCompile(`\t*debug_dump_data\((.*\n)*?.*\);\n`) result = re.ReplaceAll(result, nil) } result = bytes.Replace(result, []byte("NORETURN"), nil, -1) @@ -213,6 +183,20 @@ func (ctx *context) printf(str string, args ...interface{}) { ctx.print(fmt.Sprintf(str, args...)) } +func (ctx *context) writeLoopCall() { + if ctx.opts.Sandbox != "" { + ctx.printf("\tdo_sandbox_%v();\n", ctx.opts.Sandbox) + return + } + if ctx.opts.EnableTun { + ctx.printf("\tinitialize_tun();\n") + } + if ctx.opts.EnableNetdev { + ctx.printf("\tinitialize_netdevices();\n") + } + ctx.print("\tloop();\n") +} + func (ctx *context) generateTestFunc(calls []string, hasVars bool, name string) { opts := ctx.opts if !opts.Threaded && !opts.Collide { @@ -225,7 +209,7 @@ func (ctx *context) generateTestFunc(calls []string, hasVars bool, name string) ctx.printf("\tdebug(\"%v\\n\");\n", name) } if opts.Repro { - ctx.printf("\tsyscall(SYS_write, 1, \"executing program\\n\", strlen(\"executing program\\n\"));\n") + ctx.printf("\twrite(1, \"executing program\\n\", strlen(\"executing program\\n\"));\n") } for _, c := range calls { ctx.printf("%s", c) @@ -251,7 +235,7 @@ func (ctx *context) generateTestFunc(calls []string, hasVars bool, name string) ctx.printf("\tdebug(\"%v\\n\");\n", name) } if opts.Repro { - ctx.printf("\tsyscall(SYS_write, 1, \"executing program\\n\", strlen(\"executing program\\n\"));\n") + ctx.printf("\twrite(1, \"executing program\\n\", strlen(\"executing program\\n\"));\n") } ctx.printf("\texecute(%v);\n", len(calls)) if opts.Collide { @@ -265,7 +249,8 @@ func (ctx *context) generateTestFunc(calls []string, hasVars bool, name string) func (ctx *context) generateSyscallDefines() { prefix := ctx.sysTarget.SyscallPrefix for name, nr := range ctx.calls { - if strings.HasPrefix(name, "syz_") || !ctx.sysTarget.NeedSyscallDefine(nr) { + if !ctx.sysTarget.SyscallNumbers || + strings.HasPrefix(name, "syz_") || !ctx.sysTarget.NeedSyscallDefine(nr) { continue } ctx.printf("#ifndef %v%v\n", prefix, name) @@ -346,15 +331,21 @@ func (ctx *context) generateCalls(p prog.ExecProg) ([]string, []uint64) { // TODO: if we don't emit the call we must also not emit copyin, copyout and fault injection. // However, simply skipping whole iteration breaks tests due to unused static functions. if emitCall { - native := !strings.HasPrefix(callName, "syz_") + native := ctx.sysTarget.SyscallNumbers && !strings.HasPrefix(callName, "syz_") fmt.Fprintf(w, "\t") if resCopyout || argCopyout { fmt.Fprintf(w, "res = ") } if native { fmt.Fprintf(w, "syscall(%v%v", ctx.sysTarget.SyscallPrefix, callName) - } else { + } else if strings.HasPrefix(callName, "syz_") { fmt.Fprintf(w, "%v(", callName) + } else { + args := strings.Repeat(",long", len(call.Args)) + if args != "" { + args = args[1:] + } + fmt.Fprintf(w, "((long(*)(%v))%v)(", args, callName) } for ai, arg := range call.Args { if native || ai > 0 { @@ -374,7 +365,13 @@ func (ctx *context) generateCalls(p prog.ExecProg) ([]string, []uint64) { // Copyout. if resCopyout || argCopyout { - fmt.Fprintf(w, "\tif (res != -1)") + cast := "" + if !ctx.sysTarget.SyscallNumbers { + // On fuchsia we call libc calls to function returning long, + // as the result int -1 is returned as 0x00000000ffffffff rather than full -1. + cast = "(int)" + } + fmt.Fprintf(w, "\tif (%vres != -1)", cast) copyoutMultiple := len(call.Copyout) > 1 || resCopyout && len(call.Copyout) > 0 if copyoutMultiple { fmt.Fprintf(w, " {") |
