private void HashSubroutine(Subroutine subroutine) { var ilDecoder = this.mDriver.StackLayer.Decoder; if (hashedSubroutines.Contains(subroutine)) { return; } this.hashedSubroutines.Add(subroutine); // Hash the name this.tw.WriteLine("SUBROUTINE{0} {1}", this.subroutineIdentifier(subroutine), subroutine.Kind); // Hash all the blocks foreach (var block in subroutine.Blocks) { this.tw.WriteLine("Block {0}", block.Index); this.tw.WriteLine(" Handlers: "); // TODO : handlers - we ignore them now, as in Clousot's analysis we do it too! this.tw.WriteLine(" Code:"); foreach (var apc in block.APCs()) { ilDecoder.ForwardDecode <Unit, Unit, ILHasher>(apc, this.ilHasher, Unit.Value); } var subroutinesToVisit = new Set <Subroutine>(subroutine.UsedSubroutines()); var stackCFG = this.mDriver.StackLayer.Decoder.Context.MethodContext.CFG; this.tw.WriteLine(" Successors:"); foreach (var taggedSucc in subroutine.SuccessorEdgesFor(block)) { this.tw.Write("({0},{1}", taggedSucc.One, taggedSucc.Two.Index); // The order of successors edges is not deterministic (why?), hence the OrderBy var edgesubs = stackCFG.GetOrdinaryEdgeSubroutines(block, taggedSucc.Two, null).GetEnumerable() .Select(edgesub => new Tuple <string, Subroutine>(String.Format(" SUBROUTINE{0}({1})", this.subroutineIdentifier(edgesub.Two), edgesub.One), edgesub.Two)) .OrderBy(x => x.Item1); foreach (var edgesub in edgesubs) { this.tw.Write(edgesub.Item1); subroutinesToVisit.Add(edgesub.Item2); } this.tw.Write(") "); } this.tw.WriteLine(); // Go recursively //foreach (var usedSubroutine in subroutine.UsedSubroutines().OrderBy(s => this.subroutineIdentifier(s))) foreach (var usedSubroutine in subroutinesToVisit.OrderBy(s => this.subroutineIdentifier(s))) { HashSubroutine(usedSubroutine); } } }
private void Touch(Subroutine subroutine) { Contract.Requires(subroutine != null); if (!this.visitedSubroutines.Add(subroutine)) { return; } var usedSubroutines = new Set <Subroutine>(subroutine.UsedSubroutines()); var stackCFG = this.mDriver.StackLayer.Decoder.Context.MethodContext.CFG; foreach (var block in subroutine.Blocks) { Contract.Assume(block != null); foreach (var apc in block.APCs()) { mDriver.StackLayer.Decoder.ForwardDecode <Unit, Unit, SlicerMethodVisitor>(apc, this, Unit.Value); } foreach (var taggedSucc in subroutine.SuccessorEdgesFor(block)) { foreach (var edgeSub in stackCFG.GetOrdinaryEdgeSubroutines(block, taggedSucc.Two, null).GetEnumerable()) { var sub = edgeSub.Two; usedSubroutines.Add(sub); var methodInfo = sub as IMethodInfo <Method>; if (methodInfo != null && !this.mDriver.CurrentMethod.Equals(methodInfo.Method)) { this.parent.Touch(methodInfo.Method); } } } } foreach (var usedSubroutine in usedSubroutines) { this.Touch(usedSubroutine); } }