aboutsummaryrefslogtreecommitdiffstats
path: root/prog/analysis.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-02-19 19:35:04 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-02-19 21:48:20 +0100
commit75a7c5e2d1f09a4a58e7e1f1f4ef0b0f55a33413 (patch)
treed44c2457c44b53192005f0b89cd6633a2a2b0ff9 /prog/analysis.go
parent90fd6503136121e9494761a460898e83bc0b6b3e (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 'prog/analysis.go')
-rw-r--r--prog/analysis.go29
1 files changed, 14 insertions, 15 deletions
diff --git a/prog/analysis.go b/prog/analysis.go
index ea3a98dd0..c93a13e6c 100644
--- a/prog/analysis.go
+++ b/prog/analysis.go
@@ -12,17 +12,14 @@ import (
"fmt"
)
-const (
- maxPages = 4 << 10
-)
-
type state struct {
target *Target
ct *ChoiceTable
files map[string]bool
resources map[string][]Arg
strings map[string]bool
- pages [maxPages]bool
+ ma *memAlloc
+ va *vmaAlloc
}
// analyze analyzes the program p up to but not including call c.
@@ -44,12 +41,24 @@ func newState(target *Target, ct *ChoiceTable) *state {
files: make(map[string]bool),
resources: make(map[string][]Arg),
strings: make(map[string]bool),
+ ma: newMemAlloc(target.NumPages * target.PageSize),
+ va: newVmaAlloc(target.NumPages),
}
return s
}
func (s *state) analyze(c *Call) {
ForeachArg(c, func(arg Arg, _ *ArgCtx) {
+ switch a := arg.(type) {
+ case *PointerArg:
+ switch {
+ case a.IsNull():
+ case a.VmaSize != 0:
+ s.va.noteAlloc(a.Address/s.target.PageSize, a.VmaSize/s.target.PageSize)
+ default:
+ s.ma.noteAlloc(a.Address, a.Res.Size())
+ }
+ }
switch typ := arg.Type().(type) {
case *ResourceType:
if typ.Dir() != DirIn {
@@ -68,16 +77,6 @@ func (s *state) analyze(c *Call) {
}
}
})
- start, npages, mapped := s.target.AnalyzeMmap(c)
- if npages != 0 {
- if start+npages > uint64(len(s.pages)) {
- panic(fmt.Sprintf("address is out of bounds: page=%v len=%v bound=%v",
- start, npages, len(s.pages)))
- }
- for i := uint64(0); i < npages; i++ {
- s.pages[start+i] = mapped
- }
- }
}
type ArgCtx struct {