private void TraverseInstructions(GraphBuilderContext context, long entrypoint, IEnumerable <long> knownBlockHeaders) { var agenda = new Stack <SymbolicProgramState <TInstruction> >(); foreach (var header in knownBlockHeaders) { agenda.Push(TransitionResolver.GetInitialState(header)); } agenda.Push(TransitionResolver.GetInitialState(entrypoint)); while (agenda.Count > 0) { // Merge the current state with the recorded states. var currentState = agenda.Pop(); bool recordedStatesChanged = ApplyStateChange(context, ref currentState); // If anything changed, we must invalidate the known successors of the current // instruction and (re)visit all its successors. if (recordedStatesChanged) { var instruction = Instructions.GetCurrentInstruction(currentState); if (context.Result.ContainsInstruction(currentState.ProgramCounter)) { context.Result.ClearSuccessors(instruction); } else { context.Result.AddInstruction(instruction); } ResolveAndScheduleSuccessors(context, currentState, instruction, agenda); } } }
/// <inheritdoc /> protected override IInstructionTraversalResult <TInstruction> CollectInstructions( long entrypoint, IEnumerable <long> knownBlockHeaders) { using var context = new GraphBuilderContext(Architecture); long[] blockHeaders = knownBlockHeaders as long[] ?? knownBlockHeaders.ToArray(); // Perform traversal. TraverseInstructions(context, entrypoint, blockHeaders); // Register known block headers. context.Result.BlockHeaders.Add(entrypoint); context.Result.BlockHeaders.UnionWith(blockHeaders); // Infer remaining block headers. DetermineBlockHeaders(context); return(context.Result); }
private static bool ApplyStateChange( GraphBuilderContext context, ref SymbolicProgramState <TInstruction> currentState) { bool changed; if (context.RecordedStates.TryGetValue(currentState.ProgramCounter, out var recordedState)) { // We are revisiting this address, merge program states. changed = recordedState.MergeStates(currentState, out currentState); if (changed) { context.RecordedStates[currentState.ProgramCounter] = currentState; } } else { // This is a new unvisited address. context.RecordedStates.Add(currentState.ProgramCounter, currentState); changed = true; } return(changed); }
private void ResolveAndScheduleSuccessors( GraphBuilderContext context, SymbolicProgramState <TInstruction> currentState, in TInstruction instruction,