aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/csource/csource.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-06-29 10:47:42 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-06-29 10:47:42 +0200
commit7b45fa115b57d0a6424c369483b320acfe6a1de7 (patch)
treefbc8b30b977926c3345509358bfdc76eaa2ca495 /pkg/csource/csource.go
parent1a3c2436df1f7c9c0271aad092558d943a0ee19e (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.go83
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, " {")