예제 #1
0
        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);
                }
            }
        }
예제 #2
0
            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);
                }
            }