예제 #1
0
        /// <summary>
        /// Advance the backward slicer (paroxically by moving backwards in the
        /// RTL instruction stream).
        /// </summary>
        /// <returns>True if progress was made, false if there was no work left to do.</returns>
        public bool Step()
        {
            // Try finding a state that isn't at the beginning of its basic block.
            SliceState state;

            for (; ;)
            {
                if (!worklist.GetWorkItem(out state))
                {
                    return(false);
                }
                this.state = state;
                if (!state.IsInBeginningOfBlock())
                {
                    break;
                }

                DebugEx.Verbose(trace, "Reached beginning of block {0}", state.block.Address);
                var preds = host.GetPredecessors(state.block);
                if (preds.Count == 0)
                {
                    DebugEx.Verbose(trace, "  No predecessors found for block {0}", state.block.Address);
                    DebugEx.Verbose(trace, "  index: {0} ({1})", this.JumpTableIndex, this.JumpTableIndexInterval);
                    DebugEx.Verbose(trace, "  expr:  {0}", this.JumpTableFormat);
                    return(true);
                }
                foreach (var pred in preds)
                {
                    if (!visited.Contains(pred))
                    {
                        visited.Add(pred);
                        var stms = host.GetBlockInstructions(pred).ToArray();
                        //$TODO: the hack below works around the fact that some
                        // Code instructions don't exist in "raw" RTL. We are
                        // checking for a magic 1-length array of nulls as a
                        // sentinel.
                        if (stms.Length == 1 && stms[0] == null)
                        {
                            break;
                        }
                        SliceState pstate = state.CreateNew(pred, state.block.Address);
                        worklist.Add(pstate);
                        DebugEx.Verbose(trace, "  Added block {0} to worklist", pred.Address);
                    }
                }
            }
            if (state.Step())
            {
                worklist.Add(state);
                return(true);
            }
            else
            {
                return(worklist.Count > 0);
            }
        }
예제 #2
0
 /// <summary>
 /// Start a slice by examining any variables in the indirect jump
 /// <paramref name="indirectJump"/>, then start tracing instructions
 /// backwards beginning at instruction <paramref name="iInstr"/> in <paramref name="block"/>.
 /// </summary>
 /// <remarks>
 /// Any expressions discovered in this step become the "roots"
 /// of the backward slice. These roots are kept in the `Live` collection.
 /// </remarks>
 /// <param name="block">Basic block of instructions.</param>
 /// <param name="iInstr">Index into the instructions in <paramref name="block"/>.</param>
 /// <param name="indirectJump">Expression containing the target of the indirect call or jump.</param>
 /// <returns>If backward slicing should continue.</returns>
 public bool Start(RtlBlock block, int iInstr, Expression indirectJump)
 {
     this.state = new SliceState(this, block, iInstr);
     visited.Add(block);
     if (state.Start(indirectJump))
     {
         worklist.Add(state);
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #3
0
        public SliceState CreateNew(RtlBlock block, Address addrSucc)
        {
            var state = new SliceState(this.slicer, block, 0)
            {
                JumpTableFormat        = this.JumpTableFormat,
                JumpTableIndex         = this.JumpTableIndex,
                JumpTableIndexInterval = this.JumpTableIndexInterval,
                Live            = new Dictionary <Expression, BackwardSlicerContext>(this.Live, this.Live.Comparer),
                ccNext          = this.ccNext,
                invertCondition = this.invertCondition,
                addrSucc        = addrSucc,
                blockCount      = blockCount + 1
            };

            state.iInstr = state.instrs.Length - 1;
            return(state);
        }