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 bool AnalyseCallAccessesInRegion(InstrumentationRegion region) { int preCount = 0; int afterCount = 0; foreach (var r in region.GetResourceAccesses()) { preCount = preCount + r.Value.Count; } foreach (var call in region.CallInformation.Keys) { var calleeRegion = this.AC.InstrumentationRegions.Find(val => val.Implementation().Name.Equals(call.callee)); if (calleeRegion.IsNotAccessingResources) { continue; } foreach (var r in calleeRegion.GetResourceAccesses()) { if (!region.ExternallyReceivedAccesses[call].ContainsKey(r.Key)) { region.ExternallyReceivedAccesses[call].Add(r.Key, new HashSet <Expr>()); } foreach (var a in r.Value) { if (region.ExternallyReceivedAccesses[call][r.Key].Contains(a)) { continue; } int index; if (a is NAryExpr) { index = this.TryGetArgumentIndex(call, calleeRegion, (a as NAryExpr).Args[0]); } else { index = this.TryGetArgumentIndex(call, calleeRegion, a); } if (index < 0) { continue; } if (!region.CallInformation[call].ContainsKey(index)) { continue; } var calleeExpr = region.CallInformation[call][index]; var computedExpr = this.ComputeExpr(calleeExpr.Item1, a); var id = this.PtrAnalysisCache[region].GetIdentifier(computedExpr); if (this.PtrAnalysisCache[region].IsAxiom(id)) { if (!this.AC.AxiomAccessesMap.ContainsKey(r.Key)) { this.AC.AxiomAccessesMap.Add(r.Key, new HashSet <Expr>()); } if (!this.AC.AxiomAccessesMap[r.Key].Any(val => val.ToString().Equals(computedExpr.ToString()))) { this.AC.AxiomAccessesMap[r.Key].Add(computedExpr); } } else { region.TryAddResourceAccess(r.Key, computedExpr); region.ExternallyReceivedAccesses[call][r.Key].Add(a); } } } if (WhoopCommandLineOptions.Get().OptimiseHeavyAsyncCalls&& (this.AC.GetNumOfEntryPointRelatedFunctions(this.EP.Name) > WhoopCommandLineOptions.Get().EntryPointFunctionCallComplexity)) { continue; } foreach (var pair in region.GetResourceAccesses()) { foreach (var access in pair.Value) { foreach (var index in region.CallInformation[call].Keys) { if (!region.CallInformation[call].ContainsKey(index)) { continue; } var calleeExpr = region.CallInformation[call][index]; var mappedExpr = this.ComputeMappedExpr(access, calleeExpr.Item1, calleeExpr.Item2); if (mappedExpr != null) { this.CacheMatchedAccesses(pair.Key, access, mappedExpr); if (calleeRegion.TryAddExternalResourceAccesses(pair.Key, mappedExpr)) { afterCount++; } } } } } } foreach (var r in region.GetResourceAccesses()) { afterCount = afterCount + r.Value.Count; } if (preCount != afterCount) { return(false); } else { return(true); } }
private void InstrumentInParamAliasInformationInRegion(InstrumentationRegion region) { if (region.Procedure().InParams.Count <= 1) { return; } var inParamMap = new Dictionary <string, Dictionary <Variable, int> >(); foreach (var resource in region.GetResourceAccesses()) { if (!inParamMap.ContainsKey(resource.Key)) { inParamMap.Add(resource.Key, new Dictionary <Variable, int>()); } foreach (var access in resource.Value) { IdentifierExpr id = null; var num = 0; if (access is NAryExpr) { id = (access as NAryExpr).Args[0] as IdentifierExpr; num = ((access as NAryExpr).Args[1] as LiteralExpr).asBigNum.ToInt; } else if (access is IdentifierExpr) { id = access as IdentifierExpr; } if (id == null) { continue; } var inParam = region.Procedure().InParams.Find(val => val.Name.Equals(id.Name)); if (inParam == null) { continue; } if (!inParamMap[resource.Key].ContainsKey(inParam)) { inParamMap[resource.Key].Add(inParam, num); } else if (inParamMap[resource.Key][inParam] < num) { inParamMap[resource.Key][inParam] = num; } } } foreach (var resource in inParamMap) { if (resource.Value.Count <= 1) { continue; } var pairs = resource.Value.ToList(); for (int i = 0; i < pairs.Count - 1; i++) { for (int j = i + 1; j < pairs.Count; j++) { var id1 = new IdentifierExpr(pairs[i].Key.tok, pairs[i].Key); var id2 = new IdentifierExpr(pairs[j].Key.tok, pairs[j].Key); var num1 = new LiteralExpr(Token.NoToken, BigNum.FromInt(pairs[i].Value)); var num2 = new LiteralExpr(Token.NoToken, BigNum.FromInt(pairs[j].Value)); var lexpr = Expr.Lt(new NAryExpr(Token.NoToken, new BinaryOperator(Token.NoToken, BinaryOperator.Opcode.Add), new List <Expr> { id1, num1 }), id2); var rexpr = Expr.Lt(new NAryExpr(Token.NoToken, new BinaryOperator(Token.NoToken, BinaryOperator.Opcode.Add), new List <Expr> { id2, num2 }), id1); if (!this.InstrumentAssumes(region, id1, id2, num1, num2)) { this.RequiresMap.Clear(); this.AssumesMap.Clear(); return; } if (!this.RequiresMap.ContainsKey(region)) { this.RequiresMap.Add(region, new HashSet <Requires>()); } this.RequiresMap[region].Add(new Requires(false, Expr.Or(lexpr, rexpr))); } } } }
private bool IdentifyCallAccessesInRegion(InstrumentationRegion region) { int numberOfCalls = 0; int numberOfNonCheckedCalls = 0; foreach (var block in region.Implementation().Blocks) { for (int idx = 0; idx < block.Cmds.Count; idx++) { if (!(block.Cmds[idx] is CallCmd)) { continue; } var call = block.Cmds[idx] as CallCmd; bool isInstrumentedCall = false; if (idx + 1 < block.Cmds.Count && block.Cmds[idx + 1] is AssumeCmd) { isInstrumentedCall = QKeyValue.FindStringAttribute((block.Cmds[idx + 1] as AssumeCmd).Attributes, "captureState") != null; } if (!isInstrumentedCall) { numberOfCalls++; var calleeRegion = this.AC.InstrumentationRegions.Find(val => val.Implementation().Name.Equals(call.callee)); if (calleeRegion == null) { numberOfNonCheckedCalls++; continue; } if (calleeRegion.GetResourceAccesses().Count == 0 && calleeRegion.IsNotAccessingResources) { numberOfNonCheckedCalls++; continue; } if (!region.CallInformation.ContainsKey(call)) { region.CallInformation.Add(call, new Dictionary <int, Tuple <Expr, Expr> >()); region.ExternallyReceivedAccesses.Add(call, new Dictionary <string, HashSet <Expr> >()); for (int i = 0; i < call.Ins.Count; i++) { var id = calleeRegion.Implementation().InParams[i]; HashSet <Expr> ptrExprs = null; this.PtrAnalysisCache[region].TryComputeRootPointers(call.Ins[i], out ptrExprs); foreach (var ptrExpr in ptrExprs) { region.CallInformation[call].Add(i, new Tuple <Expr, Expr>(ptrExpr, new IdentifierExpr(id.tok, id))); break; } } } } } } if (numberOfCalls == numberOfNonCheckedCalls && region.HasWriteAccess.Count == 0 && this.EP.ForceWriteResource.Count == 0) { this.CleanUpWriteInRegion(region); region.IsNotWriteAccessingResources = true; } if (numberOfCalls == numberOfNonCheckedCalls && region.HasReadAccess.Count == 0 && this.EP.ForceReadResource.Count == 0) { this.CleanUpReadInRegion(region); region.IsNotReadAccessingResources = true; } if (numberOfCalls == numberOfNonCheckedCalls && region.GetResourceAccesses().Count == 0 && this.EP.ForceWriteResource.Count == 0 && this.EP.ForceReadResource.Count == 0) { this.CleanUpRegion(region); region.IsNotAccessingResources = true; return(false); } return(true); }
private void InstrumentMemoryLocksetInvariantsInRegion(InstrumentationRegion region) { foreach (var pair in region.GetResourceAccesses()) { var memLsVars = base.MemoryLocksetVariables.FindAll(val => val.Name.Contains(pair.Key + "_$")); if (this.EP.ForceWriteResource.Contains(pair.Key) || this.EP.ForceReadResource.Contains(pair.Key)) { continue; } if (!this.EP.HasWriteAccess.ContainsKey(pair.Key) && !this.EP.HasReadAccess.ContainsKey(pair.Key)) { foreach (var variable in memLsVars) { base.InstrumentRequires(region, variable, true); base.InstrumentEnsures(region, variable, true); foreach (var block in region.LoopHeaders()) { base.InstrumentAssert(block, variable, true); } } 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 memLsVars) { if (this.ShouldLock(region, variable)) { continue; } base.InstrumentImpliesRequiresCandidate(region, watchedExpr, variable, true, true); base.InstrumentImpliesEnsuresCandidate(region, watchedExpr, variable, true, true); foreach (var block in region.LoopHeaders()) { base.InstrumentImpliesAssertCandidate(block, watchedExpr, variable, true, 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)); } } } var lockVars = new HashSet <Variable>(); foreach (var variable in memLsVars) { if (this.ShouldLock(region, variable)) { lockVars.Add(variable); continue; } base.InstrumentImpliesRequiresCandidate(region, nonWatchedExpr, variable, true, true); base.InstrumentImpliesEnsuresCandidate(region, nonWatchedExpr, variable, true, true); foreach (var block in region.LoopHeaders()) { base.InstrumentImpliesAssertCandidate(block, nonWatchedExpr, variable, true, 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); } } } }