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