示例#1
0
        private void UpdateProcedureSummary(Context ctx, Block block)
        {
            if (!propagateToCallers || !ctx.IsDirty)
            {
                return;
            }

            // Propagate defined registers to calling procedures.
            var callingBlocks = callGraph
                                .CallerStatements(block.Procedure)
                                .Cast <Statement>()
                                .Select(s => s.Block)
                                .Where(b => ssas.ContainsKey(b.Procedure));

            foreach (var caller in callingBlocks)
            {
                if (!blockCtx.TryGetValue(caller, out var succCtx))
                {
                    var ssaCaller = ssas[caller.Procedure];
                    var fpCaller  = ssaCaller.Identifiers[caller.Procedure.Frame.FramePointer].Identifier;
                    var idsCaller = blockCtx[caller.Procedure.EntryBlock].IdState;
                    var clone     = new Context(
                        ssaCaller,
                        fpCaller,
                        idsCaller,
                        procCtx[caller.Procedure]);
                    blockCtx.Add(caller, clone);
                }
                else
                {
                    succCtx.MergeWith(ctx);
                }
                worklist.Add(caller);
            }
        }
示例#2
0
        public void BlockCloner_CloneCall()
        {
            var call   = new CallInstruction(new ProcedureConstant(arch.PointerType, procCalling), new CallSite(0, 0));
            var cloner = new BlockCloner(null, procCalling, callgraph);
            var block  = new Block(procCalling, "test");

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

            Assert.AreEqual(call.Callee, newCall.Callee);
            Assert.AreEqual(1, callgraph.CallerStatements(procCalling).Count(), "Should've added a call to the callgraph");
        }
示例#3
0
        public void BlockCloner_CloneCall()
        {
            var call   = new CallInstruction(new ProcedureConstant(arch.PointerType, procCalling), new CallSite(0, 0));
            var block  = new Block(procCalling, procCalling.EntryAddress, "test");
            var stmOld = new Statement(42, call, block);

            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());
        }