2003-04-21 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Mon, 21 Apr 2003 16:48:41 +0000 (16:48 +0000)
committerAndrew Cagney <cagney@redhat.com>
Mon, 21 Apr 2003 16:48:41 +0000 (16:48 +0000)
* 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.

27 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/ada-lang.c
gdb/ada-valprint.c
gdb/arm-tdep.c
gdb/avr-tdep.c
gdb/breakpoint.h
gdb/config/sparc/tm-sparc.h
gdb/cris-tdep.c
gdb/eval.c
gdb/gcore.c
gdb/hppa-tdep.c
gdb/infcall.c [new file with mode: 0644]
gdb/infcall.h [new file with mode: 0644]
gdb/infcmd.c
gdb/inferior.h
gdb/mcore-tdep.c
gdb/mn10300-tdep.c
gdb/objc-lang.c
gdb/scm-lang.c
gdb/sh-tdep.c
gdb/sparc-tdep.c
gdb/target.h
gdb/v850-tdep.c
gdb/valarith.c
gdb/valops.c
gdb/value.h

index ad86a90..fa435b5 100644 (file)
@@ -1,3 +1,37 @@
+2003-04-21  Andrew Cagney  <cagney@redhat.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.
+
 2003-04-19  Mark Kettenis  <kettenis@gnu.org>
 
        * i386-tdep.c (i386_num_register_names): New variable.
index a78ef16..a5d0f5f 100644 (file)
@@ -521,7 +521,9 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
        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_linux_tdep_h = i386-linux-tdep.h
 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 @@ TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR)
 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 @@ abug-rom.o: abug-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
 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 @@ ada-typeprint.o: ada-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) \
        $(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 @@ elfread.o: elfread.c $(defs_h) $(bfd_h) $(gdb_string_h) $(elf_bfd_h) \
 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 @@ frame-unwind.o: frame-unwind.c $(defs_h) $(frame_h) $(frame_unwind_h) \
 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 @@ hpacc-abi.o: hpacc-abi.c $(defs_h) $(value_h) $(gdb_regex_h) $(gdb_string_h) \
        $(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 @@ ia64-tdep.o: ia64-tdep.c $(defs_h) $(inferior_h) $(symfile_h) $(gdbcore_h) \
        $(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 @@ ns32knbsd-tdep.o: ns32knbsd-tdep.c $(defs_h) $(ns32k_tdep_h) $(gdb_string_h) \
        $(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-exp.o: scm-exp.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
        $(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 @@ v850ice.o: v850ice.c $(defs_h) $(gdb_string_h) $(frame_h) $(symtab_h) \
        $(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 bc0809d..b047442 100644 (file)
@@ -39,6 +39,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "ada-lang.h"
 #include "ui-out.h"
 #include "block.h"
+#include "infcall.h"
 
 struct cleanup *unresolved_names;
 
index 8633f2c..5b90c06 100644 (file)
@@ -30,6 +30,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #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 0a029e8..f104952 100644 (file)
@@ -1257,8 +1257,8 @@ static LONGEST arm_call_dummy_words[] =
 
    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 b787c81..16a2129 100644 (file)
@@ -753,8 +753,8 @@ avr_init_extra_frame_info (int fromleaf, struct frame_info *fi)
   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 e8c8750..b2c53fc 100644 (file)
@@ -623,7 +623,7 @@ extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_id);
    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 414b69e..7641ee1 100644 (file)
@@ -545,9 +545,9 @@ extern CORE_ADDR init_frame_pc_noop (int fromleaf, struct frame_info *prev);
  *
  *   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 f03cd14..ef5e072 100644 (file)
@@ -1216,8 +1216,8 @@ cris_init_extra_frame_info (int fromleaf, struct frame_info *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 d5d0892..af93ce9 100644 (file)
@@ -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 5ad17e8..6a0edbf 100644 (file)
@@ -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 27cfedf..affc5d3 100644 (file)
@@ -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>
diff --git a/gdb/infcall.c b/gdb/infcall.c
new file mode 100644 (file)
index 0000000..fee1397
--- /dev/null
@@ -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);
+}
diff --git a/gdb/infcall.h b/gdb/infcall.h
new file mode 100644 (file)
index 0000000..0377411
--- /dev/null
@@ -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 01ab3d7..5867655 100644 (file)
@@ -115,8 +115,6 @@ void _initialize_infcmd (void);
 
 #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 @@ signal_command (char *signum_exp, int from_tty)
   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;
-}
-\f
 /* 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 6203449..0950973 100644 (file)
@@ -164,8 +164,6 @@ extern void terminal_save_ours (void);
 
 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 ab03f3a..5d18ce8 100644 (file)
@@ -1058,8 +1058,8 @@ mcore_init_extra_frame_info (int fromleaf, struct frame_info *fi)
   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 22f3b67..d411b74 100644 (file)
@@ -892,9 +892,10 @@ mn10300_frame_saved_pc (struct frame_info *fi)
    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 bc937ca..c8524cc 100644 (file)
@@ -42,6 +42,7 @@
 #include "gdb_regex.h"
 #include "regcache.h"
 #include "block.h"
+#include "infcall.h"
 
 #include <ctype.h>
 
index 99a1fd5..1af501d 100644 (file)
@@ -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 0390e95..4bd3af1 100644 (file)
@@ -1763,8 +1763,8 @@ sh_init_extra_frame_info (int fromleaf, struct frame_info *fi)
   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 @@ sh64_init_extra_frame_info (int fromleaf, struct frame_info *fi)
   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 e1a0089..18311f6 100644 (file)
@@ -2379,10 +2379,11 @@ sparc_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
      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 b3f43fc..e757b67 100644 (file)
@@ -836,15 +836,15 @@ extern void target_load (char *arg, int from_tty);
 #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 de81056..1b14cf6 100644 (file)
@@ -1155,9 +1155,10 @@ v850_frame_init_saved_regs (struct frame_info *fi)
    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 ed0fe05..854a151 100644 (file)
@@ -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 a2a2e97..d8261c8 100644 (file)
@@ -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 @@ extern int overload_debug;
 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 @@ static int auto_abandon = 0;
 
 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;
-\f
-
 /* Find the address of function name NAME in the inferior.  */
 
 struct value *
@@ -1089,774 +1055,6 @@ legacy_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
   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 @@ _initialize_valops (void)
                  &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 ad488a7..54854e5 100644 (file)
@@ -549,9 +549,6 @@ extern struct value *varying_to_slice (struct value *);
 
 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 *);