aboutsummaryrefslogtreecommitdiff
path: root/prog/resources.go
diff options
context:
space:
mode:
Diffstat (limited to 'prog/resources.go')
-rw-r--r--prog/resources.go62
1 files changed, 44 insertions, 18 deletions
diff --git a/prog/resources.go b/prog/resources.go
index d935beb7a..08002ec27 100644
--- a/prog/resources.go
+++ b/prog/resources.go
@@ -14,33 +14,59 @@ var timespecRes = &ResourceDesc{
Kind: []string{"timespec"},
}
-func (target *Target) calcResourceCtors(kind []string, precise bool) []*Syscall {
- // Find calls that produce the necessary resources.
+func (target *Target) calcResourceCtors(res *ResourceDesc, precise bool) []*Syscall {
var metas []*Syscall
- for _, meta := range target.Syscalls {
- // Recurse into arguments to see if there is an out/inout arg of necessary type.
- ok := false
+ for _, ctor := range res.Ctors {
+ if !precise || ctor.Precise {
+ metas = append(metas, target.Syscalls[ctor.Call])
+ }
+ }
+ if res.Kind[0] == timespecRes.Name {
+ if c := target.SyscallMap["clock_gettime"]; c != nil {
+ metas = append(metas, c)
+ }
+ }
+ return metas
+}
+
+func (target *Target) populateResourceCtors() {
+ // Find resources that are created by each call.
+ callsResources := make([][]*ResourceDesc, len(target.Syscalls))
+ for call, meta := range target.Syscalls {
ForeachType(meta, func(typ Type) {
- if ok {
- return
- }
switch typ1 := typ.(type) {
case *ResourceType:
- if typ1.Dir() != DirIn && isCompatibleResourceImpl(kind, typ1.Desc.Kind, precise) {
- ok = true
+ if typ1.Dir() != DirIn {
+ callsResources[call] = append(callsResources[call], typ1.Desc)
}
}
})
- if ok {
- metas = append(metas, meta)
- }
}
- if kind[0] == timespecRes.Name {
- if c := target.SyscallMap["clock_gettime"]; c != nil {
- metas = append(metas, c)
+
+ // Populate resource ctors accounting for resource compatibility.
+ for _, res := range target.Resources {
+ for call, callResources := range callsResources {
+ preciseOk := false
+ impreciseOk := false
+ for _, callRes := range callResources {
+ if preciseOk && impreciseOk {
+ break
+ }
+ if isCompatibleResourceImpl(res.Kind, callRes.Kind, true) {
+ preciseOk = true
+ }
+ if isCompatibleResourceImpl(res.Kind, callRes.Kind, false) {
+ impreciseOk = true
+ }
+ }
+ if preciseOk {
+ res.Ctors = append(res.Ctors, ResourceCtor{call, true})
+ }
+ if impreciseOk {
+ res.Ctors = append(res.Ctors, ResourceCtor{call, false})
+ }
}
}
- return metas
}
// isCompatibleResource returns true if resource of kind src can be passed as an argument of kind dst.
@@ -172,7 +198,7 @@ func (target *Target) TransitivelyEnabledCalls(enabled map[*Syscall]bool) (map[*
}
if ctors[res.Name] == nil {
var names []string
- for _, call := range target.calcResourceCtors(res.Kind, true) {
+ for _, call := range target.calcResourceCtors(res, true) {
names = append(names, call.Name)
}
ctors[res.Name] = names