public ProcedureBase ScanProcedure(Address addr, string procedureName, ProcessorState state)
{
TerminateAnyBlockAt(addr);
ExternalProcedure ep;
if (TryGetNoDecompiledProcedure(addr, out ep))
return ep;
if (program.InterceptedCalls.TryGetValue(addr, out ep))
return ep;
var trampoline = GetTrampoline(addr);
if (trampoline != null)
return trampoline;
var imp = GetImportedProcedure(addr, addr);
if (imp != null)
return imp;
Procedure proc = EnsureProcedure(addr, procedureName);
if (visitedProcs.Contains(proc))
return proc;
visitedProcs.Add(proc);
Debug.WriteLineIf(trace.TraceInfo, string.Format("Scanning procedure at {0}", addr));
var st = state.Clone();
EstablishInitialState(addr, st, proc);
//$REFACTOR: make the stack explicit?
var oldQueue = queue;
queue = new PriorityQueue<WorkItem>();
var block = EnqueueJumpTarget(addr, addr, proc, st);
proc.ControlGraph.AddEdge(proc.EntryBlock, block);
ProcessQueue();
queue = oldQueue;
InjectProcedureEntryInstructions(addr, proc);
var usb = new UserSignatureBuilder(program);
usb.BuildSignature(addr, proc);
return proc;
}