Exemplo n.º 1
0
        /// <summary>
        /// Performs pointer alias analysis to identify and instrument functions with locks.
        /// </summary>
        /// <param name="impl">Implementation</param>
        /// <param name="ins">Optional list of expressions</param>
        private void AnalyseAndInstrumentLocks(Implementation impl, List <Expr> inPtrs = null)
        {
            if (this.AlreadyRefactoredFunctions.Contains(impl))
            {
                return;
            }
            this.AlreadyRefactoredFunctions.Add(impl);

            foreach (var block in impl.Blocks)
            {
                foreach (var cmd in block.Cmds)
                {
                    if (cmd is CallCmd)
                    {
                        CallCmd call = cmd as CallCmd;

                        if (Utilities.ShouldSkipFromAnalysis(call))
                        {
                            continue;
                        }

                        if (call.callee.Contains("pm_runtime_get_sync") ||
                            call.callee.Contains("pm_runtime_get_noresume") ||
                            call.callee.Contains("pm_runtime_put_sync") ||
                            call.callee.Contains("pm_runtime_put_noidle"))
                        {
                            this.EP.IsCallingPowerLock = true;
                            continue;
                        }
                        else if (call.callee.Contains("ASSERT_RTNL"))
                        {
                            this.EP.IsCallingRtnlLock = true;
                            continue;
                        }
                        else if (call.callee.Contains("netif_device_attach"))
                        {
                            if (!this.EP.IsNetLocked)
                            {
                                this.EP.IsCallingNetLock = true;
                            }
                            continue;
                        }
                        else if (call.callee.Contains("netif_device_detach"))
                        {
                            if (!this.EP.IsNetLocked)
                            {
                                this.EP.IsCallingNetLock = true;
                            }
                            continue;
                        }
                        else if (call.callee.Contains("netif_stop_queue"))
                        {
                            if (!this.EP.IsTxLocked)
                            {
                                this.EP.IsCallingTxLock = true;
                            }
                            continue;
                        }

                        if (call.callee.Contains("mutex_lock") ||
                            call.callee.Contains("mutex_lock_interruptible") ||
                            call.callee.Contains("mutex_unlock") ||
                            call.callee.Contains("spin_lock") ||
                            call.callee.Contains("spin_lock_irqsave") ||
                            call.callee.Contains("spin_unlock") ||
                            call.callee.Contains("spin_unlock_irqrestore"))
                        {
                            var lockExpr = PointerArithmeticAnalyser.ComputeRootPointer(impl, block.Label, call.Ins[0]);
                            if (inPtrs != null && (!(lockExpr is LiteralExpr) || (lockExpr is NAryExpr)))
                            {
                                if (lockExpr is IdentifierExpr)
                                {
                                    for (int i = 0; i < impl.InParams.Count; i++)
                                    {
                                        if (lockExpr.ToString().Equals(impl.InParams[i].ToString()))
                                        {
                                            lockExpr = inPtrs[i];
                                        }
                                    }
                                }
                                else if (lockExpr is NAryExpr)
                                {
                                    for (int i = 0; i < (lockExpr as NAryExpr).Args.Count; i++)
                                    {
                                        for (int j = 0; j < impl.InParams.Count; j++)
                                        {
                                            if ((lockExpr as NAryExpr).Args[i].ToString().Equals(impl.InParams[j].ToString()))
                                            {
                                                (lockExpr as NAryExpr).Args[i] = inPtrs[j];
                                            }
                                        }
                                    }
                                }

                                lockExpr = PointerArithmeticAnalyser.ComputeLiteralsInExpr(lockExpr);
                            }

                            bool matched = false;
                            foreach (var l in this.AC.Locks)
                            {
                                if (l.IsEqual(this.AC, this.Implementation, lockExpr))
                                {
                                    call.Ins[0] = new IdentifierExpr(l.Id.tok, l.Id);
                                    matched     = true;
                                    break;
                                }
                            }

                            if (!matched && this.AC.GetConstant(lockExpr.ToString()) != null)
                            {
                                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);
                                AnalysisContext.GlobalLocks.Add(newLock);

                                call.Ins[0] = new IdentifierExpr(newLock.Id.tok, newLock.Id);
                                matched     = true;
                            }

                            if (!matched && this.AC.Locks.FindAll(val => !val.IsKernelSpecific).Count == 1)
                            {
                                var l = this.AC.Locks.Find(val => !val.IsKernelSpecific);
                                call.Ins[0] = new IdentifierExpr(l.Id.tok, l.Id);
                            }
                            else if (!matched)
                            {
                                call.Ins[0] = lockExpr;
                            }
                        }
                        else if (!this.ShouldSkip(call.callee))
                        {
                            List <Expr> computedRootPointers = new List <Expr>();
                            foreach (var inParam in call.Ins)
                            {
                                if (inParam is NAryExpr)
                                {
                                    computedRootPointers.Add(inParam);
                                }
                                else
                                {
                                    Expr ptrExpr = PointerArithmeticAnalyser.ComputeRootPointer(impl, block.Label, inParam);
                                    computedRootPointers.Add(ptrExpr);
                                }
                            }

                            this.AnalyseAndInstrumentLocksInCall(call, computedRootPointers);
                        }
                    }
                    else if (cmd is AssignCmd)
                    {
                        this.AnalyseAndInstrumentLocksInAssign(cmd as AssignCmd);
                    }
                }
            }
        }
Exemplo n.º 2
0
        private void CreateInParamMatcher(Implementation impl1, Implementation impl2)
        {
            var         initFunc = this.AC.Checker;
            List <Expr> insEp1   = new List <Expr>();
            List <Expr> insEp2   = new List <Expr>();

            string name1 = null;

            if (this.EP1.IsClone &&
                (this.EP1.IsCalledWithNetworkDisabled || this.EP1.IsGoingToDisableNetwork))
            {
                name1 = impl1.Name.Remove(impl1.Name.IndexOf("#net"));
            }
            else
            {
                name1 = impl1.Name;
            }

            string name2 = null;

            if (this.EP2.IsClone &&
                (this.EP2.IsCalledWithNetworkDisabled || this.EP2.IsGoingToDisableNetwork))
            {
                name2 = impl2.Name.Remove(impl2.Name.IndexOf("#net"));
            }
            else
            {
                name2 = impl2.Name;
            }

            foreach (Block block in initFunc.Blocks)
            {
                foreach (CallCmd call in block.Cmds.OfType <CallCmd>())
                {
                    if (call.callee.Equals(name1))
                    {
                        foreach (var inParam in call.Ins)
                        {
                            Expr resolved = PointerArithmeticAnalyser.GetPointerArithmeticExpr(initFunc, inParam);

                            if (resolved == null)
                            {
                                insEp1.Add(inParam);
                            }
                            else
                            {
                                insEp1.Add(resolved);
                            }
                        }
                    }

                    if (call.callee.Equals(name2))
                    {
                        foreach (var inParam in call.Ins)
                        {
                            Expr resolved = PointerArithmeticAnalyser.GetPointerArithmeticExpr(initFunc, inParam);

                            if (resolved == null)
                            {
                                insEp2.Add(inParam);
                            }
                            else
                            {
                                insEp2.Add(resolved);
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < insEp2.Count; i++)
            {
                for (int j = 0; j < insEp1.Count; j++)
                {
                    if (insEp2[i].ToString().Equals(insEp1[j].ToString()))
                    {
                        if (this.InParamMatcher.ContainsKey(i))
                        {
                            continue;
                        }
                        this.InParamMatcher.Add(i, impl1.InParams[j]);
                    }
                }
            }
        }