Example #1
0
        private void InstrumentWriteAccessInvariantsInEntryPointRegion(InstrumentationRegion region)
        {
            foreach (var pair in region.GetResourceAccesses())
            {
                var waVars = base.WriteAccessCheckingVariables.FindAll(val =>
                                                                       val.Name.Contains(pair.Key + "_$"));

                if (this.EP.ForceWriteResource.Contains(pair.Key))
                {
                    continue;
                }
                if (!this.EP.HasWriteAccess.ContainsKey(pair.Key))
                {
                    foreach (var variable in waVars)
                    {
                        base.InstrumentEnsures(region, variable, false);
                        foreach (var block in region.LoopHeaders())
                        {
                            base.InstrumentAssert(block, variable, false);
                        }
                    }

                    continue;
                }

                Expr nonWatchedExpr = null;
                foreach (var watchedVar in base.AccessWatchdogConstants)
                {
                    if (!watchedVar.Name.EndsWith(pair.Key))
                    {
                        continue;
                    }

                    foreach (var access in pair.Value)
                    {
                        var watchedExpr = Expr.Eq(new IdentifierExpr(watchedVar.tok, watchedVar), access);

                        foreach (var variable in waVars)
                        {
                            base.InstrumentImpliesEnsuresCandidate(region, watchedExpr, variable, false, true);
                            foreach (var block in region.LoopHeaders())
                            {
                                base.InstrumentImpliesAssertCandidate(block, watchedExpr, variable, false, true);
                            }
                        }

                        if (nonWatchedExpr == null)
                        {
                            nonWatchedExpr = Expr.Neq(new IdentifierExpr(watchedVar.tok, watchedVar), access);
                        }
                        else
                        {
                            nonWatchedExpr = Expr.And(nonWatchedExpr,
                                                      Expr.Neq(new IdentifierExpr(watchedVar.tok, watchedVar), access));
                        }
                    }
                }

                foreach (var variable in waVars)
                {
                    base.InstrumentImpliesEnsuresCandidate(region, nonWatchedExpr, variable, false, true);
                    foreach (var block in region.LoopHeaders())
                    {
                        base.InstrumentImpliesAssertCandidate(block, nonWatchedExpr, variable, false, true);
                    }
                }
            }
        }
        private bool AnalyseCallAccessesInRegion(InstrumentationRegion region)
        {
            int preCount   = 0;
            int afterCount = 0;

            foreach (var r in region.GetResourceAccesses())
            {
                preCount = preCount + r.Value.Count;
            }

            foreach (var call in region.CallInformation.Keys)
            {
                var calleeRegion = this.AC.InstrumentationRegions.Find(val =>
                                                                       val.Implementation().Name.Equals(call.callee));
                if (calleeRegion.IsNotAccessingResources)
                {
                    continue;
                }

                foreach (var r in calleeRegion.GetResourceAccesses())
                {
                    if (!region.ExternallyReceivedAccesses[call].ContainsKey(r.Key))
                    {
                        region.ExternallyReceivedAccesses[call].Add(r.Key, new HashSet <Expr>());
                    }

                    foreach (var a in r.Value)
                    {
                        if (region.ExternallyReceivedAccesses[call][r.Key].Contains(a))
                        {
                            continue;
                        }

                        int index;
                        if (a is NAryExpr)
                        {
                            index = this.TryGetArgumentIndex(call, calleeRegion, (a as NAryExpr).Args[0]);
                        }
                        else
                        {
                            index = this.TryGetArgumentIndex(call, calleeRegion, a);
                        }
                        if (index < 0)
                        {
                            continue;
                        }

                        if (!region.CallInformation[call].ContainsKey(index))
                        {
                            continue;
                        }

                        var calleeExpr   = region.CallInformation[call][index];
                        var computedExpr = this.ComputeExpr(calleeExpr.Item1, a);

                        var id = this.PtrAnalysisCache[region].GetIdentifier(computedExpr);
                        if (this.PtrAnalysisCache[region].IsAxiom(id))
                        {
                            if (!this.AC.AxiomAccessesMap.ContainsKey(r.Key))
                            {
                                this.AC.AxiomAccessesMap.Add(r.Key, new HashSet <Expr>());
                            }
                            if (!this.AC.AxiomAccessesMap[r.Key].Any(val =>
                                                                     val.ToString().Equals(computedExpr.ToString())))
                            {
                                this.AC.AxiomAccessesMap[r.Key].Add(computedExpr);
                            }
                        }
                        else
                        {
                            region.TryAddResourceAccess(r.Key, computedExpr);
                            region.ExternallyReceivedAccesses[call][r.Key].Add(a);
                        }
                    }
                }

                if (WhoopCommandLineOptions.Get().OptimiseHeavyAsyncCalls&&
                    (this.AC.GetNumOfEntryPointRelatedFunctions(this.EP.Name) >
                     WhoopCommandLineOptions.Get().EntryPointFunctionCallComplexity))
                {
                    continue;
                }

                foreach (var pair in region.GetResourceAccesses())
                {
                    foreach (var access in pair.Value)
                    {
                        foreach (var index in region.CallInformation[call].Keys)
                        {
                            if (!region.CallInformation[call].ContainsKey(index))
                            {
                                continue;
                            }

                            var calleeExpr = region.CallInformation[call][index];
                            var mappedExpr = this.ComputeMappedExpr(access, calleeExpr.Item1, calleeExpr.Item2);

                            if (mappedExpr != null)
                            {
                                this.CacheMatchedAccesses(pair.Key, access, mappedExpr);
                                if (calleeRegion.TryAddExternalResourceAccesses(pair.Key, mappedExpr))
                                {
                                    afterCount++;
                                }
                            }
                        }
                    }
                }
            }

            foreach (var r in region.GetResourceAccesses())
            {
                afterCount = afterCount + r.Value.Count;
            }

            if (preCount != afterCount)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Example #3
0
        private void InstrumentInParamAliasInformationInRegion(InstrumentationRegion region)
        {
            if (region.Procedure().InParams.Count <= 1)
            {
                return;
            }

            var inParamMap = new Dictionary <string, Dictionary <Variable, int> >();

            foreach (var resource in region.GetResourceAccesses())
            {
                if (!inParamMap.ContainsKey(resource.Key))
                {
                    inParamMap.Add(resource.Key, new Dictionary <Variable, int>());
                }

                foreach (var access in resource.Value)
                {
                    IdentifierExpr id  = null;
                    var            num = 0;

                    if (access is NAryExpr)
                    {
                        id  = (access as NAryExpr).Args[0] as IdentifierExpr;
                        num = ((access as NAryExpr).Args[1] as LiteralExpr).asBigNum.ToInt;
                    }
                    else if (access is IdentifierExpr)
                    {
                        id = access as IdentifierExpr;
                    }

                    if (id == null)
                    {
                        continue;
                    }

                    var inParam = region.Procedure().InParams.Find(val => val.Name.Equals(id.Name));
                    if (inParam == null)
                    {
                        continue;
                    }

                    if (!inParamMap[resource.Key].ContainsKey(inParam))
                    {
                        inParamMap[resource.Key].Add(inParam, num);
                    }
                    else if (inParamMap[resource.Key][inParam] < num)
                    {
                        inParamMap[resource.Key][inParam] = num;
                    }
                }
            }

            foreach (var resource in inParamMap)
            {
                if (resource.Value.Count <= 1)
                {
                    continue;
                }

                var pairs = resource.Value.ToList();
                for (int i = 0; i < pairs.Count - 1; i++)
                {
                    for (int j = i + 1; j < pairs.Count; j++)
                    {
                        var id1  = new IdentifierExpr(pairs[i].Key.tok, pairs[i].Key);
                        var id2  = new IdentifierExpr(pairs[j].Key.tok, pairs[j].Key);
                        var num1 = new LiteralExpr(Token.NoToken, BigNum.FromInt(pairs[i].Value));
                        var num2 = new LiteralExpr(Token.NoToken, BigNum.FromInt(pairs[j].Value));

                        var lexpr = Expr.Lt(new NAryExpr(Token.NoToken, new BinaryOperator(Token.NoToken,
                                                                                           BinaryOperator.Opcode.Add), new List <Expr> {
                            id1, num1
                        }), id2);
                        var rexpr = Expr.Lt(new NAryExpr(Token.NoToken, new BinaryOperator(Token.NoToken,
                                                                                           BinaryOperator.Opcode.Add), new List <Expr> {
                            id2, num2
                        }), id1);

                        if (!this.InstrumentAssumes(region, id1, id2, num1, num2))
                        {
                            this.RequiresMap.Clear();
                            this.AssumesMap.Clear();
                            return;
                        }

                        if (!this.RequiresMap.ContainsKey(region))
                        {
                            this.RequiresMap.Add(region, new HashSet <Requires>());
                        }
                        this.RequiresMap[region].Add(new Requires(false, Expr.Or(lexpr, rexpr)));
                    }
                }
            }
        }
        private bool IdentifyCallAccessesInRegion(InstrumentationRegion region)
        {
            int numberOfCalls           = 0;
            int numberOfNonCheckedCalls = 0;

            foreach (var block in region.Implementation().Blocks)
            {
                for (int idx = 0; idx < block.Cmds.Count; idx++)
                {
                    if (!(block.Cmds[idx] is CallCmd))
                    {
                        continue;
                    }

                    var  call = block.Cmds[idx] as CallCmd;
                    bool isInstrumentedCall = false;

                    if (idx + 1 < block.Cmds.Count && block.Cmds[idx + 1] is AssumeCmd)
                    {
                        isInstrumentedCall = QKeyValue.FindStringAttribute((block.Cmds[idx + 1]
                                                                            as AssumeCmd).Attributes, "captureState") != null;
                    }

                    if (!isInstrumentedCall)
                    {
                        numberOfCalls++;

                        var calleeRegion = this.AC.InstrumentationRegions.Find(val =>
                                                                               val.Implementation().Name.Equals(call.callee));
                        if (calleeRegion == null)
                        {
                            numberOfNonCheckedCalls++;
                            continue;
                        }

                        if (calleeRegion.GetResourceAccesses().Count == 0 &&
                            calleeRegion.IsNotAccessingResources)
                        {
                            numberOfNonCheckedCalls++;
                            continue;
                        }

                        if (!region.CallInformation.ContainsKey(call))
                        {
                            region.CallInformation.Add(call, new Dictionary <int, Tuple <Expr, Expr> >());
                            region.ExternallyReceivedAccesses.Add(call, new Dictionary <string, HashSet <Expr> >());

                            for (int i = 0; i < call.Ins.Count; i++)
                            {
                                var id = calleeRegion.Implementation().InParams[i];

                                HashSet <Expr> ptrExprs = null;
                                this.PtrAnalysisCache[region].TryComputeRootPointers(call.Ins[i], out ptrExprs);
                                foreach (var ptrExpr in ptrExprs)
                                {
                                    region.CallInformation[call].Add(i, new Tuple <Expr, Expr>(ptrExpr, new IdentifierExpr(id.tok, id)));
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            if (numberOfCalls == numberOfNonCheckedCalls &&
                region.HasWriteAccess.Count == 0 &&
                this.EP.ForceWriteResource.Count == 0)
            {
                this.CleanUpWriteInRegion(region);
                region.IsNotWriteAccessingResources = true;
            }

            if (numberOfCalls == numberOfNonCheckedCalls &&
                region.HasReadAccess.Count == 0 &&
                this.EP.ForceReadResource.Count == 0)
            {
                this.CleanUpReadInRegion(region);
                region.IsNotReadAccessingResources = true;
            }

            if (numberOfCalls == numberOfNonCheckedCalls &&
                region.GetResourceAccesses().Count == 0 &&
                this.EP.ForceWriteResource.Count == 0 &&
                this.EP.ForceReadResource.Count == 0)
            {
                this.CleanUpRegion(region);
                region.IsNotAccessingResources = true;
                return(false);
            }

            return(true);
        }
Example #5
0
        private void InstrumentMemoryLocksetInvariantsInRegion(InstrumentationRegion region)
        {
            foreach (var pair in region.GetResourceAccesses())
            {
                var memLsVars = base.MemoryLocksetVariables.FindAll(val =>
                                                                    val.Name.Contains(pair.Key + "_$"));

                if (this.EP.ForceWriteResource.Contains(pair.Key) ||
                    this.EP.ForceReadResource.Contains(pair.Key))
                {
                    continue;
                }
                if (!this.EP.HasWriteAccess.ContainsKey(pair.Key) &&
                    !this.EP.HasReadAccess.ContainsKey(pair.Key))
                {
                    foreach (var variable in memLsVars)
                    {
                        base.InstrumentRequires(region, variable, true);
                        base.InstrumentEnsures(region, variable, true);
                        foreach (var block in region.LoopHeaders())
                        {
                            base.InstrumentAssert(block, variable, true);
                        }
                    }

                    continue;
                }

                Expr nonWatchedExpr = null;
                foreach (var watchedVar in base.AccessWatchdogConstants)
                {
                    if (!watchedVar.Name.EndsWith(pair.Key))
                    {
                        continue;
                    }

                    foreach (var access in pair.Value)
                    {
                        var watchedExpr = Expr.Eq(new IdentifierExpr(watchedVar.tok, watchedVar), access);

                        foreach (var variable in memLsVars)
                        {
                            if (this.ShouldLock(region, variable))
                            {
                                continue;
                            }

                            base.InstrumentImpliesRequiresCandidate(region, watchedExpr, variable, true, true);
                            base.InstrumentImpliesEnsuresCandidate(region, watchedExpr, variable, true, true);

                            foreach (var block in region.LoopHeaders())
                            {
                                base.InstrumentImpliesAssertCandidate(block, watchedExpr, variable, true, true);
                            }
                        }

                        if (nonWatchedExpr == null)
                        {
                            nonWatchedExpr = Expr.Neq(new IdentifierExpr(watchedVar.tok, watchedVar), access);
                        }
                        else
                        {
                            nonWatchedExpr = Expr.And(nonWatchedExpr,
                                                      Expr.Neq(new IdentifierExpr(watchedVar.tok, watchedVar), access));
                        }
                    }
                }

                var lockVars = new HashSet <Variable>();
                foreach (var variable in memLsVars)
                {
                    if (this.ShouldLock(region, variable))
                    {
                        lockVars.Add(variable);
                        continue;
                    }

                    base.InstrumentImpliesRequiresCandidate(region, nonWatchedExpr, variable, true, true);
                    base.InstrumentImpliesEnsuresCandidate(region, nonWatchedExpr, variable, true, true);
                    foreach (var block in region.LoopHeaders())
                    {
                        base.InstrumentImpliesAssertCandidate(block, nonWatchedExpr, variable, true, true);
                    }
                }

                foreach (var lockVar in lockVars)
                {
                    base.InstrumentRequires(region, lockVar, true);
                    base.InstrumentEnsures(region, lockVar, true);
                    foreach (var block in region.LoopHeaders())
                    {
                        base.InstrumentAssert(block, lockVar, true);
                    }
                }
            }
        }