public Block CreateCallRetThunk(Address addrFrom, Procedure procOld, Procedure procNew)
{
//$BUG: ReturnAddressOnStack property needs to be properly set, the
// EvenOdd sample shows how this doesn't work currently.
var blockName = string.Format(
"{0}_thunk_{1}",
Block.GenerateName(addrFrom),
procNew.Name);
var callRetThunkBlock = procOld.AddBlock(blockName);
callRetThunkBlock.IsSynthesized = true;
var linFrom = addrFrom.ToLinear();
callRetThunkBlock.Statements.Add(
addrFrom.ToLinear(),
new CallInstruction(
new ProcedureConstant(program.Platform.PointerType, procNew),
new CallSite(
procNew.Signature.ReturnAddressOnStack,
0)));
program.CallGraph.AddEdge(callRetThunkBlock.Statements.Last, procNew);
callRetThunkBlock.Statements.Add(linFrom, new ReturnInstruction());
procOld.ControlGraph.AddEdge(callRetThunkBlock, procOld.ExitBlock);
SetProcedureReturnAddressBytes(procOld, procNew.Frame.ReturnAddressSize, addrFrom);
return callRetThunkBlock;
}