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.")); }
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)); } }
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()); } }
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)); } }
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); } } }
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); }
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_$"))); }
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); } } } }
public LocksetInstrumentation(AnalysisContext ac, EntryPoint ep) { Contract.Requires(ac != null && ep != null); this.AC = ac; this.EP = ep; this.TransmitLockHolder = null; }
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); }
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)); }
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); } } } }
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; } } } }
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); } } } }
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); } } } }
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); } }
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); } } }
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)); } } }
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); } }
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); } } } }
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(); } } } }
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; } }
protected void InstrumentEnsures(InstrumentationRegion region, Variable variable, bool value) { Expr expr = this.CreateExpr(variable, value); region.Procedure().Ensures.Add(new Ensures(false, expr)); }
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 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; } } }
private void CleanUpReadInRegion(InstrumentationRegion region) { region.Implementation().Proc.Modifies.RemoveAll(val => val.Name.StartsWith("READ_$M.")); }