This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch rfc] New file "infcall.c" containing a merged call_function_by_hand


The attached moves _all_ the relevant code to "infrun.[hc]".

Baring comment I'll commit this in a few days,

Andrew

Hmm,

Let's try a different subject line :-) Any thoughts?

Andrew


Subject: [patch rfc] Merge call_function_by_hand & run_stack_dummy; move to infcall.c? From: Andrew Cagney <ac131313 at redhat dot com> Date: Wed, 09 Apr 2003 21:08:36 -0400 To: gdb-patches at sources dot redhat dot com

Hello,

This patch inlines run_stack_dummy into it's only caller - call_function_by_hand (nee hand_function_call). Going by some of the comments, there were once many callers but that is no more.

This opens the way for more cleanup / rationalization of call_function_by_hand. For instance:

- rationalize the computation of the the dummy breakpoint address

- ditto for the dummy entry point

- long term, split this in two; move the code handling the return to a breakpoint callback (just need to add breakpoint callbacks) and thence; make the expression evaluator async

Question is, should this code be moved to a separate file?  It's come up before:
http://sources.redhat.com/ml/gdb/2002-09/msg00485.html
dummy-frame.c now contains code implementing the `dummy-frame', so infcall.c.

Andrew



2003-04-16  Andrew Cagney  <cagney at redhat dot com>

	* infcall.c: New file.
	* infcall.h: New file.
	* valarith.c: Include "infcall.h".
	* scm-lang.c, objc-lang.cm, hppa-tdep.c, gcore.c: Ditto.
	* eval.c, ada-valprint.c, ada-lang.c: Ditto.
	* Makefile.in (valarith.o, scm-lang.o): Update dependencies.
	(objc-lang.o, hppa-tdep.o, gcore.o): Update dependencies.
	(eval.o, ada-valprint.o, ada-lang.o): Update dependencies.
	(SFILES): Add "infcall.c"
	(COMMON_OBS): Add "infcall.o".
	(infcall.o): Specify dependencies.
	* value.h (call_function_by_hand): Delete declaration.
	* inferior.h (run_stack_dummy): Delete declaration.
	* infcmd.c (breakpoint_auto_delete_contents): Move to "infcall.c".
	(run_stack_dummy): Move to "infcall.c", merged into
	call_function_by_hand.
	* valops.c (call_function_by_hand): Moved to "infcall.c".
	(find_function_addr, value_arg_coerce): Ditto.
	(unwindonsignal_p, coerce_float_to_double): Ditto.
	(_initialize_valops): Move "set/show coerce-float-to-double", and
	"set/show unwindonsignal" commands to "infcall.c".
	* v850-tdep.c, target.h: Update comments.
	* sparc-tdep.c (sparc_fix_call_dummy): Update comments.
	* sh-tdep.c (sh_init_extra_frame_info): Update comments.
	(sh64_init_extra_frame_info): Update comments.
	* mn10300-tdep.c: Update comments.
	* mcore-tdep.c (mcore_init_extra_frame_info): Update comments.
	* config/sparc/tm-sparc.h: Update comments.
	* breakpoint.h: Update comments.
	* avr-tdep.c (avr_init_extra_frame_info): Update comments.
	* arm-tdep.c: Update comment.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.364
diff -u -r1.364 Makefile.in
--- Makefile.in	15 Apr 2003 23:07:11 -0000	1.364
+++ Makefile.in	16 Apr 2003 17:18:11 -0000
@@ -521,7 +521,9 @@
 	frame-unwind.c \
 	gdbarch.c arch-utils.c gdbtypes.c gnu-v2-abi.c gnu-v3-abi.c \
 	hpacc-abi.c \
-	inf-loop.c infcmd.c inflow.c infrun.c \
+	inf-loop.c \
+	infcall.c \
+	infcmd.c inflow.c infrun.c \
 	interps.c \
 	jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
 	kod.c kod-cisco.c \
@@ -669,6 +671,7 @@
 i386_tdep_h = i386-tdep.h
 i387_tdep_h = i387-tdep.h
 inf_loop_h = inf-loop.h
+infcall_h = infcall.h
 inferior_h = inferior.h $(breakpoint_h) $(target_h) $(frame_h)
 inflow_h = inflow.h $(terminal_h)
 interps_h = interps.h
@@ -834,7 +837,9 @@
 COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
 	charset.o disasm.o dummy-frame.o \
 	source.o values.o eval.o valops.o valarith.o valprint.o printcmd.o \
-	block.o symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o \
+	block.o symtab.o symfile.o symmisc.o linespec.o \
+	infcall.o \
+	infcmd.o infrun.o \
 	expprint.o environ.o stack.o thread.o \
 	interps.o \
 	macrotab.o macrocmd.o macroexp.o macroscope.o \
@@ -1488,7 +1493,8 @@
 ada-lang.o: ada-lang.c $(gdb_string_h) $(demangle_h) $(defs_h) $(symtab_h) \
 	$(gdbtypes_h) $(gdbcmd_h) $(expression_h) $(parser_defs_h) \
 	$(language_h) $(c_lang_h) $(inferior_h) $(symfile_h) $(objfiles_h) \
-	$(breakpoint_h) $(gdbcore_h) $(ada_lang_h) $(ui_out_h) $(block_h)
+	$(breakpoint_h) $(gdbcore_h) $(ada_lang_h) $(ui_out_h) $(block_h) \
+	$(infcall_h)
 ada-tasks.o: ada-tasks.c $(defs_h) $(command_h) $(value_h) $(language_h) \
 	$(inferior_h) $(symtab_h) $(target_h) $(gdbcore_h) $(gregset_h) \
 	$(ada_lang_h)
@@ -1498,7 +1504,7 @@
 	$(c_lang_h) $(typeprint_h) $(ada_lang_h) $(gdb_string_h)
 ada-valprint.o: ada-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
 	$(expression_h) $(value_h) $(demangle_h) $(valprint_h) $(language_h) \
-	$(annotate_h) $(ada_lang_h) $(c_lang_h)
+	$(annotate_h) $(ada_lang_h) $(c_lang_h) $(infcall_h)
 aix-thread.o: aix-thread.c $(defs_h) $(gdb_assert_h) $(gdbthread_h) \
 	$(target_h) $(inferior_h) $(regcache_h) $(gdbcmd_h) $(language_h) \
 	$(ppc_tdep_h)
@@ -1681,7 +1687,7 @@
 environ.o: environ.c $(defs_h) $(environ_h) $(gdb_string_h)
 eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
 	$(value_h) $(expression_h) $(target_h) $(frame_h) $(language_h) \
-	$(f_lang_h) $(cp_abi_h)
+	$(f_lang_h) $(cp_abi_h) $(infcall_h)
 event-loop.o: event-loop.c $(defs_h) $(event_loop_h) $(event_top_h) \
 	$(gdb_string_h)
 event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \
@@ -1723,7 +1729,7 @@
 frv-tdep.o: frv-tdep.c $(defs_h) $(inferior_h) $(symfile_h) $(gdbcore_h) \
 	$(arch_utils_h) $(regcache_h)
 gcore.o: gcore.c $(defs_h) $(cli_decode_h) $(inferior_h) $(gdbcore_h) \
-	$(elf_bfd_h) $(symfile_h) $(objfiles_h)
+	$(elf_bfd_h) $(symfile_h) $(objfiles_h) $(infcall_h)
 gdb.o: gdb.c $(defs_h) $(main_h) $(gdb_string_h) $(interps_h)
 gdb-events.o: gdb-events.c $(defs_h) $(gdb_events_h) $(gdbcmd_h)
 gdbarch.o: gdbarch.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) $(inferior_h) \
@@ -1758,9 +1764,9 @@
 	$(gdbtypes_h) $(gdbcore_h) $(cp_abi_h)
 hppa-tdep.o: hppa-tdep.c $(defs_h) $(frame_h) $(bfd_h) $(inferior_h) \
 	$(value_h) $(regcache_h) $(completer_h) $(language_h) $(osabi_h) \
-	$(gdb_assert_h) $(infttrace_h) $(symtab_h) $(a_out_encap_h) \
-	$(gdb_stat_h) $(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) \
-	$(symfile_h) $(objfiles_h)
+	$(gdb_assert_h) $(infttrace_h) $(symtab_h) $(infcall_h) \
+	$(a_out_encap_h) $(gdb_stat_h) $(gdb_wait_h) $(gdbcore_h) \
+	$(gdbcmd_h) $(target_h) $(symfile_h) $(objfiles_h)
 hppa-hpux-tdep.o: hppa-hpux-tdep.c $(defs_h) $(arch_utils_h) $(gdbcore_h) \
 	$(osabi_h) $(gdb_string_h)
 hppab-nat.o: hppab-nat.c $(defs_h) $(inferior_h) $(target_h) $(regcache_h)
@@ -1830,6 +1836,9 @@
 	$(value_h) $(objfiles_h) $(elf_common_h) $(elf_bfd_h)
 inf-loop.o: inf-loop.c $(defs_h) $(inferior_h) $(target_h) $(event_loop_h) \
 	$(event_top_h) $(inf_loop_h) $(remote_h)
+infcall.o: infcall.c $(defs_h) $(breakpoint_h) $(target_h) $(regcache_h) \
+	$(inferior_h) $(gdb_assert_h) $(block_h) $(gdbcore_h) $(language_h) \
+	$(symfile_h) $(gdbcmd_h) $(command_h) $(gdb_string_h)
 infcmd.o: infcmd.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
 	$(frame_h) $(inferior_h) $(environ_h) $(value_h) $(gdbcmd_h) \
 	$(symfile_h) $(gdbcore_h) $(target_h) $(language_h) $(symfile_h) \
@@ -1995,9 +2004,9 @@
 	$(osabi_h)
 objc-lang.o: objc-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
 	$(parser_defs_h) $(language_h) $(c_lang_h) $(objc_lang_h) \
-	$(complaints_h) $(value_h) $(symfile_h) $(objfiles_h) \
-	$(gdb_string_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(frame_h) \
-	$(gdb_regex_h) $(regcache_h) $(block_h)
+	$(complaints_h) $(value_h) $(symfile_h) $(objfiles_h) $(gdb_string_h) \
+	$(target_h) $(gdbcore_h) $(gdbcmd_h) $(frame_h) $(gdb_regex_h) \
+	$(regcache_h) $(block_h) $(infcall_h)
 objfiles.o: objfiles.c $(defs_h) $(bfd_h) $(symtab_h) $(symfile_h) \
 	$(objfiles_h) $(gdb_stabs_h) $(target_h) $(bcache_h) $(gdb_stat_h) \
 	$(gdb_obstack_h) $(gdb_string_h) $(breakpoint_h) $(mmalloc_h) \
@@ -2150,7 +2159,7 @@
 	$(scm_tags_h)
 scm-lang.o: scm-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
 	$(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \
-	$(scm_tags_h) $(gdb_string_h) $(gdbcore_h) $(source_h)
+	$(scm_tags_h) $(source_h) $(gdb_string_h) $(gdbcore_h) $(infcall_h)
 scm-valprint.o: scm-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
 	$(expression_h) $(parser_defs_h) $(language_h) $(value_h) \
 	$(scm_lang_h) $(valprint_h) $(gdbcore_h)
@@ -2308,7 +2317,7 @@
 	$(gdbcore_h) $(value_h) $(command_h) $(regcache_h)
 valarith.o: valarith.c $(defs_h) $(value_h) $(symtab_h) $(gdbtypes_h) \
 	$(expression_h) $(target_h) $(language_h) $(gdb_string_h) \
-	$(doublest_h)
+	$(doublest_h) $(infcall_h)
 valops.o: valops.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) $(frame_h) \
 	$(inferior_h) $(gdbcore_h) $(target_h) $(demangle_h) $(language_h) \
 	$(gdbcmd_h) $(regcache_h) $(cp_abi_h) $(gdb_string_h) \
Index: ada-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/ada-lang.c,v
retrieving revision 1.23
diff -u -r1.23 ada-lang.c
--- ada-lang.c	2 Apr 2003 03:02:46 -0000	1.23
+++ ada-lang.c	16 Apr 2003 17:18:13 -0000
@@ -39,6 +39,7 @@
 #include "ada-lang.h"
 #include "ui-out.h"
 #include "block.h"
+#include "infcall.h"
 
 struct cleanup *unresolved_names;
 
Index: ada-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/ada-valprint.c,v
retrieving revision 1.6
diff -u -r1.6 ada-valprint.c
--- ada-valprint.c	18 Jan 2003 15:55:51 -0000	1.6
+++ ada-valprint.c	16 Apr 2003 17:18:13 -0000
@@ -30,6 +30,7 @@
 #include "annotate.h"
 #include "ada-lang.h"
 #include "c-lang.h"
+#include "infcall.h"
 
 /* Encapsulates arguments to ada_val_print. */
 struct ada_val_print_args
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.129
diff -u -r1.129 arm-tdep.c
--- arm-tdep.c	11 Apr 2003 18:15:38 -0000	1.129
+++ arm-tdep.c	16 Apr 2003 17:18:15 -0000
@@ -1257,8 +1257,8 @@
 
    FIXME rearnsha 2002-02018: Tweeking current_gdbarch is not an
    optimal solution, but the call to arm_fix_call_dummy is immediately
-   followed by a call to run_stack_dummy, which is the only function
-   where call_dummy_breakpoint_offset is actually used.  */
+   followed by a call to call_function_by_hand, which is the only
+   function where call_dummy_breakpoint_offset is actually used.  */
 
 
 static void
Index: avr-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/avr-tdep.c,v
retrieving revision 1.42
diff -u -r1.42 avr-tdep.c
--- avr-tdep.c	11 Apr 2003 18:15:38 -0000	1.42
+++ avr-tdep.c	16 Apr 2003 17:18:16 -0000
@@ -753,8 +753,8 @@
   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
 				   get_frame_base (fi)))
     {
-      /* We need to setup fi->frame here because run_stack_dummy gets it wrong
-         by assuming it's always FP.  */
+      /* We need to setup fi->frame here because call_function_by_hand
+         gets it wrong by assuming it's always FP.  */
       deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi),
 									     AVR_PC_REGNUM));
     }
Index: breakpoint.h
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.h,v
retrieving revision 1.19
diff -u -r1.19 breakpoint.h
--- breakpoint.h	20 Feb 2003 00:01:05 -0000	1.19
+++ breakpoint.h	16 Apr 2003 17:18:16 -0000
@@ -623,7 +623,7 @@
    enabled watchpoints.  When disabled, the watchpoints are marked
    call_disabled.  When reenabled, they are marked enabled.
 
-   The intended client of these functions is infcmd.c\run_stack_dummy.
+   The intended client of these functions is call_function_by_hand.
 
    The inferior must be stopped, and all breakpoints removed, when
    these functions are used.
Index: cris-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/cris-tdep.c,v
retrieving revision 1.67
diff -u -r1.67 cris-tdep.c
--- cris-tdep.c	11 Apr 2003 18:15:38 -0000	1.67
+++ cris-tdep.c	16 Apr 2003 17:18:17 -0000
@@ -1216,8 +1216,8 @@
 				   get_frame_base (fi),
 				   get_frame_base (fi)))
     {    
-      /* We need to setup fi->frame here because run_stack_dummy gets it wrong
-         by assuming it's always FP.  */
+      /* We need to setup fi->frame here because call_function_by_hand
+         gets it wrong by assuming it's always FP.  */
       deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), SP_REGNUM));
       get_frame_extra_info (fi)->return_pc = 
         deprecated_read_register_dummy (get_frame_pc (fi),
Index: eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.28
diff -u -r1.28 eval.c
--- eval.c	12 Mar 2003 22:39:15 -0000	1.28
+++ eval.c	16 Apr 2003 17:18:17 -0000
@@ -32,6 +32,7 @@
 #include "language.h"		/* For CAST_IS_CONVERSION */
 #include "f-lang.h"		/* for array bound stuff */
 #include "cp-abi.h"
+#include "infcall.h"
 
 /* Defined in symtab.c */
 extern int hp_som_som_object_present;
Index: gcore.c
===================================================================
RCS file: /cvs/src/src/gdb/gcore.c,v
retrieving revision 1.9
diff -u -r1.9 gcore.c
--- gcore.c	14 Jan 2003 00:49:04 -0000	1.9
+++ gcore.c	16 Apr 2003 17:18:17 -0000
@@ -26,6 +26,7 @@
 #include "elf-bfd.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "infcall.h"
 
 static char                  *default_gcore_target (void);
 static enum bfd_architecture  default_gcore_arch (void);
Index: hppa-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppa-tdep.c,v
retrieving revision 1.69
diff -u -r1.69 hppa-tdep.c
--- hppa-tdep.c	13 Apr 2003 15:54:58 -0000	1.69
+++ hppa-tdep.c	16 Apr 2003 17:18:18 -0000
@@ -36,6 +36,7 @@
 #include "infttrace.h"
 /* For argument passing to the inferior */
 #include "symtab.h"
+#include "infcall.h"
 
 #ifdef USG
 #include <sys/types.h>
Index: infcall.c
===================================================================
RCS file: infcall.c
diff -N infcall.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ infcall.c	16 Apr 2003 17:18:19 -0000
@@ -0,0 +1,981 @@
+/* Perform an inferior function call, for GDB, the GNU debugger.
+
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "breakpoint.h"
+#include "target.h"
+#include "regcache.h"
+#include "inferior.h"
+#include "gdb_assert.h"
+#include "block.h"
+#include "gdbcore.h"
+#include "language.h"
+#include "symfile.h"
+#include "gdbcmd.h"
+#include "command.h"
+#include "gdb_string.h"
+
+/* 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.  */
+
+/* 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_FLAG_PROTOTYPED flag may be clear, even if the function was
+   defined in prototype style.  When calling a function whose
+   TYPE_FLAG_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 int coerce_float_to_double_p = 1;
+
+/* 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. */
+
+int unwind_on_signal_p = 0;
+
+/* Perform the standard coercions that are specified
+   for arguments to be passed to C 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 value *arg, struct type *param_type,
+		  int is_prototyped)
+{
+  register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+  register struct type *type
+    = param_type ? check_typedef (param_type) : arg_type;
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_REF:
+      if (TYPE_CODE (arg_type) != TYPE_CODE_REF
+	  && TYPE_CODE (arg_type) != TYPE_CODE_PTR)
+	{
+	  arg = value_addr (arg);
+	  VALUE_TYPE (arg) = param_type;
+	  return arg;
+	}
+      break;
+    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_type_int))
+	    type = builtin_type_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_type_int))
+	type = builtin_type_int;
+      break;
+    case TYPE_CODE_FLT:
+      if (!is_prototyped && coerce_float_to_double_p)
+	{
+	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
+	    type = builtin_type_double;
+	  else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
+	    type = builtin_type_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)
+	if (!TYPE_VECTOR (type))
+	  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_BITSTRING:
+    case TYPE_CODE_ERROR:
+    case TYPE_CODE_MEMBER:
+    case TYPE_CODE_METHOD:
+    case TYPE_CODE_COMPLEX:
+    default:
+      break;
+    }
+
+  return value_cast (type, arg);
+}
+
+/* Determine a function's address and its return type from its value.
+   Calls error() if the function is not valid for calling.  */
+
+static CORE_ADDR
+find_function_addr (struct value *function, struct type **retval_type)
+{
+  register struct type *ftype = check_typedef (VALUE_TYPE (function));
+  register enum type_code code = TYPE_CODE (ftype);
+  struct type *value_type;
+  CORE_ADDR funaddr;
+
+  /* If it's a member function, just look at the function
+     part of it.  */
+
+  /* Determine address to call.  */
+  if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
+    {
+      funaddr = VALUE_ADDRESS (function);
+      value_type = TYPE_TARGET_TYPE (ftype);
+    }
+  else if (code == TYPE_CODE_PTR)
+    {
+      funaddr = value_as_address (function);
+      ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
+      if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
+	  || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+	{
+	  funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
+	  value_type = TYPE_TARGET_TYPE (ftype);
+	}
+      else
+	value_type = builtin_type_int;
+    }
+  else if (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 integer used as address of a function.  */
+	funaddr = (CORE_ADDR) value_as_long (function);
+
+      value_type = builtin_type_int;
+    }
+  else
+    error ("Invalid data type for function to be called.");
+
+  *retval_type = value_type;
+  return funaddr;
+}
+
+/* Call breakpoint_auto_delete on the current contents of the bpstat
+   pointed to by arg (which is really a bpstat *).  */
+
+static void
+breakpoint_auto_delete_contents (void *arg)
+{
+  breakpoint_auto_delete (*(bpstat *) arg);
+}
+
+/* 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 (NARGS of them).
+   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 (struct value *function, int nargs, struct value **args)
+{
+  register CORE_ADDR sp;
+  register int i;
+  int rc;
+  CORE_ADDR start_sp;
+  /* CALL_DUMMY is an array of words (REGISTER_SIZE), but each word
+     is in host byte order.  Before calling FIX_CALL_DUMMY, we byteswap it
+     and remove any extra bytes which might exist because ULONGEST is
+     bigger than REGISTER_SIZE.
+
+     NOTE: This is pretty wierd, as the call dummy is actually a
+     sequence of instructions.  But CISC machines will have
+     to pack the instructions into REGISTER_SIZE units (and
+     so will RISC machines for which INSTRUCTION_SIZE is not
+     REGISTER_SIZE).
+
+     NOTE: This is pretty stupid.  CALL_DUMMY should be in strict
+     target byte order. */
+
+  static ULONGEST *dummy;
+  int sizeof_dummy1;
+  char *dummy1;
+  CORE_ADDR dummy_addr;
+  CORE_ADDR old_sp;
+  struct type *value_type;
+  unsigned char struct_return;
+  CORE_ADDR struct_addr = 0;
+  struct regcache *retbuf;
+  struct cleanup *retbuf_cleanup;
+  struct inferior_status *inf_status;
+  struct cleanup *inf_status_cleanup;
+  CORE_ADDR funaddr;
+  int using_gcc;		/* Set to version of gcc in use, or zero if not gcc */
+  CORE_ADDR real_pc;
+  struct type *param_type = NULL;
+  struct type *ftype = check_typedef (SYMBOL_TYPE (function));
+  int n_method_args = 0;
+
+  dummy = alloca (SIZEOF_CALL_DUMMY_WORDS);
+  sizeof_dummy1 = REGISTER_SIZE * SIZEOF_CALL_DUMMY_WORDS / sizeof (ULONGEST);
+  dummy1 = alloca (sizeof_dummy1);
+  memcpy (dummy, CALL_DUMMY_WORDS, SIZEOF_CALL_DUMMY_WORDS);
+
+  if (!target_has_execution)
+    noprocess ();
+
+  /* Create a cleanup chain that contains the retbuf (buffer
+     containing the register values).  This chain is create BEFORE the
+     inf_status chain so that the inferior status can cleaned up
+     (restored or discarded) without having the retbuf freed.  */
+  retbuf = regcache_xmalloc (current_gdbarch);
+  retbuf_cleanup = make_cleanup_regcache_xfree (retbuf);
+
+  /* A cleanup for the inferior status.  Create this AFTER the retbuf
+     so that this can be discarded or applied without interfering with
+     the regbuf.  */
+  inf_status = save_inferior_status (1);
+  inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status);
+
+  if (DEPRECATED_PUSH_DUMMY_FRAME_P ())
+    {
+      /* DEPRECATED_PUSH_DUMMY_FRAME is responsible for saving the
+	 inferior registers (and frame_pop() for restoring them).  (At
+	 least on most machines) they are saved on the stack in the
+	 inferior.  */
+      DEPRECATED_PUSH_DUMMY_FRAME;
+    }
+  else
+    {
+      /* FIXME: cagney/2003-02-26: Step zero of this little tinker is
+      to extract the generic dummy frame code from the architecture
+      vector.  Hence this direct call.
+
+      A follow-on change is to modify this interface so that it takes
+      thread OR frame OR tpid as a parameter, and returns a dummy
+      frame handle.  The handle can then be used further down as a
+      parameter SAVE_DUMMY_FRAME_TOS.  Hmm, thinking about it, since
+      everything is ment to be using generic dummy frames, why not
+      even use some of the dummy frame code to here - do a regcache
+      dup and then pass the duped regcache, along with all the other
+      stuff, at one single point.
+
+      In fact, you can even save the structure's return address in the
+      dummy frame and fix one of those nasty lost struct return edge
+      conditions.  */
+      generic_push_dummy_frame ();
+    }
+
+  old_sp = read_sp ();
+
+  /* Ensure that the initial SP is correctly aligned.  */
+  if (gdbarch_frame_align_p (current_gdbarch))
+    {
+      /* 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 framelss (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
+	 suprisingly, 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
+	 :-).  */
+      sp = gdbarch_frame_align (current_gdbarch, old_sp);
+      if (sp == old_sp)
+	{
+	  if (INNER_THAN (1, 2))
+	    /* Stack grows down.  */
+	    sp = gdbarch_frame_align (current_gdbarch, old_sp - 1);
+	  else
+	    /* Stack grows up.  */
+	    sp = gdbarch_frame_align (current_gdbarch, old_sp + 1);
+	}
+      gdb_assert ((INNER_THAN (1, 2) && sp <= old_sp)
+		  || (INNER_THAN (2, 1) && sp >= old_sp));
+    }
+  else
+    /* FIXME: cagney/2002-09-18: Hey, you loose!  Who knows how badly
+       aligned the SP is!  Further, per comment above, 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 its architecture vector.  After that, try
+       adding SAVE_DUMMY_FRAME_TOS() and modifying
+       DEPRECATED_FRAME_CHAIN so that when the next outer frame is a
+       generic dummy, it returns the current frame's base.  */
+    sp = old_sp;
+
+  if (INNER_THAN (1, 2))
+    {
+      /* Stack grows down */
+      sp -= sizeof_dummy1;
+      start_sp = sp;
+    }
+  else
+    {
+      /* Stack grows up */
+      start_sp = sp;
+      sp += sizeof_dummy1;
+    }
+
+  /* NOTE: cagney/2002-09-10: Don't bother re-adjusting the stack
+     after allocating space for the call dummy.  A target can specify
+     a SIZEOF_DUMMY1 (via SIZEOF_CALL_DUMMY_WORDS) such that all local
+     alignment requirements are met.  */
+
+  funaddr = find_function_addr (function, &value_type);
+  CHECK_TYPEDEF (value_type);
+
+  {
+    struct block *b = block_for_pc (funaddr);
+    /* If compiled without -g, assume GCC 2.  */
+    using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
+  }
+
+  /* Are we returning a value using a structure return or a normal
+     value return? */
+
+  struct_return = using_struct_return (function, funaddr, value_type,
+				       using_gcc);
+
+  /* Create a call sequence customized for this function
+     and the number of arguments for it.  */
+  for (i = 0; i < (int) (SIZEOF_CALL_DUMMY_WORDS / sizeof (dummy[0])); i++)
+    store_unsigned_integer (&dummy1[i * REGISTER_SIZE],
+			    REGISTER_SIZE,
+			    (ULONGEST) dummy[i]);
+
+#ifdef GDB_TARGET_IS_HPPA
+  real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
+			    value_type, using_gcc);
+#else
+  if (FIX_CALL_DUMMY_P ())
+    {
+      /* gdb_assert (CALL_DUMMY_LOCATION == ON_STACK) true?  */
+      FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args, value_type,
+		      using_gcc);
+    }
+  real_pc = start_sp;
+#endif
+
+  switch (CALL_DUMMY_LOCATION)
+    {
+    case ON_STACK:
+      dummy_addr = start_sp;
+      write_memory (start_sp, (char *) dummy1, sizeof_dummy1);
+      if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
+	generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1);
+      break;
+    case AT_ENTRY_POINT:
+      real_pc = funaddr;
+      dummy_addr = CALL_DUMMY_ADDRESS ();
+      if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
+	/* NOTE: cagney/2002-04-13: The entry point is going to be
+           modified with a single breakpoint.  */
+	generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (),
+				      CALL_DUMMY_ADDRESS () + 1);
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, "bad switch");
+    }
+
+#ifdef lint
+  sp = old_sp;			/* It really is used, for some ifdef's... */
+#endif
+
+  if (nargs < TYPE_NFIELDS (ftype))
+    error ("too few arguments in function call");
+
+  for (i = nargs - 1; i >= 0; i--)
+    {
+      int prototyped;
+
+      /* FIXME drow/2002-05-31: Should just always mark methods as
+	 prototyped.  Can we respect TYPE_VARARGS?  Probably not.  */
+      if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+	prototyped = 1;
+      else
+	prototyped = TYPE_PROTOTYPED (ftype);
+
+      if (i < TYPE_NFIELDS (ftype))
+	args[i] = value_arg_coerce (args[i], TYPE_FIELD_TYPE (ftype, i),
+				    prototyped);
+      else
+	args[i] = value_arg_coerce (args[i], NULL, 0);
+
+      /*elz: this code is to handle the case in which the function to be called
+         has a pointer to function as parameter and the corresponding actual argument
+         is the address of a function and not a pointer to function variable.
+         In aCC compiled code, the calls through pointers to functions (in the body
+         of the function called by hand) are made via $$dyncall_external which
+         requires some registers setting, this is taken care of if we call
+         via a function pointer variable, but not via a function address.
+         In cc this is not a problem. */
+
+      if (using_gcc == 0)
+	if (param_type && TYPE_CODE (ftype) != TYPE_CODE_METHOD)
+	  /* if this parameter is a pointer to function */
+	  if (TYPE_CODE (param_type) == TYPE_CODE_PTR)
+	    if (TYPE_CODE (TYPE_TARGET_TYPE (param_type)) == TYPE_CODE_FUNC)
+	      /* elz: FIXME here should go the test about the compiler used
+	         to compile the target. We want to issue the error
+	         message only if the compiler used was HP's aCC.
+	         If we used HP's cc, then there is no problem and no need
+	         to return at this point */
+	      if (using_gcc == 0)	/* && compiler == aCC */
+		/* go see if the actual parameter is a variable of type
+		   pointer to function or just a function */
+		if (args[i]->lval == not_lval)
+		  {
+		    char *arg_name;
+		    if (find_pc_partial_function ((CORE_ADDR) args[i]->aligner.contents[0], &arg_name, NULL, NULL))
+		      error ("\
+You cannot use function <%s> as argument. \n\
+You must use a pointer to function type variable. Command ignored.", arg_name);
+		  }
+    }
+
+  if (REG_STRUCT_HAS_ADDR_P ())
+    {
+      /* This is a machine like the sparc, where we may need to pass a
+	 pointer to the structure, not the structure itself.  */
+      for (i = nargs - 1; i >= 0; i--)
+	{
+	  struct type *arg_type = check_typedef (VALUE_TYPE (args[i]));
+	  if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
+	       || TYPE_CODE (arg_type) == TYPE_CODE_UNION
+	       || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
+	       || TYPE_CODE (arg_type) == TYPE_CODE_STRING
+	       || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING
+	       || TYPE_CODE (arg_type) == TYPE_CODE_SET
+	       || (TYPE_CODE (arg_type) == TYPE_CODE_FLT
+		   && TYPE_LENGTH (arg_type) > 8)
+	       )
+	      && REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
+	    {
+	      CORE_ADDR addr;
+	      int len;		/*  = TYPE_LENGTH (arg_type); */
+	      int aligned_len;
+	      arg_type = check_typedef (VALUE_ENCLOSING_TYPE (args[i]));
+	      len = TYPE_LENGTH (arg_type);
+
+	      if (STACK_ALIGN_P ())
+		/* MVS 11/22/96: I think at least some of this
+		   stack_align code is really broken.  Better to let
+		   PUSH_ARGUMENTS adjust the stack in a target-defined
+		   manner.  */
+		aligned_len = STACK_ALIGN (len);
+	      else
+		aligned_len = len;
+	      if (INNER_THAN (1, 2))
+		{
+		  /* stack grows downward */
+		  sp -= aligned_len;
+		  /* ... so the address of the thing we push is the
+		     stack pointer after we push it.  */
+		  addr = sp;
+		}
+	      else
+		{
+		  /* The stack grows up, so the address of the thing
+		     we push is the stack pointer before we push it.  */
+		  addr = sp;
+		  sp += aligned_len;
+		}
+	      /* Push the structure.  */
+	      write_memory (addr, VALUE_CONTENTS_ALL (args[i]), len);
+	      /* The value we're going to pass is the address of the
+		 thing we just pushed.  */
+	      /*args[i] = value_from_longest (lookup_pointer_type (value_type),
+		(LONGEST) addr); */
+	      args[i] = value_from_pointer (lookup_pointer_type (arg_type),
+					    addr);
+	    }
+	}
+    }
+
+
+  /* Reserve space for the return structure to be written on the
+     stack, if necessary.  Make certain that the value is correctly
+     aligned. */
+
+  if (struct_return)
+    {
+      int len = TYPE_LENGTH (value_type);
+      if (STACK_ALIGN_P ())
+	/* NOTE: cagney/2003-03-22: Should rely on frame align, rather
+           than stack align to force the alignment of the stack.  */
+	len = STACK_ALIGN (len);
+      if (INNER_THAN (1, 2))
+	{
+	  /* Stack grows downward.  Align STRUCT_ADDR and SP after
+             making space for the return value.  */
+	  sp -= len;
+	  if (gdbarch_frame_align_p (current_gdbarch))
+	    sp = gdbarch_frame_align (current_gdbarch, sp);
+	  struct_addr = sp;
+	}
+      else
+	{
+	  /* Stack grows upward.  Align the frame, allocate space, and
+             then again, re-align the frame??? */
+	  if (gdbarch_frame_align_p (current_gdbarch))
+	    sp = gdbarch_frame_align (current_gdbarch, sp);
+	  struct_addr = sp;
+	  sp += len;
+	  if (gdbarch_frame_align_p (current_gdbarch))
+	    sp = gdbarch_frame_align (current_gdbarch, sp);
+	}
+    }
+
+  /* elz: on HPPA no need for this extra alignment, maybe it is needed
+     on other architectures. This is because all the alignment is
+     taken care of in the above code (ifdef REG_STRUCT_HAS_ADDR) and
+     in hppa_push_arguments */
+  /* NOTE: cagney/2003-03-24: The below code is very broken.  Given an
+     odd sized parameter the below will mis-align the stack.  As was
+     suggested back in '96, better to let PUSH_ARGUMENTS handle it.  */
+  if (DEPRECATED_EXTRA_STACK_ALIGNMENT_NEEDED)
+    {
+      /* MVS 11/22/96: I think at least some of this stack_align code
+	 is really broken.  Better to let push_dummy_call() adjust the
+	 stack in a target-defined manner.  */
+      if (STACK_ALIGN_P () && INNER_THAN (1, 2))
+	{
+	  /* If stack grows down, we must leave a hole at the top. */
+	  int len = 0;
+
+	  for (i = nargs - 1; i >= 0; i--)
+	    len += TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
+	  if (DEPRECATED_CALL_DUMMY_STACK_ADJUST_P ())
+	    len += DEPRECATED_CALL_DUMMY_STACK_ADJUST;
+	  sp -= STACK_ALIGN (len) - len;
+	}
+    }
+
+  /* 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.  */
+  if (gdbarch_push_dummy_call_p (current_gdbarch))
+    /* When there is no push_dummy_call method, should this code
+       simply error out.  That would the implementation of this method
+       for all ABIs (which is probably a good thing).  */
+    sp = gdbarch_push_dummy_call (current_gdbarch, current_regcache,
+				  dummy_addr, nargs, args, sp, struct_return,
+				  struct_addr);
+  else  if (DEPRECATED_PUSH_ARGUMENTS_P ())
+    /* Keep old targets working.  */
+    sp = DEPRECATED_PUSH_ARGUMENTS (nargs, args, sp, struct_return,
+				    struct_addr);
+  else
+    sp = legacy_push_arguments (nargs, args, sp, struct_return, struct_addr);
+
+  if (DEPRECATED_PUSH_RETURN_ADDRESS_P ())
+    /* for targets that use no CALL_DUMMY */
+    /* There are a number of targets now which actually don't write
+       any CALL_DUMMY instructions into the target, but instead just
+       save the machine state, push the arguments, and jump directly
+       to the callee function.  Since this doesn't actually involve
+       executing a JSR/BSR instruction, the return address must be set
+       up by hand, either by pushing onto the stack or copying into a
+       return-address register as appropriate.  Formerly this has been
+       done in PUSH_ARGUMENTS, but that's overloading its
+       functionality a bit, so I'm making it explicit to do it here.  */
+    sp = DEPRECATED_PUSH_RETURN_ADDRESS (real_pc, sp);
+
+  /* NOTE: cagney/2003-03-23: Diable this code when there is a
+     push_dummy_call() method.  Since that method will have already
+     handled any alignment issues, the code below is entirely
+     redundant.  */
+  if (!gdbarch_push_dummy_call_p (current_gdbarch)
+      && STACK_ALIGN_P () && !INNER_THAN (1, 2))
+    {
+      /* If stack grows up, we must leave a hole at the bottom, note
+         that sp already has been advanced for the arguments!  */
+      if (DEPRECATED_CALL_DUMMY_STACK_ADJUST_P ())
+	sp += DEPRECATED_CALL_DUMMY_STACK_ADJUST;
+      sp = STACK_ALIGN (sp);
+    }
+
+/* XXX This seems wrong.  For stacks that grow down we shouldn't do
+   anything here!  */
+  /* MVS 11/22/96: I think at least some of this stack_align code is
+     really broken.  Better to let PUSH_ARGUMENTS adjust the stack in
+     a target-defined manner.  */
+  if (DEPRECATED_CALL_DUMMY_STACK_ADJUST_P ())
+    if (INNER_THAN (1, 2))
+      {
+	/* stack grows downward */
+	sp -= DEPRECATED_CALL_DUMMY_STACK_ADJUST;
+      }
+
+  /* Store the address at which the structure is supposed to be
+     written.  */
+  /* NOTE: 2003-03-24: Since PUSH_ARGUMENTS can (and typically does)
+     store the struct return address, this call is entirely redundant.  */
+  if (struct_return && DEPRECATED_STORE_STRUCT_RETURN_P ())
+    DEPRECATED_STORE_STRUCT_RETURN (struct_addr, sp);
+
+  /* Write the stack pointer.  This is here because the statements above
+     might fool with it.  On SPARC, this write also stores the register
+     window into the right place in the new stack frame, which otherwise
+     wouldn't happen.  (See store_inferior_registers in sparc-nat.c.)  */
+  /* NOTE: cagney/2003-03-23: Disable this code when there is a
+     push_dummy_call() method.  Since that method will have already
+     stored the stack pointer (as part of creating the fake call
+     frame), and none of the code following that code adjusts the
+     stack-pointer value, the below call is entirely redundant.  */
+  if (DEPRECATED_DUMMY_WRITE_SP_P ())
+    DEPRECATED_DUMMY_WRITE_SP (sp);
+
+  if (SAVE_DUMMY_FRAME_TOS_P ())
+    SAVE_DUMMY_FRAME_TOS (sp);
+
+  {
+    char *name;
+    struct symbol *symbol;
+
+    name = NULL;
+    symbol = find_pc_function (funaddr);
+    if (symbol)
+      {
+	name = SYMBOL_PRINT_NAME (symbol);
+      }
+    else
+      {
+	/* Try the minimal symbols.  */
+	struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr);
+
+	if (msymbol)
+	  {
+	    name = SYMBOL_PRINT_NAME (msymbol);
+	  }
+      }
+    if (name == NULL)
+      {
+	char format[80];
+	sprintf (format, "at %s", local_hex_format ());
+	name = alloca (80);
+	/* FIXME-32x64: assumes funaddr fits in a long.  */
+	sprintf (name, format, (unsigned long) funaddr);
+      }
+
+    {
+      /* Execute a "stack dummy", a piece of code stored in the stack
+	 by the debugger to be executed in the inferior.
+
+	 The dummy's frame is automatically popped whenever that break
+	 is hit.  If that is the first time the program stops,
+	 call_function_by_hand returns to its caller with that frame
+	 already gone and sets RC to 0.
+   
+	 Otherwise, set RC to a non-zero value.  If the called
+	 function receives a random signal, we do not allow the user
+	 to continue executing it as this may not work.  The dummy
+	 frame is poped and we return 1.  If we hit a breakpoint, we
+	 leave the frame in place and return 2 (the frame will
+	 eventually be popped when we do hit the dummy end
+	 breakpoint).  */
+
+      CORE_ADDR addr = real_pc + CALL_DUMMY_START_OFFSET;
+      struct regcache *buffer = retbuf;
+      struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
+      int saved_async = 0;
+      struct breakpoint *bpt;
+      struct symtab_and_line sal;
+
+      /* Now proceed, having reached the desired place.  */
+      clear_proceed_status ();
+
+      init_sal (&sal);		/* initialize to zeroes */
+      if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
+	{
+	  sal.pc = CALL_DUMMY_ADDRESS ();
+	}
+      else
+	{
+	  /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need
+	     to put a breakpoint instruction.  If not, the call dummy
+	     already has the breakpoint instruction in it.
+
+	     ADDR IS THE ADDRESS of the call dummy plus the
+	     CALL_DUMMY_START_OFFSET, so we need to subtract the
+	     CALL_DUMMY_START_OFFSET.  */
+	  sal.pc = (addr - (CALL_DUMMY_START_OFFSET
+			    + CALL_DUMMY_BREAKPOINT_OFFSET));
+	}
+      sal.section = find_pc_overlay (sal.pc);
+  
+      {
+	/* 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.  */
+	struct frame_id frame = frame_id_build (read_fp (), sal.pc);
+	/* Create a momentary breakpoint at the return address of the
+	   inferior.  That way it breaks when it returns.  */
+	bpt = set_momentary_breakpoint (sal, frame, bp_call_dummy);
+	bpt->disposition = disp_del;
+      }
+
+      /* 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.  */
+      make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat);
+
+      disable_watchpoints_before_interactive_call_start ();
+      proceed_to_finish = 1;	/* We want stop_registers, please... */
+
+      if (target_can_async_p ())
+	saved_async = target_async_mask (0);
+
+      proceed (addr, TARGET_SIGNAL_0, 0);
+
+      if (saved_async)
+	target_async_mask (saved_async);
+      
+      enable_watchpoints_after_interactive_call_stop ();
+      
+      discard_cleanups (old_cleanups);
+  
+      if (stopped_by_random_signal)
+	/* We can stop during an inferior call because a signal is
+	   received. */
+	rc = 1;
+      else if (!stop_stack_dummy)
+	/* We may also stop prematurely because we hit a breakpoint in
+	   the called routine. */
+	rc = 2;
+      else
+	{
+	  /* On normal return, the stack dummy has been popped
+             already.  */
+	  regcache_cpy_no_passthrough (buffer, stop_registers);
+	  rc = 0;
+	}
+    }
+
+    if (rc == 1)
+      {
+	/* 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. */
+	    frame_pop (get_current_frame ());
+
+	    /* 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 (%s) will be abandoned.",
+		   name);
+	  }
+	else
+	  {
+	    /* The user wants to stay in the frame where we stopped (default).*/
+
+	    /* If we restored the inferior status (via the cleanup),
+	       we would print a spurious error message (Unable to
+	       restore previously selected frame), would write the
+	       registers from the inf_status (which is wrong), and
+	       would do other wrong things.  */
+	    discard_cleanups (inf_status_cleanup);
+	    discard_inferior_status (inf_status);
+
+	    /* 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 (%s) will be abandoned.",
+		   name);
+	  }
+      }
+
+    if (rc == 2)
+      {
+	/* We hit a breakpoint inside the FUNCTION. */
+
+	/* If we restored the inferior status (via the cleanup), we
+	   would print a spurious error message (Unable to restore
+	   previously selected frame), would write the registers from
+	   the inf_status (which is wrong), and would do other wrong
+	   things.  */
+	discard_cleanups (inf_status_cleanup);
+	discard_inferior_status (inf_status);
+
+	/* 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\
+When the function (%s) is done executing, GDB will silently\n\
+stop (instead of continuing to evaluate the expression containing\n\
+the function call).", name);
+      }
+
+    /* If we get here the called FUNCTION run to completion. */
+
+    /* Restore the inferior status, via its cleanup.  At this stage,
+       leave the RETBUF alone.  */
+    do_cleanups (inf_status_cleanup);
+
+    /* Figure out the value returned by the function.  */
+    /* elz: I defined this new macro for the hppa architecture only.
+       this gives us a way to get the value returned by the function
+       from the stack, at the same address we told the function to put
+       it.  We cannot assume on the pa that r28 still contains the
+       address of the returned structure. Usually this will be
+       overwritten by the callee.  I don't know about other
+       architectures, so I defined this macro */
+#ifdef VALUE_RETURNED_FROM_STACK
+    if (struct_return)
+      {
+	do_cleanups (retbuf_cleanup);
+	return VALUE_RETURNED_FROM_STACK (value_type, struct_addr);
+      }
+#endif
+    /* NOTE: cagney/2002-09-10: Only when the stack has been correctly
+       aligned (using frame_align()) do we can trust STRUCT_ADDR and
+       fetch the return value direct from the stack.  This lack of
+       trust comes about because legacy targets have a nasty habit of
+       silently, and local to PUSH_ARGUMENTS(), moving STRUCT_ADDR.
+       For such targets, just hope that value_being_returned() can
+       find the adjusted value.  */
+    if (struct_return && gdbarch_frame_align_p (current_gdbarch))
+      {
+        struct value *retval = value_at (value_type, struct_addr, NULL);
+        do_cleanups (retbuf_cleanup);
+        return retval;
+      }
+    else
+      {
+	struct value *retval = value_being_returned (value_type, retbuf,
+						     struct_return);
+	do_cleanups (retbuf_cleanup);
+	return retval;
+      }
+  }
+}
+
+void _initialize_infcall (void);
+
+void
+_initialize_infcall (void)
+{
+  add_setshow_boolean_cmd ("coerce-float-to-double", class_obscure,
+			   &coerce_float_to_double_p, "\
+Set coercion of floats to doubles when calling functions\n\
+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.\n", "\
+Show coercion of floats to doubles when calling functions\n\
+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.\n",
+			   NULL, NULL, &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.\n\
+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.", "\
+Set unwinding of stack if a signal is received while in a call dummy.\n\
+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, NULL, &setlist, &showlist);
+}
Index: infcall.h
===================================================================
RCS file: infcall.h
diff -N infcall.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ infcall.h	16 Apr 2003 17:18:19 -0000
@@ -0,0 +1,39 @@
+/* Perform an inferior function call, for GDB, the GNU debugger.
+
+   Copyright 2003 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef INFCALL_H
+#define INFCALL_H
+
+struct value;
+
+/* Perform a function call in the inferior.
+
+   ARGS is a vector of values of arguments (NARGS of them).  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. */
+
+extern struct value *call_function_by_hand (struct value *function, int nargs,
+					    struct value **args);
+
+#endif
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.78
diff -u -r1.78 infcmd.c
--- infcmd.c	8 Apr 2003 19:21:14 -0000	1.78
+++ infcmd.c	16 Apr 2003 17:18:19 -0000
@@ -115,8 +115,6 @@
 
 #define GO_USAGE   "Usage: go <location>\n"
 
-static void breakpoint_auto_delete_contents (void *);
-
 #define ERROR_NO_INFERIOR \
    if (!target_has_execution) error ("The program is not being run.");
 
@@ -950,112 +948,6 @@
   proceed (oursig == TARGET_SIGNAL_0 ? (CORE_ADDR) -1 : stop_pc, oursig, 0);
 }
 
-/* Call breakpoint_auto_delete on the current contents of the bpstat
-   pointed to by arg (which is really a bpstat *).  */
-
-static void
-breakpoint_auto_delete_contents (void *arg)
-{
-  breakpoint_auto_delete (*(bpstat *) arg);
-}
-
-
-/* Execute a "stack dummy", a piece of code stored in the stack
-   by the debugger to be executed in the inferior.
-
-   To call: first, do PUSH_DUMMY_FRAME.
-   Then push the contents of the dummy.  It should end with a breakpoint insn.
-   Then call here, passing address at which to start the dummy.
-
-   The contents of all registers are saved before the dummy frame is popped
-   and copied into the buffer BUFFER.
-
-   The dummy's frame is automatically popped whenever that break is hit.
-   If that is the first time the program stops, run_stack_dummy
-   returns to its caller with that frame already gone and returns 0.
-   
-   Otherwise, run_stack-dummy returns a non-zero value.
-   If the called function receives a random signal, we do not allow the user
-   to continue executing it as this may not work.  The dummy frame is poped
-   and we return 1.
-   If we hit a breakpoint, we leave the frame in place and return 2 (the frame
-   will eventually be popped when we do hit the dummy end breakpoint).  */
-
-int
-run_stack_dummy (CORE_ADDR addr, struct regcache *buffer)
-{
-  struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
-  int saved_async = 0;
-  struct breakpoint *bpt;
-  struct symtab_and_line sal;
-
-  /* Now proceed, having reached the desired place.  */
-  clear_proceed_status ();
-
-  init_sal (&sal);		/* initialize to zeroes */
-  if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
-    {
-      sal.pc = CALL_DUMMY_ADDRESS ();
-    }
-  else
-    {
-      /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need to
-	 put a breakpoint instruction.  If not, the call dummy already
-	 has the breakpoint instruction in it.
-
-	 ADDR IS THE ADDRESS of the call dummy plus the
-	 CALL_DUMMY_START_OFFSET, so we need to subtract the
-	 CALL_DUMMY_START_OFFSET.  */
-      sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET;
-    }
-  sal.section = find_pc_overlay (sal.pc);
-  
-  {
-    /* 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.  */
-    struct frame_id frame = frame_id_build (read_fp (), sal.pc);
-    /* Create a momentary breakpoint at the return address of the
-       inferior.  That way it breaks when it returns.  */
-    bpt = set_momentary_breakpoint (sal, frame, bp_call_dummy);
-    bpt->disposition = disp_del;
-  }
-
-  /* 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.  */
-  make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat);
-
-  disable_watchpoints_before_interactive_call_start ();
-  proceed_to_finish = 1;	/* We want stop_registers, please... */
-
-  if (target_can_async_p ())
-    saved_async = target_async_mask (0);
-
-  proceed (addr, TARGET_SIGNAL_0, 0);
-
-  if (saved_async)
-    target_async_mask (saved_async);
-
-  enable_watchpoints_after_interactive_call_stop ();
-
-  discard_cleanups (old_cleanups);
-
-  /* We can stop during an inferior call because a signal is received. */
-  if (stopped_by_random_signal)
-    return 1;
-    
-  /* We may also stop prematurely because we hit a breakpoint in the
-     called routine. */
-  if (!stop_stack_dummy)
-    return 2;
-
-  /* On normal return, the stack dummy has been popped already.  */
-  regcache_cpy_no_passthrough (buffer, stop_registers);
-  return 0;
-}
-
 /* Proceed until we reach a different source line with pc greater than
    our current one or exit the function.  We skip calls in both cases.
 
Index: inferior.h
===================================================================
RCS file: /cvs/src/src/gdb/inferior.h,v
retrieving revision 1.52
diff -u -r1.52 inferior.h
--- inferior.h	12 Apr 2003 17:41:25 -0000	1.52
+++ inferior.h	16 Apr 2003 17:18:19 -0000
@@ -164,8 +164,6 @@
 
 extern void terminal_ours (void);
 
-extern int run_stack_dummy (CORE_ADDR , struct regcache *);
-
 extern CORE_ADDR read_pc (void);
 
 extern CORE_ADDR read_pc_pid (ptid_t);
Index: mcore-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mcore-tdep.c,v
retrieving revision 1.56
diff -u -r1.56 mcore-tdep.c
--- mcore-tdep.c	11 Apr 2003 18:15:38 -0000	1.56
+++ mcore-tdep.c	16 Apr 2003 17:18:20 -0000
@@ -1058,8 +1058,8 @@
   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
 				   get_frame_base (fi)))
     {
-      /* We need to setup fi->frame here because run_stack_dummy gets it wrong
-         by assuming it's always FP.  */
+      /* We need to setup fi->frame here because call_function_by_hand
+         gets it wrong by assuming it's always FP.  */
       deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), SP_REGNUM));
     }
   else
Index: mn10300-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mn10300-tdep.c,v
retrieving revision 1.71
diff -u -r1.71 mn10300-tdep.c
--- mn10300-tdep.c	11 Apr 2003 18:15:39 -0000	1.71
+++ mn10300-tdep.c	16 Apr 2003 17:18:20 -0000
@@ -892,9 +892,10 @@
    always be correct.  mn10300_analyze_prologue will fix fi->frame if
    it's not valid.
 
-   We can be called with the PC in the call dummy under two circumstances.
-   First, during normal backtracing, second, while figuring out the frame
-   pointer just prior to calling the target function (see run_stack_dummy).  */
+   We can be called with the PC in the call dummy under two
+   circumstances.  First, during normal backtracing, second, while
+   figuring out the frame pointer just prior to calling the target
+   function (see call_function_by_hand).  */
 
 static void
 mn10300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
Index: objc-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/objc-lang.c,v
retrieving revision 1.17
diff -u -r1.17 objc-lang.c
--- objc-lang.c	6 Apr 2003 19:25:04 -0000	1.17
+++ objc-lang.c	16 Apr 2003 17:18:20 -0000
@@ -42,6 +42,7 @@
 #include "gdb_regex.h"
 #include "regcache.h"
 #include "block.h"
+#include "infcall.h"
 
 #include <ctype.h>
 
Index: scm-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/scm-lang.c,v
retrieving revision 1.15
diff -u -r1.15 scm-lang.c
--- scm-lang.c	2 Apr 2003 03:02:46 -0000	1.15
+++ scm-lang.c	16 Apr 2003 17:18:20 -0000
@@ -33,6 +33,7 @@
 #include "source.h"
 #include "gdb_string.h"
 #include "gdbcore.h"
+#include "infcall.h"
 
 extern void _initialize_scheme_language (void);
 static struct value *evaluate_subexp_scm (struct type *, struct expression *,
Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.117
diff -u -r1.117 sh-tdep.c
--- sh-tdep.c	11 Apr 2003 18:15:39 -0000	1.117
+++ sh-tdep.c	16 Apr 2003 17:18:21 -0000
@@ -1763,8 +1763,8 @@
   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
 				   get_frame_base (fi)))
     {
-      /* We need to setup fi->frame here because run_stack_dummy gets it wrong
-         by assuming it's always FP.  */
+      /* We need to setup fi->frame here because call_function_by_hand
+         gets it wrong by assuming it's always FP.  */
       deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi),
 									     SP_REGNUM));
       get_frame_extra_info (fi)->return_pc = deprecated_read_register_dummy (get_frame_pc (fi),
@@ -1795,8 +1795,8 @@
   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
 				   get_frame_base (fi)))
     {
-      /* We need to setup fi->frame here because run_stack_dummy gets it wrong
-         by assuming it's always FP.  */
+      /* We need to setup fi->frame here because call_function_by_hand
+         gets it wrong by assuming it's always FP.  */
       deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), SP_REGNUM));
       get_frame_extra_info (fi)->return_pc = 
 	deprecated_read_register_dummy (get_frame_pc (fi),
Index: sparc-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.c,v
retrieving revision 1.89
diff -u -r1.89 sparc-tdep.c
--- sparc-tdep.c	16 Apr 2003 14:32:21 -0000	1.89
+++ sparc-tdep.c	16 Apr 2003 17:18:21 -0000
@@ -2379,10 +2379,11 @@
      Adjust the call_dummy_breakpoint_offset for the bp_call_dummy breakpoint
      to the proper address in the call dummy, so that `finish' after a stop
      in a call dummy works.
-     Tweeking current_gdbarch is not an optimal solution, but the call to
-     sparc_fix_call_dummy is immediately followed by a call to run_stack_dummy,
-     which is the only function where dummy_breakpoint_offset is actually
-     used, if it is non-zero.  */
+
+     Tweeking current_gdbarch is not an optimal solution, but the call
+     to sparc_fix_call_dummy is immediately followed by a call to
+     call_function_by_hand, which is the only function where
+     dummy_breakpoint_offset is actually used, if it is non-zero.  */
   if (TYPE_CODE (value_type) == TYPE_CODE_STRUCT
        || TYPE_CODE (value_type) == TYPE_CODE_UNION)
     {
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.37
diff -u -r1.37 target.h
--- target.h	12 Apr 2003 17:41:26 -0000	1.37
+++ target.h	16 Apr 2003 17:18:22 -0000
@@ -836,15 +836,15 @@
 #define target_async(CALLBACK,CONTEXT) \
      (current_target.to_async((CALLBACK), (CONTEXT)))
 
-/* This is to be used ONLY within run_stack_dummy(). It
-   provides a workaround, to have inferior function calls done in
-   sychronous mode, even though the target is asynchronous. After
+/* This is to be used ONLY within call_function_by_hand(). It provides
+   a workaround, to have inferior function calls done in sychronous
+   mode, even though the target is asynchronous. After
    target_async_mask(0) is called, calls to target_can_async_p() will
    return FALSE , so that target_resume() will not try to start the
    target asynchronously. After the inferior stops, we IMMEDIATELY
    restore the previous nature of the target, by calling
    target_async_mask(1). After that, target_can_async_p() will return
-   TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED. 
+   TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED.
 
    FIXME ezannoni 1999-12-13: we won't need this once we move
    the turning async on and off to the single execution commands,
Index: v850-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/v850-tdep.c,v
retrieving revision 1.55
diff -u -r1.55 v850-tdep.c
--- v850-tdep.c	11 Apr 2003 18:15:39 -0000	1.55
+++ v850-tdep.c	16 Apr 2003 17:18:22 -0000
@@ -1155,9 +1155,10 @@
    be valid only if this routine uses FP.  For previous frames, fi-frame will
    always be correct (since that is derived from v850_frame_chain ()).
 
-   We can be called with the PC in the call dummy under two circumstances.
-   First, during normal backtracing, second, while figuring out the frame
-   pointer just prior to calling the target function (see run_stack_dummy).  */
+   We can be called with the PC in the call dummy under two
+   circumstances.  First, during normal backtracing, second, while
+   figuring out the frame pointer just prior to calling the target
+   function (see call_function_by_hand).  */
 
 static void
 v850_init_extra_frame_info (int fromleaf, struct frame_info *fi)
Index: valarith.c
===================================================================
RCS file: /cvs/src/src/gdb/valarith.c,v
retrieving revision 1.19
diff -u -r1.19 valarith.c
--- valarith.c	8 Mar 2003 19:27:12 -0000	1.19
+++ valarith.c	16 Apr 2003 17:18:22 -0000
@@ -31,6 +31,7 @@
 #include "gdb_string.h"
 #include "doublest.h"
 #include <math.h>
+#include "infcall.h"
 
 /* Define whether or not the C operator '/' truncates towards zero for
    differently signed operands (truncation direction is undefined in C). */
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.104
diff -u -r1.104 valops.c
--- valops.c	31 Mar 2003 23:52:38 -0000	1.104
+++ valops.c	16 Apr 2003 17:18:23 -0000
@@ -34,6 +34,7 @@
 #include "regcache.h"
 #include "cp-abi.h"
 #include "block.h"
+#include "infcall.h"
 
 #include <errno.h>
 #include "gdb_string.h"
@@ -49,10 +50,6 @@
 static int typecmp (int staticp, int varargs, int nargs,
 		    struct field t1[], struct value *t2[]);
 
-static CORE_ADDR find_function_addr (struct value *, struct type **);
-static struct value *value_arg_coerce (struct value *, struct type *, int);
-
-
 static CORE_ADDR value_push (CORE_ADDR, struct value *);
 
 static struct value *search_struct_field (char *, struct value *, int,
@@ -84,37 +81,6 @@
 
 int overload_resolution = 0;
 
-/* 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. */
-
-int unwind_on_signal_p = 0;
-
-/* 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_FLAG_PROTOTYPED flag may be clear, even if the function was
-   defined in prototype style.  When calling a function whose
-   TYPE_FLAG_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 int coerce_float_to_double;
-
-
 /* Find the address of function name NAME in the inferior.  */
 
 struct value *
@@ -1089,774 +1055,6 @@
   return sp;
 }
 
-/* Perform the standard coercions that are specified
-   for arguments to be passed to C 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 value *arg, struct type *param_type,
-		  int is_prototyped)
-{
-  register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
-  register struct type *type
-    = param_type ? check_typedef (param_type) : arg_type;
-
-  switch (TYPE_CODE (type))
-    {
-    case TYPE_CODE_REF:
-      if (TYPE_CODE (arg_type) != TYPE_CODE_REF
-	  && TYPE_CODE (arg_type) != TYPE_CODE_PTR)
-	{
-	  arg = value_addr (arg);
-	  VALUE_TYPE (arg) = param_type;
-	  return arg;
-	}
-      break;
-    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_type_int))
-	    type = builtin_type_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_type_int))
-	type = builtin_type_int;
-      break;
-    case TYPE_CODE_FLT:
-      if (!is_prototyped && coerce_float_to_double)
-	{
-	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
-	    type = builtin_type_double;
-	  else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
-	    type = builtin_type_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)
-	if (!TYPE_VECTOR (type))
-	  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_BITSTRING:
-    case TYPE_CODE_ERROR:
-    case TYPE_CODE_MEMBER:
-    case TYPE_CODE_METHOD:
-    case TYPE_CODE_COMPLEX:
-    default:
-      break;
-    }
-
-  return value_cast (type, arg);
-}
-
-/* Determine a function's address and its return type from its value.
-   Calls error() if the function is not valid for calling.  */
-
-static CORE_ADDR
-find_function_addr (struct value *function, struct type **retval_type)
-{
-  register struct type *ftype = check_typedef (VALUE_TYPE (function));
-  register enum type_code code = TYPE_CODE (ftype);
-  struct type *value_type;
-  CORE_ADDR funaddr;
-
-  /* If it's a member function, just look at the function
-     part of it.  */
-
-  /* Determine address to call.  */
-  if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
-    {
-      funaddr = VALUE_ADDRESS (function);
-      value_type = TYPE_TARGET_TYPE (ftype);
-    }
-  else if (code == TYPE_CODE_PTR)
-    {
-      funaddr = value_as_address (function);
-      ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
-      if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
-	  || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
-	{
-	  funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
-	  value_type = TYPE_TARGET_TYPE (ftype);
-	}
-      else
-	value_type = builtin_type_int;
-    }
-  else if (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 integer used as address of a function.  */
-	funaddr = (CORE_ADDR) value_as_long (function);
-
-      value_type = builtin_type_int;
-    }
-  else
-    error ("Invalid data type for function to be called.");
-
-  *retval_type = value_type;
-  return funaddr;
-}
-
-/* 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 (NARGS of them).
-   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 (struct value *function, int nargs, struct value **args)
-{
-  register CORE_ADDR sp;
-  register int i;
-  int rc;
-  CORE_ADDR start_sp;
-  /* CALL_DUMMY is an array of words (REGISTER_SIZE), but each word
-     is in host byte order.  Before calling FIX_CALL_DUMMY, we byteswap it
-     and remove any extra bytes which might exist because ULONGEST is
-     bigger than REGISTER_SIZE.
-
-     NOTE: This is pretty wierd, as the call dummy is actually a
-     sequence of instructions.  But CISC machines will have
-     to pack the instructions into REGISTER_SIZE units (and
-     so will RISC machines for which INSTRUCTION_SIZE is not
-     REGISTER_SIZE).
-
-     NOTE: This is pretty stupid.  CALL_DUMMY should be in strict
-     target byte order. */
-
-  static ULONGEST *dummy;
-  int sizeof_dummy1;
-  char *dummy1;
-  CORE_ADDR dummy_addr;
-  CORE_ADDR old_sp;
-  struct type *value_type;
-  unsigned char struct_return;
-  CORE_ADDR struct_addr = 0;
-  struct regcache *retbuf;
-  struct cleanup *retbuf_cleanup;
-  struct inferior_status *inf_status;
-  struct cleanup *inf_status_cleanup;
-  CORE_ADDR funaddr;
-  int using_gcc;		/* Set to version of gcc in use, or zero if not gcc */
-  CORE_ADDR real_pc;
-  struct type *param_type = NULL;
-  struct type *ftype = check_typedef (SYMBOL_TYPE (function));
-  int n_method_args = 0;
-
-  dummy = alloca (SIZEOF_CALL_DUMMY_WORDS);
-  sizeof_dummy1 = REGISTER_SIZE * SIZEOF_CALL_DUMMY_WORDS / sizeof (ULONGEST);
-  dummy1 = alloca (sizeof_dummy1);
-  memcpy (dummy, CALL_DUMMY_WORDS, SIZEOF_CALL_DUMMY_WORDS);
-
-  if (!target_has_execution)
-    noprocess ();
-
-  /* Create a cleanup chain that contains the retbuf (buffer
-     containing the register values).  This chain is create BEFORE the
-     inf_status chain so that the inferior status can cleaned up
-     (restored or discarded) without having the retbuf freed.  */
-  retbuf = regcache_xmalloc (current_gdbarch);
-  retbuf_cleanup = make_cleanup_regcache_xfree (retbuf);
-
-  /* A cleanup for the inferior status.  Create this AFTER the retbuf
-     so that this can be discarded or applied without interfering with
-     the regbuf.  */
-  inf_status = save_inferior_status (1);
-  inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status);
-
-  if (DEPRECATED_PUSH_DUMMY_FRAME_P ())
-    {
-      /* DEPRECATED_PUSH_DUMMY_FRAME is responsible for saving the
-	 inferior registers (and frame_pop() for restoring them).  (At
-	 least on most machines) they are saved on the stack in the
-	 inferior.  */
-      DEPRECATED_PUSH_DUMMY_FRAME;
-    }
-  else
-    {
-      /* FIXME: cagney/2003-02-26: Step zero of this little tinker is
-      to extract the generic dummy frame code from the architecture
-      vector.  Hence this direct call.
-
-      A follow-on change is to modify this interface so that it takes
-      thread OR frame OR tpid as a parameter, and returns a dummy
-      frame handle.  The handle can then be used further down as a
-      parameter SAVE_DUMMY_FRAME_TOS.  Hmm, thinking about it, since
-      everything is ment to be using generic dummy frames, why not
-      even use some of the dummy frame code to here - do a regcache
-      dup and then pass the duped regcache, along with all the other
-      stuff, at one single point.
-
-      In fact, you can even save the structure's return address in the
-      dummy frame and fix one of those nasty lost struct return edge
-      conditions.  */
-      generic_push_dummy_frame ();
-    }
-
-  old_sp = read_sp ();
-
-  /* Ensure that the initial SP is correctly aligned.  */
-  if (gdbarch_frame_align_p (current_gdbarch))
-    {
-      /* 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 framelss (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
-	 suprisingly, 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
-	 :-).  */
-      sp = gdbarch_frame_align (current_gdbarch, old_sp);
-      if (sp == old_sp)
-	{
-	  if (INNER_THAN (1, 2))
-	    /* Stack grows down.  */
-	    sp = gdbarch_frame_align (current_gdbarch, old_sp - 1);
-	  else
-	    /* Stack grows up.  */
-	    sp = gdbarch_frame_align (current_gdbarch, old_sp + 1);
-	}
-      gdb_assert ((INNER_THAN (1, 2) && sp <= old_sp)
-		  || (INNER_THAN (2, 1) && sp >= old_sp));
-    }
-  else
-    /* FIXME: cagney/2002-09-18: Hey, you loose!  Who knows how badly
-       aligned the SP is!  Further, per comment above, 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 its architecture vector.  After that, try
-       adding SAVE_DUMMY_FRAME_TOS() and modifying
-       DEPRECATED_FRAME_CHAIN so that when the next outer frame is a
-       generic dummy, it returns the current frame's base.  */
-    sp = old_sp;
-
-  if (INNER_THAN (1, 2))
-    {
-      /* Stack grows down */
-      sp -= sizeof_dummy1;
-      start_sp = sp;
-    }
-  else
-    {
-      /* Stack grows up */
-      start_sp = sp;
-      sp += sizeof_dummy1;
-    }
-
-  /* NOTE: cagney/2002-09-10: Don't bother re-adjusting the stack
-     after allocating space for the call dummy.  A target can specify
-     a SIZEOF_DUMMY1 (via SIZEOF_CALL_DUMMY_WORDS) such that all local
-     alignment requirements are met.  */
-
-  funaddr = find_function_addr (function, &value_type);
-  CHECK_TYPEDEF (value_type);
-
-  {
-    struct block *b = block_for_pc (funaddr);
-    /* If compiled without -g, assume GCC 2.  */
-    using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
-  }
-
-  /* Are we returning a value using a structure return or a normal
-     value return? */
-
-  struct_return = using_struct_return (function, funaddr, value_type,
-				       using_gcc);
-
-  /* Create a call sequence customized for this function
-     and the number of arguments for it.  */
-  for (i = 0; i < (int) (SIZEOF_CALL_DUMMY_WORDS / sizeof (dummy[0])); i++)
-    store_unsigned_integer (&dummy1[i * REGISTER_SIZE],
-			    REGISTER_SIZE,
-			    (ULONGEST) dummy[i]);
-
-#ifdef GDB_TARGET_IS_HPPA
-  real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
-			    value_type, using_gcc);
-#else
-  if (FIX_CALL_DUMMY_P ())
-    {
-      /* gdb_assert (CALL_DUMMY_LOCATION == ON_STACK) true?  */
-      FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args, value_type,
-		      using_gcc);
-    }
-  real_pc = start_sp;
-#endif
-
-  switch (CALL_DUMMY_LOCATION)
-    {
-    case ON_STACK:
-      dummy_addr = start_sp;
-      write_memory (start_sp, (char *) dummy1, sizeof_dummy1);
-      if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
-	generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1);
-      break;
-    case AT_ENTRY_POINT:
-      real_pc = funaddr;
-      dummy_addr = CALL_DUMMY_ADDRESS ();
-      if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
-	/* NOTE: cagney/2002-04-13: The entry point is going to be
-           modified with a single breakpoint.  */
-	generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (),
-				      CALL_DUMMY_ADDRESS () + 1);
-      break;
-    default:
-      internal_error (__FILE__, __LINE__, "bad switch");
-    }
-
-#ifdef lint
-  sp = old_sp;			/* It really is used, for some ifdef's... */
-#endif
-
-  if (nargs < TYPE_NFIELDS (ftype))
-    error ("too few arguments in function call");
-
-  for (i = nargs - 1; i >= 0; i--)
-    {
-      int prototyped;
-
-      /* FIXME drow/2002-05-31: Should just always mark methods as
-	 prototyped.  Can we respect TYPE_VARARGS?  Probably not.  */
-      if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
-	prototyped = 1;
-      else
-	prototyped = TYPE_PROTOTYPED (ftype);
-
-      if (i < TYPE_NFIELDS (ftype))
-	args[i] = value_arg_coerce (args[i], TYPE_FIELD_TYPE (ftype, i),
-				    prototyped);
-      else
-	args[i] = value_arg_coerce (args[i], NULL, 0);
-
-      /*elz: this code is to handle the case in which the function to be called
-         has a pointer to function as parameter and the corresponding actual argument
-         is the address of a function and not a pointer to function variable.
-         In aCC compiled code, the calls through pointers to functions (in the body
-         of the function called by hand) are made via $$dyncall_external which
-         requires some registers setting, this is taken care of if we call
-         via a function pointer variable, but not via a function address.
-         In cc this is not a problem. */
-
-      if (using_gcc == 0)
-	if (param_type && TYPE_CODE (ftype) != TYPE_CODE_METHOD)
-	  /* if this parameter is a pointer to function */
-	  if (TYPE_CODE (param_type) == TYPE_CODE_PTR)
-	    if (TYPE_CODE (TYPE_TARGET_TYPE (param_type)) == TYPE_CODE_FUNC)
-	      /* elz: FIXME here should go the test about the compiler used
-	         to compile the target. We want to issue the error
-	         message only if the compiler used was HP's aCC.
-	         If we used HP's cc, then there is no problem and no need
-	         to return at this point */
-	      if (using_gcc == 0)	/* && compiler == aCC */
-		/* go see if the actual parameter is a variable of type
-		   pointer to function or just a function */
-		if (args[i]->lval == not_lval)
-		  {
-		    char *arg_name;
-		    if (find_pc_partial_function ((CORE_ADDR) args[i]->aligner.contents[0], &arg_name, NULL, NULL))
-		      error ("\
-You cannot use function <%s> as argument. \n\
-You must use a pointer to function type variable. Command ignored.", arg_name);
-		  }
-    }
-
-  if (REG_STRUCT_HAS_ADDR_P ())
-    {
-      /* This is a machine like the sparc, where we may need to pass a
-	 pointer to the structure, not the structure itself.  */
-      for (i = nargs - 1; i >= 0; i--)
-	{
-	  struct type *arg_type = check_typedef (VALUE_TYPE (args[i]));
-	  if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
-	       || TYPE_CODE (arg_type) == TYPE_CODE_UNION
-	       || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
-	       || TYPE_CODE (arg_type) == TYPE_CODE_STRING
-	       || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING
-	       || TYPE_CODE (arg_type) == TYPE_CODE_SET
-	       || (TYPE_CODE (arg_type) == TYPE_CODE_FLT
-		   && TYPE_LENGTH (arg_type) > 8)
-	       )
-	      && REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
-	    {
-	      CORE_ADDR addr;
-	      int len;		/*  = TYPE_LENGTH (arg_type); */
-	      int aligned_len;
-	      arg_type = check_typedef (VALUE_ENCLOSING_TYPE (args[i]));
-	      len = TYPE_LENGTH (arg_type);
-
-	      if (STACK_ALIGN_P ())
-		/* MVS 11/22/96: I think at least some of this
-		   stack_align code is really broken.  Better to let
-		   PUSH_ARGUMENTS adjust the stack in a target-defined
-		   manner.  */
-		aligned_len = STACK_ALIGN (len);
-	      else
-		aligned_len = len;
-	      if (INNER_THAN (1, 2))
-		{
-		  /* stack grows downward */
-		  sp -= aligned_len;
-		  /* ... so the address of the thing we push is the
-		     stack pointer after we push it.  */
-		  addr = sp;
-		}
-	      else
-		{
-		  /* The stack grows up, so the address of the thing
-		     we push is the stack pointer before we push it.  */
-		  addr = sp;
-		  sp += aligned_len;
-		}
-	      /* Push the structure.  */
-	      write_memory (addr, VALUE_CONTENTS_ALL (args[i]), len);
-	      /* The value we're going to pass is the address of the
-		 thing we just pushed.  */
-	      /*args[i] = value_from_longest (lookup_pointer_type (value_type),
-		(LONGEST) addr); */
-	      args[i] = value_from_pointer (lookup_pointer_type (arg_type),
-					    addr);
-	    }
-	}
-    }
-
-
-  /* Reserve space for the return structure to be written on the
-     stack, if necessary.  Make certain that the value is correctly
-     aligned. */
-
-  if (struct_return)
-    {
-      int len = TYPE_LENGTH (value_type);
-      if (STACK_ALIGN_P ())
-	/* NOTE: cagney/2003-03-22: Should rely on frame align, rather
-           than stack align to force the alignment of the stack.  */
-	len = STACK_ALIGN (len);
-      if (INNER_THAN (1, 2))
-	{
-	  /* Stack grows downward.  Align STRUCT_ADDR and SP after
-             making space for the return value.  */
-	  sp -= len;
-	  if (gdbarch_frame_align_p (current_gdbarch))
-	    sp = gdbarch_frame_align (current_gdbarch, sp);
-	  struct_addr = sp;
-	}
-      else
-	{
-	  /* Stack grows upward.  Align the frame, allocate space, and
-             then again, re-align the frame??? */
-	  if (gdbarch_frame_align_p (current_gdbarch))
-	    sp = gdbarch_frame_align (current_gdbarch, sp);
-	  struct_addr = sp;
-	  sp += len;
-	  if (gdbarch_frame_align_p (current_gdbarch))
-	    sp = gdbarch_frame_align (current_gdbarch, sp);
-	}
-    }
-
-  /* elz: on HPPA no need for this extra alignment, maybe it is needed
-     on other architectures. This is because all the alignment is
-     taken care of in the above code (ifdef REG_STRUCT_HAS_ADDR) and
-     in hppa_push_arguments */
-  /* NOTE: cagney/2003-03-24: The below code is very broken.  Given an
-     odd sized parameter the below will mis-align the stack.  As was
-     suggested back in '96, better to let PUSH_ARGUMENTS handle it.  */
-  if (DEPRECATED_EXTRA_STACK_ALIGNMENT_NEEDED)
-    {
-      /* MVS 11/22/96: I think at least some of this stack_align code
-	 is really broken.  Better to let push_dummy_call() adjust the
-	 stack in a target-defined manner.  */
-      if (STACK_ALIGN_P () && INNER_THAN (1, 2))
-	{
-	  /* If stack grows down, we must leave a hole at the top. */
-	  int len = 0;
-
-	  for (i = nargs - 1; i >= 0; i--)
-	    len += TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
-	  if (DEPRECATED_CALL_DUMMY_STACK_ADJUST_P ())
-	    len += DEPRECATED_CALL_DUMMY_STACK_ADJUST;
-	  sp -= STACK_ALIGN (len) - len;
-	}
-    }
-
-  /* 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.  */
-  if (gdbarch_push_dummy_call_p (current_gdbarch))
-    /* When there is no push_dummy_call method, should this code
-       simply error out.  That would the implementation of this method
-       for all ABIs (which is probably a good thing).  */
-    sp = gdbarch_push_dummy_call (current_gdbarch, current_regcache,
-				  dummy_addr, nargs, args, sp, struct_return,
-				  struct_addr);
-  else  if (DEPRECATED_PUSH_ARGUMENTS_P ())
-    /* Keep old targets working.  */
-    sp = DEPRECATED_PUSH_ARGUMENTS (nargs, args, sp, struct_return,
-				    struct_addr);
-  else
-    sp = legacy_push_arguments (nargs, args, sp, struct_return, struct_addr);
-
-  if (DEPRECATED_PUSH_RETURN_ADDRESS_P ())
-    /* for targets that use no CALL_DUMMY */
-    /* There are a number of targets now which actually don't write
-       any CALL_DUMMY instructions into the target, but instead just
-       save the machine state, push the arguments, and jump directly
-       to the callee function.  Since this doesn't actually involve
-       executing a JSR/BSR instruction, the return address must be set
-       up by hand, either by pushing onto the stack or copying into a
-       return-address register as appropriate.  Formerly this has been
-       done in PUSH_ARGUMENTS, but that's overloading its
-       functionality a bit, so I'm making it explicit to do it here.  */
-    sp = DEPRECATED_PUSH_RETURN_ADDRESS (real_pc, sp);
-
-  /* NOTE: cagney/2003-03-23: Diable this code when there is a
-     push_dummy_call() method.  Since that method will have already
-     handled any alignment issues, the code below is entirely
-     redundant.  */
-  if (!gdbarch_push_dummy_call_p (current_gdbarch)
-      && STACK_ALIGN_P () && !INNER_THAN (1, 2))
-    {
-      /* If stack grows up, we must leave a hole at the bottom, note
-         that sp already has been advanced for the arguments!  */
-      if (DEPRECATED_CALL_DUMMY_STACK_ADJUST_P ())
-	sp += DEPRECATED_CALL_DUMMY_STACK_ADJUST;
-      sp = STACK_ALIGN (sp);
-    }
-
-/* XXX This seems wrong.  For stacks that grow down we shouldn't do
-   anything here!  */
-  /* MVS 11/22/96: I think at least some of this stack_align code is
-     really broken.  Better to let PUSH_ARGUMENTS adjust the stack in
-     a target-defined manner.  */
-  if (DEPRECATED_CALL_DUMMY_STACK_ADJUST_P ())
-    if (INNER_THAN (1, 2))
-      {
-	/* stack grows downward */
-	sp -= DEPRECATED_CALL_DUMMY_STACK_ADJUST;
-      }
-
-  /* Store the address at which the structure is supposed to be
-     written.  */
-  /* NOTE: 2003-03-24: Since PUSH_ARGUMENTS can (and typically does)
-     store the struct return address, this call is entirely redundant.  */
-  if (struct_return && DEPRECATED_STORE_STRUCT_RETURN_P ())
-    DEPRECATED_STORE_STRUCT_RETURN (struct_addr, sp);
-
-  /* Write the stack pointer.  This is here because the statements above
-     might fool with it.  On SPARC, this write also stores the register
-     window into the right place in the new stack frame, which otherwise
-     wouldn't happen.  (See store_inferior_registers in sparc-nat.c.)  */
-  /* NOTE: cagney/2003-03-23: Disable this code when there is a
-     push_dummy_call() method.  Since that method will have already
-     stored the stack pointer (as part of creating the fake call
-     frame), and none of the code following that code adjusts the
-     stack-pointer value, the below call is entirely redundant.  */
-  if (DEPRECATED_DUMMY_WRITE_SP_P ())
-    DEPRECATED_DUMMY_WRITE_SP (sp);
-
-  if (SAVE_DUMMY_FRAME_TOS_P ())
-    SAVE_DUMMY_FRAME_TOS (sp);
-
-  {
-    char *name;
-    struct symbol *symbol;
-
-    name = NULL;
-    symbol = find_pc_function (funaddr);
-    if (symbol)
-      {
-	name = SYMBOL_PRINT_NAME (symbol);
-      }
-    else
-      {
-	/* Try the minimal symbols.  */
-	struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr);
-
-	if (msymbol)
-	  {
-	    name = SYMBOL_PRINT_NAME (msymbol);
-	  }
-      }
-    if (name == NULL)
-      {
-	char format[80];
-	sprintf (format, "at %s", local_hex_format ());
-	name = alloca (80);
-	/* FIXME-32x64: assumes funaddr fits in a long.  */
-	sprintf (name, format, (unsigned long) funaddr);
-      }
-
-    /* Execute the stack dummy routine, calling FUNCTION.
-       When it is done, discard the empty frame
-       after storing the contents of all regs into retbuf.  */
-    rc = run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf);
-
-    if (rc == 1)
-      {
-	/* 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. */
-	    frame_pop (get_current_frame ());
-
-	    /* 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 (%s) will be abandoned.",
-		   name);
-	  }
-	else
-	  {
-	    /* The user wants to stay in the frame where we stopped (default).*/
-
-	    /* If we restored the inferior status (via the cleanup),
-	       we would print a spurious error message (Unable to
-	       restore previously selected frame), would write the
-	       registers from the inf_status (which is wrong), and
-	       would do other wrong things.  */
-	    discard_cleanups (inf_status_cleanup);
-	    discard_inferior_status (inf_status);
-
-	    /* 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 (%s) will be abandoned.",
-		   name);
-	  }
-      }
-
-    if (rc == 2)
-      {
-	/* We hit a breakpoint inside the FUNCTION. */
-
-	/* If we restored the inferior status (via the cleanup), we
-	   would print a spurious error message (Unable to restore
-	   previously selected frame), would write the registers from
-	   the inf_status (which is wrong), and would do other wrong
-	   things.  */
-	discard_cleanups (inf_status_cleanup);
-	discard_inferior_status (inf_status);
-
-	/* 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\
-When the function (%s) is done executing, GDB will silently\n\
-stop (instead of continuing to evaluate the expression containing\n\
-the function call).", name);
-      }
-
-    /* If we get here the called FUNCTION run to completion. */
-
-    /* Restore the inferior status, via its cleanup.  At this stage,
-       leave the RETBUF alone.  */
-    do_cleanups (inf_status_cleanup);
-
-    /* Figure out the value returned by the function.  */
-    /* elz: I defined this new macro for the hppa architecture only.
-       this gives us a way to get the value returned by the function
-       from the stack, at the same address we told the function to put
-       it.  We cannot assume on the pa that r28 still contains the
-       address of the returned structure. Usually this will be
-       overwritten by the callee.  I don't know about other
-       architectures, so I defined this macro */
-#ifdef VALUE_RETURNED_FROM_STACK
-    if (struct_return)
-      {
-	do_cleanups (retbuf_cleanup);
-	return VALUE_RETURNED_FROM_STACK (value_type, struct_addr);
-      }
-#endif
-    /* NOTE: cagney/2002-09-10: Only when the stack has been correctly
-       aligned (using frame_align()) do we can trust STRUCT_ADDR and
-       fetch the return value direct from the stack.  This lack of
-       trust comes about because legacy targets have a nasty habit of
-       silently, and local to PUSH_ARGUMENTS(), moving STRUCT_ADDR.
-       For such targets, just hope that value_being_returned() can
-       find the adjusted value.  */
-    if (struct_return && gdbarch_frame_align_p (current_gdbarch))
-      {
-        struct value *retval = value_at (value_type, struct_addr, NULL);
-        do_cleanups (retbuf_cleanup);
-        return retval;
-      }
-    else
-      {
-	struct value *retval = value_being_returned (value_type, retbuf,
-						     struct_return);
-	do_cleanups (retbuf_cleanup);
-	return retval;
-      }
-  }
-}
-
 /* Create a value for an array by allocating space in the inferior, copying
    the data into that space, and then setting up an array value.
 
@@ -3485,29 +2683,4 @@
 		  &setlist),
      &showlist);
   overload_resolution = 1;
-
-  add_show_from_set (
-  add_set_cmd ("unwindonsignal", no_class, var_boolean,
-	       (char *) &unwind_on_signal_p,
-"Set unwinding of stack if a signal is received while in a call dummy.\n\
-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.", &setlist),
-		     &showlist);
-
-  add_show_from_set
-    (add_set_cmd ("coerce-float-to-double", class_obscure, var_boolean,
-		  (char *) &coerce_float_to_double,
-		  "Set coercion of floats to doubles when calling functions\n"
- "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.\n",
-		  &setlist),
-     &showlist);
-  coerce_float_to_double = 1;
 }
Index: value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.45
diff -u -r1.45 value.h
--- value.h	12 Apr 2003 17:41:26 -0000	1.45
+++ value.h	16 Apr 2003 17:18:23 -0000
@@ -549,9 +549,6 @@
 
 extern struct value *value_slice (struct value *, int, int);
 
-extern struct value *call_function_by_hand (struct value *, int,
-					    struct value **);
-
 extern struct value *value_literal_complex (struct value *, struct value *,
 					    struct type *);
 
Index: config/sparc/tm-sparc.h
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/tm-sparc.h,v
retrieving revision 1.45
diff -u -r1.45 tm-sparc.h
--- config/sparc/tm-sparc.h	11 Apr 2003 18:15:40 -0000	1.45
+++ config/sparc/tm-sparc.h	16 Apr 2003 17:18:23 -0000
@@ -545,9 +545,9 @@
  *
  *   call_function then writes CALL_DUMMY, pushes the args onto the
  * stack, and adjusts the stack pointer.
- *
- *   run_stack_dummy then starts execution (in the middle of
- * CALL_DUMMY, as directed by call_function).  */
+ 
+   call_function_by_hand then starts execution (in the middle of
+   CALL_DUMMY, as directed by call_function).  */
 
 #ifndef CALL_DUMMY
 /* This sequence of words is the instructions

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]