/// <summary> /// Rewrites CALL instructions to function applications. /// </summary> /// <remarks> /// Converts an instruction: /// <code> /// call procExpr /// </code> /// to one of: /// <code> /// ax = procExpr(bindings); /// procEexpr(bindings); /// </code> /// </remarks> /// <param name="ssaCaller">SSA state of the procedure in which the CALL instruction exists</param> /// <param name="stm">The particular statement of the call instruction</param> /// <param name="call">The actuall CALL instruction.</param> public bool RewriteCall(SsaState ssaCaller, Statement stm, CallInstruction call) { if (call.Callee is ProcedureConstant callee) { var procCallee = callee.Procedure; var sigCallee = procCallee.Signature; var fn = new ProcedureConstant(platform.PointerType, procCallee); if (sigCallee == null || !sigCallee.ParametersValid) { return(false); } if (stm.LinearAddress == 0x000000000001e32) { stm.ToString(); //$DEBUG } ApplicationBuilder ab = CreateApplicationBuilder(ssaCaller, stm, call, fn); var instr = ab.CreateInstruction(sigCallee, procCallee.Characteristics); var instrOld = stm.Instruction; stm.Instruction = instr; var ssam = new SsaMutator(ssaCaller); ssam.AdjustSsa(stm, call); return(true); } else { return(false); #if NOT_READY_YET //$TODO // We have an indirect call with an unknown signature. // Use the guessed `uses` and `defs` to construct a signature. // It's likely going to be wrong, but it can be overridden with // user-provided metadata. var sigCallee = MakeSignature(ssaCaller, call.Uses, call.Definitions); var ab = CreateApplicationBuilder(ssaCaller, stm, call, call.Callee); var instr = ab.CreateInstruction(sigCallee, Core.Serialization.DefaultProcedureCharacteristics.Instance); stm.Instruction = instr; var ssam = new SsaMutator(ssaCaller); ssam.AdjustSsa(stm, call); return(true); #endif } }
private void RewriteCall( Statement stm, CallInstruction ci, FunctionType sig, ProcedureCharacteristics?chr) { ssam.AdjustRegisterAfterCall( stm, ci, this.arch.StackRegister, sig.StackDelta - ci.CallSite.SizeOfReturnAddressOnStack); ssam.AdjustRegisterAfterCall( stm, ci, this.arch.FpuStackRegister, -sig.FpuStackDelta); var ab = new CallApplicationBuilder(this.ssa, stm, ci, ci.Callee, true); stm.Instruction = ab.CreateInstruction(sig, chr); ssam.AdjustSsa(stm, ci); }