2004-02-14 Elena Zannoni <ezannoni@redhat.com>
[deliverable/binutils-gdb.git] / gdb / infcall.c
index 546e33c5d526388a1c5a06dd74fa37ee3c0e166e..f859ec3ea5ae6f61dddbe87cfc824f48a7116aaa 100644 (file)
@@ -1,8 +1,8 @@
 /* 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.
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "block.h"
 #include "gdbcore.h"
 #include "language.h"
-#include "symfile.h"
+#include "objfiles.h"
 #include "gdbcmd.h"
 #include "command.h"
 #include "gdb_string.h"
+#include "infcall.h"
 
 /* NOTE: cagney/2003-04-16: What's the future of this code?
 
@@ -83,8 +84,8 @@ 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
+  struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+  struct type *type
     = param_type ? check_typedef (param_type) : arg_type;
 
   switch (TYPE_CODE (type))
@@ -160,8 +161,8 @@ value_arg_coerce (struct value *arg, struct type *param_type,
 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 *ftype = check_typedef (VALUE_TYPE (function));
+  enum type_code code = TYPE_CODE (ftype);
   struct type *value_type;
   CORE_ADDR funaddr;
 
@@ -181,7 +182,9 @@ find_function_addr (struct value *function, struct type **retval_type)
       if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
          || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
        {
-         funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
+         funaddr = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+                                                       funaddr,
+                                                       &current_target);
          value_type = TYPE_TARGET_TYPE (ftype);
        }
       else
@@ -273,8 +276,8 @@ legacy_push_dummy_code (struct gdbarch *gdbarch,
      with the values.  Instead a DEPRECATED_FIX_CALL_DUMMY replacement
      (PUSH_DUMMY_BREAKPOINT?) should just do everything.  */
 #ifdef GDB_TARGET_IS_HPPA
-  real_pc = DEPRECATED_FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
-                                      value_type, using_gcc);
+  (*real_pc) = DEPRECATED_FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs,
+                                         args, value_type, using_gcc);
 #else
   if (DEPRECATED_FIX_CALL_DUMMY_P ())
     {
@@ -374,7 +377,7 @@ push_dummy_code (struct gdbarch *gdbarch,
 struct value *
 call_function_by_hand (struct value *function, int nargs, struct value **args)
 {
-  register CORE_ADDR sp;
+  CORE_ADDR sp;
   CORE_ADDR dummy_addr;
   struct type *value_type;
   unsigned char struct_return;
@@ -420,13 +423,13 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
       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
+      thread OR frame OR ptid 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.
+      parameter to generic_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
@@ -439,12 +442,24 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
     CORE_ADDR old_sp = read_sp ();
     if (gdbarch_frame_align_p (current_gdbarch))
       {
+       sp = gdbarch_frame_align (current_gdbarch, old_sp);
+       /* NOTE: cagney/2003-08-13: Skip the "red zone".  For some
+          ABIs, a function can use memory beyond the inner most stack
+          address.  AMD64 called that region the "red zone".  Skip at
+          least the "red zone" size before allocating any space on
+          the stack.  */
+       if (INNER_THAN (1, 2))
+         sp -= gdbarch_frame_red_zone_size (current_gdbarch);
+       else
+         sp += gdbarch_frame_red_zone_size (current_gdbarch);
+       /* Still aligned?  */
+       gdb_assert (sp == gdbarch_frame_align (current_gdbarch, sp));
        /* NOTE: cagney/2002-09-18:
           
           On a RISC architecture, a void parameterless generic dummy
           frame (i.e., no parameters, no result) typically does not
           need to push anything the stack and hence can leave SP and
-          FP.  Similarly, a framelss (possibly leaf) function does
+          FP.  Similarly, a frameless (possibly leaf) function does
           not push anything on the stack and, hence, that too can
           leave FP and SP unchanged.  As a consequence, a sequence of
           void parameterless generic dummy frame calls to frameless
@@ -459,7 +474,6 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
           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))
@@ -473,15 +487,18 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
                    || (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.  */
+      /* FIXME: cagney/2002-09-18: Hey, you loose!
+
+        Who knows how badly aligned the SP is!
+
+        If the generic dummy frame ends up empty (because nothing is
+        pushed) GDB won't be able to correctly perform back traces.
+        If a target is having trouble with backtraces, first thing to
+        do is add FRAME_ALIGN() to the architecture vector. If that
+        fails, try unwind_dummy_id().
+
+         If the ABI specifies a "Red Zone" (see the doco) the code
+         below will quietly trash it.  */
       sp = old_sp;
   }
 
@@ -497,8 +514,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
   /* 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);
+  struct_return = using_struct_return (value_type, using_gcc);
 
   /* Determine the location of the breakpoint (and possibly other
      stuff) that the called function will return to.  The SPARC, for a
@@ -542,11 +558,43 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
                                     value_type, using_gcc);
        }
       real_pc = funaddr;
-      dummy_addr = CALL_DUMMY_ADDRESS ();
+      dummy_addr = entry_point_address ();
+      if (DEPRECATED_CALL_DUMMY_ADDRESS_P ())
+       /* Override it.  */
+       dummy_addr = DEPRECATED_CALL_DUMMY_ADDRESS ();
+      /* Make certain that the address points at real code, and not a
+         function descriptor.  */
+      dummy_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+                                                      dummy_addr,
+                                                      &current_target);
       /* A call dummy always consists of just a single breakpoint, so
          it's address is the same as the address of the dummy.  */
       bp_addr = dummy_addr;
       break;
+    case AT_SYMBOL:
+      /* Some executables define a symbol __CALL_DUMMY_ADDRESS whose
+        address is the location where the breakpoint should be
+        placed.  Once all targets are using the overhauled frame code
+        this can be deleted - ON_STACK is a better option.  */
+      {
+       struct minimal_symbol *sym;
+
+       sym = lookup_minimal_symbol ("__CALL_DUMMY_ADDRESS", NULL, NULL);
+       real_pc = funaddr;
+       if (sym)
+         dummy_addr = SYMBOL_VALUE_ADDRESS (sym);
+       else
+         dummy_addr = entry_point_address ();
+       /* Make certain that the address points at real code, and not
+          a function descriptor.  */
+       dummy_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+                                                        dummy_addr,
+                                                        &current_target);
+       /* A call dummy always consists of just a single breakpoint,
+          so it's address is the same as the address of the dummy.  */
+       bp_addr = dummy_addr;
+       break;
+      }
     default:
       internal_error (__FILE__, __LINE__, "bad switch");
     }
@@ -621,7 +669,7 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
       }
   }
 
-  if (REG_STRUCT_HAS_ADDR_P ())
+  if (DEPRECATED_REG_STRUCT_HAS_ADDR_P ())
     {
       int i;
       /* This is a machine like the sparc, where we may need to pass a
@@ -638,7 +686,7 @@ 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)
               )
-             && REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
+             && DEPRECATED_REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
            {
              CORE_ADDR addr;
              int len;          /*  = TYPE_LENGTH (arg_type); */
@@ -646,12 +694,12 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
              arg_type = check_typedef (VALUE_ENCLOSING_TYPE (args[i]));
              len = TYPE_LENGTH (arg_type);
 
-             if (STACK_ALIGN_P ())
+             if (DEPRECATED_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);
+               aligned_len = DEPRECATED_STACK_ALIGN (len);
              else
                aligned_len = len;
              if (INNER_THAN (1, 2))
@@ -689,10 +737,10 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
   if (struct_return)
     {
       int len = TYPE_LENGTH (value_type);
-      if (STACK_ALIGN_P ())
+      if (DEPRECATED_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);
+       len = DEPRECATED_STACK_ALIGN (len);
       if (INNER_THAN (1, 2))
        {
          /* Stack grows downward.  Align STRUCT_ADDR and SP after
@@ -717,8 +765,8 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
 
   /* 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 */
+     taken care of in the above code (ifdef DEPRECATED_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.  */
@@ -727,7 +775,7 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
       /* 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 (DEPRECATED_STACK_ALIGN_P () && INNER_THAN (1, 2))
        {
          /* If stack grows down, we must leave a hole at the top. */
          int len = 0;
@@ -736,7 +784,7 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
            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;
+         sp -= DEPRECATED_STACK_ALIGN (len) - len;
        }
     }
 
@@ -781,13 +829,13 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
      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))
+      && DEPRECATED_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);
+      sp = DEPRECATED_STACK_ALIGN (sp);
     }
 
 /* XXX This seems wrong.  For stacks that grow down we shouldn't do
@@ -822,8 +870,16 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
   if (DEPRECATED_DUMMY_WRITE_SP_P ())
     DEPRECATED_DUMMY_WRITE_SP (sp);
 
-  if (SAVE_DUMMY_FRAME_TOS_P ())
-    SAVE_DUMMY_FRAME_TOS (sp);
+  if (gdbarch_unwind_dummy_id_p (current_gdbarch))
+    {
+      /* Sanity.  The exact same SP value is returned by
+        PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by
+        unwind_dummy_id to form the frame ID's stack address.  */
+      gdb_assert (DEPRECATED_USE_GENERIC_DUMMY_FRAMES);
+      generic_save_dummy_frame_tos (sp);
+    }
+  else if (DEPRECATED_SAVE_DUMMY_FRAME_TOS_P ())
+    DEPRECATED_SAVE_DUMMY_FRAME_TOS (sp);
 
   /* Now proceed, having reached the desired place.  */
   clear_proceed_status ();
@@ -842,17 +898,29 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
        set_momentary_breakpoint.  We need to give the breakpoint a
        frame ID so that the breakpoint code can correctly re-identify
        the dummy breakpoint.  */
-    /* The assumption here is that push_dummy_call() returned the
-       stack part of the frame ID.  Unfortunatly, many older
-       architectures were, via a convoluted mess, relying on the
-       poorly defined and greatly overloaded DEPRECATED_TARGET_READ_FP
-       or DEPRECATED_FP_REGNUM to supply the value.  */
-    if (DEPRECATED_TARGET_READ_FP_P ())
-      frame = frame_id_build (DEPRECATED_TARGET_READ_FP (), sal.pc);
-    else if (DEPRECATED_FP_REGNUM >= 0)
-      frame = frame_id_build (read_register (DEPRECATED_FP_REGNUM), sal.pc);
+    if (gdbarch_unwind_dummy_id_p (current_gdbarch))
+      {
+       /* Sanity.  The exact same SP value is returned by
+        PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by
+        unwind_dummy_id to form the frame ID's stack address.  */
+       gdb_assert (DEPRECATED_USE_GENERIC_DUMMY_FRAMES);
+       frame = frame_id_build (sp, sal.pc);
+      }
     else
-      frame = frame_id_build (sp, sal.pc);
+      {
+       /* The assumption here is that push_dummy_call() returned the
+          stack part of the frame ID.  Unfortunately, many older
+          architectures were, via a convoluted mess, relying on the
+          poorly defined and greatly overloaded
+          DEPRECATED_TARGET_READ_FP or DEPRECATED_FP_REGNUM to supply
+          the value.  */
+       if (DEPRECATED_TARGET_READ_FP_P ())
+         frame = frame_id_build (DEPRECATED_TARGET_READ_FP (), sal.pc);
+       else if (DEPRECATED_FP_REGNUM >= 0)
+         frame = frame_id_build (read_register (DEPRECATED_FP_REGNUM), sal.pc);
+       else
+         frame = frame_id_build (sp, sal.pc);
+      }
     bpt = set_momentary_breakpoint (sal, frame, bp_call_dummy);
     bpt->disposition = disp_del;
   }
@@ -900,7 +968,7 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
   if (stopped_by_random_signal || !stop_stack_dummy)
     {
       /* Find the name of the function we're about to complain about.  */
-      char *name = NULL;
+      const char *name = NULL;
       {
        struct symbol *symbol = find_pc_function (funaddr);
        if (symbol)
@@ -912,17 +980,17 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
            if (msymbol)
              name = SYMBOL_PRINT_NAME (msymbol);
          }
+       if (name == NULL)
+         {
+           /* Can't use a cleanup here.  It is discarded, instead use
+               an alloca.  */
+           char *tmp = xstrprintf ("at %s", local_hex_string (funaddr));
+           char *a = alloca (strlen (tmp) + 1);
+           strcpy (a, tmp);
+           xfree (tmp);
+           name = a;
+         }
       }
-      if (name == NULL)
-       {
-         /* NOTE: cagney/2003-04-23: Don't blame me.  This code dates
-             back to 1993-07-08, I simply moved it.  */
-         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);
-       }
       if (stopped_by_random_signal)
        {
          /* We stopped inside the FUNCTION because of a random
@@ -1007,37 +1075,25 @@ the function call).", name);
   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))
-    {
+      /* 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.  */
       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);
+      /* The non-register case was handled above.  */
+      struct value *retval = register_value_being_returned (value_type,
+                                                           retbuf);
       do_cleanups (retbuf_cleanup);
       return retval;
     }
This page took 0.030701 seconds and 4 git commands to generate.