/* Perform an inferior function call, for GDB, the GNU debugger.

   Copyright (C) 1986-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "infcall.h"
#include "breakpoint.h"
#include "tracepoint.h"
#include "target.h"
#include "regcache.h"
#include "inferior.h"
#include "infrun.h"
#include "block.h"
#include "gdbcore.h"
#include "language.h"
#include "objfiles.h"
#include "gdbcmd.h"
#include "command.h"
#include "dummy-frame.h"
#include "ada-lang.h"
#include "f-lang.h"
#include "gdbthread.h"
#include "event-top.h"
#include "observable.h"
#include "top.h"
#include "interps.h"
#include "thread-fsm.h"
#include <algorithm>
#include "gdbsupport/scope-exit.h"
#include <list>

/* If we can't find a function's name from its address,
   we print this instead.  */
#define RAW_FUNCTION_ADDRESS_FORMAT "at 0x%s"
#define RAW_FUNCTION_ADDRESS_SIZE (sizeof (RAW_FUNCTION_ADDRESS_FORMAT) \
				   + 2 * sizeof (CORE_ADDR))

/* NOTE: cagney/2003-04-16: What's the future of this code?

   GDB needs an asynchronous expression evaluator, that means an
   asynchronous inferior function call implementation, and that in
   turn means restructuring the code so that it is event driven.  */

static bool may_call_functions_p = true;
static void
show_may_call_functions_p (struct ui_file *file, int from_tty,
			   struct cmd_list_element *c,
			   const char *value)
{
  fprintf_filtered (file,
		    _("Permission to call functions in the program is %s.\n"),
		    value);
}

/* How you should pass arguments to a function depends on whether it
   was defined in K&R style or prototype style.  If you define a
   function using the K&R syntax that takes a `float' argument, then
   callers must pass that argument as a `double'.  If you define the
   function using the prototype syntax, then you must pass the
   argument as a `float', with no promotion.

   Unfortunately, on certain older platforms, the debug info doesn't
   indicate reliably how each function was defined.  A function type's
   TYPE_PROTOTYPED flag may be clear, even if the function was defined
   in prototype style.  When calling a function whose TYPE_PROTOTYPED
   flag is clear, GDB consults this flag to decide what to do.

   For modern targets, it is proper to assume that, if the prototype
   flag is clear, that can be trusted: `float' arguments should be
   promoted to `double'.  For some older targets, if the prototype
   flag is clear, that doesn't tell us anything.  The default is to
   trust the debug information; the user can override this behavior
   with "set coerce-float-to-double 0".  */

static bool coerce_float_to_double_p = true;
static void
show_coerce_float_to_double_p (struct ui_file *file, int from_tty,
			       struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Coercion of floats to doubles "
		      "when calling functions is %s.\n"),
		    value);
}

/* This boolean tells what gdb should do if a signal is received while
   in a function called from gdb (call dummy).  If set, gdb unwinds
   the stack and restore the context to what as it was before the
   call.

   The default is to stop in the frame where the signal was received.  */

static bool unwind_on_signal_p = false;
static void
show_unwind_on_signal_p (struct ui_file *file, int from_tty,
			 struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Unwinding of stack if a signal is "
		      "received while in a call dummy is %s.\n"),
		    value);
}

/* This boolean tells what gdb should do if a std::terminate call is
   made while in a function called from gdb (call dummy).
   As the confines of a single dummy stack prohibit out-of-frame
   handlers from handling a raised exception, and as out-of-frame
   handlers are common in C++, this can lead to no handler being found
   by the unwinder, and a std::terminate call.  This is a false positive.
   If set, gdb unwinds the stack and restores the context to what it
   was before the call.

   The default is to unwind the frame if a std::terminate call is
   made.  */

static bool unwind_on_terminating_exception_p = true;

static void
show_unwind_on_terminating_exception_p (struct ui_file *file, int from_tty,
					struct cmd_list_element *c,
					const char *value)

{
  fprintf_filtered (file,
		    _("Unwind stack if a C++ exception is "
		      "unhandled while in a call dummy is %s.\n"),
		    value);
}

/* Perform the standard coercions that are specified
   for arguments to be passed to C, Ada or Fortran functions.

   If PARAM_TYPE is non-NULL, it is the expected parameter type.
   IS_PROTOTYPED is non-zero if the function declaration is prototyped.  */

static struct value *
value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
		  struct type *param_type, int is_prototyped)
{
  const struct builtin_type *builtin = builtin_type (gdbarch);
  struct type *arg_type = check_typedef (value_type (arg));
  struct type *type
    = param_type ? check_typedef (param_type) : arg_type;

  /* Perform any Ada- and Fortran-specific coercion first.  */
  if (current_language->la_language == language_ada)
    arg = ada_convert_actual (arg, type);
  else if (current_language->la_language == language_fortran)
    type = fortran_preserve_arg_pointer (arg, type);

  /* Force the value to the target if we will need its address.  At
     this point, we could allocate arguments on the stack instead of
     calling malloc if we knew that their addresses would not be
     saved by the called function.  */
  arg = value_coerce_to_target (arg);

  switch (type->code ())
    {
    case TYPE_CODE_REF:
    case TYPE_CODE_RVALUE_REF:
      {
	struct value *new_value;

	if (TYPE_IS_REFERENCE (arg_type))
	  return value_cast_pointers (type, arg, 0);

	/* Cast the value to the reference's target type, and then
	   convert it back to a reference.  This will issue an error
	   if the value was not previously in memory - in some cases
	   we should clearly be allowing this, but how?  */
	new_value = value_cast (TYPE_TARGET_TYPE (type), arg);
	new_value = value_ref (new_value, type->code ());
	return new_value;
      }
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_ENUM:
      /* If we don't have a prototype, coerce to integer type if necessary.  */
      if (!is_prototyped)
	{
	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_int))
	    type = builtin->builtin_int;
	}
      /* Currently all target ABIs require at least the width of an integer
	 type for an argument.  We may have to conditionalize the following
	 type coercion for future targets.  */
      if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_int))
	type = builtin->builtin_int;
      break;
    case TYPE_CODE_FLT:
      if (!is_prototyped && coerce_float_to_double_p)
	{
	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_double))
	    type = builtin->builtin_double;
	  else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin->builtin_double))
	    type = builtin->builtin_long_double;
	}
      break;
    case TYPE_CODE_FUNC:
      type = lookup_pointer_type (type);
      break;
    case TYPE_CODE_ARRAY:
      /* Arrays are coerced to pointers to their first element, unless
	 they are vectors, in which case we want to leave them alone,
	 because they are passed by value.  */
      if (current_language->c_style_arrays_p ())
	if (!type->is_vector ())
	  type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
      break;
    case TYPE_CODE_UNDEF:
    case TYPE_CODE_PTR:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_VOID:
    case TYPE_CODE_SET:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_STRING:
    case TYPE_CODE_ERROR:
    case TYPE_CODE_MEMBERPTR:
    case TYPE_CODE_METHODPTR:
    case TYPE_CODE_METHOD:
    case TYPE_CODE_COMPLEX:
    default:
      break;
    }

  return value_cast (type, arg);
}

/* See infcall.h.  */

CORE_ADDR
find_function_addr (struct value *function,
		    struct type **retval_type,
		    struct type **function_type)
{
  struct type *ftype = check_typedef (value_type (function));
  struct gdbarch *gdbarch = ftype->arch ();
  struct type *value_type = NULL;
  /* Initialize it just to avoid a GCC false warning.  */
  CORE_ADDR funaddr = 0;

  /* If it's a member function, just look at the function
     part of it.  */

  /* Determine address to call.  */
  if (ftype->code () == TYPE_CODE_FUNC
      || ftype->code () == TYPE_CODE_METHOD)
    funaddr = value_address (function);
  else if (ftype->code () == TYPE_CODE_PTR)
    {
      funaddr = value_as_address (function);
      ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
      if (ftype->code () == TYPE_CODE_FUNC
	  || ftype->code () == TYPE_CODE_METHOD)
	funaddr = gdbarch_convert_from_func_ptr_addr
	  (gdbarch, funaddr, current_inferior ()->top_target());
    }
  if (ftype->code () == TYPE_CODE_FUNC
      || ftype->code () == TYPE_CODE_METHOD)
    {
      if (ftype->is_gnu_ifunc ())
	{
	  CORE_ADDR resolver_addr = funaddr;

	  /* Resolve the ifunc.  Note this may call the resolver
	     function in the inferior.  */
	  funaddr = gnu_ifunc_resolve_addr (gdbarch, resolver_addr);

	  /* Skip querying the function symbol if no RETVAL_TYPE or
	     FUNCTION_TYPE have been asked for.  */
	  if (retval_type != NULL || function_type != NULL)
	    {
	      type *target_ftype = find_function_type (funaddr);
	      /* If we don't have debug info for the target function,
		 see if we can instead extract the target function's
		 type from the type that the resolver returns.  */
	      if (target_ftype == NULL)
		target_ftype = find_gnu_ifunc_target_type (resolver_addr);
	      if (target_ftype != NULL)
		{
		  value_type = TYPE_TARGET_TYPE (check_typedef (target_ftype));
		  ftype = target_ftype;
		}
	    }
	}
      else
	value_type = TYPE_TARGET_TYPE (ftype);
    }
  else if (ftype->code () == TYPE_CODE_INT)
    {
      /* Handle the case of functions lacking debugging info.
	 Their values are characters since their addresses are char.  */
      if (TYPE_LENGTH (ftype) == 1)
	funaddr = value_as_address (value_addr (function));
      else
	{
	  /* Handle function descriptors lacking debug info.  */
	  int found_descriptor = 0;

	  funaddr = 0;	/* pacify "gcc -Werror" */
	  if (VALUE_LVAL (function) == lval_memory)
	    {
	      CORE_ADDR nfunaddr;

	      funaddr = value_as_address (value_addr (function));
	      nfunaddr = funaddr;
	      funaddr = gdbarch_convert_from_func_ptr_addr
		(gdbarch, funaddr, current_inferior ()->top_target ());
	      if (funaddr != nfunaddr)
		found_descriptor = 1;
	    }
	  if (!found_descriptor)
	    /* Handle integer used as address of a function.  */
	    funaddr = (CORE_ADDR) value_as_long (function);
	}
    }
  else
    error (_("Invalid data type for function to be called."));

  if (retval_type != NULL)
    *retval_type = value_type;
  if (function_type != NULL)
    *function_type = ftype;
  return funaddr + gdbarch_deprecated_function_start_offset (gdbarch);
}

/* For CALL_DUMMY_ON_STACK, push a breakpoint sequence that the called
   function returns to.  */

static CORE_ADDR
push_dummy_code (struct gdbarch *gdbarch,
		 CORE_ADDR sp, CORE_ADDR funaddr,
		 gdb::array_view<value *> args,
		 struct type *value_type,
		 CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
		 struct regcache *regcache)
{
  gdb_assert (gdbarch_push_dummy_code_p (gdbarch));

  return gdbarch_push_dummy_code (gdbarch, sp, funaddr,
				  args.data (), args.size (),
				  value_type, real_pc, bp_addr,
				  regcache);
}

/* See infcall.h.  */

void
error_call_unknown_return_type (const char *func_name)
{
  if (func_name != NULL)
    error (_("'%s' has unknown return type; "
	     "cast the call to its declared return type"),
	   func_name);
  else
    error (_("function has unknown return type; "
	     "cast the call to its declared return type"));
}

/* Fetch the name of the function at FUNADDR.
   This is used in printing an error message for call_function_by_hand.
   BUF is used to print FUNADDR in hex if the function name cannot be
   determined.  It must be large enough to hold formatted result of
   RAW_FUNCTION_ADDRESS_FORMAT.  */

static const char *
get_function_name (CORE_ADDR funaddr, char *buf, int buf_size)
{
  {
    struct symbol *symbol = find_pc_function (funaddr);

    if (symbol)
      return symbol->print_name ();
  }

  {
    /* Try the minimal symbols.  */
    struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (funaddr);

    if (msymbol.minsym)
      return msymbol.minsym->print_name ();
  }

  {
    std::string tmp = string_printf (_(RAW_FUNCTION_ADDRESS_FORMAT),
				     hex_string (funaddr));

    gdb_assert (tmp.length () + 1 <= buf_size);
    return strcpy (buf, tmp.c_str ());
  }
}

/* All the meta data necessary to extract the call's return value.  */

struct call_return_meta_info
{
  /* The caller frame's architecture.  */
  struct gdbarch *gdbarch;

  /* The called function.  */
  struct value *function;

  /* The return value's type.  */
  struct type *value_type;

  /* Are we returning a value using a structure return or a normal
     value return?  */
  int struct_return_p;

  /* If using a structure return, this is the structure's address.  */
  CORE_ADDR struct_addr;
};

/* Extract the called function's return value.  */

static struct value *
get_call_return_value (struct call_return_meta_info *ri)
{
  struct value *retval = NULL;
  thread_info *thr = inferior_thread ();
  bool stack_temporaries = thread_stack_temporaries_enabled_p (thr);

  if (ri->value_type->code () == TYPE_CODE_VOID)
    retval = allocate_value (ri->value_type);
  else if (ri->struct_return_p)
    {
      if (stack_temporaries)
	{
	  retval = value_from_contents_and_address (ri->value_type, NULL,
						    ri->struct_addr);
	  push_thread_stack_temporary (thr, retval);
	}
      else
	{
	  retval = allocate_value (ri->value_type);
	  read_value_memory (retval, 0, 1, ri->struct_addr,
			     value_contents_raw (retval).data (),
			     TYPE_LENGTH (ri->value_type));
	}
    }
  else
    {
      retval = allocate_value (ri->value_type);
      gdbarch_return_value (ri->gdbarch, ri->function, ri->value_type,
			    get_current_regcache (),
			    value_contents_raw (retval).data (), NULL);
      if (stack_temporaries && class_or_union_p (ri->value_type))
	{
	  /* Values of class type returned in registers are copied onto
	     the stack and their lval_type set to lval_memory.  This is
	     required because further evaluation of the expression
	     could potentially invoke methods on the return value
	     requiring GDB to evaluate the "this" pointer.  To evaluate
	     the this pointer, GDB needs the memory address of the
	     value.  */
	  value_force_lval (retval, ri->struct_addr);
	  push_thread_stack_temporary (thr, retval);
	}
    }

  gdb_assert (retval != NULL);
  return retval;
}

/* Data for the FSM that manages an infcall.  It's main job is to
   record the called function's return value.  */

struct call_thread_fsm : public thread_fsm
{
  /* All the info necessary to be able to extract the return
     value.  */
  struct call_return_meta_info return_meta_info;

  /* The called function's return value.  This is extracted from the
     target before the dummy frame is popped.  */
  struct value *return_value = nullptr;

  /* The top level that started the infcall (and is synchronously
     waiting for it to end).  */
  struct ui *waiting_ui;

  call_thread_fsm (struct ui *waiting_ui, struct interp *cmd_interp,
		   struct gdbarch *gdbarch, struct value *function,
		   struct type *value_type,
		   int struct_return_p, CORE_ADDR struct_addr);

  bool should_stop (struct thread_info *thread) override;

  bool should_notify_stop () override;
};

/* Allocate a new call_thread_fsm object.  */

call_thread_fsm::call_thread_fsm (struct ui *waiting_ui,
				  struct interp *cmd_interp,
				  struct gdbarch *gdbarch,
				  struct value *function,
				  struct type *value_type,
				  int struct_return_p, CORE_ADDR struct_addr)
  : thread_fsm (cmd_interp),
    waiting_ui (waiting_ui)
{
  return_meta_info.gdbarch = gdbarch;
  return_meta_info.function = function;
  return_meta_info.value_type = value_type;
  return_meta_info.struct_return_p = struct_return_p;
  return_meta_info.struct_addr = struct_addr;
}

/* Implementation of should_stop method for infcalls.  */

bool
call_thread_fsm::should_stop (struct thread_info *thread)
{
  if (stop_stack_dummy == STOP_STACK_DUMMY)
    {
      /* Done.  */
      set_finished ();

      /* Stash the return value before the dummy frame is popped and
	 registers are restored to what they were before the
	 call..  */
      return_value = get_call_return_value (&return_meta_info);

      /* Break out of wait_sync_command_done.  */
      scoped_restore save_ui = make_scoped_restore (&current_ui, waiting_ui);
      target_terminal::ours ();
      waiting_ui->prompt_state = PROMPT_NEEDED;
    }

  return true;
}

/* Implementation of should_notify_stop method for infcalls.  */

bool
call_thread_fsm::should_notify_stop ()
{
  if (finished_p ())
    {
      /* Infcall succeeded.  Be silent and proceed with evaluating the
	 expression.  */
      return false;
    }

  /* Something wrong happened.  E.g., an unexpected breakpoint
     triggered, or a signal was intercepted.  Notify the stop.  */
  return true;
}

/* Subroutine of call_function_by_hand to simplify it.
   Start up the inferior and wait for it to stop.
   Return the exception if there's an error, or an exception with
   reason >= 0 if there's no error.

   This is done inside a TRY_CATCH so the caller needn't worry about
   thrown errors.  The caller should rethrow if there's an error.  */

static struct gdb_exception
run_inferior_call (std::unique_ptr<call_thread_fsm> sm,
		   struct thread_info *call_thread, CORE_ADDR real_pc)
{
  struct gdb_exception caught_error;
  int saved_in_infcall = call_thread->control.in_infcall;
  ptid_t call_thread_ptid = call_thread->ptid;
  enum prompt_state saved_prompt_state = current_ui->prompt_state;
  int was_running = call_thread->state == THREAD_RUNNING;
  int saved_ui_async = current_ui->async;

  /* Infcalls run synchronously, in the foreground.  */
  current_ui->prompt_state = PROMPT_BLOCKED;
  /* So that we don't print the prompt prematurely in
     fetch_inferior_event.  */
  current_ui->async = 0;

  delete_file_handler (current_ui->input_fd);

  call_thread->control.in_infcall = 1;

  clear_proceed_status (0);

  /* Associate the FSM with the thread after clear_proceed_status
     (otherwise it'd clear this FSM).  */
  call_thread->set_thread_fsm (std::move (sm));

  disable_watchpoints_before_interactive_call_start ();

  /* We want to print return value, please...  */
  call_thread->control.proceed_to_finish = 1;

  try
    {
      proceed (real_pc, GDB_SIGNAL_0);

      /* Inferior function calls are always synchronous, even if the
	 target supports asynchronous execution.  */
      wait_sync_command_done ();
    }
  catch (gdb_exception &e)
    {
      caught_error = std::move (e);
    }

  /* If GDB has the prompt blocked before, then ensure that it remains
     so.  normal_stop calls async_enable_stdin, so reset the prompt
     state again here.  In other cases, stdin will be re-enabled by
     inferior_event_handler, when an exception is thrown.  */
  current_ui->prompt_state = saved_prompt_state;
  if (current_ui->prompt_state == PROMPT_BLOCKED)
    delete_file_handler (current_ui->input_fd);
  else
    ui_register_input_event_handler (current_ui);
  current_ui->async = saved_ui_async;

  /* If the infcall does NOT succeed, normal_stop will have already
     finished the thread states.  However, on success, normal_stop
     defers here, so that we can set back the thread states to what
     they were before the call.  Note that we must also finish the
     state of new threads that might have spawned while the call was
     running.  The main cases to handle are:

     - "(gdb) print foo ()", or any other command that evaluates an
     expression at the prompt.  (The thread was marked stopped before.)

     - "(gdb) break foo if return_false()" or similar cases where we
     do an infcall while handling an event (while the thread is still
     marked running).  In this example, whether the condition
     evaluates true and thus we'll present a user-visible stop is
     decided elsewhere.  */
  if (!was_running
      && call_thread_ptid == inferior_ptid
      && stop_stack_dummy == STOP_STACK_DUMMY)
    finish_thread_state (call_thread->inf->process_target (),
			 user_visible_resume_ptid (0));

  enable_watchpoints_after_interactive_call_stop ();

  /* Call breakpoint_auto_delete on the current contents of the bpstat
     of inferior call thread.
     If all error()s out of proceed ended up calling normal_stop
     (and perhaps they should; it already does in the special case
     of error out of resume()), then we wouldn't need this.  */
  if (caught_error.reason < 0)
    {
      if (call_thread->state != THREAD_EXITED)
	breakpoint_auto_delete (call_thread->control.stop_bpstat);
    }

  call_thread->control.in_infcall = saved_in_infcall;

  return caught_error;
}

/* Reserve space on the stack for a value of the given type.
   Return the address of the allocated space.
   Make certain that the value is correctly aligned.
   The SP argument is modified.  */

static CORE_ADDR
reserve_stack_space (const type *values_type, CORE_ADDR &sp)
{
  struct frame_info *frame = get_current_frame ();
  struct gdbarch *gdbarch = get_frame_arch (frame);
  CORE_ADDR addr = 0;

  if (gdbarch_inner_than (gdbarch, 1, 2))
    {
      /* Stack grows downward.  Align STRUCT_ADDR and SP after
	 making space.  */
      sp -= TYPE_LENGTH (values_type);
      if (gdbarch_frame_align_p (gdbarch))
	sp = gdbarch_frame_align (gdbarch, sp);
      addr = sp;
    }
  else
    {
      /* Stack grows upward.  Align the frame, allocate space, and
	 then again, re-align the frame???  */
      if (gdbarch_frame_align_p (gdbarch))
	sp = gdbarch_frame_align (gdbarch, sp);
      addr = sp;
      sp += TYPE_LENGTH (values_type);
      if (gdbarch_frame_align_p (gdbarch))
	sp = gdbarch_frame_align (gdbarch, sp);
    }

  return addr;
}

/* The data structure which keeps a destructor function and
   its implicit 'this' parameter.  */

struct destructor_info
{
  destructor_info (struct value *function, struct value *self)
    : function (function), self (self) { }

  struct value *function;
  struct value *self;
};


/* Auxiliary function that takes a list of destructor functions
   with their 'this' parameters, and invokes the functions.  */

static void
call_destructors (const std::list<destructor_info> &dtors_to_invoke,
		  struct type *default_return_type)
{
  for (auto vals : dtors_to_invoke)
    {
      call_function_by_hand (vals.function, default_return_type,
			     gdb::make_array_view (&(vals.self), 1));
    }
}

/* See infcall.h.  */

struct value *
call_function_by_hand (struct value *function,
		       type *default_return_type,
		       gdb::array_view<value *> args)
{
  return call_function_by_hand_dummy (function, default_return_type,
				      args, NULL, NULL);
}

/* All this stuff with a dummy frame may seem unnecessarily complicated
   (why not just save registers in GDB?).  The purpose of pushing a dummy
   frame which looks just like a real frame is so that if you call a
   function and then hit a breakpoint (get a signal, etc), "backtrace"
   will look right.  Whether the backtrace needs to actually show the
   stack at the time the inferior function was called is debatable, but
   it certainly needs to not display garbage.  So if you are contemplating
   making dummy frames be different from normal frames, consider that.  */

/* Perform a function call in the inferior.
   ARGS is a vector of values of arguments.
   FUNCTION is a value, the function to be called.
   Returns a value representing what the function returned.
   May fail to return, if a breakpoint or signal is hit
   during the execution of the function.

   ARGS is modified to contain coerced values.  */

struct value *
call_function_by_hand_dummy (struct value *function,
			     type *default_return_type,
			     gdb::array_view<value *> args,
			     dummy_frame_dtor_ftype *dummy_dtor,
			     void *dummy_dtor_data)
{
  CORE_ADDR sp;
  struct type *target_values_type;
  function_call_return_method return_method = return_method_normal;
  CORE_ADDR struct_addr = 0;
  CORE_ADDR real_pc;
  CORE_ADDR bp_addr;
  struct frame_id dummy_id;
  struct frame_info *frame;
  struct gdbarch *gdbarch;
  ptid_t call_thread_ptid;
  struct gdb_exception e;
  char name_buf[RAW_FUNCTION_ADDRESS_SIZE];

  if (!may_call_functions_p)
    error (_("Cannot call functions in the program: "
	     "may-call-functions is off."));

  if (!target_has_execution ())
    noprocess ();

  if (get_traceframe_number () >= 0)
    error (_("May not call functions while looking at trace frames."));

  if (execution_direction == EXEC_REVERSE)
    error (_("Cannot call functions in reverse mode."));

  /* We're going to run the target, and inspect the thread's state
     afterwards.  Hold a strong reference so that the pointer remains
     valid even if the thread exits.  */
  thread_info_ref call_thread
    = thread_info_ref::new_reference (inferior_thread ());

  bool stack_temporaries = thread_stack_temporaries_enabled_p (call_thread.get ());

  frame = get_current_frame ();
  gdbarch = get_frame_arch (frame);

  if (!gdbarch_push_dummy_call_p (gdbarch))
    error (_("This target does not support function calls."));

  /* Find the function type and do a sanity check.  */
  type *ftype;
  type *values_type;
  CORE_ADDR funaddr = find_function_addr (function, &values_type, &ftype);

  if (values_type == NULL)
    values_type = default_return_type;
  if (values_type == NULL)
    {
      const char *name = get_function_name (funaddr,
					    name_buf, sizeof (name_buf));
      error (_("'%s' has unknown return type; "
	       "cast the call to its declared return type"),
	     name);
    }

  values_type = check_typedef (values_type);

  if (args.size () < ftype->num_fields ())
    error (_("Too few arguments in function call."));

  /* A holder for the inferior status.
     This is only needed while we're preparing the inferior function call.  */
  infcall_control_state_up inf_status (save_infcall_control_state ());

  /* Save the caller's registers and other state associated with the
     inferior itself so that they can be restored once the
     callee returns.  To allow nested calls the registers are (further
     down) pushed onto a dummy frame stack.  This unique pointer
     is released once the regcache has been pushed).  */
  infcall_suspend_state_up caller_state (save_infcall_suspend_state ());

  /* Ensure that the initial SP is correctly aligned.  */
  {
    CORE_ADDR old_sp = get_frame_sp (frame);

    if (gdbarch_frame_align_p (gdbarch))
      {
	sp = gdbarch_frame_align (gdbarch, old_sp);
	/* NOTE: cagney/2003-08-13: Skip the "red zone".  For some
	   ABIs, a function can use memory beyond the inner most stack
	   address.  AMD64 called that region the "red zone".  Skip at
	   least the "red zone" size before allocating any space on
	   the stack.  */
	if (gdbarch_inner_than (gdbarch, 1, 2))
	  sp -= gdbarch_frame_red_zone_size (gdbarch);
	else
	  sp += gdbarch_frame_red_zone_size (gdbarch);
	/* Still aligned?  */
	gdb_assert (sp == gdbarch_frame_align (gdbarch, sp));
	/* NOTE: cagney/2002-09-18:
	   
	   On a RISC architecture, a void parameterless generic dummy
	   frame (i.e., no parameters, no result) typically does not
	   need to push anything the stack and hence can leave SP and
	   FP.  Similarly, a frameless (possibly leaf) function does
	   not push anything on the stack and, hence, that too can
	   leave FP and SP unchanged.  As a consequence, a sequence of
	   void parameterless generic dummy frame calls to frameless
	   functions will create a sequence of effectively identical
	   frames (SP, FP and TOS and PC the same).  This, not
	   surprisingly, results in what appears to be a stack in an
	   infinite loop --- when GDB tries to find a generic dummy
	   frame on the internal dummy frame stack, it will always
	   find the first one.

	   To avoid this problem, the code below always grows the
	   stack.  That way, two dummy frames can never be identical.
	   It does burn a few bytes of stack but that is a small price
	   to pay :-).  */
	if (sp == old_sp)
	  {
	    if (gdbarch_inner_than (gdbarch, 1, 2))
	      /* Stack grows down.  */
	      sp = gdbarch_frame_align (gdbarch, old_sp - 1);
	    else
	      /* Stack grows up.  */
	      sp = gdbarch_frame_align (gdbarch, old_sp + 1);
	  }
	/* SP may have underflown address zero here from OLD_SP.  Memory access
	   functions will probably fail in such case but that is a target's
	   problem.  */
      }
    else
      /* FIXME: cagney/2002-09-18: Hey, you loose!

	 Who knows how badly aligned the SP is!

	 If the generic dummy frame ends up empty (because nothing is
	 pushed) GDB won't be able to correctly perform back traces.
	 If a target is having trouble with backtraces, first thing to
	 do is add FRAME_ALIGN() to the architecture vector.  If that
	 fails, try dummy_id().

	 If the ABI specifies a "Red Zone" (see the doco) the code
	 below will quietly trash it.  */
      sp = old_sp;

    /* Skip over the stack temporaries that might have been generated during
       the evaluation of an expression.  */
    if (stack_temporaries)
      {
	struct value *lastval;

	lastval = get_last_thread_stack_temporary (call_thread.get ());
	if (lastval != NULL)
	  {
	    CORE_ADDR lastval_addr = value_address (lastval);

	    if (gdbarch_inner_than (gdbarch, 1, 2))
	      {
		gdb_assert (sp >= lastval_addr);
		sp = lastval_addr;
	      }
	    else
	      {
		gdb_assert (sp <= lastval_addr);
		sp = lastval_addr + TYPE_LENGTH (value_type (lastval));
	      }

	    if (gdbarch_frame_align_p (gdbarch))
	      sp = gdbarch_frame_align (gdbarch, sp);
	  }
      }
  }

  /* Are we returning a value using a structure return?  */

  if (gdbarch_return_in_first_hidden_param_p (gdbarch, values_type))
    {
      return_method = return_method_hidden_param;

      /* Tell the target specific argument pushing routine not to
	 expect a value.  */
      target_values_type = builtin_type (gdbarch)->builtin_void;
    }
  else
    {
      if (using_struct_return (gdbarch, function, values_type))
	return_method = return_method_struct;
      target_values_type = values_type;
    }

  gdb::observers::inferior_call_pre.notify (inferior_ptid, funaddr);

  /* Determine the location of the breakpoint (and possibly other
     stuff) that the called function will return to.  The SPARC, for a
     function returning a structure or union, needs to make space for
     not just the breakpoint but also an extra word containing the
     size (?) of the structure being passed.  */

  switch (gdbarch_call_dummy_location (gdbarch))
    {
    case ON_STACK:
      {
	const gdb_byte *bp_bytes;
	CORE_ADDR bp_addr_as_address;
	int bp_size;

	/* Be careful BP_ADDR is in inferior PC encoding while
	   BP_ADDR_AS_ADDRESS is a plain memory address.  */

	sp = push_dummy_code (gdbarch, sp, funaddr, args,
			      target_values_type, &real_pc, &bp_addr,
			      get_current_regcache ());

	/* Write a legitimate instruction at the point where the infcall
	   breakpoint is going to be inserted.  While this instruction
	   is never going to be executed, a user investigating the
	   memory from GDB would see this instruction instead of random
	   uninitialized bytes.  We chose the breakpoint instruction
	   as it may look as the most logical one to the user and also
	   valgrind 3.7.0 needs it for proper vgdb inferior calls.

	   If software breakpoints are unsupported for this target we
	   leave the user visible memory content uninitialized.  */

	bp_addr_as_address = bp_addr;
	bp_bytes = gdbarch_breakpoint_from_pc (gdbarch, &bp_addr_as_address,
					       &bp_size);
	if (bp_bytes != NULL)
	  write_memory (bp_addr_as_address, bp_bytes, bp_size);
      }
      break;
    case AT_ENTRY_POINT:
      {
	CORE_ADDR dummy_addr;

	real_pc = funaddr;
	dummy_addr = entry_point_address ();

	/* A call dummy always consists of just a single breakpoint, so
	   its address is the same as the address of the dummy.

	   The actual breakpoint is inserted separatly so there is no need to
	   write that out.  */
	bp_addr = dummy_addr;
	break;
      }
    default:
      internal_error (__FILE__, __LINE__, _("bad switch"));
    }

  /* Coerce the arguments and handle pass-by-reference.
     We want to remember the destruction required for pass-by-ref values.
     For these, store the dtor function and the 'this' argument
     in DTORS_TO_INVOKE.  */
  std::list<destructor_info> dtors_to_invoke;

  for (int i = args.size () - 1; i >= 0; i--)
    {
      int prototyped;
      struct type *param_type;

      /* FIXME drow/2002-05-31: Should just always mark methods as
	 prototyped.  Can we respect TYPE_VARARGS?  Probably not.  */
      if (ftype->code () == TYPE_CODE_METHOD)
	prototyped = 1;
      else if (TYPE_TARGET_TYPE (ftype) == NULL && ftype->num_fields () == 0
	       && default_return_type != NULL)
	{
	  /* Calling a no-debug function with the return type
	     explicitly cast.  Assume the function is prototyped,
	     with a prototype matching the types of the arguments.
	     E.g., with:
	     float mult (float v1, float v2) { return v1 * v2; }
	     This:
	     (gdb) p (float) mult (2.0f, 3.0f)
	     Is a simpler alternative to:
	     (gdb) p ((float (*) (float, float)) mult) (2.0f, 3.0f)
	  */
	  prototyped = 1;
	}
      else if (i < ftype->num_fields ())
	prototyped = ftype->is_prototyped ();
      else
	prototyped = 0;

      if (i < ftype->num_fields ())
	param_type = ftype->field (i).type ();
      else
	param_type = NULL;

      value *original_arg = args[i];
      args[i] = value_arg_coerce (gdbarch, args[i],
				  param_type, prototyped);

      if (param_type == NULL)
	continue;

      auto info = language_pass_by_reference (param_type);
      if (!info.copy_constructible)
	error (_("expression cannot be evaluated because the type '%s' "
		 "is not copy constructible"), param_type->name ());

      if (!info.destructible)
	error (_("expression cannot be evaluated because the type '%s' "
		 "is not destructible"), param_type->name ());

      if (info.trivially_copyable)
	continue;

      /* Make a copy of the argument on the stack.  If the argument is
	 trivially copy ctor'able, copy bit by bit.  Otherwise, call
	 the copy ctor to initialize the clone.  */
      CORE_ADDR addr = reserve_stack_space (param_type, sp);
      value *clone
	= value_from_contents_and_address (param_type, nullptr, addr);
      push_thread_stack_temporary (call_thread.get (), clone);
      value *clone_ptr
	= value_from_pointer (lookup_pointer_type (param_type), addr);

      if (info.trivially_copy_constructible)
	{
	  int length = TYPE_LENGTH (param_type);
	  write_memory (addr, value_contents (args[i]).data (), length);
	}
      else
	{
	  value *copy_ctor;
	  value *cctor_args[2] = { clone_ptr, original_arg };
	  find_overload_match (gdb::make_array_view (cctor_args, 2),
			       param_type->name (), METHOD,
			       &clone_ptr, nullptr, &copy_ctor, nullptr,
			       nullptr, 0, EVAL_NORMAL);

	  if (copy_ctor == nullptr)
	    error (_("expression cannot be evaluated because a copy "
		     "constructor for the type '%s' could not be found "
		     "(maybe inlined?)"), param_type->name ());

	  call_function_by_hand (copy_ctor, default_return_type,
				 gdb::make_array_view (cctor_args, 2));
	}

      /* If the argument has a destructor, remember it so that we
	 invoke it after the infcall is complete.  */
      if (!info.trivially_destructible)
	{
	  /* Looking up the function via overload resolution does not
	     work because the compiler (in particular, gcc) adds an
	     artificial int parameter in some cases.  So we look up
	     the function by using the "~" name.  This should be OK
	     because there can be only one dtor definition.  */
	  const char *dtor_name = nullptr;
	  for (int fieldnum = 0;
	       fieldnum < TYPE_NFN_FIELDS (param_type);
	       fieldnum++)
	    {
	      fn_field *fn
		= TYPE_FN_FIELDLIST1 (param_type, fieldnum);
	      const char *field_name
		= TYPE_FN_FIELDLIST_NAME (param_type, fieldnum);

	      if (field_name[0] == '~')
		dtor_name = TYPE_FN_FIELD_PHYSNAME (fn, 0);
	    }

	  if (dtor_name == nullptr)
	    error (_("expression cannot be evaluated because a destructor "
		     "for the type '%s' could not be found "
		     "(maybe inlined?)"), param_type->name ());

	  value *dtor
	    = find_function_in_inferior (dtor_name, 0);

	  /* Insert the dtor to the front of the list to call them
	     in reverse order later.  */
	  dtors_to_invoke.emplace_front (dtor, clone_ptr);
	}

      args[i] = clone_ptr;
    }

  /* Reserve space for the return structure to be written on the
     stack, if necessary.

     While evaluating expressions, we reserve space on the stack for
     return values of class type even if the language ABI and the target
     ABI do not require that the return value be passed as a hidden first
     argument.  This is because we want to store the return value as an
     on-stack temporary while the expression is being evaluated.  This
     enables us to have chained function calls in expressions.

     Keeping the return values as on-stack temporaries while the expression
     is being evaluated is OK because the thread is stopped until the
     expression is completely evaluated.  */

  if (return_method != return_method_normal
      || (stack_temporaries && class_or_union_p (values_type)))
    struct_addr = reserve_stack_space (values_type, sp);

  std::vector<struct value *> new_args;
  if (return_method == return_method_hidden_param)
    {
      /* Add the new argument to the front of the argument list.  */
      new_args.reserve (args.size ());
      new_args.push_back
	(value_from_pointer (lookup_pointer_type (values_type), struct_addr));
      new_args.insert (new_args.end (), args.begin (), args.end ());
      args = new_args;
    }

  /* Create the dummy stack frame.  Pass in the call dummy address as,
     presumably, the ABI code knows where, in the call dummy, the
     return address should be pointed.  */
  sp = gdbarch_push_dummy_call (gdbarch, function, get_current_regcache (),
				bp_addr, args.size (), args.data (),
				sp, return_method, struct_addr);

  /* Set up a frame ID for the dummy frame so we can pass it to
     set_momentary_breakpoint.  We need to give the breakpoint a frame
     ID so that the breakpoint code can correctly re-identify the
     dummy breakpoint.  */
  /* Sanity.  The exact same SP value is returned by PUSH_DUMMY_CALL,
     saved as the dummy-frame TOS, and used by dummy_id to form
     the frame ID's stack address.  */
  dummy_id = frame_id_build (sp, bp_addr);

  /* Create a momentary breakpoint at the return address of the
     inferior.  That way it breaks when it returns.  */

  {
    symtab_and_line sal;
    sal.pspace = current_program_space;
    sal.pc = bp_addr;
    sal.section = find_pc_overlay (sal.pc);

    /* Sanity.  The exact same SP value is returned by
       PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by
       dummy_id to form the frame ID's stack address.  */
    breakpoint *bpt
      = set_momentary_breakpoint (gdbarch, sal,
				  dummy_id, bp_call_dummy).release ();

    /* set_momentary_breakpoint invalidates FRAME.  */
    frame = NULL;

    bpt->disposition = disp_del;
    gdb_assert (bpt->related_breakpoint == bpt);

    breakpoint *longjmp_b = set_longjmp_breakpoint_for_call_dummy ();
    if (longjmp_b)
      {
	/* Link BPT into the chain of LONGJMP_B.  */
	bpt->related_breakpoint = longjmp_b;
	while (longjmp_b->related_breakpoint != bpt->related_breakpoint)
	  longjmp_b = longjmp_b->related_breakpoint;
	longjmp_b->related_breakpoint = bpt;
      }
  }

  /* Create a breakpoint in std::terminate.
     If a C++ exception is raised in the dummy-frame, and the
     exception handler is (normally, and expected to be) out-of-frame,
     the default C++ handler will (wrongly) be called in an inferior
     function call.  This is wrong, as an exception can be  normally
     and legally handled out-of-frame.  The confines of the dummy frame
     prevent the unwinder from finding the correct handler (or any
     handler, unless it is in-frame).  The default handler calls
     std::terminate.  This will kill the inferior.  Assert that
     terminate should never be called in an inferior function
     call.  Place a momentary breakpoint in the std::terminate function
     and if triggered in the call, rewind.  */
  if (unwind_on_terminating_exception_p)
    set_std_terminate_breakpoint ();

  /* Everything's ready, push all the info needed to restore the
     caller (and identify the dummy-frame) onto the dummy-frame
     stack.  */
  dummy_frame_push (caller_state.release (), &dummy_id, call_thread.get ());
  if (dummy_dtor != NULL)
    register_dummy_frame_dtor (dummy_id, call_thread.get (),
			       dummy_dtor, dummy_dtor_data);

  /* Register a clean-up for unwind_on_terminating_exception_breakpoint.  */
  SCOPE_EXIT { delete_std_terminate_breakpoint (); };

  /* - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP -
     If you're looking to implement asynchronous dummy-frames, then
     just below is the place to chop this function in two..  */

  {
    /* Save the current FSM.  We'll override it.  */
    std::unique_ptr<thread_fsm> saved_sm = call_thread->release_thread_fsm ();
    struct call_thread_fsm *sm;

    /* Save this thread's ptid, we need it later but the thread
       may have exited.  */
    call_thread_ptid = call_thread->ptid;

    /* Run the inferior until it stops.  */

    /* Create the FSM used to manage the infcall.  It tells infrun to
       not report the stop to the user, and captures the return value
       before the dummy frame is popped.  run_inferior_call registers
       it with the thread ASAP.  */
    sm = new call_thread_fsm (current_ui, command_interp (),
			      gdbarch, function,
			      values_type,
			      return_method != return_method_normal,
			      struct_addr);
    {
      std::unique_ptr<call_thread_fsm> sm_up (sm);
      e = run_inferior_call (std::move (sm_up), call_thread.get (), real_pc);
    }

    gdb::observers::inferior_call_post.notify (call_thread_ptid, funaddr);

    if (call_thread->state != THREAD_EXITED)
      {
	/* The FSM should still be the same.  */
	gdb_assert (call_thread->thread_fsm () == sm);

	if (call_thread->thread_fsm ()->finished_p ())
	  {
	    struct value *retval;

	    /* The inferior call is successful.  Pop the dummy frame,
	       which runs its destructors and restores the inferior's
	       suspend state, and restore the inferior control
	       state.  */
	    dummy_frame_pop (dummy_id, call_thread.get ());
	    restore_infcall_control_state (inf_status.release ());

	    /* Get the return value.  */
	    retval = sm->return_value;

	    /* Restore the original FSM and clean up / destroh the call FSM.
	       Doing it in this order ensures that if the call to clean_up
	       throws, the original FSM is properly restored.  */
	    {
	      std::unique_ptr<thread_fsm> finalizing
		= call_thread->release_thread_fsm ();
	      call_thread->set_thread_fsm (std::move (saved_sm));

	      finalizing->clean_up (call_thread.get ());
	    }

	    maybe_remove_breakpoints ();

	    gdb_assert (retval != NULL);

	    /* Destruct the pass-by-ref argument clones.  */
	    call_destructors (dtors_to_invoke, default_return_type);

	    return retval;
	  }

	/* Didn't complete.  Clean up / destroy the call FSM, and restore the
	   previous state machine, and handle the error.  */
	{
	  std::unique_ptr<thread_fsm> finalizing
	    = call_thread->release_thread_fsm ();
	  call_thread->set_thread_fsm (std::move (saved_sm));

	  finalizing->clean_up (call_thread.get ());
	}
      }
  }

  /* Rethrow an error if we got one trying to run the inferior.  */

  if (e.reason < 0)
    {
      const char *name = get_function_name (funaddr,
					    name_buf, sizeof (name_buf));

      discard_infcall_control_state (inf_status.release ());

      /* We could discard the dummy frame here if the program exited,
	 but it will get garbage collected the next time the program is
	 run anyway.  */

      switch (e.reason)
	{
	case RETURN_ERROR:
	  throw_error (e.error, _("%s\n\
An error occurred while in a function called from GDB.\n\
Evaluation of the expression containing the function\n\
(%s) will be abandoned.\n\
When the function is done executing, GDB will silently stop."),
		       e.what (), name);
	case RETURN_QUIT:
	default:
	  throw_exception (std::move (e));
	}
    }

  /* If the program has exited, or we stopped at a different thread,
     exit and inform the user.  */

  if (! target_has_execution ())
    {
      const char *name = get_function_name (funaddr,
					    name_buf, sizeof (name_buf));

      /* If we try to restore the inferior status,
	 we'll crash as the inferior is no longer running.  */
      discard_infcall_control_state (inf_status.release ());

      /* We could discard the dummy frame here given that the program exited,
	 but it will get garbage collected the next time the program is
	 run anyway.  */

      error (_("The program being debugged exited while in a function "
	       "called from GDB.\n"
	       "Evaluation of the expression containing the function\n"
	       "(%s) will be abandoned."),
	     name);
    }

  if (call_thread_ptid != inferior_ptid)
    {
      const char *name = get_function_name (funaddr,
					    name_buf, sizeof (name_buf));

      /* We've switched threads.  This can happen if another thread gets a
	 signal or breakpoint while our thread was running.
	 There's no point in restoring the inferior status,
	 we're in a different thread.  */
      discard_infcall_control_state (inf_status.release ());
      /* Keep the dummy frame record, if the user switches back to the
	 thread with the hand-call, we'll need it.  */
      if (stopped_by_random_signal)
	error (_("\
The program received a signal in another thread while\n\
making a function call from GDB.\n\
Evaluation of the expression containing the function\n\
(%s) will be abandoned.\n\
When the function is done executing, GDB will silently stop."),
	       name);
      else
	error (_("\
The program stopped in another thread while making a function call from GDB.\n\
Evaluation of the expression containing the function\n\
(%s) will be abandoned.\n\
When the function is done executing, GDB will silently stop."),
	       name);
    }

    {
      /* Make a copy as NAME may be in an objfile freed by dummy_frame_pop.  */
      std::string name = get_function_name (funaddr, name_buf,
					    sizeof (name_buf));

      if (stopped_by_random_signal)
	{
	  /* We stopped inside the FUNCTION because of a random
	     signal.  Further execution of the FUNCTION is not
	     allowed.  */

	  if (unwind_on_signal_p)
	    {
	      /* The user wants the context restored.  */

	      /* We must get back to the frame we were before the
		 dummy call.  */
	      dummy_frame_pop (dummy_id, call_thread.get ());

	      /* We also need to restore inferior status to that before the
		 dummy call.  */
	      restore_infcall_control_state (inf_status.release ());

	      /* FIXME: Insert a bunch of wrap_here; name can be very
		 long if it's a C++ name with arguments and stuff.  */
	      error (_("\
The program being debugged was signaled while in a function called from GDB.\n\
GDB has restored the context to what it was before the call.\n\
To change this behavior use \"set unwindonsignal off\".\n\
Evaluation of the expression containing the function\n\
(%s) will be abandoned."),
		     name.c_str ());
	    }
	  else
	    {
	      /* The user wants to stay in the frame where we stopped
		 (default).
		 Discard inferior status, we're not at the same point
		 we started at.  */
	      discard_infcall_control_state (inf_status.release ());

	      /* FIXME: Insert a bunch of wrap_here; name can be very
		 long if it's a C++ name with arguments and stuff.  */
	      error (_("\
The program being debugged was signaled while in a function called from GDB.\n\
GDB remains in the frame where the signal was received.\n\
To change this behavior use \"set unwindonsignal on\".\n\
Evaluation of the expression containing the function\n\
(%s) will be abandoned.\n\
When the function is done executing, GDB will silently stop."),
		     name.c_str ());
	    }
	}

      if (stop_stack_dummy == STOP_STD_TERMINATE)
	{
	  /* We must get back to the frame we were before the dummy
	     call.  */
	  dummy_frame_pop (dummy_id, call_thread.get ());

	  /* We also need to restore inferior status to that before
	     the dummy call.  */
	  restore_infcall_control_state (inf_status.release ());

	  error (_("\
The program being debugged entered a std::terminate call, most likely\n\
caused by an unhandled C++ exception.  GDB blocked this call in order\n\
to prevent the program from being terminated, and has restored the\n\
context to its original state before the call.\n\
To change this behaviour use \"set unwind-on-terminating-exception off\".\n\
Evaluation of the expression containing the function (%s)\n\
will be abandoned."),
		 name.c_str ());
	}
      else if (stop_stack_dummy == STOP_NONE)
	{

	  /* We hit a breakpoint inside the FUNCTION.
	     Keep the dummy frame, the user may want to examine its state.
	     Discard inferior status, we're not at the same point
	     we started at.  */
	  discard_infcall_control_state (inf_status.release ());

	  /* The following error message used to say "The expression
	     which contained the function call has been discarded."
	     It is a hard concept to explain in a few words.  Ideally,
	     GDB would be able to resume evaluation of the expression
	     when the function finally is done executing.  Perhaps
	     someday this will be implemented (it would not be easy).  */
	  /* FIXME: Insert a bunch of wrap_here; name can be very long if it's
	     a C++ name with arguments and stuff.  */
	  error (_("\
The program being debugged stopped while in a function called from GDB.\n\
Evaluation of the expression containing the function\n\
(%s) will be abandoned.\n\
When the function is done executing, GDB will silently stop."),
		 name.c_str ());
	}

    }

  /* The above code errors out, so ...  */
  gdb_assert_not_reached ("... should not be here");
}

void _initialize_infcall ();
void
_initialize_infcall ()
{
  add_setshow_boolean_cmd ("may-call-functions", no_class,
			   &may_call_functions_p, _("\
Set permission to call functions in the program."), _("\
Show permission to call functions in the program."), _("\
When this permission is on, GDB may call functions in the program.\n\
Otherwise, any sort of attempt to call a function in the program\n\
will result in an error."),
			   NULL,
			   show_may_call_functions_p,
			   &setlist, &showlist);

  add_setshow_boolean_cmd ("coerce-float-to-double", class_obscure,
			   &coerce_float_to_double_p, _("\
Set coercion of floats to doubles when calling functions."), _("\
Show coercion of floats to doubles when calling functions."), _("\
Variables of type float should generally be converted to doubles before\n\
calling an unprototyped function, and left alone when calling a prototyped\n\
function.  However, some older debug info formats do not provide enough\n\
information to determine that a function is prototyped.  If this flag is\n\
set, GDB will perform the conversion for a function it considers\n\
unprototyped.\n\
The default is to perform the conversion."),
			   NULL,
			   show_coerce_float_to_double_p,
			   &setlist, &showlist);

  add_setshow_boolean_cmd ("unwindonsignal", no_class,
			   &unwind_on_signal_p, _("\
Set unwinding of stack if a signal is received while in a call dummy."), _("\
Show unwinding of stack if a signal is received while in a call dummy."), _("\
The unwindonsignal lets the user determine what gdb should do if a signal\n\
is received while in a function called from gdb (call dummy).  If set, gdb\n\
unwinds the stack and restore the context to what as it was before the call.\n\
The default is to stop in the frame where the signal was received."),
			   NULL,
			   show_unwind_on_signal_p,
			   &setlist, &showlist);

  add_setshow_boolean_cmd ("unwind-on-terminating-exception", no_class,
			   &unwind_on_terminating_exception_p, _("\
Set unwinding of stack if std::terminate is called while in call dummy."), _("\
Show unwinding of stack if std::terminate() is called while in a call dummy."),
			   _("\
The unwind on terminating exception flag lets the user determine\n\
what gdb should do if a std::terminate() call is made from the\n\
default exception handler.  If set, gdb unwinds the stack and restores\n\
the context to what it was before the call.  If unset, gdb allows the\n\
std::terminate call to proceed.\n\
The default is to unwind the frame."),
			   NULL,
			   show_unwind_on_terminating_exception_p,
			   &setlist, &showlist);

}
