Ejemplo n.º 1
0
		public void Creation()
		{
			CallGraph g = new CallGraph();
			Procedure p1 = new Procedure("p1000", null);
			Procedure p2 = new Procedure("p2000", null);
			Procedure p3 = new Procedure("p3000", null);
			Procedure p4 = new Procedure("p4000", null);

            var pc1 = new ProcedureConstant(PrimitiveType.Pointer32, p1);
            var pc2 = new ProcedureConstant(PrimitiveType.Pointer32, p2);
            var pc3 = new ProcedureConstant(PrimitiveType.Pointer32, p3);
            var pc4 = new ProcedureConstant(PrimitiveType.Pointer32, p4);

            Statement s11 = new Statement(0, CreateCall(pc2), p1.EntryBlock);
            Statement s12 = new Statement(0, CreateCall(pc2), p1.EntryBlock);
            Statement s13 = new Statement(0, CreateCall(pc3), p1.EntryBlock);
			p1.EntryBlock.Statements.Add(s11);
			p1.EntryBlock.Statements.Add(s12);
			p1.EntryBlock.Statements.Add(s13);

            Statement s21 = new Statement(0, CreateCall(pc3), p2.EntryBlock);
            Statement s22 = new Statement(0, CreateCall(pc4), p2.EntryBlock);
			p2.EntryBlock.Statements.Add(s21);
			p2.EntryBlock.Statements.Add(s22);

            Statement s31 = new Statement(0, CreateCall(pc4), p3.EntryBlock);
			p3.EntryBlock.Statements.Add(s31);

            Statement s41 = new Statement(0, CreateCall(pc4), p4.EntryBlock);

			g.AddEntryPoint(p1);
			g.AddEdge(s11, p2);
			g.AddEdge(s12, p2);
			g.AddEdge(s13, p3);

			g.AddEdge(s21, p3);
			g.AddEdge(s22, p4);

			g.AddEdge(s31, p4);

			g.AddEdge(s41, p4);		// recursion!

            //$TODO: need Count
//			Assert.IsTrue(g.Callees(p1).Count == 3);
//			Assert.IsTrue(g.CallerStatements(p4).Count == 3);
		}
Ejemplo n.º 2
0
        public void BlockCloner_CloneCall()
        {
            var call   = new CallInstruction(new ProcedureConstant(arch.PointerType, procCalling), new CallSite(0, 0));
            var block  = new Block(procCalling, "test");
            var stmOld = new Statement(42, call, block);

            callgraph.AddStatement(stmOld);
            callgraph.AddProcedure(procCalling);
            callgraph.AddEdge(stmOld, procCalling);

            var cloner = new BlockCloner(null, procCalling, callgraph);

            cloner.Statement    = stmOld;
            cloner.StatementNew = new Statement(42, null, block);
            var newCall = (CallInstruction)call.Accept(cloner);

            cloner.StatementNew.Instruction = newCall;
            Assert.AreEqual(call.Callee, newCall.Callee);
            Assert.AreEqual(2, callgraph.CallerStatements(procCalling).Count(), "Should've added a call to the callgraph");
            Assert.AreEqual(1, callgraph.Callees(cloner.Statement).Count());
            Assert.AreEqual(1, callgraph.Callees(cloner.StatementNew).Count());
        }
Ejemplo n.º 3
0
        public bool EnqueueRoutine(IPhpRoutineSymbol routine, T caller, BoundRoutineCall callExpression)
        {
            Contract.ThrowIfNull(routine);

            if (routine.ControlFlowGraph == null)
            {
                var routine2 = routine is SynthesizedMethodSymbol sr
                    ? sr.ForwardedCall
                    : routine.OriginalDefinition as IPhpRoutineSymbol;

                if (routine2 != null && !ReferenceEquals(routine, routine2))
                {
                    return(EnqueueRoutine(routine2, caller, callExpression));
                }

                // library (sourceless) function
                return(false);
            }

            var sourceRoutine = (SourceRoutineSymbol)routine;

            if (sourceRoutine.SyntaxReturnType != null)
            {
                // we don't have to wait for return type,
                // nor reanalyse itself when routine analyses
                return(false);
            }

            _callGraph.AddEdge(caller.FlowState.Routine, sourceRoutine, new CallSite(caller, callExpression));

            // ensure caller is subscribed to routine's ExitBlock
            ((ExitBlock)routine.ControlFlowGraph.Exit).Subscribe(caller);

            // TODO: check if routine has to be reanalyzed => enqueue routine's StartBlock

            // Return whether the routine exit block will certainly be analysed in the future
            return(!sourceRoutine.IsReturnAnalysed);
        }
Ejemplo n.º 4
0
        public Instruction VisitCallInstruction(CallInstruction ci)
        {
            var oldCallee = ci.Callee;

            ci.Callee = ci.Callee.Accept(eval);
            if (ci.Callee is ProcedureConstant pc)
            {
                if (pc.Procedure.Signature.ParametersValid)
                {
                    var sig = pc.Procedure.Signature;
                    var chr = pc.Procedure.Characteristics;
                    RewriteCall(stmCur, ci, sig, chr);
                    return(stmCur.Instruction);
                }
                if (oldCallee != pc && pc.Procedure is Procedure procCallee)
                {
                    // This was an indirect call, but is now a direct call.
                    // Make sure the call graph knows about the link between
                    // this statement and the callee.
                    callGraph.AddEdge(stmCur, procCallee);
                }
            }
            return(ci);
        }