Ejemplo n.º 1
0
        private bool OnAfterCall(FunctionType sigCallee, ProcedureCharacteristics characteristics)
        {
            if (program.User.Calls.TryGetUpperBound(ric.Address, out var 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 && 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);
        }