Beispiel #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 (PointerAnalysis.ShouldSkipFromAnalysis(expr as NAryExpr))
                {
                    toRemove.Add(expr);
                    continue;
                }

                if (PointerAnalysis.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);
        }
Beispiel #2
0
        /// <summary>
        /// Performs an analysis to identify lock creation.
        /// </summary>
        /// <param name="parent">Thread</param>
        /// <param name="child">Thread</param>
        /// <param name="impl">Implementation</param>
        /// <param name="ins">Optional list of expressions</param>
        private void IdentifyLockCreationInImplementation(Thread parent, Implementation impl, List <Expr> inPtrs = null)
        {
            if (this.AlreadyAnalyzedImplementations.Contains(impl))
            {
                return;
            }
            this.AlreadyAnalyzedImplementations.Add(impl);

            foreach (var block in impl.Blocks)
            {
                foreach (var cmd in block.Cmds)
                {
                    if (cmd is CallCmd)
                    {
                        CallCmd call = cmd as CallCmd;
                        if (call.callee.Equals("pthread_mutex_init"))
                        {
                            var exprs    = new HashSet <Expr>();
                            var result   = new PointerAnalysis(this.AC, impl).GetPointerOrigins(call.Ins[0], out exprs);
                            var lockExpr = exprs.FirstOrDefault();

                            if (result != PointerAnalysis.ResultType.Allocated &&
                                result != PointerAnalysis.ResultType.Shared &&
                                inPtrs != null)
                            {
                                lockExpr = new PointerAnalysis(this.AC, impl).RecomputeExprFromInParams(lockExpr, inPtrs);
                            }

                            this.AbstractInitializedLock(parent, lockExpr, call);
                        }

                        if (!Utilities.ShouldSkipFromAnalysis(call.callee) ||
                            call.callee.StartsWith("pthread_create$"))
                        {
                            List <Expr> computedRootPointers = new List <Expr>();
                            foreach (var inParam in call.Ins)
                            {
                                if (inParam is NAryExpr)
                                {
                                    computedRootPointers.Add(inParam);
                                }
                                else
                                {
                                    var exprs = new HashSet <Expr>();
                                    new PointerAnalysis(this.AC, impl).GetPointerOrigins(inParam, out exprs);
                                    var ptrExpr = exprs.FirstOrDefault();

                                    computedRootPointers.Add(ptrExpr);
                                }
                            }

                            this.IdentifyLockCreationInCall(parent, call, computedRootPointers);
                        }
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Performs an analysis to identify lock usage.
        /// </summary>
        /// <param name="parent">Thread</param>
        /// <param name="impl">Implementation</param>
        /// <param name="ins">Optional list of expressions</param>
        private void IdentifyLockUsageInImplementation(Thread parent, Implementation impl, List <Expr> inPtrs = null)
        {
            if (this.AlreadyAnalyzedImplementations.Contains(impl))
            {
                return;
            }
            this.AlreadyAnalyzedImplementations.Add(impl);

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

                        if (call.callee.Equals("pthread_mutex_lock") ||
                            call.callee.Equals("pthread_mutex_unlock"))
                        {
                            var exprs    = new HashSet <Expr>();
                            var result   = new PointerAnalysis(this.AC, impl).GetPointerOrigins(call.Ins[0], out exprs);
                            var lockExpr = exprs.FirstOrDefault();

                            if (result != PointerAnalysis.ResultType.Allocated &&
                                result != PointerAnalysis.ResultType.Shared &&
                                inPtrs != null)
                            {
                                lockExpr = new PointerAnalysis(this.AC, impl).RecomputeExprFromInParams(lockExpr, inPtrs);
                            }

                            bool matched = false;
                            foreach (var l in this.AC.Locks)
                            {
                                if (l.IsEqual(this.AC, impl, lockExpr))
                                {
                                    if (ToolCommandLineOptions.Get().SuperVerboseMode)
                                    {
                                        Output.PrintLine("..... {0} uses lock '{1}'", parent, l.Name);
                                    }

                                    if (Output.Debugging)
                                    {
                                        Output.PrintLine("....... replacing lock '{0}' in call '{1}', line {2}",
                                                         call.Ins[0], call.callee, call.Line);
                                    }

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

                                    break;
                                }
                            }

                            if (!matched && this.AC.Locks.Count == 1)
                            {
                                var l = this.AC.Locks[0];

                                if (ToolCommandLineOptions.Get().SuperVerboseMode)
                                {
                                    Output.PrintLine("..... {0} uses lock '{1}'", parent, l.Name);
                                }

                                if (Output.Debugging)
                                {
                                    Output.PrintLine("....... replacing lock '{0}' in call '{1}', line {2}",
                                                     call.Ins[0], call.callee, call.Line);
                                }

                                call.Ins[0] = new IdentifierExpr(l.Id.tok, l.Id);
                            }
                            else if (!matched)
                            {
                                this.AbstractUsedLock(parent, lockExpr, call);
                            }
                        }

                        if (!Utilities.ShouldSkipFromAnalysis(call.callee) ||
                            call.callee.StartsWith("pthread_create$") ||
                            call.callee.StartsWith("__call_wrapper$"))
                        {
                            List <Expr> computedRootPointers = new List <Expr>();
                            foreach (var inParam in call.Ins)
                            {
                                if (inParam is NAryExpr)
                                {
                                    computedRootPointers.Add(inParam);
                                }
                                else
                                {
                                    var exprs = new HashSet <Expr>();
                                    new PointerAnalysis(this.AC, impl).GetPointerOrigins(inParam, out exprs);
                                    var ptrExpr = exprs.FirstOrDefault();
                                    computedRootPointers.Add(ptrExpr);
                                }
                            }

                            Thread child = null;
                            if (call.callee.StartsWith("pthread_create$"))
                            {
                                var tid = computedRootPointers[0] as IdentifierExpr;
                                child  = this.AC.Threads.First(val => !val.IsMain && val.Id.IsEqual(tid));
                                parent = child;
                            }

                            this.IdentifyLockUsageInCall(parent, call, computedRootPointers);
                        }
                    }
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Performs an analysis to identify thread usage.
        /// </summary>
        /// <param name="parent">Thread</param>
        /// <param name="parent">child</param>
        /// <param name="impl">Implementation</param>
        /// <param name="ins">Optional list of expressions</param>
        private void IdentifyThreadUsageInImplementation(Thread parent, Thread child,
                                                         Implementation impl, List <Expr> inPtrs = null)
        {
            if (this.AlreadyAnalyzedImplementations.Contains(impl))
            {
                return;
            }
            this.AlreadyAnalyzedImplementations.Add(impl);

            if (child != null && impl.Name.Equals(child.Name))
            {
                parent = child;
            }

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

                        if (call.callee.Equals("pthread_create"))
                        {
                            var exprs   = new HashSet <Expr>();
                            var result  = new PointerAnalysis(this.AC, impl).GetPointerOrigins(call.Ins[0], out exprs);
                            var tidExpr = exprs.FirstOrDefault();

                            if (result != PointerAnalysis.ResultType.Allocated &&
                                result != PointerAnalysis.ResultType.Shared &&
                                inPtrs != null)
                            {
                                tidExpr = new PointerAnalysis(this.AC, impl).RecomputeExprFromInParams(tidExpr, inPtrs);
                            }

                            spawned = this.GetAbstractSpawnedThread(parent, impl, tidExpr, call);
                        }
                        else if (call.callee.Equals("pthread_join"))
                        {
                            var exprs   = new HashSet <Expr>();
                            var result  = new PointerAnalysis(this.AC, impl).GetPointerOrigins(call.Ins[0], out exprs);
                            var tidExpr = exprs.FirstOrDefault();

                            if (result != PointerAnalysis.ResultType.Allocated &&
                                result != PointerAnalysis.ResultType.Shared &&
                                inPtrs != null)
                            {
                                tidExpr = new PointerAnalysis(this.AC, impl).RecomputeExprFromInParams(tidExpr, inPtrs);
                            }

                            bool matched = false;
                            foreach (var tid in this.AC.ThreadIds)
                            {
                                if (tid.IsEqual(this.AC, impl, tidExpr))
                                {
                                    var thread = parent.Children.FirstOrDefault(val => val.Id.Equals(tid));
                                    if (thread == null)
                                    {
                                        continue;
                                    }

                                    call.Ins[0]   = new IdentifierExpr(tid.Id.tok, tid.Id);
                                    thread.Joiner = new Tuple <Implementation, Block, CallCmd>(impl, block, call);

                                    if (ToolCommandLineOptions.Get().SuperVerboseMode)
                                    {
                                        Output.PrintLine("..... {0} blocks {1}", parent, thread);
                                    }

                                    matched = true;
                                    break;
                                }
                            }

                            if (!matched)
                            {
                                this.AbstractBlockedThread(parent, impl, tidExpr, call);
                            }
                        }

                        if (!Utilities.ShouldSkipFromAnalysis(call.callee) ||
                            call.callee.Equals("pthread_create") ||
                            call.callee.Equals("__call_wrapper"))
                        {
                            List <Expr> computedRootPointers = new List <Expr>();
                            foreach (var inParam in call.Ins)
                            {
                                if (inParam is NAryExpr)
                                {
                                    computedRootPointers.Add(inParam);
                                }
                                else
                                {
                                    var exprs = new HashSet <Expr>();
                                    new PointerAnalysis(this.AC, impl).GetPointerOrigins(inParam, out exprs);
                                    var ptrExpr = exprs.FirstOrDefault();

                                    computedRootPointers.Add(ptrExpr);
                                }
                            }

                            this.IdentifyThreadUsageInCall(parent, spawned, call, computedRootPointers);
                        }
                    }
                }
            }
        }