From ae2f24aa70517d79d364a7202e070f2de6fd4451 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 1 Aug 2018 20:33:33 +0200 Subject: prog: refactor calcStaticPriorities Factor out several helper functions. Update #538 --- prog/prio.go | 94 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 44 deletions(-) (limited to 'prog/prio.go') diff --git a/prog/prio.go b/prog/prio.go index 35eb6e9d9..0e726f702 100644 --- a/prog/prio.go +++ b/prog/prio.go @@ -36,25 +36,48 @@ func (target *Target) CalculatePriorities(corpus []*Prog) [][]float32 { } func (target *Target) calcStaticPriorities() [][]float32 { - uses := make(map[string]map[int]float32) - for _, c := range target.Syscalls { - noteUsage := func(weight float32, str string, args ...interface{}) { - id := fmt.Sprintf(str, args...) - if uses[id] == nil { - uses[id] = make(map[int]float32) + uses := target.calcResourceUsage() + prios := make([][]float32, len(target.Syscalls)) + for i := range prios { + prios[i] = make([]float32, len(target.Syscalls)) + } + for _, calls := range uses { + for c0, w0 := range calls { + for c1, w1 := range calls { + if c0 == c1 { + // Self-priority is assigned below. + continue + } + prios[c0][c1] += w0 * w1 } - old := uses[id][c.ID] - if weight > old { - uses[id][c.ID] = weight + } + } + + // Self-priority (call wrt itself) is assigned to the maximum priority + // this call has wrt other calls. This way the priority is high, but not too high. + for c0, pp := range prios { + var max float32 + for _, p := range pp { + if max < p { + max = p } } + pp[c0] = max + } + normalizePrio(prios) + return prios +} + +func (target *Target) calcResourceUsage() map[string]map[int]float32 { + uses := make(map[string]map[int]float32) + for _, c := range target.Syscalls { ForeachType(c, func(t Type) { switch a := t.(type) { case *ResourceType: if a.Desc.Name == "pid" || a.Desc.Name == "uid" || a.Desc.Name == "gid" { // Pid/uid/gid usually play auxiliary role, // but massively happen in some structs. - noteUsage(0.1, "res%v", a.Desc.Name) + noteUsage(uses, c, 0.1, "res%v", a.Desc.Name) } else { str := "res" for i, k := range a.Desc.Kind { @@ -63,33 +86,33 @@ func (target *Target) calcStaticPriorities() [][]float32 { if i < len(a.Desc.Kind)-1 { w = 0.2 } - noteUsage(float32(w), str) + noteUsage(uses, c, float32(w), str) } } case *PtrType: if _, ok := a.Type.(*StructType); ok { - noteUsage(1.0, "ptrto-%v", a.Type.Name()) + noteUsage(uses, c, 1.0, "ptrto-%v", a.Type.Name()) } if _, ok := a.Type.(*UnionType); ok { - noteUsage(1.0, "ptrto-%v", a.Type.Name()) + noteUsage(uses, c, 1.0, "ptrto-%v", a.Type.Name()) } if arr, ok := a.Type.(*ArrayType); ok { - noteUsage(1.0, "ptrto-%v", arr.Type.Name()) + noteUsage(uses, c, 1.0, "ptrto-%v", arr.Type.Name()) } case *BufferType: switch a.Kind { case BufferBlobRand, BufferBlobRange, BufferText: case BufferString: if a.SubKind != "" { - noteUsage(0.2, fmt.Sprintf("str-%v", a.SubKind)) + noteUsage(uses, c, 0.2, fmt.Sprintf("str-%v", a.SubKind)) } case BufferFilename: - noteUsage(1.0, "filename") + noteUsage(uses, c, 1.0, "filename") default: panic("unknown buffer kind") } case *VmaType: - noteUsage(0.5, "vma") + noteUsage(uses, c, 0.5, "vma") case *IntType: switch a.Kind { case IntPlain, IntFileoff, IntRange: @@ -99,35 +122,18 @@ func (target *Target) calcStaticPriorities() [][]float32 { } }) } - prios := make([][]float32, len(target.Syscalls)) - for i := range prios { - prios[i] = make([]float32, len(target.Syscalls)) - } - for _, calls := range uses { - for c0, w0 := range calls { - for c1, w1 := range calls { - if c0 == c1 { - // Self-priority is assigned below. - continue - } - prios[c0][c1] += w0 * w1 - } - } - } + return uses +} - // Self-priority (call wrt itself) is assigned to the maximum priority - // this call has wrt other calls. This way the priority is high, but not too high. - for c0, pp := range prios { - var max float32 - for _, p := range pp { - if max < p { - max = p - } - } - pp[c0] = max +func noteUsage(uses map[string]map[int]float32, c *Syscall, weight float32, str string, args ...interface{}) { + id := fmt.Sprintf(str, args...) + if uses[id] == nil { + uses[id] = make(map[int]float32) + } + old := uses[id][c.ID] + if weight > old { + uses[id][c.ID] = weight } - normalizePrio(prios) - return prios } func (target *Target) calcDynamicPrio(corpus []*Prog) [][]float32 { -- cgit mrf-deployment