* cris.h (R_CRIS_32_IE): New relocation.
[deliverable/binutils-gdb.git] / gdb / infcall.c
index 33a098ff59ee571785798066e7fe3612d5f52830..d50bcca978ac96e46f0c4125dba2b659056e61eb 100644 (file)
@@ -35,6 +35,7 @@
 #include "infcall.h"
 #include "dummy-frame.h"
 #include "ada-lang.h"
+#include "gdbthread.h"
 
 /* NOTE: cagney/2003-04-16: What's the future of this code?
 
@@ -100,9 +101,10 @@ Unwinding of stack if a signal is received while in a call dummy is %s.\n"),
    its value as needed).  */
 
 static struct value *
-value_arg_coerce (struct value *arg, struct type *param_type,
-                 int is_prototyped, CORE_ADDR *sp)
+value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
+                 struct type *param_type, int is_prototyped, CORE_ADDR *sp)
 {
+  const struct builtin_type *builtin = builtin_type (gdbarch);
   struct type *arg_type = check_typedef (value_type (arg));
   struct type *type
     = param_type ? check_typedef (param_type) : arg_type;
@@ -141,22 +143,22 @@ value_arg_coerce (struct value *arg, struct type *param_type,
       /* 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;
+         if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_int))
+           type = builtin->builtin_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;
+      if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_int))
+       type = builtin->builtin_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;
+         if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_double))
+           type = builtin->builtin_double;
+         else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin->builtin_double))
+           type = builtin->builtin_long_double;
        }
       break;
     case TYPE_CODE_FUNC:
@@ -199,7 +201,7 @@ find_function_addr (struct value *function, struct type **retval_type)
 {
   struct type *ftype = check_typedef (value_type (function));
   enum type_code code = TYPE_CODE (ftype);
-  struct type *value_type;
+  struct type *value_type = NULL;
   CORE_ADDR funaddr;
 
   /* If it's a member function, just look at the function
@@ -223,8 +225,6 @@ find_function_addr (struct value *function, struct type **retval_type)
                                                        &current_target);
          value_type = TYPE_TARGET_TYPE (ftype);
        }
-      else
-       value_type = builtin_type_int;
     }
   else if (code == TYPE_CODE_INT)
     {
@@ -251,8 +251,6 @@ find_function_addr (struct value *function, struct type **retval_type)
            /* 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."));
@@ -263,49 +261,13 @@ find_function_addr (struct value *function, struct type **retval_type)
 }
 
 /* Call breakpoint_auto_delete on the current contents of the bpstat
-   pointed to by arg (which is really a bpstat *).  */
+   of the current thread.  */
 
 static void
 breakpoint_auto_delete_contents (void *arg)
 {
-  breakpoint_auto_delete (*(bpstat *) arg);
-}
-
-static CORE_ADDR
-generic_push_dummy_code (struct gdbarch *gdbarch,
-                        CORE_ADDR sp, CORE_ADDR funaddr,
-                        struct value **args, int nargs,
-                        struct type *value_type,
-                        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.  */
-  int bplen;
-  /* This code assumes frame align.  */
-  gdb_assert (gdbarch_frame_align_p (gdbarch));
-  /* Force the stack's alignment.  The intent is to ensure that the SP
-     is aligned to at least a breakpoint instruction's boundary.  */
-  sp = gdbarch_frame_align (gdbarch, sp);
-  /* Allocate space for, and then position the breakpoint on the
-     stack.  */
-  if (gdbarch_inner_than (gdbarch, 1, 2))
-    {
-      CORE_ADDR bppc = sp;
-      gdbarch_breakpoint_from_pc (gdbarch, &bppc, &bplen);
-      sp = gdbarch_frame_align (gdbarch, sp - bplen);
-      (*bp_addr) = sp;
-      /* Should the breakpoint size/location be re-computed here?  */
-    }      
-  else
-    {
-      (*bp_addr) = sp;
-      gdbarch_breakpoint_from_pc (gdbarch, bp_addr, &bplen);
-      sp = gdbarch_frame_align (gdbarch, sp + bplen);
-    }
-  /* Inferior resumes at the function entry point.  */
-  (*real_pc) = funaddr;
-  return sp;
+  if (!ptid_equal (inferior_ptid, null_ptid))
+    breakpoint_auto_delete (inferior_thread ()->stop_bpstat);
 }
 
 /* For CALL_DUMMY_ON_STACK, push a breakpoint sequence that the called
@@ -319,14 +281,11 @@ push_dummy_code (struct gdbarch *gdbarch,
                 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,
-                                   args, nargs, value_type, real_pc, bp_addr,
-                                   regcache);
-  else    
-    return generic_push_dummy_code (gdbarch, sp, funaddr,
-                                   args, nargs, value_type, real_pc, bp_addr,
-                                   regcache);
+  gdb_assert (gdbarch_push_dummy_code_p (gdbarch));
+
+  return gdbarch_push_dummy_code (gdbarch, sp, funaddr,
+                                 args, nargs, value_type, real_pc, bp_addr,
+                                 regcache);
 }
 
 /* All this stuff with a dummy frame may seem unnecessarily complicated
@@ -351,7 +310,6 @@ struct value *
 call_function_by_hand (struct value *function, int nargs, struct value **args)
 {
   CORE_ADDR sp;
-  CORE_ADDR dummy_addr;
   struct type *values_type, *target_values_type;
   unsigned char struct_return = 0, lang_struct_return = 0;
   CORE_ADDR struct_addr = 0;
@@ -380,7 +338,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
   gdbarch = get_frame_arch (frame);
 
   if (!gdbarch_push_dummy_call_p (gdbarch))
-    error (_("This target does not support function calls"));
+    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
@@ -470,6 +428,9 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
   }
 
   funaddr = find_function_addr (function, &values_type);
+  if (!values_type)
+    values_type = builtin_type (gdbarch)->builtin_int;
+
   CHECK_TYPEDEF (values_type);
 
   /* Are we returning a value using a structure return (passing a
@@ -509,35 +470,26 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
   switch (gdbarch_call_dummy_location (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 (gdbarch_inner_than (gdbarch, 1, 2))
-       {
-         sp = push_dummy_code (gdbarch, sp, funaddr,
-                               args, nargs, target_values_type,
-                               &real_pc, &bp_addr, get_current_regcache ());
-         dummy_addr = sp;
-       }
-      else
-       {
-         dummy_addr = sp;
-         sp = push_dummy_code (gdbarch, sp, funaddr,
+      sp = push_dummy_code (gdbarch, sp, funaddr,
                                args, nargs, target_values_type,
                                &real_pc, &bp_addr, get_current_regcache ());
-       }
       break;
     case AT_ENTRY_POINT:
-      real_pc = funaddr;
-      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 (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;
+      {
+       CORE_ADDR dummy_addr;
+
+       real_pc = funaddr;
+       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 (gdbarch,
+                                                        dummy_addr,
+                                                        &current_target);
+       /* A call dummy always consists of just a single breakpoint, so
+          its 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
@@ -545,6 +497,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
         this can be deleted - ON_STACK is a better option.  */
       {
        struct minimal_symbol *sym;
+       CORE_ADDR dummy_addr;
 
        sym = lookup_minimal_symbol ("__CALL_DUMMY_ADDRESS", NULL, NULL);
        real_pc = funaddr;
@@ -567,7 +520,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
     }
 
   if (nargs < TYPE_NFIELDS (ftype))
-    error (_("too few arguments in function call"));
+    error (_("Too few arguments in function call."));
 
   {
     int i;
@@ -590,7 +543,8 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
        else
          param_type = NULL;
 
-       args[i] = value_arg_coerce (args[i], param_type, prototyped, &sp);
+       args[i] = value_arg_coerce (gdbarch, args[i],
+                                   param_type, prototyped, &sp);
 
        if (param_type != NULL && language_pass_by_reference (param_type))
          args[i] = value_addr (args[i]);
@@ -708,21 +662,23 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
     struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
     struct cleanup *old_cleanups2;
     int saved_async = 0;
+    struct thread_info *tp = inferior_thread ();
 
     /* 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);
+    make_cleanup (breakpoint_auto_delete_contents, NULL);
 
     disable_watchpoints_before_interactive_call_start ();
-    proceed_to_finish = 1;     /* We want stop_registers, please... */
+    tp->proceed_to_finish = 1; /* We want stop_registers, please... */
 
     if (target_can_async_p ())
       saved_async = target_async_mask (0);
 
-    old_cleanups2 = make_cleanup_restore_integer 
-      (&suppress_run_stop_observers);
-    suppress_run_stop_observers = 1;
+    old_cleanups2 = make_cleanup_restore_integer (&suppress_resume_observer);
+    suppress_resume_observer = 1;
+    make_cleanup_restore_integer (&suppress_stop_observer);
+    suppress_stop_observer = 1;
     proceed (real_pc, TARGET_SIGNAL_0, 0);
     do_cleanups (old_cleanups2);
     
@@ -734,6 +690,16 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
     discard_cleanups (old_cleanups);
   }
 
+  if (! target_has_execution)
+    {
+      /* If we try to restore the inferior status (via the cleanup),
+        we'll crash as the inferior is no longer running.  */
+      discard_cleanups (inf_status_cleanup);
+      discard_inferior_status (inf_status);
+      error (_("\
+The program being debugged exited while in a function called from GDB."));
+    }
+
   if (stopped_by_random_signal || !stop_stack_dummy)
     {
       /* Find the name of the function we're about to complain about.  */
@@ -779,7 +745,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
              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\
+To change this behavior use \"set unwindonsignal off\".\n\
 Evaluation of the expression containing the function (%s) will be abandoned."),
                     name);
            }
@@ -799,7 +765,7 @@ Evaluation of the expression containing the function (%s) will be abandoned."),
              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\
+To change this behavior use \"set unwindonsignal on\".\n\
 Evaluation of the expression containing the function (%s) will be abandoned."),
                     name);
            }
This page took 0.028255 seconds and 4 git commands to generate.