* breakpoint.c:
[deliverable/binutils-gdb.git] / gdb / infcall.c
index f32f8e170b5f3bd0419affa2d285f22242791243..c8a63348ee3743d90011b68bffcdbc00a9a52902 100644 (file)
@@ -1,6 +1,6 @@
 /* Perform an inferior function call, for GDB, the GNU debugger.
 
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
@@ -18,8 +18,8 @@
 
    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.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "breakpoint.h"
@@ -333,6 +333,9 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
   if (!target_has_execution)
     noprocess ();
 
+  if (!gdbarch_push_dummy_call_p (current_gdbarch))
+    error (_("This target does not support function calls"));
+
   /* 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
@@ -653,19 +656,9 @@ You must use a pointer to function type variable. Command ignored."), arg_name);
   /* 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, function, current_regcache,
-                                 bp_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
-    error (_("This target does not support function calls"));
+  sp = gdbarch_push_dummy_call (current_gdbarch, function, current_regcache,
+                               bp_addr, nargs, args, sp, struct_return,
+                               struct_addr);
 
   /* Set up a frame ID for the dummy frame so we can pass it to
      set_momentary_breakpoint.  We need to give the breakpoint a frame
@@ -854,39 +847,44 @@ the function call)."), name);
      leave the RETBUF alone.  */
   do_cleanups (inf_status_cleanup);
 
-  /* Figure out the value returned by the function, return that.  */
+  /* Figure out the value returned by the function.  */
   {
-    struct value *retval;
+    struct value *retval = NULL;
+
     if (TYPE_CODE (values_type) == TYPE_CODE_VOID)
-      /* If the function returns void, don't bother fetching the
-        return value.  */
-      retval = allocate_value (values_type);
-    else if (struct_return)
-      /* NOTE: cagney/2003-09-27: This assumes that PUSH_DUMMY_CALL
-        has correctly stored STRUCT_ADDR in the target.  In the past
-        that hasn't been the case, the old MIPS PUSH_ARGUMENTS
-        (PUSH_DUMMY_CALL precursor) would silently move the location
-        of the struct return value making STRUCT_ADDR bogus.  If
-        you're seeing problems with values being returned using the
-        "struct return convention", check that PUSH_DUMMY_CALL isn't
-        playing tricks.  */
-      retval = value_at (values_type, struct_addr);
-    else
       {
-       /* This code only handles "register convention".  */
+       /* If the function returns void, don't bother fetching the
+          return value.  */
        retval = allocate_value (values_type);
-       gdb_assert (gdbarch_return_value (current_gdbarch, values_type,
-                                         NULL, NULL, NULL)
-                   == RETURN_VALUE_REGISTER_CONVENTION);
-       gdbarch_return_value (current_gdbarch, values_type, retbuf,
-                             value_contents_raw (retval) /*read*/,
-                             NULL /*write*/);
       }
+    else
+      {
+       struct gdbarch *arch = current_gdbarch;
+
+       switch (gdbarch_return_value (arch, values_type, NULL, NULL, NULL))
+         {
+         case RETURN_VALUE_REGISTER_CONVENTION:
+         case RETURN_VALUE_ABI_RETURNS_ADDRESS:
+         case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
+           retval = allocate_value (values_type);
+           gdbarch_return_value (current_gdbarch, values_type, retbuf,
+                                 value_contents_raw (retval), NULL);
+           break;
+         case RETURN_VALUE_STRUCT_CONVENTION:
+           retval = value_at (values_type, struct_addr);
+           break;
+         }
+      }
+
     do_cleanups (retbuf_cleanup);
+
+    gdb_assert(retval);
     return retval;
   }
 }
+\f
 
+/* Provide a prototype to silence -Wmissing-prototypes.  */
 void _initialize_infcall (void);
 
 void
This page took 0.02672 seconds and 4 git commands to generate.