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.ParametersValid) { return; } var sb = new SignatureBuilder(proc.Frame, proc.Architecture); var frame = proc.Frame; if (flow.grfLiveOut != 0) { sb.AddFlagGroupReturnValue(flow.grfLiveOut, frame); } var implicitRegs = Program.Platform.CreateImplicitArgumentRegisters(); var mayUse = new HashSet <RegisterStorage>(flow.MayUse); mayUse.ExceptWith(implicitRegs); foreach (var reg in mayUse.OrderBy(r => r.Number)) { if (!IsSubRegisterOfRegisters(reg, mayUse)) { sb.AddRegisterArgument(reg); } } foreach (var id in GetSortedStackArguments(proc.Frame).Values) { AddStackArgument(id, flow, sb); } foreach (KeyValuePair <int, Identifier> de in GetSortedFpuStackArguments(proc.Frame, 0)) { sb.AddFpuStackArgument(de.Key, de.Value); } var liveOut = new HashSet <RegisterStorage>(flow.LiveOut); liveOut.ExceptWith(implicitRegs); // Sort the names in a stable way to avoid regression tests failing. foreach (var r in liveOut.OrderBy(r => r.Number).ThenBy(r => r.BitAddress)) { if (!IsSubRegisterOfRegisters(r, liveOut)) { sb.AddOutParam(frame.EnsureRegister(r)); } } foreach (KeyValuePair <int, Identifier> de in GetSortedFpuStackArguments(proc.Frame, -proc.Signature.FpuStackDelta)) { int i = de.Key; if (i <= proc.Signature.FpuStackOutArgumentMax) { sb.AddOutParam(frame.EnsureFpuStackVariable(i, de.Value.DataType)); } } var sig = sb.BuildSignature(); flow.Signature = sig; proc.Signature = sig; }
/// <summary> /// Formats a program/module and a procedure name together. /// </summary> /// <remarks> /// This is done in the Windows way {module}!{procname}. Other platforms /// may have other conventions. Please override this in the other platforms /// to give the correct output.</remarks> /// <param name="program"></param> /// <param name="proc"></param> /// <returns></returns> public virtual string FormatProcedureName(Program program, Procedure proc) { return(string.Format("{0}!{1}", program.Name, proc.Name)); }
public virtual void InjectProcedureEntryStatements(Procedure proc, Address addr, CodeEmitter emitter) { }
public IEnumerable <object> CallerStatements(Procedure proc) { return(graphStms.Predecessors(proc)); }
public Identifier CreateOutIdentifier(Procedure proc, Identifier id) { return(proc.Frame.CreateTemporary(id.Name + "Out", id.DataType)); }
public IEnumerable <Procedure> CallerProcedures(Procedure proc) { return(graphProcs.Predecessors(proc)); }
public IEnumerable <Procedure> Callees(Procedure proc) { return(graphProcs.Successors(proc)); }
public void AddProcedure(Procedure proc) { graphProcs.AddNode(proc); graphStms.AddNode(proc); }
public SignatureBuilder(Procedure proc, IProcessorArchitecture arch) { this.proc = proc; this.arch = arch; args = new List <Identifier>(); }
public Address GetProcedureAddress(Procedure proc) { return(Procedures.Where(de => de.Value == proc) .Select(de => de.Key) .FirstOrDefault()); }