aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/csource/csource.go
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2021-10-08 11:50:11 +0000
committerDmitry Vyukov <dvyukov@google.com>2021-10-09 12:51:35 +0200
commit65c1bd6430f500cfdfea651ea482b761da215e69 (patch)
treeada3c80dab0c7b4fecfafe5f582920971dea747a /pkg/csource/csource.go
parentefe0f24dd913d90b2c6a2dbe7b8dac779c266144 (diff)
pkg/csource: fix call list filtering not being consistent
There is a bug in the current implementation that leads to csource using the original and the new call lists at the same time. That has led to a bunch of TestGenerate failures. Enforce the module only to use variables put into the csource context in order to avoid similar mistakes in the future.
Diffstat (limited to 'pkg/csource/csource.go')
-rw-r--r--pkg/csource/csource.go43
1 files changed, 23 insertions, 20 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go
index df5b60896..68f961526 100644
--- a/pkg/csource/csource.go
+++ b/pkg/csource/csource.go
@@ -47,20 +47,31 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
sysTarget: targets.Get(p.Target.OS, p.Target.Arch),
calls: make(map[string]uint64),
}
+ return ctx.generateSource()
+}
+
+type context struct {
+ p *prog.Prog
+ opts Options
+ target *prog.Target
+ sysTarget *targets.Target
+ calls map[string]uint64 // CallName -> NR
+}
+func (ctx *context) generateSource() ([]byte, error) {
ctx.filterCalls()
- calls, vars, err := ctx.generateProgCalls(ctx.p, opts.Trace)
+ calls, vars, err := ctx.generateProgCalls(ctx.p, ctx.opts.Trace)
if err != nil {
return nil, err
}
- mmapProg := p.Target.DataMmapProg()
+ mmapProg := ctx.p.Target.DataMmapProg()
mmapCalls, _, err := ctx.generateProgCalls(mmapProg, false)
if err != nil {
return nil, err
}
- for _, c := range append(mmapProg.Calls, p.Calls...) {
+ for _, c := range append(mmapProg.Calls, ctx.p.Calls...) {
ctx.calls[c.Meta.CallName] = c.Meta.NR
}
@@ -77,34 +88,34 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
}
sandboxFunc := "loop();"
- if opts.Sandbox != "" {
- sandboxFunc = "do_sandbox_" + opts.Sandbox + "();"
+ if ctx.opts.Sandbox != "" {
+ sandboxFunc = "do_sandbox_" + ctx.opts.Sandbox + "();"
}
replacements := map[string]string{
- "PROCS": fmt.Sprint(opts.Procs),
- "REPEAT_TIMES": fmt.Sprint(opts.RepeatTimes),
- "NUM_CALLS": fmt.Sprint(len(p.Calls)),
+ "PROCS": fmt.Sprint(ctx.opts.Procs),
+ "REPEAT_TIMES": fmt.Sprint(ctx.opts.RepeatTimes),
+ "NUM_CALLS": fmt.Sprint(len(ctx.p.Calls)),
"MMAP_DATA": strings.Join(mmapCalls, ""),
"SYSCALL_DEFINES": ctx.generateSyscallDefines(),
"SANDBOX_FUNC": sandboxFunc,
"RESULTS": varsBuf.String(),
"SYSCALLS": ctx.generateSyscalls(calls, len(vars) != 0),
}
- if !opts.Threaded && !opts.Repeat && opts.Sandbox == "" {
+ if !ctx.opts.Threaded && !ctx.opts.Repeat && ctx.opts.Sandbox == "" {
// This inlines syscalls right into main for the simplest case.
replacements["SANDBOX_FUNC"] = replacements["SYSCALLS"]
replacements["SYSCALLS"] = "unused"
}
- timeouts := ctx.sysTarget.Timeouts(opts.Slowdown)
+ timeouts := ctx.sysTarget.Timeouts(ctx.opts.Slowdown)
replacements["PROGRAM_TIMEOUT_MS"] = fmt.Sprint(int(timeouts.Program / time.Millisecond))
timeoutExpr := fmt.Sprint(int(timeouts.Syscall / time.Millisecond))
- for i, call := range p.Calls {
+ for i, call := range ctx.p.Calls {
if timeout := call.Meta.Attrs.Timeout; timeout != 0 {
timeoutExpr += fmt.Sprintf(" + (call == %v ? %v : 0)", i, timeout*uint64(timeouts.Scale))
}
}
replacements["CALL_TIMEOUT_MS"] = timeoutExpr
- result, err := createCommonHeader(p, mmapProg, replacements, opts)
+ result, err := createCommonHeader(ctx.p, mmapProg, replacements, ctx.opts)
if err != nil {
return nil, err
}
@@ -114,14 +125,6 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
return result, nil
}
-type context struct {
- p *prog.Prog
- opts Options
- target *prog.Target
- sysTarget *targets.Target
- calls map[string]uint64 // CallName -> NR
-}
-
// This is a kludge, but we keep it here until a better approach is implemented.
// TODO: untie syz_emit_ethernet/syz_extract_tcp_res and NetInjection. And also
// untie VhciInjection and syz_emit_vhci. Then we could remove this method.