Allow integer immediate for VFP vmov instructions.
[deliverable/binutils-gdb.git] / gdb / infcall.c
index ab7426d6f3c45987ce213d87784956fca366cf00..b13f5b61d96e84f5cc892d2f1a834169a0f1ec2b 100644 (file)
@@ -1,6 +1,6 @@
 /* Perform an inferior function call, for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2016 Free Software Foundation, Inc.
+   Copyright (C) 1986-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "ada-lang.h"
 #include "gdbthread.h"
 #include "event-top.h"
-#include "observer.h"
+#include "observable.h"
 #include "top.h"
 #include "interps.h"
 #include "thread-fsm.h"
+#include <algorithm>
 
 /* If we can't find a function's name from its address,
    we print this instead.  */
@@ -157,10 +158,11 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
        struct value *new_value;
 
-       if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+       if (TYPE_IS_REFERENCE (arg_type))
          return value_cast_pointers (type, arg, 0);
 
        /* Cast the value to the reference's target type, and then
@@ -168,7 +170,7 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
           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);
+       new_value = value_ref (new_value, TYPE_CODE (type));
        return new_value;
       }
     case TYPE_CODE_INT:
@@ -227,26 +229,12 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
   return value_cast (type, arg);
 }
 
-/* Return the return type of a function with its first instruction exactly at
-   the PC address.  Return NULL otherwise.  */
-
-static struct type *
-find_function_return_type (CORE_ADDR pc)
-{
-  struct symbol *sym = find_pc_function (pc);
-
-  if (sym != NULL && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) == pc
-      && SYMBOL_TYPE (sym) != NULL)
-    return TYPE_TARGET_TYPE (SYMBOL_TYPE (sym));
-
-  return NULL;
-}
-
-/* Determine a function's address and its return type from its value.
-   Calls error() if the function is not valid for calling.  */
+/* See infcall.h.  */
 
 CORE_ADDR
-find_function_addr (struct value *function, struct type **retval_type)
+find_function_addr (struct value *function,
+                   struct type **retval_type,
+                   struct type **function_type)
 {
   struct type *ftype = check_typedef (value_type (function));
   struct gdbarch *gdbarch = get_type_arch (ftype);
@@ -268,22 +256,38 @@ find_function_addr (struct value *function, struct type **retval_type)
       if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
          || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
        funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr,
-                                                     &current_target);
+                                                     target_stack);
     }
   if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
       || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
     {
-      value_type = TYPE_TARGET_TYPE (ftype);
-
       if (TYPE_GNU_IFUNC (ftype))
        {
-         funaddr = gnu_ifunc_resolve_addr (gdbarch, funaddr);
+         CORE_ADDR resolver_addr = funaddr;
 
-         /* Skip querying the function symbol if no RETVAL_TYPE has been
-            asked for.  */
-         if (retval_type)
-           value_type = find_function_return_type (funaddr);
+         /* Resolve the ifunc.  Note this may call the resolver
+            function in the inferior.  */
+         funaddr = gnu_ifunc_resolve_addr (gdbarch, resolver_addr);
+
+         /* Skip querying the function symbol if no RETVAL_TYPE or
+            FUNCTION_TYPE have been asked for.  */
+         if (retval_type != NULL || function_type != NULL)
+           {
+             type *target_ftype = find_function_type (funaddr);
+             /* If we don't have debug info for the target function,
+                see if we can instead extract the target function's
+                type from the type that the resolver returns.  */
+             if (target_ftype == NULL)
+               target_ftype = find_gnu_ifunc_target_type (resolver_addr);
+             if (target_ftype != NULL)
+               {
+                 value_type = TYPE_TARGET_TYPE (check_typedef (target_ftype));
+                 ftype = target_ftype;
+               }
+           }
        }
+      else
+       value_type = TYPE_TARGET_TYPE (ftype);
     }
   else if (TYPE_CODE (ftype) == TYPE_CODE_INT)
     {
@@ -304,7 +308,7 @@ find_function_addr (struct value *function, struct type **retval_type)
              funaddr = value_as_address (value_addr (function));
              nfunaddr = funaddr;
              funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr,
-                                                           &current_target);
+                                                           target_stack);
              if (funaddr != nfunaddr)
                found_descriptor = 1;
            }
@@ -318,6 +322,8 @@ find_function_addr (struct value *function, struct type **retval_type)
 
   if (retval_type != NULL)
     *retval_type = value_type;
+  if (function_type != NULL)
+    *function_type = ftype;
   return funaddr + gdbarch_deprecated_function_start_offset (gdbarch);
 }
 
@@ -339,6 +345,20 @@ push_dummy_code (struct gdbarch *gdbarch,
                                  regcache);
 }
 
+/* See infcall.h.  */
+
+void
+error_call_unknown_return_type (const char *func_name)
+{
+  if (func_name != NULL)
+    error (_("'%s' has unknown return type; "
+            "cast the call to its declared return type"),
+          func_name);
+  else
+    error (_("function has unknown return type; "
+            "cast the call to its declared return type"));
+}
+
 /* Fetch the name of the function at FUNADDR.
    This is used in printing an error message for call_function_by_hand.
    BUF is used to print FUNADDR in hex if the function name cannot be
@@ -393,9 +413,6 @@ struct call_return_meta_info
 
   /* If using a structure return, this is the structure's address.  */
   CORE_ADDR struct_addr;
-
-  /* Whether stack temporaries are enabled.  */
-  int stack_temporaries_enabled;
 };
 
 /* Extract the called function's return value.  */
@@ -404,7 +421,7 @@ static struct value *
 get_call_return_value (struct call_return_meta_info *ri)
 {
   struct value *retval = NULL;
-  int stack_temporaries = thread_stack_temporaries_enabled_p (inferior_ptid);
+  bool stack_temporaries = thread_stack_temporaries_enabled_p (inferior_ptid);
 
   if (TYPE_CODE (ri->value_type) == TYPE_CODE_VOID)
     retval = allocate_value (ri->value_type);
@@ -519,8 +536,6 @@ call_thread_fsm_should_stop (struct thread_fsm *self,
 
   if (stop_stack_dummy == STOP_STACK_DUMMY)
     {
-      struct cleanup *old_chain;
-
       /* Done.  */
       thread_fsm_set_finished (self);
 
@@ -530,13 +545,9 @@ call_thread_fsm_should_stop (struct thread_fsm *self,
       f->return_value = get_call_return_value (&f->return_meta_info);
 
       /* Break out of wait_sync_command_done.  */
-      old_chain = make_cleanup_restore_current_ui ();
-      current_ui = f->waiting_ui;
-      target_terminal_ours ();
+      scoped_restore save_ui = make_scoped_restore (&current_ui, f->waiting_ui);
+      target_terminal::ours ();
       f->waiting_ui->prompt_state = PROMPT_NEEDED;
-
-      /* This restores the previous UI.  */
-      do_cleanups (old_chain);
     }
 
   return 1;
@@ -678,9 +689,12 @@ cleanup_delete_std_terminate_breakpoint (void *ignore)
 /* See infcall.h.  */
 
 struct value *
-call_function_by_hand (struct value *function, int nargs, struct value **args)
+call_function_by_hand (struct value *function,
+                      type *default_return_type,
+                      int nargs, struct value **args)
 {
-  return call_function_by_hand_dummy (function, nargs, args, NULL, NULL);
+  return call_function_by_hand_dummy (function, default_return_type,
+                                     nargs, args, NULL, NULL);
 }
 
 /* All this stuff with a dummy frame may seem unnecessarily complicated
@@ -703,33 +717,28 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
 
 struct value *
 call_function_by_hand_dummy (struct value *function,
+                            type *default_return_type,
                             int nargs, struct value **args,
                             dummy_frame_dtor_ftype *dummy_dtor,
                             void *dummy_dtor_data)
 {
   CORE_ADDR sp;
-  struct type *values_type, *target_values_type;
+  struct type *target_values_type;
   unsigned char struct_return = 0, hidden_first_param_p = 0;
   CORE_ADDR struct_addr = 0;
   struct infcall_control_state *inf_status;
   struct cleanup *inf_status_cleanup;
   struct infcall_suspend_state *caller_state;
-  CORE_ADDR funaddr;
   CORE_ADDR real_pc;
-  struct type *ftype = check_typedef (value_type (function));
   CORE_ADDR bp_addr;
   struct frame_id dummy_id;
-  struct cleanup *args_cleanup;
   struct frame_info *frame;
   struct gdbarch *gdbarch;
   struct cleanup *terminate_bp_cleanup;
   ptid_t call_thread_ptid;
   struct gdb_exception e;
   char name_buf[RAW_FUNCTION_ADDRESS_SIZE];
-  int stack_temporaries = thread_stack_temporaries_enabled_p (inferior_ptid);
-
-  if (TYPE_CODE (ftype) == TYPE_CODE_PTR)
-    ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
+  bool stack_temporaries = thread_stack_temporaries_enabled_p (inferior_ptid);
 
   if (!target_has_execution)
     noprocess ();
@@ -854,9 +863,20 @@ call_function_by_hand_dummy (struct value *function,
       }
   }
 
-  funaddr = find_function_addr (function, &values_type);
-  if (!values_type)
-    values_type = builtin_type (gdbarch)->builtin_int;
+  type *ftype;
+  type *values_type;
+  CORE_ADDR funaddr = find_function_addr (function, &values_type, &ftype);
+
+  if (values_type == NULL)
+    values_type = default_return_type;
+  if (values_type == NULL)
+    {
+      const char *name = get_function_name (funaddr,
+                                           name_buf, sizeof (name_buf));
+      error (_("'%s' has unknown return type; "
+              "cast the call to its declared return type"),
+            name);
+    }
 
   values_type = check_typedef (values_type);
 
@@ -885,7 +905,7 @@ call_function_by_hand_dummy (struct value *function,
       target_values_type = values_type;
     }
 
-  observer_notify_inferior_call_pre (inferior_ptid, funaddr);
+  gdb::observers::inferior_call_pre.notify (inferior_ptid, funaddr);
 
   /* Determine the location of the breakpoint (and possibly other
      stuff) that the called function will return to.  The SPARC, for a
@@ -960,6 +980,21 @@ call_function_by_hand_dummy (struct value *function,
           prototyped.  Can we respect TYPE_VARARGS?  Probably not.  */
        if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
          prototyped = 1;
+       if (TYPE_TARGET_TYPE (ftype) == NULL && TYPE_NFIELDS (ftype) == 0
+           && default_return_type != NULL)
+         {
+           /* Calling a no-debug function with the return type
+              explicitly cast.  Assume the function is prototyped,
+              with a prototype matching the types of the arguments.
+              E.g., with:
+                float mult (float v1, float v2) { return v1 * v2; }
+              This:
+                (gdb) p (float) mult (2.0f, 3.0f)
+              Is a simpler alternative to:
+                (gdb) p ((float (*) (float, float)) mult) (2.0f, 3.0f)
+            */
+           prototyped = 1;
+         }
        else if (i < TYPE_NFIELDS (ftype))
          prototyped = TYPE_PROTOTYPED (ftype);
        else
@@ -1018,21 +1053,16 @@ call_function_by_hand_dummy (struct value *function,
        }
     }
 
+  std::vector<struct value *> new_args;
   if (hidden_first_param_p)
     {
-      struct value **new_args;
-
       /* Add the new argument to the front of the argument list.  */
-      new_args = XNEWVEC (struct value *, nargs + 1);
-      new_args[0] = value_from_pointer (lookup_pointer_type (values_type),
-                                       struct_addr);
-      memcpy (&new_args[1], &args[0], sizeof (struct value *) * nargs);
-      args = new_args;
+      new_args.push_back
+       (value_from_pointer (lookup_pointer_type (values_type), struct_addr));
+      std::copy (&args[0], &args[nargs], std::back_inserter (new_args));
+      args = new_args.data ();
       nargs++;
-      args_cleanup = make_cleanup (xfree, args);
     }
-  else
-    args_cleanup = make_cleanup (null_cleanup, NULL);
 
   /* Create the dummy stack frame.  Pass in the call dummy address as,
      presumably, the ABI code knows where, in the call dummy, the
@@ -1041,8 +1071,6 @@ call_function_by_hand_dummy (struct value *function,
                                bp_addr, nargs, args,
                                sp, struct_return, struct_addr);
 
-  do_cleanups (args_cleanup);
-
   /* 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
@@ -1056,17 +1084,17 @@ call_function_by_hand_dummy (struct value *function,
      inferior.  That way it breaks when it returns.  */
 
   {
-    struct breakpoint *bpt, *longjmp_b;
-    struct symtab_and_line sal;
-
-    init_sal (&sal);           /* initialize to zeroes */
+    symtab_and_line sal;
     sal.pspace = current_program_space;
     sal.pc = bp_addr;
     sal.section = find_pc_overlay (sal.pc);
+
     /* Sanity.  The exact same SP value is returned by
        PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by
        dummy_id to form the frame ID's stack address.  */
-    bpt = set_momentary_breakpoint (gdbarch, sal, dummy_id, bp_call_dummy);
+    breakpoint *bpt
+      = set_momentary_breakpoint (gdbarch, sal,
+                                 dummy_id, bp_call_dummy).release ();
 
     /* set_momentary_breakpoint invalidates FRAME.  */
     frame = NULL;
@@ -1074,7 +1102,7 @@ call_function_by_hand_dummy (struct value *function,
     bpt->disposition = disp_del;
     gdb_assert (bpt->related_breakpoint == bpt);
 
-    longjmp_b = set_longjmp_breakpoint_for_call_dummy ();
+    breakpoint *longjmp_b = set_longjmp_breakpoint_for_call_dummy ();
     if (longjmp_b)
       {
        /* Link BPT into the chain of LONGJMP_B.  */
@@ -1150,7 +1178,7 @@ call_function_by_hand_dummy (struct value *function,
 
     e = run_inferior_call (sm, tp, real_pc);
 
-    observer_notify_inferior_call_post (call_thread_ptid, funaddr);
+    gdb::observers::inferior_call_post.notify (call_thread_ptid, funaddr);
 
     tp = find_thread_ptid (call_thread_ptid);
     if (tp != NULL)
@@ -1273,10 +1301,8 @@ When the function is done executing, GDB will silently stop."),
 
     {
       /* Make a copy as NAME may be in an objfile freed by dummy_frame_pop.  */
-      char *name = xstrdup (get_function_name (funaddr,
-                                              name_buf, sizeof (name_buf)));
-      make_cleanup (xfree, name);
-
+      std::string name = get_function_name (funaddr, name_buf,
+                                           sizeof (name_buf));
 
       if (stopped_by_random_signal)
        {
@@ -1304,7 +1330,7 @@ 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\n\
 (%s) will be abandoned."),
-                    name);
+                    name.c_str ());
            }
          else
            {
@@ -1323,7 +1349,7 @@ To change this behavior use \"set unwindonsignal on\".\n\
 Evaluation of the expression containing the function\n\
 (%s) will be abandoned.\n\
 When the function is done executing, GDB will silently stop."),
-                    name);
+                    name.c_str ());
            }
        }
 
@@ -1345,7 +1371,7 @@ context to its original state before the call.\n\
 To change this behaviour use \"set unwind-on-terminating-exception off\".\n\
 Evaluation of the expression containing the function (%s)\n\
 will be abandoned."),
-                name);
+                name.c_str ());
        }
       else if (stop_stack_dummy == STOP_NONE)
        {
@@ -1369,7 +1395,7 @@ The program being debugged stopped while in a function called from GDB.\n\
 Evaluation of the expression containing the function\n\
 (%s) will be abandoned.\n\
 When the function is done executing, GDB will silently stop."),
-                name);
+                name.c_str ());
        }
 
     }
@@ -1377,10 +1403,6 @@ When the function is done executing, GDB will silently stop."),
   /* The above code errors out, so ...  */
   gdb_assert_not_reached ("... should not be here");
 }
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-void _initialize_infcall (void);
 
 void
 _initialize_infcall (void)
This page took 0.034526 seconds and 4 git commands to generate.