public void AddUseInstructionsForOutArguments(Procedure proc) { foreach (Identifier id in proc.Signature.Parameters) { var os = id.Storage as OutArgumentStorage; if (os == null) continue; var r = os.OriginalIdentifier.Storage as RegisterStorage; if (r == null) continue; proc.ExitBlock.Statements.Add(0, new UseInstruction(os.OriginalIdentifier, id)); } }
/// <summary> /// Creates a signature for this procedure, and ensures that all registers accessed by the procedure are in the procedure /// Frame. /// </summary> public void EnsureSignature(Procedure proc, ProcedureFlow flow) { if (proc.Signature != null && proc.Signature.ParametersValid) return; SignatureBuilder sb = new SignatureBuilder(proc, Program.Architecture); Frame frame = proc.Frame; if (flow.grfLiveOut != 0) { sb.AddFlagGroupReturnValue(flow.grfLiveOut, frame); } var implicitRegs = Program.Platform.CreateImplicitArgumentRegisters(); BitSet mayUse = flow.MayUse - implicitRegs; foreach (int r in mayUse) { if (!IsSubRegisterOfRegisters(r, mayUse)) { sb.AddRegisterArgument(r); } } foreach (KeyValuePair<int,Identifier> de in GetSortedStackArguments(proc.Frame)) { AddStackArgument(de.Key, de.Value, flow, sb); } foreach (KeyValuePair<int, Identifier> de in GetSortedFpuStackArguments(proc.Frame, 0)) { sb.AddFpuStackArgument(de.Key, de.Value); } BitSet liveOut = flow.LiveOut - implicitRegs; foreach (int r in liveOut) { if (!IsSubRegisterOfRegisters(r, liveOut)) { sb.AddArgument(frame.EnsureRegister(Program.Architecture.GetRegister(r)), true); } } foreach (KeyValuePair<int, Identifier> de in GetSortedFpuStackArguments(proc.Frame, -proc.Signature.FpuStackDelta)) { int i = de.Key; if (i <= proc.Signature.FpuStackOutArgumentMax) { sb.AddArgument(frame.EnsureFpuStackVariable(i, de.Value.DataType), true); } } var sig = sb.BuildSignature(); flow.Signature = sig; proc.Signature = sig; }
/// <summary> /// Having identified the return variable -- if any, rewrite all /// return statements to return that variable. /// </summary> /// <param name="proc"></param> private void RewriteReturns(Procedure proc) { Identifier idRet = proc.Signature.ReturnValue; if (idRet == null) return; foreach (Statement stm in proc.Statements) { var ret = stm.Instruction as ReturnInstruction; if (ret != null) { ret.Expression = idRet; } } }