예제 #1
0
        /// <summary>
        /// Processes the data flow of a block by beginning with
        /// the dataOut after the last instruction, simluates all instructions
        /// until the beginning of the block is reached, and percolates any
        /// *changes* to predecessor blocks to the worklist for futher processing.
        /// </summary>
        /// <param name="item">The block dataflow item we are about to process</param>
        public void ProcessBlock(BlockFlow item)
        {
            bool t = trace.TraceInfo;

            if (t)
            {
                Debug.Write(item.Block.Procedure.Name + ", ");
                DumpBlock(item.Block);
            }

            varLive.Identifiers  = new HashSet <RegisterStorage>(item.DataOut);
            varLive.Grf          = item.grfOut;
            varLive.LiveStorages = new Dictionary <Storage, int>(item.StackVarsOut);
            Debug.WriteLineIf(t, string.Format("   out: {0}", DumpRegisters(varLive.Identifiers)));
            Procedure = item.Block.Procedure;                           // Used by statements because we need to look up registers using identifiers and the procedure frame.
            StatementList stms = item.Block.Statements;

            for (int i = stms.Count - 1; i >= 0; --i)
            {
                stmCur = stms[i];
                Debug.WriteLineIf(t, stms[i].Instruction);
                stmCur.Instruction.Accept(this);
                Debug.WriteLineIf(t, string.Format("\tin: {0}", DumpRegisters(varLive.Identifiers)));
            }

            if (item.Block == item.Block.Procedure.EntryBlock)
            {
                PropagateToProcedureSummary(varLive, item.Block.Procedure);
            }
            else
            {
                PropagateToPredecessorBlocks(item);
            }
        }
예제 #2
0
 /// <summary>
 /// Propagates liveness information to predecessor blocks, but only
 /// if there are changes to their dataOut fields.
 /// </summary>
 /// <param name="item"></param>
 private void PropagateToPredecessorBlocks(BlockFlow item)
 {
     foreach (Block p in item.Block.Pred)
     {
         MergeBlockInfo(p);
     }
 }
예제 #3
0
        public void EnsureEvaluationContext(BlockFlow bf)
        {
            this.ctx = bf.SymbolicIn.Clone();
            var tes = new TrashedExpressionSimplifier(this, ctx);

            this.se = new SymbolicEvaluator(tes, ctx);
        }
예제 #4
0
            /// <summary>
            /// Merges the liveness information accumulated in <paramref name="varLive"/> into <paramref name="blockFlow"/>
            /// </summary>
            /// <param name="varLive">Current liveness state</param>
            /// <param name="blockFlow">liveness information associated with a block</param>
            /// <returns>Return true if merging the livness information changed the information in the block flow.</returns>
            public virtual bool MergeBlockInfo(IdentifierLiveness varLive, BlockFlow blockFlow)
            {
                bool ret      = false;
                int  oldCount = blockFlow.DataOut.Count;

                blockFlow.DataOut.UnionWith(varLive.Identifiers);
                if (blockFlow.DataOut.Count != oldCount)
                {
                    ret = true;
                }
                if ((varLive.Grf & (~blockFlow.grfOut)) != 0)
                {
                    blockFlow.grfOut |= varLive.Grf;
                    ret = true;
                }
                IDictionary <Storage, int> dict = blockFlow.StackVarsOut;

                foreach (KeyValuePair <Storage, int> de in varLive.LiveStorages)
                {
                    if (!dict.ContainsKey(de.Key))
                    {
                        dict.Add(de.Key, de.Value);
                        ret = true;
                    }
                }
                return(ret);
            }
예제 #5
0
        public void DumpProgram()
        {
            foreach (Procedure proc in program.Procedures.Values)
            {
                StringWriter  output = new StringWriter();
                ProcedureFlow pf     = this.flow[proc];
                TextFormatter f      = new TextFormatter(output);
                if (pf.Signature != null)
                {
                    pf.Signature.Emit(proc.Name, FunctionType.EmitFlags.None, f);
                }
                else
                {
                    proc.Signature.Emit(proc.Name, FunctionType.EmitFlags.None, f);
                }
                output.WriteLine();
                pf.Emit(proc.Architecture, output);

                output.WriteLine("// {0}", proc.Name);
                proc.Signature.Emit(proc.Name, FunctionType.EmitFlags.None, f);
                output.WriteLine();
                foreach (Block block in proc.ControlGraph.Blocks)
                {
                    if (block != null)
                    {
                        BlockFlow bf = this.flow[block];
                        bf.Emit(proc.Architecture, output);
                        output.WriteLine();
                        block.Write(output);
                    }
                }
                Debug.WriteLine(output.ToString());
            }
        }
예제 #6
0
        public void MergeBlockInfo(Block block)
        {
            BlockFlow blockFlow = mpprocData[block];

            if (state.MergeBlockInfo(varLive, blockFlow))
            {
                worklist.Add(blockFlow);
            }
        }
예제 #7
0
        public void PropagateToSuccessorBlock(Block s)
        {
            BlockFlow succFlow = flow[s];
            bool      changed  = MergeDataFlow(succFlow);

            if (changed)
            {
                worklist.Add(s);
            }
        }
 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;
 }
예제 #9
0
 public void StartProcessingBlock(Block block)
 {
     bf = flow[block];
     EnsureEvaluationContext(bf);
     if (block.Procedure.EntryBlock == block)
     {
         var sp = block.Procedure.Frame.EnsureRegister(program.Architecture.StackRegister);
         bf.SymbolicIn.RegisterState[sp.Storage] = block.Procedure.Frame.FramePointer;
     }
     ctx.TrashedFlags = bf.grfTrashedIn;
 }
예제 #10
0
 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;
 }
예제 #11
0
        /// <summary>
        /// Make summary information available in LiveIn and LiveOut for each procedure.
        /// </summary>
        private void CompleteWork()
        {
            foreach (Procedure proc in program.Procedures.Values)
            {
                ProcedureFlow pi = mpprocData[proc];

                BlockFlow bi = mpprocData[proc.ExitBlock];
                pi.LiveOut    = bi.DataOut;
                pi.grfLiveOut = bi.grfOut;

                // Remove unneeded data. Done for performance (and to give GC something to do).

                pi.ByPass.Clear();
            }
        }
예제 #12
0
 public void StartBlock(Block block)
 {
     this.block = block;
     if (this.pdf != null)
     {
         BlockFlow bf     = pdf[block];
         var       marker = new AliasDeadVariableMarker(bf.DataOut, bf.grfOut);
         deadIn = marker.Compute(arch, proc.Frame);
     }
     else
     {
         // If no global analysis available, be pessimistic and assume
         // all variables are live-out of every block.
         deadIn = new HashSet <Identifier>();
     }
 }
예제 #13
0
            public override bool MergeBlockInfo(IdentifierLiveness varLive, BlockFlow blockFlow)
            {
                bool ret = false;

                if (!(~varLive.BitSet & blockFlow.DataOut).IsEmpty)
                {
                    blockFlow.DataOut |= varLive.BitSet;
                    ret = true;
                }
                if ((~varLive.Grf & blockFlow.grfOut) != 0)
                {
                    blockFlow.grfOut |= varLive.Grf;
                    ret = true;
                }
                return(ret);
            }
예제 #14
0
		public ProgramDataFlow(Program program) : this()
		{
			foreach (Procedure proc in program.Procedures.Values)
			{
				procFlow[proc] = new ProcedureFlow(proc, program.Architecture);
				foreach (Block block in proc.ControlGraph.Blocks)
				{
					blockFlow[block] = new BlockFlow(
                        block, 
                        new HashSet<RegisterStorage>(),
                        new SymbolicEvaluationContext(
                            program.Architecture,
                            proc.Frame));
				}
			}
		}
예제 #15
0
		public ProgramDataFlow(Program prog) : this()
		{
			foreach (Procedure proc in prog.Procedures.Values)
			{
				procFlow[proc] = new ProcedureFlow(proc, prog.Architecture);
				foreach (Block block in proc.ControlGraph.Blocks)
				{
					blockFlow[block] = new BlockFlow(
                        block, 
                        prog.Architecture.CreateRegisterBitset(),
                        new SymbolicEvaluationContext(
                            prog.Architecture,
                            proc.Frame));
				}
			}
		}
예제 #16
0
 public ProgramDataFlow(Program program) : this()
 {
     foreach (Procedure proc in program.Procedures.Values)
     {
         procFlow[proc] = new ProcedureFlow(proc, proc.Architecture);
         foreach (Block block in proc.ControlGraph.Blocks)
         {
             blockFlow[block] = new BlockFlow(
                 block,
                 new HashSet <RegisterStorage>(),
                 new SymbolicEvaluationContext(
                     proc.Architecture,
                     proc.Frame));
         }
     }
 }
예제 #17
0
 public ProgramDataFlow(Program prog) : this()
 {
     foreach (Procedure proc in prog.Procedures.Values)
     {
         procFlow[proc] = new ProcedureFlow(proc, prog.Architecture);
         foreach (Block block in proc.ControlGraph.Blocks)
         {
             blockFlow[block] = new BlockFlow(
                 block,
                 prog.Architecture.CreateRegisterBitset(),
                 new SymbolicEvaluationContext(
                     prog.Architecture,
                     proc.Frame));
         }
     }
 }
예제 #18
0
            public override bool MergeBlockInfo(IdentifierLiveness varLive, BlockFlow blockFlow)
            {
                bool changed  = false;
                int  oldCount = blockFlow.DataOut.Count;

                blockFlow.DataOut.UnionWith(varLive.Identifiers);
                if (blockFlow.DataOut.Count != oldCount)
                {
                    changed = true;
                }
                if ((~varLive.Grf & blockFlow.grfOut) != 0)
                {
                    blockFlow.grfOut |= varLive.Grf;
                    changed           = true;
                }
                return(changed);
            }
예제 #19
0
            public override void InitializeBlockFlow(Block block, ProgramDataFlow flow, bool isExitBlock)
            {
                BlockFlow bf = flow[block];

                if (isExitBlock && block.Procedure.Signature.ParametersValid)
                {
                    Identifier ret = block.Procedure.Signature.ReturnValue;
                    if (ret != null)
                    {
                        RegisterStorage rs = ret.Storage as RegisterStorage;
                        if (rs != null)
                        {
                            bf.DataOut.UnionWith(arch.GetAliases(rs));
                        }
                    }
                    foreach (Identifier id in block.Procedure.Signature.Parameters)
                    {
                        OutArgumentStorage os = id.Storage as OutArgumentStorage;
                        if (os == null)
                        {
                            continue;
                        }
                        RegisterStorage rs = os.OriginalIdentifier.Storage as RegisterStorage;
                        if (rs != null)
                        {
                            bf.DataOut.UnionWith(arch.GetAliases(rs));
                        }
                    }
                }
                else if (bf.TerminatesProcess)
                {
                    bf.DataOut.Clear();
                }
                else
                {
                    bf.DataOut.Clear();
                    if (isExitBlock)
                    {
                        //Add all registers except preserved registers
                        bf.DataOut.UnionWith(arch.GetRegisters());
                        bf.DataOut.ExceptWith(flow[block.Procedure].PreservedRegisters);
                    }
                }
            }
예제 #20
0
        public bool MergeDataFlow(BlockFlow succFlow)
        {
            var  ctxSucc = succFlow.SymbolicIn;
            bool changed = false;

            foreach (var de in ctx.RegisterState)
            {
                Expression oldValue;
                if (!ctxSucc.RegisterState.TryGetValue(de.Key, out oldValue))
                {
                    ctxSucc.RegisterState[de.Key] = de.Value;
                    changed = true;
                }
                else if (oldValue != Constant.Invalid && !ecomp.Equals(oldValue, de.Value))
                {
                    ctxSucc.RegisterState[de.Key] = Constant.Invalid;
                    changed = true;
                }
            }

            foreach (var de in ctx.StackState)
            {
                Expression oldValue;
                if (!ctxSucc.StackState.TryGetValue(de.Key, out oldValue))
                {
                    ctxSucc.StackState[de.Key] = de.Value;
                    changed = true;
                }
                else if (!ecomp.Equals(oldValue, de.Value) && oldValue != Constant.Invalid)
                {
                    ctxSucc.StackState[de.Key] = Constant.Invalid;
                    changed = true;
                }
            }

            uint grfNew = succFlow.grfTrashedIn | ctx.TrashedFlags;

            if (grfNew != succFlow.grfTrashedIn)
            {
                succFlow.grfTrashedIn = grfNew;
                changed = true;
            }
            return(changed);
        }
예제 #21
0
            public override void InitializeBlockFlow(Block block, ProgramDataFlow flow, bool isExitBlock)
            {
                BlockFlow bf = flow[block];

                if (isExitBlock && block.Procedure.Signature.ParametersValid)
                {
                    Identifier ret = block.Procedure.Signature.ReturnValue;
                    if (ret != null)
                    {
                        RegisterStorage rs = ret.Storage as RegisterStorage;
                        if (rs != null)
                        {
                            rs.SetAliases(bf.DataOut, true);
                        }
                    }
                    foreach (Identifier id in block.Procedure.Signature.Parameters)
                    {
                        OutArgumentStorage os = id.Storage as OutArgumentStorage;
                        if (os == null)
                        {
                            continue;
                        }
                        RegisterStorage rs = os.OriginalIdentifier.Storage as RegisterStorage;
                        if (rs != null)
                        {
                            rs.SetAliases(bf.DataOut, true);
                        }
                    }
                }
                else if (bf.TerminatesProcess)
                {
                    bf.DataOut.SetAll(false);
                }
                else
                {
                    bf.DataOut.SetAll(isExitBlock);
                    bf.DataOut &= ~flow[block.Procedure].PreservedRegisters;
                }
            }
예제 #22
0
 private void Given_Contexts()
 {
     frame = new Frame(PrimitiveType.Pointer32);
     ctx = new SymbolicEvaluationContext(arch, frame);
     blockflow = new BlockFlow(null, new HashSet<RegisterStorage>(), ctx);
     trf.EnsureEvaluationContext(blockflow);
 }
예제 #23
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);
 }
예제 #24
0
        public void TrfPropagateToSuccessorBlocks()
        {
            Procedure proc = new Procedure("test", program.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(program.Architecture, frame));
            flow[e] = new BlockFlow(e, null, new SymbolicEvaluationContext(program.Architecture, frame));

            trf = CreateTrashedRegisterFinder(program);
            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");
        }