private bool OnAfterCall(FunctionType sigCallee, ProcedureCharacteristics characteristics) { UserCallData userCall = null; if (program.User.Calls.TryGetUpperBound(ric.Address, out userCall)) { var linStart = ric.Address.ToLinear(); var linEnd = linStart + ric.Length; var linUserCall = userCall.Address.ToLinear(); if (linStart > linUserCall || linUserCall >= linEnd) { userCall = null; } } if ((characteristics != null && characteristics.Terminates) || (userCall != null && userCall.NoReturn)) { scanner.TerminateBlock(blockCur, ric.Address + ric.Length); return(false); } if (sigCallee != null) { if (sigCallee.StackDelta != 0) { Expression newVal = new BinaryExpression( Operator.IAdd, stackReg.DataType, stackReg, Constant.Create( PrimitiveType.CreateWord(stackReg.DataType.Size), sigCallee.StackDelta)); newVal = newVal.Accept(eval); SetValue(stackReg, newVal); } } state.OnAfterCall(sigCallee); // Adjust stack after call if (sigCallee != null) { int delta = sigCallee.StackDelta - sigCallee.ReturnAddressOnStack; if (delta != 0) { var d = Constant.Create(stackReg.DataType, delta); this.Emit(new Assignment( stackReg, new BinaryExpression(Operator.IAdd, stackReg.DataType, stackReg, d))); } } return(true); }
private bool GenerateCallToOutsideProcedure(CallSite site, Address addr) { scanner.Warn(ric.Address, "Call target address {0} is invalid.", addr); var sig = new FunctionType(); ProcedureCharacteristics chr = null; EmitCall( CreateProcedureConstant( new ExternalProcedure(Procedure.GenerateName(addr), sig)), sig, chr, site); return(OnAfterCall(sig, chr)); }
private void EmitCall( Expression callee, FunctionType sig, ProcedureCharacteristics chr, CallSite site) { if (vaScanner.TryScan(ric.Address, sig, chr)) { Emit(vaScanner.BuildInstruction(callee, site)); } else if (sig != null && sig.ParametersValid) { Emit(BuildApplication(callee, sig, site)); } else { Emit(new CallInstruction(callee, site)); } }
private bool OnAfterCall(ProcedureSignature sigCallee, ProcedureCharacteristics characteristics) { if (sigCallee == null) { return(true); } state.OnAfterCall(stackReg, sigCallee, eval); if (characteristics != null && characteristics.Terminates) { scanner.TerminateBlock(blockCur, ric.Address + ric.Length); return(false); } int delta = sigCallee.StackDelta - sigCallee.ReturnAddressOnStack; if (delta != 0) { var d = Constant.Create(stackReg.DataType, delta); this.Emit(new Assignment( stackReg, new BinaryExpression(Operator.IAdd, stackReg.DataType, stackReg, d))); } return(true); }
public bool VisitCall(RtlCall call) { if ((call.Class & RtlClass.Delay) != 0) { // Get delay slot instruction cluster. rtlStream.MoveNext(); ProcessRtlCluster(rtlStream.Current); } var site = OnBeforeCall(stackReg, call.ReturnAddressSize); FunctionType sig; ProcedureCharacteristics chr = null; Address addr = call.Target as Address; if (addr != null) { var impProc = scanner.GetImportedProcedure(addr, this.ric.Address); if (impProc != null) { sig = impProc.Signature; chr = impProc.Characteristics; if (chr != null && chr.IsAlloca) { return(ProcessAlloca(site, impProc)); } EmitCall(CreateProcedureConstant(impProc), sig, chr, site); return(OnAfterCall(sig, chr)); } if (!program.SegmentMap.IsValidAddress(addr)) { return(GenerateCallToOutsideProcedure(site, addr)); } var callee = scanner.ScanProcedure(addr, null, state); var pcCallee = CreateProcedureConstant(callee); sig = callee.Signature; chr = callee.Characteristics; EmitCall(pcCallee, sig, chr, site); var pCallee = callee as Procedure; if (pCallee != null) { program.CallGraph.AddEdge(blockCur.Statements.Last, pCallee); } return(OnAfterCall(sig, chr)); } var procCallee = call.Target as ProcedureConstant; if (procCallee != null) { sig = procCallee.Procedure.Signature; chr = procCallee.Procedure.Characteristics; EmitCall(procCallee, sig, chr, site); return(OnAfterCall(sig, chr)); } sig = GetCallSignatureAtAddress(ric.Address); if (sig != null) { EmitCall(call.Target, sig, chr, site); return(OnAfterCall(sig, chr)); //$TODO: make characteristics available } Identifier id; if (call.Target.As <Identifier>(out id)) { var ppp = SearchBackForProcedureConstant(id); if (ppp != null) { var e = CreateProcedureConstant(ppp); sig = ppp.Signature; chr = ppp.Characteristics; EmitCall(e, sig, chr, site); return(OnAfterCall(sig, chr)); } } var imp = ImportedProcedureName(call.Target); if (imp != null) { sig = imp.Signature; chr = imp.Characteristics; EmitCall(CreateProcedureConstant(imp), sig, chr, site); return(OnAfterCall(sig, chr)); } var syscall = program.Platform.FindService(call, state); if (syscall != null) { return(!EmitSystemServiceCall(syscall)); } ProcessIndirectControlTransfer(ric.Address, call); var ic = new CallInstruction(call.Target, site); Emit(ic); sig = GuessProcedureSignature(ic); return(OnAfterCall(sig, chr)); }