From 874c5754bb22dbf77d6b600ff91f0f4f1fc5073a Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 12 Oct 2015 10:16:57 +0200 Subject: initial commit --- prog/clone.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 prog/clone.go (limited to 'prog/clone.go') diff --git a/prog/clone.go b/prog/clone.go new file mode 100644 index 000000000..dd8e6e4db --- /dev/null +++ b/prog/clone.go @@ -0,0 +1,49 @@ +// Copyright 2015 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package prog + +func (p *Prog) Clone() *Prog { + p1 := new(Prog) + newargs := make(map[*Arg]*Arg) + for _, c := range p.Calls { + c1 := new(Call) + c1.Meta = c.Meta + c1.Ret = c.Ret.clone(c1, newargs) + for _, arg := range c.Args { + c1.Args = append(c1.Args, arg.clone(c1, newargs)) + } + p1.Calls = append(p1.Calls, c1) + } + if err := p1.validate(); err != nil { + panic(err) + } + return p1 +} + +func (arg *Arg) clone(c *Call, newargs map[*Arg]*Arg) *Arg { + arg1 := new(Arg) + *arg1 = *arg + arg1.Call = c + arg1.Data = append([]byte{}, arg.Data...) + switch arg.Kind { + case ArgPointer: + if arg.Res != nil { + arg1.Res = arg.Res.clone(c, newargs) + } + case ArgResult: + r := newargs[arg.Res] + arg1.Res = r + if r.Uses == nil { + r.Uses = make(map[*Arg]bool) + } + r.Uses[arg1] = true + } + arg1.Inner = nil + for _, arg2 := range arg.Inner { + arg1.Inner = append(arg1.Inner, arg2.clone(c, newargs)) + } + arg1.Uses = nil // filled when we clone the referent + newargs[arg] = arg1 + return arg1 +} -- cgit mrf-deployment