Пример #1
0
 /// <summary>
 /// Given block flow, computes its live branches given the cells to
 /// which values evaluate.
 /// </summary>
 /// <param name="flow">
 /// The block flow to consider.
 /// </param>
 /// <param name="cells">
 /// The lattice cells currently assigned to values in the graph.
 /// </param>
 /// <param name="graph">
 /// The control-flow graph that defines <paramref name="flow"/>.
 /// </param>
 /// <returns>A sequence of live branches.</returns>
 public virtual IEnumerable <Branch> GetLiveBranches(
     BlockFlow flow,
     IReadOnlyDictionary <ValueTag, TCell> cells,
     FlowGraph graph)
 {
     return(flow.Branches);
 }
Пример #2
0
 private void Given_Contexts()
 {
     frame     = new Frame(PrimitiveType.Pointer32);
     ctx       = new SymbolicEvaluationContext(arch, frame);
     blockflow = new BlockFlow(null, arch.CreateRegisterBitset(), ctx);
     trf.EnsureEvaluationContext(blockflow);
 }
 private void Given_Contexts()
 {
     frame     = new Frame(PrimitiveType.Ptr32);
     ctx       = new SymbolicEvaluationContext(arch, frame);
     blockflow = new BlockFlow(null, new HashSet <RegisterStorage>(), ctx);
     trf.EnsureEvaluationContext(blockflow);
 }
Пример #4
0
        private LNode Encode(
            BlockFlow flow,
            UniqueNameMap <UniqueTag> blockNameMap,
            UniqueNameMap <UniqueTag> valueNameMap)
        {
            if (flow is UnreachableFlow)
            {
                return(Factory.Id(unreachableFlowSymbol));
            }
            else if (flow is JumpFlow)
            {
                return(Factory.Call(
                           CodeSymbols.Goto,
                           Encode(((JumpFlow)flow).Branch, blockNameMap, valueNameMap)));
            }
            else if (flow is ReturnFlow)
            {
                return(Factory.Call(
                           CodeSymbols.Return,
                           Encode(((ReturnFlow)flow).ReturnValue, valueNameMap)));
            }
            else if (flow is TryFlow)
            {
                var tryFlow = (TryFlow)flow;

                return(Factory.Call(
                           CodeSymbols.Try,
                           Encode(tryFlow.Instruction, valueNameMap),
                           Encode(tryFlow.SuccessBranch, blockNameMap, valueNameMap),
                           Encode(tryFlow.ExceptionBranch, blockNameMap, valueNameMap)));
            }
            else if (flow is SwitchFlow)
            {
                var switchFlow = (SwitchFlow)flow;

                var caseNodes = new List <LNode>();
                foreach (var switchCase in switchFlow.Cases)
                {
                    caseNodes.Add(
                        Factory.Call(
                            CodeSymbols.Case,
                            Factory.Call(CodeSymbols.AltList, switchCase.Values.Select(Encode)),
                            Encode(switchCase.Branch, blockNameMap, valueNameMap)));
                }

                return(Factory.Call(
                           CodeSymbols.Switch,
                           Encode(switchFlow.SwitchValue, valueNameMap),
                           Encode(switchFlow.DefaultBranch, blockNameMap, valueNameMap),
                           Factory.Call(CodeSymbols.Braces, caseNodes)));
            }
            else
            {
                throw new NotSupportedException(
                          "Cannot encode unknown block flow '" + flow + "'.");
            }
        }
Пример #5
0
        private BlockFlow CreateBlockFlow(Block block, Frame frame)
        {
            var bflow = new BlockFlow(
                block,
                prog.Architecture.CreateRegisterBitset(),
                new SymbolicEvaluationContext(
                    prog.Architecture,
                    frame));

            flow[block] = bflow;
            return(bflow);
        }
        private BlockFlow CreateBlockFlow(Block block, Frame frame)
        {
            var bflow = new BlockFlow(
                block,
                new HashSet <RegisterStorage>(),
                new SymbolicEvaluationContext(
                    program.Architecture,
                    frame));

            flow[block] = bflow;
            return(bflow);
        }
Пример #7
0
        private void EmitProgram(Program program, DataFlowAnalysis dfa, TextWriter output)
        {
            if (output == null)
            {
                return;
            }
            foreach (Procedure proc in program.Procedures.Values)
            {
                if (program.NeedsSsaTransform && dfa != null)
                {
                    ProcedureFlow flow = dfa.ProgramDataFlow[proc];
                    TextFormatter f    = new TextFormatter(output);
                    if (flow.Signature != null)
                    {
                        flow.Signature.Emit(proc.Name, FunctionType.EmitFlags.LowLevelInfo, f);
                    }
                    else if (proc.Signature != null)
                    {
                        proc.Signature.Emit(proc.Name, FunctionType.EmitFlags.LowLevelInfo, f);
                    }
                    else
                    {
                        output.Write("Warning: no signature found for {0}", proc.Name);
                    }
                    output.WriteLine();
                    flow.Emit(program.Architecture, output);
                    foreach (Block block in new DfsIterator <Block>(proc.ControlGraph).PostOrder().Reverse())
                    {
                        if (block == null)
                        {
                            continue;
                        }
                        block.Write(output);

                        BlockFlow bf = dfa.ProgramDataFlow[block];
                        if (bf != null)
                        {
                            bf.Emit(program.Architecture, output);
                            output.WriteLine();
                        }
                    }
                }
                else
                {
                    proc.Write(false, output);
                }
                output.WriteLine();
                output.WriteLine();
            }
            output.Flush();
        }
Пример #8
0
 public override IEnumerable <Branch> GetLiveBranches(
     BlockFlow flow,
     IReadOnlyDictionary <ValueTag, LatticeCell> cells,
     FlowGraph graph)
 {
     if (flow is SwitchFlow)
     {
         var switchFlow = (SwitchFlow)flow;
         var condition  = Evaluate(switchFlow.SwitchValue, cells, graph);
         if (condition.Kind == LatticeCellKind.Top)
         {
             // Do nothing for now.
             return(EmptyArray <Branch> .Value);
         }
         else if (condition.Kind == LatticeCellKind.Constant)
         {
             // If a switch flow has a constant condition (for now),
             // then pick a single branch.
             var valuesToBranches = switchFlow.ValueToBranchMap;
             return(new[]
             {
                 valuesToBranches.ContainsKey(condition.Value)
                     ? valuesToBranches[condition.Value]
                     : switchFlow.DefaultBranch
             });
         }
         else if (condition.Kind == LatticeCellKind.NonNull)
         {
             // If a switch flow has a non-null condition, then we
             // work on all branches except for the null branch, if
             // it exists.
             return(switchFlow.ValueToBranchMap
                    .Where(pair => pair.Key != NullConstant.Instance)
                    .Select(pair => pair.Value)
                    .Concat(new[] { switchFlow.DefaultBranch })
                    .ToArray());
         }
         else
         {
             // If a switch flow has a bottom condition, then everything
             // is possible.
             return(flow.Branches);
         }
     }
     else
     {
         return(flow.Branches);
     }
 }
Пример #9
0
        public void Rl_ProcedureWithTrashedAndPreservedRegisters()
        {
            Procedure     proc = new Procedure("test", prog.Architecture.CreateFrame());
            ProcedureFlow pf   = new ProcedureFlow(proc, prog.Architecture);

            mpprocflow[proc] = pf;
            pf.TrashedRegisters[Registers.eax.Number]   = true;
            pf.TrashedRegisters[Registers.ebx.Number]   = true;
            pf.PreservedRegisters[Registers.ebp.Number] = true;
            pf.PreservedRegisters[Registers.bp.Number]  = true;

            RegisterLiveness.State st = new RegisterLiveness.ByPassState();
            BlockFlow bf = CreateBlockFlow(proc.ExitBlock, proc.Frame);

            mpprocflow[proc.ExitBlock] = bf;
            st.InitializeBlockFlow(proc.ExitBlock, mpprocflow, true);
            Assert.IsFalse(bf.DataOut[Registers.ebp.Number], "preserved registers cannot be live out");
            Assert.IsFalse(bf.DataOut[Registers.bp.Number], "preserved registers cannot be live out");
            Assert.IsTrue(bf.DataOut[Registers.eax.Number], "trashed registers may be live out");
            Assert.IsTrue(bf.DataOut[Registers.esi.Number], "Unmentioned registers may be live out");
        }
Пример #10
0
            /// <inheritdoc/>
            public override BlockFlow Emit(FlowGraphBuilder graph, ValueTag value)
            {
                int caseCounter = 0;
                BasicBlockBuilder currentBlock = null;
                var       defaultJump          = new JumpFlow(flow.DefaultBranch);
                BlockFlow result = defaultJump;

                foreach (var switchCase in flow.Cases)
                {
                    foreach (var pattern in switchCase.Values)
                    {
                        caseCounter++;
                        var nextBlock = graph.AddBasicBlock("case" + caseCounter);
                        var blockFlow = new SwitchFlow(
                            Instruction.CreateCopy(graph.GetValueType(value), value),
                            new[]
                        {
                            new SwitchCase(ImmutableHashSet.Create(pattern), switchCase.Branch)
                        },
                            new Branch(nextBlock));

                        if (currentBlock == null)
                        {
                            result = blockFlow;
                        }
                        else
                        {
                            currentBlock.Flow = blockFlow;
                        }
                        currentBlock = nextBlock;
                    }
                }

                if (currentBlock != null)
                {
                    currentBlock.Flow = defaultJump;
                }

                return(result);
            }
Пример #11
0
        public void TrfPropagateToSuccessorBlocks()
        {
            Procedure  proc  = new Procedure("test", prog.Architecture.CreateFrame());
            var        frame = proc.Frame;
            Identifier ecx   = m.Register(1);
            Identifier edx   = m.Register(2);
            Identifier ebx   = m.Register(3);
            Block      b     = proc.AddBlock("b");
            Block      t     = proc.AddBlock("t");
            Block      e     = proc.AddBlock("e");

            proc.ControlGraph.AddEdge(b, e);
            proc.ControlGraph.AddEdge(b, t);
            flow[t] = new BlockFlow(t, null, new SymbolicEvaluationContext(prog.Architecture, frame));
            flow[e] = new BlockFlow(e, null, new SymbolicEvaluationContext(prog.Architecture, frame));

            trf = CreateTrashedRegisterFinder(prog);
            CreateBlockFlow(b, frame);
            trf.StartProcessingBlock(b);
            trf.RegisterSymbolicValues[(RegisterStorage)ecx.Storage] = Constant.Invalid;
            trf.RegisterSymbolicValues[(RegisterStorage)edx.Storage] = ebx;

            flow[e].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage] = edx;
            flow[e].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage] = ebx;

            flow[t].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage] = Constant.Invalid;
            flow[t].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage] = edx;

            trf.PropagateToSuccessorBlock(e);
            trf.PropagateToSuccessorBlock(t);
            Assert.AreEqual(2, proc.ControlGraph.Successors(b).Count);
            Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage].ToString(), "trash & r2 => trash");
            Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage].ToString(), "ebx & ebx => ebx");
            Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage].ToString(), "trash & r2 => trash");
            Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage].ToString(), "ebx & ebx => ebx");

            Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage].ToString(), "trash & trash => trash");
            Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage].ToString(), "r3 & r2 => trash");
        }
Пример #12
0
        public void Rl_PredefinedSignature()
        {
            Procedure  callee = new Procedure(program.Architecture, "callee", null);
            Identifier edx    = new Identifier("edx", PrimitiveType.Word32, Registers.edx);

            callee.Signature = new FunctionType(
                new Identifier("eax", PrimitiveType.Word32, Registers.eax),
                new Identifier[] { new Identifier("ecx", PrimitiveType.Word32, Registers.ecx),
                                   new Identifier("arg04", PrimitiveType.Word16, new StackArgumentStorage(4, PrimitiveType.Word16)),
                                   new Identifier("edxOut", PrimitiveType.Word32, new OutArgumentStorage(edx)) });

            RegisterLiveness.State st = new RegisterLiveness.ByPassState(program.Architecture);
            BlockFlow bf = CreateBlockFlow(callee.ExitBlock, null);

            mpprocflow[callee.ExitBlock] = bf;
            st.InitializeBlockFlow(callee.ExitBlock, mpprocflow, true);
            Assert.IsTrue(bf.DataOut.Contains(Registers.eax), "eax is a return register");
            Assert.IsTrue(bf.DataOut.Contains(Registers.edx), "edx is an out register");
            Assert.IsTrue(bf.DataOut.Contains(Registers.ax), "ax is aliased by eax");
            Assert.IsFalse(bf.DataOut.Contains(Registers.ecx), "ecx is an in register");
            Assert.IsFalse(bf.DataOut.Contains(Registers.esi), "esi is not present in signature");
        }
Пример #13
0
 /// <summary>
 /// Terminates the block with a particular flow.
 /// </summary>
 /// <param name="flow">The flow to terminate the block with.</param>
 public void Terminate(BlockFlow flow)
 {
     Block.Flow   = flow;
     IsTerminated = true;
 }