private void CleanUpRegion(InstrumentationRegion region)
 {
     region.Implementation().Proc.Modifies.RemoveAll(val =>
                                                     val.Name.Contains("_in_LS_$M.") ||
                                                     val.Name.StartsWith("WRITTEN_$M.") ||
                                                     val.Name.StartsWith("READ_$M."));
 }
Example #2
0
        private void InstrumentProcedure(InstrumentationRegion region)
        {
            foreach (var ls in this.AC.CurrentLocksets)
            {
                if (this.ShouldSkipLockset(ls))
                {
                    continue;
                }

                region.Procedure().Modifies.Add(new IdentifierExpr(ls.Id.tok, ls.Id));
            }

            List <Variable> vars = SharedStateAnalyser.GetMemoryRegions(DeviceDriver.GetEntryPoint(this.EP.Name));

            foreach (var ls in this.AC.MemoryLocksets)
            {
                if (!vars.Any(val => val.Name.Equals(ls.TargetName)))
                {
                    continue;
                }
                if (this.ShouldSkipLockset(ls))
                {
                    continue;
                }

                region.Procedure().Modifies.Add(new IdentifierExpr(ls.Id.tok, ls.Id));
            }
        }
Example #3
0
        public void Run()
        {
            if (WhoopCommandLineOptions.Get().MeasurePassExecutionTime)
            {
                this.Timer = new ExecutionTimer();
                this.Timer.Start();
            }

            foreach (var impl in this.AC.TopLevelDeclarations.OfType <Implementation>())
            {
                if (this.SkipFromAnalysis(impl))
                {
                    continue;
                }

                InstrumentationRegion region = new InstrumentationRegion(this.AC, this.EP, impl);
                this.AC.InstrumentationRegions.Add(region);
            }

            this.EP.RebuildCallGraph(this.AC);

            if (WhoopCommandLineOptions.Get().MeasurePassExecutionTime)
            {
                this.Timer.Stop();
                Console.WriteLine(" |  |------ [InstrumentationRegionsConstructor] {0}", this.Timer.Result());
            }
        }
Example #4
0
        public static void CleanReadWriteModsets(AnalysisContext ac, EntryPoint ep, InstrumentationRegion region)
        {
            var vars = SharedStateAnalyser.GetMemoryRegions(ep);

            foreach (var acv in ac.GetWriteAccessCheckingVariables())
            {
                string targetName = acv.Name.Split('_')[1];
                if (!vars.Any(val => val.Name.Equals(targetName)))
                {
                    continue;
                }
                if (ep.HasWriteAccess.ContainsKey(targetName))
                {
                    continue;
                }

                region.Procedure().Modifies.RemoveAll(val => val.Name.Equals(acv.Name));
            }

            foreach (var acv in ac.GetReadAccessCheckingVariables())
            {
                string targetName = acv.Name.Split('_')[1];
                if (!vars.Any(val => val.Name.Equals(targetName)))
                {
                    continue;
                }
                if (ep.HasReadAccess.ContainsKey(targetName))
                {
                    continue;
                }

                region.Procedure().Modifies.RemoveAll(val => val.Name.Equals(acv.Name));
            }
        }
Example #5
0
        public static void CleanReadWriteSets(EntryPoint ep, InstrumentationRegion region, CallCmd call)
        {
            if (call.callee.StartsWith("_WRITE_LS_$M."))
            {
                var write = call.callee.Split(new string[] { "_" }, StringSplitOptions.None)[3];

                region.HasWriteAccess[write] = region.HasWriteAccess[write] - 1;
                ep.HasWriteAccess[write]     = ep.HasWriteAccess[write] - 1;

                if (region.HasWriteAccess[write] <= 0)
                {
                    region.HasWriteAccess.Remove(write);
                }
                if (ep.HasWriteAccess[write] <= 0)
                {
                    ep.HasWriteAccess.Remove(write);
                }
            }
            else
            {
                var read = call.callee.Split(new string[] { "_" }, StringSplitOptions.None)[3];

                region.HasReadAccess[read] = region.HasReadAccess[read] - 1;
                ep.HasReadAccess[read]     = ep.HasReadAccess[read] - 1;

                if (region.HasReadAccess[read] <= 0)
                {
                    region.HasReadAccess.Remove(read);
                }
                if (ep.HasReadAccess[read] <= 0)
                {
                    ep.HasReadAccess.Remove(read);
                }
            }
        }
Example #6
0
        protected void SliceRegion(InstrumentationRegion region)
        {
            foreach (var write in region.HasWriteAccess)
            {
                if (!this.EP.HasWriteAccess.ContainsKey(write.Key))
                {
                    continue;
                }
                this.EP.HasWriteAccess[write.Key] = this.EP.HasWriteAccess[write.Key] - write.Value;
                if (this.EP.HasWriteAccess[write.Key] <= 0)
                {
                    this.EP.HasWriteAccess.Remove(write.Key);
                }
            }

            foreach (var read in region.HasReadAccess)
            {
                if (!this.EP.HasReadAccess.ContainsKey(read.Key))
                {
                    continue;
                }
                this.EP.HasReadAccess[read.Key] = this.EP.HasReadAccess[read.Key] - read.Value;
                if (this.EP.HasReadAccess[read.Key] <= 0)
                {
                    this.EP.HasReadAccess.Remove(read.Key);
                }
            }

            this.AC.TopLevelDeclarations.RemoveAll(val =>
                                                   (val is Procedure && (val as Procedure).Name.Equals(region.Implementation().Name)) ||
                                                   (val is Implementation && (val as Implementation).Name.Equals(region.Implementation().Name)) ||
                                                   (val is Constant && (val as Constant).Name.Equals(region.Implementation().Name)));
            this.AC.InstrumentationRegions.Remove(region);
            this.EP.CallGraph.Remove(region);
        }
Example #7
0
 private void CleanUpModset(InstrumentationRegion region)
 {
     region.Procedure().Modifies.RemoveAll(val => !(val.Name.Equals("$Alloc") ||
                                                    val.Name.Equals("$CurrAddr") || val.Name.Equals("CLS") ||
                                                    val.Name.Contains("LS_$") ||
                                                    val.Name.Contains("WRITTEN_$") || val.Name.Contains("READ_$")));
 }
Example #8
0
        private void FindUseOfFunctionPointers(InstrumentationRegion region, int regionIndex,
                                               IdentifierExpr constant, HashSet <InstrumentationRegion> alreadyFound)
        {
            if (alreadyFound.Contains(region))
            {
                return;
            }
            alreadyFound.Add(region);

            var id = region.Implementation().InParams[regionIndex];

            if (region.FunctionPointers.Contains(id))
            {
                return;
            }
            region.FunctionPointers.Add(id);

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

                    var call         = block.Cmds[idx] as CallCmd;
                    var calleeRegion = this.AC.InstrumentationRegions.Find(val =>
                                                                           val.Implementation().Name.Equals(call.callee));
                    if (calleeRegion == null)
                    {
                        continue;
                    }

                    var indexes = new HashSet <int>();
                    for (int i = 0; i < call.Ins.Count; i++)
                    {
                        if (!(call.Ins[i] is IdentifierExpr))
                        {
                            continue;
                        }

                        if (id.Name.Equals((call.Ins[i] as IdentifierExpr).Name))
                        {
                            indexes.Add(i);
                        }
                    }

                    if (indexes.Count == 0)
                    {
                        continue;
                    }

                    foreach (var index in indexes)
                    {
                        this.FindUseOfFunctionPointers(calleeRegion, index, constant, alreadyFound);
                    }
                }
            }
        }
Example #9
0
        public LocksetInstrumentation(AnalysisContext ac, EntryPoint ep)
        {
            Contract.Requires(ac != null && ep != null);
            this.AC = ac;
            this.EP = ep;

            this.TransmitLockHolder = null;
        }
Example #10
0
 private bool ShouldLock(InstrumentationRegion region, Variable var)
 {
     if ((region.IsHoldingRtnlLock && var.Name.StartsWith("lock$rtnl")) ||
         (region.IsHoldingTxLock && var.Name.StartsWith("lock$tx")))
     {
         return(true);
     }
     return(false);
 }
Example #11
0
        private void SimplifyAccessInBlocks(InstrumentationRegion region, Graph <Block> blockGraph,
                                            Block netBlock, CallCmd netCall)
        {
            var predecessorBlocks = blockGraph.NestedPredecessors(netBlock);
            var successorBlocks   = blockGraph.NestedSuccessors(netBlock);

            successorBlocks.RemoveWhere(val =>
                                        predecessorBlocks.Contains(val) || val.Equals(netBlock));

            foreach (var block in successorBlocks)
            {
                foreach (var call in block.Cmds.OfType <CallCmd>())
                {
                    if (!(call.callee.StartsWith("_WRITE_LS_$M.") ||
                          call.callee.StartsWith("_READ_LS_$M.")))
                    {
                        continue;
                    }

                    ReadWriteSlicing.CleanReadWriteSets(base.EP, region, call);

                    call.callee = "_NO_OP_$" + base.EP.Name;
                    call.Ins.Clear();
                    call.Outs.Clear();
                }
            }

            if (!predecessorBlocks.Contains(netBlock))
            {
                bool foundCall = false;
                foreach (var call in netBlock.Cmds.OfType <CallCmd>())
                {
                    if (!foundCall && call.Equals(netCall))
                    {
                        foundCall = true;
                        continue;
                    }

                    if (!foundCall)
                    {
                        continue;
                    }

                    if (!(call.callee.StartsWith("_WRITE_LS_$M.") ||
                          call.callee.StartsWith("_READ_LS_$M.")))
                    {
                        continue;
                    }

                    ReadWriteSlicing.CleanReadWriteSets(base.EP, region, call);

                    call.callee = "_NO_OP_$" + base.EP.Name;
                    call.Ins.Clear();
                    call.Outs.Clear();
                }
            }
        }
        public DomainKnowledgeInstrumentation(AnalysisContext ac, EntryPoint ep)
        {
            Contract.Requires(ac != null && ep != null);
            this.AC = ac;
            this.EP = ep;

            this.DeviceRegisterRegion   = null;
            this.DeviceUnregisterRegion = null;
            this.NetworkEnableRegion    = null;
        }
        private void AnalyseDomainSpecificDisableUsage(string type)
        {
            if ((type.Equals("unregister_netdev") || type.Equals("misc_deregister") ||
                 type.Equals("nfc_free_device")) &&
                this.DeviceUnregisterRegion == null)
            {
                return;
            }

            InstrumentationRegion hotRegion = null;

            if (type.Equals("unregister_netdev") || type.Equals("misc_deregister") ||
                type.Equals("nfc_free_device"))
            {
                hotRegion = this.DeviceUnregisterRegion;
            }

            var predecessorCallees = new HashSet <InstrumentationRegion>();
            var successorCallees   = new HashSet <InstrumentationRegion>();

            if (type.Equals("unregister_netdev") || type.Equals("misc_deregister") ||
                type.Equals("nfc_free_device"))
            {
                this.AnalyseBlocksForDeviceRegisterRegion(hotRegion, false,
                                                          predecessorCallees, successorCallees);
            }

            var predecessors = this.EP.CallGraph.NestedPredecessors(hotRegion);

            predecessorCallees.UnionWith(predecessors);

            var predSuccs = new HashSet <InstrumentationRegion>();

            foreach (var pred in predecessorCallees)
            {
                var succs = this.EP.CallGraph.NestedSuccessors(pred, hotRegion);
                predSuccs.UnionWith(succs);
            }

            predecessorCallees.UnionWith(predSuccs);

            var successors = this.EP.CallGraph.NestedSuccessors(hotRegion);

            successorCallees.UnionWith(successors);
            successorCallees.RemoveWhere(val => predecessorCallees.Contains(val));

            foreach (var succ in successorCallees)
            {
                if (type.Equals("unregister_netdev") || type.Equals("misc_deregister") ||
                    type.Equals("nfc_free_device"))
                {
                    succ.IsDeviceRegistered = false;
                }
            }
        }
        public PairWatchdogInformationAnalysis(AnalysisContext ac, EntryPoint ep)
        {
            Contract.Requires(ac != null && ep != null);
            this.AC = ac;
            this.EP = ep;

            this.PairEntryPoints = DeviceDriver.GetPairs(ep);
            this.PairAccesses    = new HashSet <Expr>();

            this.Region = this.AC.InstrumentationRegions.Find(val =>
                                                              val.Implementation().Name.Equals(ep.Name));
        }
Example #15
0
        private void InstrumentSourceLocationInfo(InstrumentationRegion region)
        {
            foreach (var b in region.Blocks())
            {
                for (int idx = 0; idx < b.Cmds.Count; idx++)
                {
                    if (!(b.Cmds[idx] is CallCmd))
                    {
                        continue;
                    }
                    CallCmd call = b.Cmds[idx] as CallCmd;

                    AssumeCmd assume = null;
                    for (int i = idx; i >= 0; i--)
                    {
                        if (b.Cmds[i] is AssumeCmd)
                        {
                            assume = b.Cmds[i] as AssumeCmd;
                            break;
                        }
                    }

                    if (assume == null)
                    {
                        for (int i = idx; i < b.Cmds.Count; i++)
                        {
                            if (b.Cmds[i] is AssumeCmd)
                            {
                                assume = b.Cmds[i] as AssumeCmd;
                                break;
                            }
                        }
                    }

                    if (call.callee.Contains("_UPDATE_CLS"))
                    {
                        call.Attributes = this.GetSourceLocationAttributes(
                            assume.Attributes, call.Attributes);
                    }
                    else if (call.callee.Contains("_WRITE_LS_"))
                    {
                        call.Attributes = this.GetSourceLocationAttributes(
                            assume.Attributes, call.Attributes);
                    }
                    else if (call.callee.Contains("_READ_LS_"))
                    {
                        call.Attributes = this.GetSourceLocationAttributes(
                            assume.Attributes, call.Attributes);
                    }
                }
            }
        }
Example #16
0
        private void AbstractReadAccesses(InstrumentationRegion region)
        {
            foreach (var b in region.Blocks())
            {
                for (int k = 0; k < b.Cmds.Count; k++)
                {
                    if (!(b.Cmds[k] is AssignCmd))
                    {
                        continue;
                    }

                    foreach (var rhs in (b.Cmds[k] as AssignCmd).Rhss.OfType <NAryExpr>())
                    {
                        if (!(rhs.Fun is MapSelect) || rhs.Args.Count != 2 ||
                            !((rhs.Args[0] as IdentifierExpr).Name.StartsWith("$M.")))
                        {
                            continue;
                        }

                        Variable v     = (b.Cmds[k] as AssignCmd).Lhss[0].DeepAssignedVariable;
                        HavocCmd havoc = new HavocCmd(Token.NoToken,
                                                      new List <IdentifierExpr> {
                            new IdentifierExpr(v.tok, v)
                        });
                        b.Cmds[k] = havoc;
                    }

                    if (!(b.Cmds[k] is AssignCmd))
                    {
                        continue;
                    }
                    foreach (var rhs in (b.Cmds[k] as AssignCmd).Rhss.OfType <IdentifierExpr>())
                    {
                        if (!(rhs.Name.StartsWith("$M.")))
                        {
                            continue;
                        }

                        Variable v     = (b.Cmds[k] as AssignCmd).Lhss[0].DeepAssignedVariable;
                        HavocCmd havoc = new HavocCmd(Token.NoToken,
                                                      new List <IdentifierExpr> {
                            new IdentifierExpr(v.tok, v)
                        });
                        b.Cmds[k] = havoc;
                    }
                }
            }
        }
Example #17
0
        private void FindUseOfFunctionPointers(InstrumentationRegion region)
        {
            foreach (var block in region.Blocks())
            {
                for (int idx = 0; idx < block.Cmds.Count; idx++)
                {
                    if (!(block.Cmds[idx] is CallCmd))
                    {
                        continue;
                    }

                    var call         = block.Cmds[idx] as CallCmd;
                    var calleeRegion = this.AC.InstrumentationRegions.Find(val =>
                                                                           val.Implementation().Name.Equals(call.callee));
                    if (calleeRegion == null)
                    {
                        continue;
                    }

                    var idxConst = new Dictionary <int, IdentifierExpr>();
                    for (int i = 0; i < call.Ins.Count; i++)
                    {
                        if (!(call.Ins[i] is IdentifierExpr))
                        {
                            continue;
                        }
                        if (!this.AC.TopLevelDeclarations.OfType <Constant>().Any(val =>
                                                                                  val.Name.Equals((call.Ins[i] as IdentifierExpr).Name)))
                        {
                            continue;
                        }

                        idxConst.Add(i, call.Ins[i] as IdentifierExpr);
                    }

                    if (idxConst.Count == 0)
                    {
                        continue;
                    }

                    foreach (var ic in idxConst)
                    {
                        var alreadyFound = new HashSet <InstrumentationRegion>();
                        this.FindUseOfFunctionPointers(calleeRegion, ic.Key, ic.Value, alreadyFound);
                    }
                }
            }
        }
Example #18
0
        private void InstrumentCurrentLocksetInvariantsInRegion(InstrumentationRegion region)
        {
            if (this.EP.IsHoldingLock)
            {
                var lockVars = new HashSet <Variable>();
                foreach (var variable in base.CurrentLocksetVariables)
                {
                    if (this.ShouldLock(region, variable))
                    {
                        lockVars.Add(variable);
                        continue;
                    }

                    base.InstrumentRequiresCandidate(region, variable, true);
                    base.InstrumentEnsuresCandidate(region, variable, true);
                    foreach (var block in region.LoopHeaders())
                    {
                        base.InstrumentAssertCandidate(block, variable, 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);
                    }
                }
            }
            else
            {
                foreach (var variable in base.CurrentLocksetVariables)
                {
                    base.InstrumentRequires(region, variable, false);
                    base.InstrumentEnsures(region, variable, false);
                    foreach (var block in region.LoopHeaders())
                    {
                        base.InstrumentAssert(block, variable, false);
                    }
                }
            }
        }
Example #19
0
        protected void InstrumentImpliesEnsuresCandidate(InstrumentationRegion region, Expr implExpr,
                                                         Variable variable, bool value, bool capture = false)
        {
            if (this.EP.IsInlined)
            {
                return;
            }
            if (!WhoopCommandLineOptions.Get().MergeExistentials)
            {
                capture = false;
            }

            var dict = this.GetExistentialDictionary(value);

            Constant cons       = null;
            bool     consExists = false;

            if (capture && dict.ContainsKey(variable) &&
                GetConstantFromDictionary(out cons, dict[variable], implExpr))
            {
                consExists = true;
            }
            else
            {
                cons = this.CreateConstant();
            }

            Expr rExpr = this.CreateImplExpr(implExpr, variable, value);
            Expr lExpr = Expr.Imp(new IdentifierExpr(cons.tok, cons), rExpr);

            region.Procedure().Ensures.Add(new Ensures(false, lExpr));

            if (capture && !dict.ContainsKey(variable) && !consExists)
            {
                dict.Add(variable, new Dictionary <string, Constant>());
                dict[variable].Add(implExpr.ToString(), cons);
            }
            else if (capture && !consExists)
            {
                dict[variable].Add(implExpr.ToString(), cons);
            }
        }
Example #20
0
        private void AbstractWriteAccesses(InstrumentationRegion region)
        {
            foreach (var b in region.Blocks())
            {
                List <Cmd> cmdsToRemove = new List <Cmd>();

                for (int k = 0; k < b.Cmds.Count; k++)
                {
                    if (!(b.Cmds[k] is AssignCmd))
                    {
                        continue;
                    }

                    foreach (var lhs in (b.Cmds[k] as AssignCmd).Lhss.OfType <MapAssignLhs>())
                    {
                        if (!(lhs.DeepAssignedIdentifier.Name.StartsWith("$M.")) ||
                            !(lhs.Map is SimpleAssignLhs) || lhs.Indexes.Count != 1)
                        {
                            continue;
                        }

                        cmdsToRemove.Add(b.Cmds[k]);
                    }

                    foreach (var lhs in (b.Cmds[k] as AssignCmd).Lhss.OfType <SimpleAssignLhs>())
                    {
                        if (!(lhs.DeepAssignedIdentifier.Name.StartsWith("$M.")))
                        {
                            continue;
                        }

                        cmdsToRemove.Add(b.Cmds[k]);
                    }
                }

                foreach (var c in cmdsToRemove)
                {
                    b.Cmds.Remove(c);
                }
            }
        }
Example #21
0
        private void InstrumentProcedure(InstrumentationRegion region)
        {
            var vars = SharedStateAnalyser.GetMemoryRegions(this.EP);

            foreach (var acv in this.AC.GetWriteAccessCheckingVariables())
            {
                string targetName = acv.Name.Split('_')[1];
                if (!vars.Any(val => val.Name.Equals(targetName)))
                {
                    continue;
                }
                if (!this.EP.HasWriteAccess.ContainsKey(targetName))
                {
                    continue;
                }

                if (!region.Procedure().Modifies.Any(mod => mod.Name.Equals(acv.Name)))
                {
                    region.Procedure().Modifies.Add(new IdentifierExpr(acv.tok, acv));
                }
            }

            foreach (var acv in this.AC.GetReadAccessCheckingVariables())
            {
                string targetName = acv.Name.Split('_')[1];
                if (!vars.Any(val => val.Name.Equals(targetName)))
                {
                    continue;
                }
                if (!this.EP.HasReadAccess.ContainsKey(targetName))
                {
                    continue;
                }

                if (!region.Procedure().Modifies.Any(mod => mod.Name.Equals(acv.Name)))
                {
                    region.Procedure().Modifies.Add(new IdentifierExpr(acv.tok, acv));
                }
            }
        }
Example #22
0
        protected void InstrumentEnsuresCandidate(InstrumentationRegion region, Variable variable,
                                                  bool value, bool capture = false)
        {
            if (this.EP.IsInlined)
            {
                return;
            }
            if (!WhoopCommandLineOptions.Get().MergeExistentials)
            {
                capture = false;
            }

            var dict = this.GetExistentialDictionary(value);

            Constant cons = null;

            if (capture && dict.ContainsKey(variable) && dict[variable].ContainsKey("$whoop$"))
            {
                cons = dict[variable]["$whoop$"];
            }
            else
            {
                cons = this.CreateConstant();
            }

            Expr expr = this.CreateImplExpr(cons, variable, value);

            region.Procedure().Ensures.Add(new Ensures(false, expr));

            if (capture && !dict.ContainsKey(variable))
            {
                dict.Add(variable, new Dictionary <string, Constant>());
                dict[variable].Add("$whoop$", cons);
            }
            else if (capture && !dict[variable].ContainsKey("$whoop$"))
            {
                dict[variable].Add("$whoop$", cons);
            }
        }
Example #23
0
        private void SimplifyCallsInRegion(InstrumentationRegion region)
        {
            foreach (var call in region.Cmds().OfType <CallCmd>())
            {
                var calleeRegion = base.AC.InstrumentationRegions.Find(val =>
                                                                       val.Implementation().Name.Equals(call.callee));
                if (calleeRegion == null)
                {
                    continue;
                }
                if (calleeRegion.IsEnablingNetwork || calleeRegion.IsChangingNetAvailability)
                {
                    continue;
                }

                call.callee = "_NO_OP_$" + base.EP.Name;
                call.Ins.Clear();
                call.Outs.Clear();

                base.SlicedRegions.Add(calleeRegion);
            }
        }
        private void AnalyseBlocksForDeviceRegisterRegion(InstrumentationRegion hotRegion, bool type,
                                                          HashSet <InstrumentationRegion> predecessorCallees, HashSet <InstrumentationRegion> successorCallees)
        {
            bool foundCall = false;

            foreach (var block in hotRegion.Blocks())
            {
                foreach (var call in block.Cmds.OfType <CallCmd>())
                {
                    if (type && !foundCall && call.callee.StartsWith("_REGISTER_DEVICE_"))
                    {
                        foundCall = true;
                    }
                    else if (!type && !foundCall && call.callee.StartsWith("_UNREGISTER_DEVICE_"))
                    {
                        foundCall = true;
                    }

                    var region = this.AC.InstrumentationRegions.Find(val =>
                                                                     val.Name().Equals(call.callee + "$instrumented"));
                    if (region == null)
                    {
                        continue;
                    }

                    if (foundCall && !predecessorCallees.Contains(region))
                    {
                        successorCallees.Add(region);
                    }
                    else
                    {
                        predecessorCallees.Add(region);
                    }
                }
            }
        }
Example #25
0
        private void InstrumentImplementation(InstrumentationRegion region)
        {
            foreach (var c in region.Cmds().OfType <CallCmd>())
            {
                if (c.callee.Equals("mutex_lock") ||
                    c.callee.Equals("spin_lock"))
                {
                    c.callee = "_UPDATE_CLS_$" + this.EP.Name;
                    c.Ins.Add(Expr.True);

                    this.EP.IsHoldingLock = true;
                }
                else if (c.callee.Equals("mutex_lock_interruptible"))
                {
                    c.callee = "_UPDATE_CLS_$bool$" + this.EP.Name;
                    c.Ins.Add(Expr.True);

                    this.EP.IsHoldingLock = true;
                }
                else if (c.callee.Equals("mutex_unlock") ||
                         c.callee.Equals("spin_unlock"))
                {
                    c.callee = "_UPDATE_CLS_$" + this.EP.Name;
                    c.Ins.Add(Expr.False);

                    this.EP.IsHoldingLock = true;
                }
                else if (c.callee.Equals("spin_lock_irqsave"))
                {
                    c.callee = "_UPDATE_CLS_$" + this.EP.Name;
                    c.Ins.RemoveAt(1);
                    c.Ins.Add(Expr.True);

                    this.EP.IsHoldingLock = true;
                }
                else if (c.callee.Equals("spin_unlock_irqrestore"))
                {
                    c.callee = "_UPDATE_CLS_$" + this.EP.Name;
                    c.Ins.RemoveAt(1);
                    c.Ins.Add(Expr.False);

                    this.EP.IsHoldingLock = true;
                }
                else if (c.callee.Equals("pm_runtime_get_sync") ||
                         c.callee.Equals("pm_runtime_get_noresume"))
                {
                    c.callee = "_UPDATE_CLS_$" + this.EP.Name;
                    c.Ins.Clear();
                    c.Outs.Clear();

                    var powerLock = this.AC.GetLockVariables().Find(val => val.Name.Equals("lock$power"));
                    c.Ins.Add(new IdentifierExpr(powerLock.tok, powerLock));
                    c.Ins.Add(Expr.True);

                    this.EP.IsHoldingLock = true;
                }
                else if (c.callee.Equals("pm_runtime_put_sync") ||
                         c.callee.Equals("pm_runtime_put_noidle"))
                {
                    c.callee = "_UPDATE_CLS_$" + this.EP.Name;
                    c.Ins.Clear();
                    c.Outs.Clear();

                    var powerLock = this.AC.GetLockVariables().Find(val => val.Name.Equals("lock$power"));
                    c.Ins.Add(new IdentifierExpr(powerLock.tok, powerLock));
                    c.Ins.Add(Expr.False);

                    this.EP.IsHoldingLock = true;
                }
                else if (c.callee.Equals("ASSERT_RTNL"))
                {
                    c.callee = "_UPDATE_CLS_$" + this.EP.Name;
                    c.Ins.Clear();
                    c.Outs.Clear();

                    var rtnl = this.AC.GetLockVariables().Find(val => val.Name.Equals("lock$rtnl"));
                    c.Ins.Add(new IdentifierExpr(rtnl.tok, rtnl));
                    c.Ins.Add(Expr.True);

                    this.EP.IsHoldingLock = true;
                }
                else if (c.callee.Equals("netif_stop_queue"))
                {
                    if (!this.EP.IsTxLocked)
                    {
                        c.callee = "_UPDATE_CLS_$" + this.EP.Name;
                        c.Ins.Clear();
                        c.Outs.Clear();

                        var tx = this.AC.GetLockVariables().Find(val => val.Name.Equals("lock$tx"));
                        c.Ins.Add(new IdentifierExpr(tx.tok, tx));
                        c.Ins.Add(Expr.True);

                        if (this.TransmitLockHolder == null)
                        {
                            this.TransmitLockHolder = region;
                        }

                        this.EP.IsHoldingLock = true;
                    }
                    else
                    {
                        c.callee = "_NO_OP_$" + this.EP.Name;
                        c.Ins.Clear();
                        c.Outs.Clear();
                    }
                }
            }
        }
Example #26
0
        private void InstrumentImplementation(InstrumentationRegion region)
        {
            foreach (var block in region.Blocks())
            {
                for (int idx = 0; idx < block.Cmds.Count; idx++)
                {
                    if (!(block.Cmds[idx] is AssignCmd))
                    {
                        continue;
                    }
                    var assign = block.Cmds[idx] as AssignCmd;

                    var lhssMap = assign.Lhss.OfType <MapAssignLhs>();
                    var lhss    = assign.Lhss.OfType <SimpleAssignLhs>();
                    var rhssMap = assign.Rhss.OfType <NAryExpr>();
                    var rhss    = assign.Rhss.OfType <IdentifierExpr>();

                    CallCmd call = null;
                    if (lhssMap.Count() == 1)
                    {
                        var lhs = lhssMap.First();
                        if (lhs.DeepAssignedIdentifier.Name.StartsWith("$M.") &&
                            lhs.Map is SimpleAssignLhs && lhs.Indexes.Count == 1)
                        {
                            if (SharedStateAnalyser.GetMemoryRegions(this.EP).Any(val =>
                                                                                  val.Name.Equals(lhs.DeepAssignedIdentifier.Name)))
                            {
                                var ind = lhs.Indexes[0];
                                call = new CallCmd(Token.NoToken,
                                                   this.MakeAccessFuncName(AccessType.WRITE, lhs.DeepAssignedIdentifier.Name),
                                                   new List <Expr> {
                                    ind
                                }, new List <IdentifierExpr>());

                                if (rhssMap.Count() == 0 && assign.Rhss.Count == 1 &&
                                    assign.Rhss[0].ToString().StartsWith("$p"))
                                {
                                    call.Attributes = new QKeyValue(Token.NoToken, "rhs",
                                                                    new List <object>()
                                    {
                                        assign.Rhss[0]
                                    }, call.Attributes);
                                }

                                if (!region.HasWriteAccess.ContainsKey(lhs.DeepAssignedIdentifier.Name))
                                {
                                    region.HasWriteAccess.Add(lhs.DeepAssignedIdentifier.Name, 0);
                                }
                                region.HasWriteAccess[lhs.DeepAssignedIdentifier.Name] =
                                    region.HasWriteAccess[lhs.DeepAssignedIdentifier.Name] + 1;
                            }
                            else
                            {
                                call = new CallCmd(Token.NoToken, "_NO_OP_$" + this.EP.Name,
                                                   new List <Expr>(), new List <IdentifierExpr>());
                            }
                        }
                    }
                    else if (lhss.Count() == 1)
                    {
                        var lhs = lhss.First();
                        if (lhs.DeepAssignedIdentifier.Name.StartsWith("$M."))
                        {
                            if (SharedStateAnalyser.GetMemoryRegions(this.EP).Any(val =>
                                                                                  val.Name.Equals(lhs.DeepAssignedIdentifier.Name)))
                            {
                                call = new CallCmd(Token.NoToken,
                                                   this.MakeAccessFuncName(AccessType.WRITE, lhs.DeepAssignedIdentifier.Name),
                                                   new List <Expr>(), new List <IdentifierExpr>());

                                if (rhssMap.Count() == 0 && assign.Rhss.Count == 1 &&
                                    assign.Rhss[0].ToString().StartsWith("$p"))
                                {
                                    call.Attributes = new QKeyValue(Token.NoToken, "rhs",
                                                                    new List <object>()
                                    {
                                        assign.Rhss[0]
                                    }, call.Attributes);
                                }

                                if (!region.HasWriteAccess.ContainsKey(lhs.DeepAssignedIdentifier.Name))
                                {
                                    region.HasWriteAccess.Add(lhs.DeepAssignedIdentifier.Name, 0);
                                }
                                region.HasWriteAccess[lhs.DeepAssignedIdentifier.Name] =
                                    region.HasWriteAccess[lhs.DeepAssignedIdentifier.Name] + 1;
                            }
                            else
                            {
                                call = new CallCmd(Token.NoToken, "_NO_OP_$" + this.EP.Name,
                                                   new List <Expr>(), new List <IdentifierExpr>());
                            }
                        }
                    }

                    if (rhssMap.Count() == 1)
                    {
                        var rhs = rhssMap.First();
                        if (rhs.Fun is MapSelect && rhs.Args.Count == 2 &&
                            (rhs.Args[0] as IdentifierExpr).Name.StartsWith("$M."))
                        {
                            if (SharedStateAnalyser.GetMemoryRegions(this.EP).Any(val =>
                                                                                  val.Name.Equals((rhs.Args[0] as IdentifierExpr).Name)))
                            {
                                call = new CallCmd(Token.NoToken,
                                                   this.MakeAccessFuncName(AccessType.READ, (rhs.Args[0] as IdentifierExpr).Name),
                                                   new List <Expr> {
                                    rhs.Args[1]
                                }, new List <IdentifierExpr>());

                                if (!region.HasReadAccess.ContainsKey((rhs.Args[0] as IdentifierExpr).Name))
                                {
                                    region.HasReadAccess.Add((rhs.Args[0] as IdentifierExpr).Name, 0);
                                }
                                region.HasReadAccess[(rhs.Args[0] as IdentifierExpr).Name] =
                                    region.HasReadAccess[(rhs.Args[0] as IdentifierExpr).Name] + 1;
                            }
                            else
                            {
                                call = new CallCmd(Token.NoToken, "_NO_OP_$" + this.EP.Name,
                                                   new List <Expr>(), new List <IdentifierExpr>());
                            }
                        }
                    }
                    else if (rhss.Count() == 1)
                    {
                        var rhs = rhss.First();
                        if (rhs.Name.StartsWith("$M."))
                        {
                            if (SharedStateAnalyser.GetMemoryRegions(this.EP).Any(val =>
                                                                                  val.Name.Equals(rhs.Name)))
                            {
                                call = new CallCmd(Token.NoToken,
                                                   this.MakeAccessFuncName(AccessType.READ, rhs.Name),
                                                   new List <Expr>(), new List <IdentifierExpr>());

                                if (!region.HasReadAccess.ContainsKey(rhs.Name))
                                {
                                    region.HasReadAccess.Add(rhs.Name, 0);
                                }
                                region.HasReadAccess[rhs.Name] = region.HasReadAccess[rhs.Name] + 1;
                            }
                            else
                            {
                                call = new CallCmd(Token.NoToken, "_NO_OP_$" + this.EP.Name,
                                                   new List <Expr>(), new List <IdentifierExpr>());
                            }
                        }
                    }

                    if (call != null)
                    {
                        block.Cmds.Insert(idx + 1, call);
                    }
                }
            }

            foreach (var write in region.HasWriteAccess)
            {
                if (!this.EP.HasWriteAccess.ContainsKey(write.Key))
                {
                    this.EP.HasWriteAccess.Add(write.Key, 0);
                }
                this.EP.HasWriteAccess[write.Key] = this.EP.HasWriteAccess[write.Key] + write.Value;
            }

            foreach (var read in region.HasReadAccess)
            {
                if (!this.EP.HasReadAccess.ContainsKey(read.Key))
                {
                    this.EP.HasReadAccess.Add(read.Key, 0);
                }
                this.EP.HasReadAccess[read.Key] = this.EP.HasReadAccess[read.Key] + read.Value;
            }
        }
Example #27
0
        protected void InstrumentEnsures(InstrumentationRegion region, Variable variable, bool value)
        {
            Expr expr = this.CreateExpr(variable, value);

            region.Procedure().Ensures.Add(new Ensures(false, expr));
        }
Example #28
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);
                    }
                }
            }
        }
Example #29
0
        private void AnalyseLocksetFuncForwardsUsage(string type)
        {
            if (type.Equals("tx") && this.TransmitLockHolder == null)
            {
                return;
            }

            InstrumentationRegion lockHolder = null;

            if (type.Equals("tx"))
            {
                lockHolder = this.TransmitLockHolder;
            }

            var predecessorCallees = new HashSet <InstrumentationRegion>();
            var successorCallees   = new HashSet <InstrumentationRegion>();

            bool foundCall = false;

            foreach (var block in lockHolder.Blocks())
            {
                foreach (var call in block.Cmds.OfType <CallCmd>())
                {
                    if (!foundCall && call.callee.StartsWith("_UPDATE_CLS_") &&
                        call.Ins[0].ToString().Equals("lock$" + type))
                    {
                        foundCall = true;
                    }

                    var region = this.AC.InstrumentationRegions.Find(val =>
                                                                     val.Name().Equals(call.callee + "$instrumented"));
                    if (region == null)
                    {
                        continue;
                    }

                    if (foundCall && !predecessorCallees.Contains(region))
                    {
                        successorCallees.Add(region);
                    }
                    else
                    {
                        predecessorCallees.Add(region);
                    }
                }
            }

            var predecessors = this.EP.CallGraph.NestedPredecessors(lockHolder);

            predecessorCallees.UnionWith(predecessors);

            var predSuccs = new HashSet <InstrumentationRegion>();

            foreach (var pred in predecessorCallees)
            {
                var succs = this.EP.CallGraph.NestedSuccessors(pred, lockHolder);
                predSuccs.UnionWith(succs);
            }

            predecessorCallees.UnionWith(predSuccs);

            var successors = this.EP.CallGraph.NestedSuccessors(lockHolder);

            successorCallees.UnionWith(successors);
            successorCallees.RemoveWhere(val => predecessorCallees.Contains(val));

            foreach (var succ in successorCallees)
            {
                if (type.Equals("tx"))
                {
                    succ.IsHoldingTxLock = true;
                }
            }
        }
Example #30
0
 private void CleanUpReadInRegion(InstrumentationRegion region)
 {
     region.Implementation().Proc.Modifies.RemoveAll(val =>
                                                     val.Name.StartsWith("READ_$M."));
 }