'This function performs the actions of the callee as it\'s getting ready to return.
It returns the address to return to.
:param state:                   The state to mutate
:param return_val:              The value to return
:param arg_types:               The fp-ness of each of the args. Used to calculate sizes to clean up
:param force_callee_cleanup:    If we should clean up the stack allocation for the arguments even if it\'s not
the callee\'s job to do so
TODO: support the stack_base parameter from setup_callsite...? Does that make sense in this context?
Maybe it could make sense by saying that you pass it in as something like the "saved base pointer" value?'

def teardown_callsite(self, state, return_val=None, arg_types=None, force_callee_cleanup=False):

    if (return_val is not None):
        self.set_return_val(state, return_val)
    ret_addr = self.return_addr.get_value(state)
    if (state.arch.sp_offset is not None):
        if (force_callee_cleanup or self.CALLEE_CLEANUP):
            if (arg_types is not None):
                session = self.arg_session
                state.regs.sp += self.stack_space([session.next_arg(x) for x in arg_types])
            elif (self.args is not None):
                state.regs.sp += self.stack_space(self.args)
            else:
                l.warning("Can't    perform    callee    cleanup    when    I    have    no    idea    how    many    arguments    there    are!    Assuming    0")
                state.regs.sp += self.STACKARG_SP_DIFF
        else:
            state.regs.sp += self.STACKARG_SP_DIFF
    return ret_addr
