diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-02-19 19:35:04 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-02-19 21:48:20 +0100 |
| commit | 75a7c5e2d1f09a4a58e7e1f1f4ef0b0f55a33413 (patch) | |
| tree | d44c2457c44b53192005f0b89cd6633a2a2b0ff9 /pkg/csource/csource.go | |
| parent | 90fd6503136121e9494761a460898e83bc0b6b3e (diff) | |
prog: rework address allocation
1. mmap all memory always, without explicit mmap calls in the program.
This makes lots of things much easier and removes lots of code.
Makes mmap not a special syscall and allows to fuzz without mmap enabled.
2. Change address assignment algorithm.
Current algorithm allocates unmapped addresses too frequently
and allows collisions between arguments of a single syscall.
The new algorithm analyzes actual allocations in the program
and places new arguments at unused locations.
Diffstat (limited to 'pkg/csource/csource.go')
| -rw-r--r-- | pkg/csource/csource.go | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index bede09122..5c1b0208e 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -26,7 +26,19 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { w: new(bytes.Buffer), calls: make(map[string]uint64), } - for _, c := range p.Calls { + + calls, nvar, err := ctx.generateProgCalls(ctx.p) + if err != nil { + return nil, err + } + + mmapProg := p.Target.GenerateUberMmapProg() + mmapCalls, _, err := ctx.generateProgCalls(mmapProg) + if err != nil { + return nil, err + } + + for _, c := range append(mmapProg.Calls, p.Calls...) { ctx.calls[c.Meta.CallName] = c.Meta.NR } @@ -41,16 +53,6 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.generateSyscallDefines() - exec := make([]byte, prog.ExecBufferSize) - progSize, err := ctx.p.SerializeForExec(exec) - if err != nil { - return nil, fmt.Errorf("failed to serialize program: %v", err) - } - decoded, err := ctx.target.DeserializeExec(exec[:progSize]) - if err != nil { - return nil, err - } - calls, nvar := ctx.generateCalls(decoded) if nvar != 0 { ctx.printf("long r[%v];\n", nvar) } @@ -62,6 +64,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.generateTestFunc(calls, nvar, "loop") ctx.print("int main()\n{\n") + for _, c := range mmapCalls { + ctx.printf("%s", c) + } if opts.HandleSegv { ctx.printf("\tinstall_segv_handler();\n") } @@ -83,6 +88,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.generateTestFunc(calls, nvar, "test") if opts.Procs <= 1 { ctx.print("int main()\n{\n") + for _, c := range mmapCalls { + ctx.printf("%s", c) + } if opts.HandleSegv { ctx.print("\tinstall_segv_handler();\n") } @@ -108,6 +116,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.print("\t}\n}\n") } else { ctx.print("int main()\n{\n") + for _, c := range mmapCalls { + ctx.printf("%s", c) + } if opts.UseTmpDir { ctx.print("\tchar *cwd = get_current_dir_name();\n") } @@ -254,6 +265,20 @@ func (ctx *context) generateSyscallDefines() { ctx.printf("\n") } +func (ctx *context) generateProgCalls(p *prog.Prog) ([]string, uint64, error) { + exec := make([]byte, prog.ExecBufferSize) + progSize, err := p.SerializeForExec(exec) + if err != nil { + return nil, 0, fmt.Errorf("failed to serialize program: %v", err) + } + decoded, err := ctx.target.DeserializeExec(exec[:progSize]) + if err != nil { + return nil, 0, err + } + calls, nvar := ctx.generateCalls(decoded) + return calls, nvar, nil +} + func (ctx *context) generateCalls(p prog.ExecProg) ([]string, uint64) { var calls []string csumSeq := 0 |
