예제 #1
0
        private bool TryComputeNAryExprs(IdentifierExpr id)
        {
            var toRemove = new HashSet <Expr>();

            foreach (var expr in this.ExpressionMap[id].Keys.ToList())
            {
                if (!(expr is NAryExpr))
                {
                    continue;
                }

                int ixs = 0;

                if (((expr as NAryExpr).Args[0] is IdentifierExpr) &&
                    ((expr as NAryExpr).Args[0] as IdentifierExpr).Name.StartsWith("$M."))
                {
                    toRemove.Add(expr);
                    continue;
                }

                if (PointerArithmeticAnalyser.ShouldSkipFromAnalysis(expr as NAryExpr))
                {
                    toRemove.Add(expr);
                    continue;
                }

                if (PointerArithmeticAnalyser.IsArithmeticExpression(expr as NAryExpr))
                {
                    toRemove.Add(expr);
                    continue;
                }

                Expr p = (expr as NAryExpr).Args[0];
                Expr i = (expr as NAryExpr).Args[1];
                Expr s = (expr as NAryExpr).Args[2];

                if (!(i is LiteralExpr && s is LiteralExpr))
                {
                    toRemove.Add(expr);
                    continue;
                }

                ixs = (i as LiteralExpr).asBigNum.ToInt * (s as LiteralExpr).asBigNum.ToInt;

                this.ExpressionMap[id].Add(p, this.ExpressionMap[id][expr] + ixs);
                toRemove.Add(expr);
            }

            foreach (var expr in toRemove)
            {
                this.ExpressionMap[id].Remove(expr);
            }

            if (this.ExpressionMap[id].Any(val => val.Key is NAryExpr))
            {
                return(false);
            }

            return(true);
        }
예제 #2
0
        /// <summary>
        /// Performs pointer analysis to identify and create unique locks.
        /// </summary>
        private void IdentifyAndCreateUniqueLocks()
        {
            var initialImpl = this.AC.GetImplementation(DeviceDriver.InitEntryPoint);

            foreach (var block in initialImpl.Blocks)
            {
                for (int idx = 0; idx < block.Cmds.Count; idx++)
                {
                    if (!(block.Cmds[idx] is CallCmd))
                    {
                        continue;
                    }
                    if (!(block.Cmds[idx] as CallCmd).callee.Contains("mutex_init") &&
                        !(block.Cmds[idx] as CallCmd).callee.Contains("spin_lock_init"))
                    {
                        continue;
                    }

                    Expr lockExpr = PointerArithmeticAnalyser.ComputeRootPointer(initialImpl,
                                                                                 block.Label, (block.Cmds[idx] as CallCmd).Ins[0]);

                    Lock newLock = new Lock(new Constant(Token.NoToken,
                                                         new TypedIdent(Token.NoToken, "lock$" + this.AC.Locks.Count,
                                                                        Microsoft.Boogie.Type.Int), true), lockExpr);

                    newLock.Id.AddAttribute("lock", new object[] { });
                    this.AC.TopLevelDeclarations.Add(newLock.Id);
                    this.AC.Locks.Add(newLock);
                }
            }

            foreach (var l in AnalysisContext.GlobalLocks)
            {
                if (!this.AC.Locks.Any(val => val.Id.Name.Equals(l.Id.Name)))
                {
                    this.AC.TopLevelDeclarations.Add(l.Id);
                    this.AC.Locks.Add(l);
                }
            }
        }
예제 #3
0
        private void ComputeMapsForIdentifierExpr(IdentifierExpr id)
        {
            if (PointerArithmeticAnalyser.Cache[this.EP][this.Implementation].ContainsKey(id))
            {
                return;
            }

            if (!this.ExpressionMap.ContainsKey(id))
            {
                this.ExpressionMap.Add(id, new Dictionary <Expr, int>());
            }
            if (!this.AssignmentMap.ContainsKey(id))
            {
                this.AssignmentMap.Add(id, new HashSet <Expr>());
            }
            if (!this.CallMap.ContainsKey(id))
            {
                this.CallMap.Add(id, new HashSet <CallCmd>());
            }

            foreach (var block in this.Implementation.Blocks)
            {
                for (int i = block.Cmds.Count - 1; i >= 0; i--)
                {
                    if (block.Cmds[i] is AssignCmd)
                    {
                        var assign = block.Cmds[i] as AssignCmd;
                        if (!assign.Lhss[0].DeepAssignedIdentifier.Name.Equals(id.Name))
                        {
                            continue;
                        }
                        if (this.AssignmentMap[id].Contains(assign.Rhss[0]))
                        {
                            continue;
                        }

                        var expr = assign.Rhss[0];
                        PointerArithmeticAnalyser.TryPerformCast(ref expr);
                        this.AssignmentMap[id].Add(expr);

                        if (expr.ToString().StartsWith("$pa("))
                        {
                            this.ExpressionMap[id].Add(expr, 0);
                        }
                        if (expr is IdentifierExpr && this.InParams.Any(val =>
                                                                        val.Name.Equals((expr as IdentifierExpr).Name)))
                        {
                            this.ExpressionMap[id].Add(expr, 0);
                        }
                        if (expr is IdentifierExpr && this.AC.TopLevelDeclarations.OfType <Constant>().
                            Any(val => val.Name.Equals((expr as IdentifierExpr).Name)))
                        {
                            this.ExpressionMap[id].Add(expr, 0);
                        }
                        if (expr is LiteralExpr)
                        {
                            this.ExpressionMap[id].Add(expr, 0);
                        }
                    }
                    else if (block.Cmds[i] is CallCmd)
                    {
                        var call = block.Cmds[i] as CallCmd;
                        if (call.callee.Equals("$alloca"))
                        {
                            if (!call.Outs[0].Name.Equals(id.Name))
                            {
                                continue;
                            }

                            this.CallMap[id].Add(call);
                        }
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Compute $pa(p, i, s) == p + i * s);
        /// </summary>
        /// <returns>The root pointer.</returns>
        /// <param name="impl">Implementation</param>
        /// <param name="label">Root block label</param>
        /// <param name="id">Identifier expression</param>
        public static Expr ComputeRootPointer(Implementation impl, string label, Expr id)
        {
            if (id is LiteralExpr)
            {
                return(id);
            }
            if (id is NAryExpr && (id as NAryExpr).Args.Count == 1 &&
                (id as NAryExpr).Fun.FunctionName.Equals("-"))
            {
                return(id);
            }

            NAryExpr root = PointerArithmeticAnalyser.GetPointerArithmeticExpr(impl, id) as NAryExpr;

            if (root == null)
            {
                return(id);
            }

            Expr result     = root;
            Expr resolution = result;
            int  ixs        = 0;

            var alreadyVisited = new HashSet <Tuple <string, Expr> >();

            do
            {
                if (result is NAryExpr)
                {
                    if (((result as NAryExpr).Args[0] is IdentifierExpr) &&
                        ((result as NAryExpr).Args[0] as IdentifierExpr).Name.StartsWith("$M."))
                    {
                        return(id);
                    }

                    if (PointerArithmeticAnalyser.TryPerformCast(ref result))
                    {
                        continue;
                    }

                    if (PointerArithmeticAnalyser.ShouldSkipFromAnalysis(result as NAryExpr))
                    {
                        return(id);
                    }

                    if (alreadyVisited.Any(v => v.Item1.Equals(label) && v.Item2.Equals(result)))
                    {
                        return(id);
                    }

                    alreadyVisited.Add(new Tuple <string, Expr>(label, result));

                    if (PointerArithmeticAnalyser.IsArithmeticExpression(result as NAryExpr))
                    {
                        return(id);
                    }

                    Expr p = (result as NAryExpr).Args[0];
                    Expr i = (result as NAryExpr).Args[1];
                    Expr s = (result as NAryExpr).Args[2];

                    if ((i is LiteralExpr) && (s is LiteralExpr))
                    {
                        ixs += (i as LiteralExpr).asBigNum.ToInt * (s as LiteralExpr).asBigNum.ToInt;
                    }
                    else
                    {
                        return(id);
                    }

                    result = p;
                }
                else
                {
                    resolution = PointerArithmeticAnalyser.GetPointerArithmeticExpr(impl, result);
                    if (resolution != null)
                    {
                        result = resolution;
                    }
                }
            }while (resolution != null);

            return(Expr.Add(result, new LiteralExpr(Token.NoToken, BigNum.FromInt(ixs))));
        }