2007-06-18 Markus Deuling <deuling@de.ibm.com>
[deliverable/binutils-gdb.git] / gdb / infcall.c
index 9c104ad0fcc3b1dcdfac817674b71f8e316a1861..537596984c159216dcf526e6b02f57d441265780 100644 (file)
@@ -1,7 +1,7 @@
 /* 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, 2004, 2005
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -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"
@@ -109,14 +109,20 @@ value_arg_coerce (struct value *arg, struct type *param_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);
-         deprecated_set_value_type (arg, param_type);
-         return arg;
-       }
-      break;
+      {
+       struct value *new_value;
+
+       if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+         return value_cast_pointers (type, arg);
+
+       /* Cast the value to the reference's target type, and then
+          convert it back to a reference.  This will issue an error
+          if the value was not previously in memory - in some cases
+          we should clearly be allowing this, but how?  */
+       new_value = value_cast (TYPE_TARGET_TYPE (type), arg);
+       new_value = value_ref (new_value);
+       return new_value;
+      }
     case TYPE_CODE_INT:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
@@ -163,7 +169,8 @@ value_arg_coerce (struct value *arg, struct type *param_type,
     case TYPE_CODE_STRING:
     case TYPE_CODE_BITSTRING:
     case TYPE_CODE_ERROR:
-    case TYPE_CODE_MEMBER:
+    case TYPE_CODE_MEMBERPTR:
+    case TYPE_CODE_METHODPTR:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_COMPLEX:
     default:
@@ -225,7 +232,7 @@ find_function_addr (struct value *function, struct type **retval_type)
 
   if (retval_type != NULL)
     *retval_type = value_type;
-  return funaddr + DEPRECATED_FUNCTION_START_OFFSET;
+  return funaddr + gdbarch_deprecated_function_start_offset (current_gdbarch);
 }
 
 /* Call breakpoint_auto_delete on the current contents of the bpstat
@@ -242,7 +249,8 @@ generic_push_dummy_code (struct gdbarch *gdbarch,
                         CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc,
                         struct value **args, int nargs,
                         struct type *value_type,
-                        CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
+                        CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
+                        struct regcache *regcache)
 {
   /* Something here to findout the size of a breakpoint and then
      allocate space for it on the stack.  */
@@ -281,14 +289,17 @@ push_dummy_code (struct gdbarch *gdbarch,
                 CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc,
                 struct value **args, int nargs,
                 struct type *value_type,
-                CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
+                CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
+                struct regcache *regcache)
 {
   if (gdbarch_push_dummy_code_p (gdbarch))
     return gdbarch_push_dummy_code (gdbarch, sp, funaddr, using_gcc,
-                                   args, nargs, value_type, real_pc, bp_addr);
+                                   args, nargs, value_type, real_pc, bp_addr,
+                                   regcache);
   else    
     return generic_push_dummy_code (gdbarch, sp, funaddr, using_gcc,
-                                   args, nargs, value_type, real_pc, bp_addr);
+                                   args, nargs, value_type, real_pc, bp_addr,
+                                   regcache);
 }
 
 /* All this stuff with a dummy frame may seem unnecessarily complicated
@@ -330,6 +341,9 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
   struct cleanup *caller_regcache_cleanup;
   struct frame_id dummy_id;
 
+  if (TYPE_CODE (ftype) == TYPE_CODE_PTR)
+    ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
+
   if (!target_has_execution)
     noprocess ();
 
@@ -358,7 +372,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
 
   /* Ensure that the initial SP is correctly aligned.  */
   {
-    CORE_ADDR old_sp = read_sp ();
+    CORE_ADDR old_sp = get_frame_sp (get_current_frame ());
     if (gdbarch_frame_align_p (current_gdbarch))
       {
        sp = gdbarch_frame_align (current_gdbarch, old_sp);
@@ -367,7 +381,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
           address.  AMD64 called that region the "red zone".  Skip at
           least the "red zone" size before allocating any space on
           the stack.  */
-       if (INNER_THAN (1, 2))
+       if (gdbarch_inner_than (current_gdbarch, 1, 2))
          sp -= gdbarch_frame_red_zone_size (current_gdbarch);
        else
          sp += gdbarch_frame_red_zone_size (current_gdbarch);
@@ -395,15 +409,17 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
           to pay :-).  */
        if (sp == old_sp)
          {
-           if (INNER_THAN (1, 2))
+           if (gdbarch_inner_than (current_gdbarch, 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));
+       gdb_assert ((gdbarch_inner_than (current_gdbarch, 1, 2)
+                   && sp <= old_sp)
+                   || (gdbarch_inner_than (current_gdbarch, 2, 1)
+                      && sp >= old_sp));
       }
     else
       /* FIXME: cagney/2002-09-18: Hey, you loose!
@@ -444,16 +460,16 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
   /* The actual breakpoint (at BP_ADDR) is inserted separatly so there
      is no need to write that out.  */
 
-  switch (CALL_DUMMY_LOCATION)
+  switch (gdbarch_call_dummy_location (current_gdbarch))
     {
     case ON_STACK:
       /* "dummy_addr" is here just to keep old targets happy.  New
         targets return that same information via "sp" and "bp_addr".  */
-      if (INNER_THAN (1, 2))
+      if (gdbarch_inner_than (current_gdbarch, 1, 2))
        {
          sp = push_dummy_code (current_gdbarch, sp, funaddr,
                                using_gcc, args, nargs, values_type,
-                               &real_pc, &bp_addr);
+                               &real_pc, &bp_addr, get_current_regcache ());
          dummy_addr = sp;
        }
       else
@@ -461,7 +477,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
          dummy_addr = sp;
          sp = push_dummy_code (current_gdbarch, sp, funaddr,
                                using_gcc, args, nargs, values_type,
-                               &real_pc, &bp_addr);
+                               &real_pc, &bp_addr, get_current_regcache ());
        }
       break;
     case AT_ENTRY_POINT:
@@ -570,7 +586,7 @@ You must use a pointer to function type variable. Command ignored."), arg_name);
       }
   }
 
-  if (DEPRECATED_REG_STRUCT_HAS_ADDR_P ())
+  if (gdbarch_deprecated_reg_struct_has_addr_p (current_gdbarch))
     {
       int i;
       /* This is a machine like the sparc, where we may need to pass a
@@ -587,7 +603,8 @@ You must use a pointer to function type variable. Command ignored."), arg_name);
               || (TYPE_CODE (arg_type) == TYPE_CODE_FLT
                   && TYPE_LENGTH (arg_type) > 8)
               )
-             && DEPRECATED_REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
+             && gdbarch_deprecated_reg_struct_has_addr
+                  (current_gdbarch, using_gcc, arg_type))
            {
              CORE_ADDR addr;
              int len;          /*  = TYPE_LENGTH (arg_type); */
@@ -596,7 +613,7 @@ You must use a pointer to function type variable. Command ignored."), arg_name);
              len = TYPE_LENGTH (arg_type);
 
              aligned_len = len;
-             if (INNER_THAN (1, 2))
+             if (gdbarch_inner_than (current_gdbarch, 1, 2))
                {
                  /* stack grows downward */
                  sp -= aligned_len;
@@ -631,7 +648,7 @@ You must use a pointer to function type variable. Command ignored."), arg_name);
   if (struct_return)
     {
       int len = TYPE_LENGTH (values_type);
-      if (INNER_THAN (1, 2))
+      if (gdbarch_inner_than (current_gdbarch, 1, 2))
        {
          /* Stack grows downward.  Align STRUCT_ADDR and SP after
              making space for the return value.  */
@@ -656,9 +673,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.  */
-  sp = gdbarch_push_dummy_call (current_gdbarch, function, current_regcache,
-                               bp_addr, nargs, args, sp, struct_return,
-                               struct_addr);
+  sp = gdbarch_push_dummy_call (current_gdbarch, function,
+                               get_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
This page took 0.028073 seconds and 4 git commands to generate.