inf-ptrace: Return an IGNORE event if waitpid() fails.
[binutils-gdb.git] / gdb / infcall.c
index 8df7523f1576881e3f42fb98f06f97a72a258fb9..f8c812c8f611c82a6f37f8f714cbfaec3737d2ce 100644 (file)
@@ -1,6 +1,6 @@
 /* Perform an inferior function call, for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2020 Free Software Foundation, Inc.
+   Copyright (C) 1986-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -48,7 +48,7 @@
    we print this instead.  */
 #define RAW_FUNCTION_ADDRESS_FORMAT "at 0x%s"
 #define RAW_FUNCTION_ADDRESS_SIZE (sizeof (RAW_FUNCTION_ADDRESS_FORMAT) \
-                                   + 2 * sizeof (CORE_ADDR))
+                                  + 2 * sizeof (CORE_ADDR))
 
 /* NOTE: cagney/2003-04-16: What's the future of this code?
 
@@ -198,8 +198,8 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
            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.  */
+        type for an argument.  We may have to conditionalize the following
+        type coercion for future targets.  */
       if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_int))
        type = builtin->builtin_int;
       break;
@@ -217,8 +217,8 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
       break;
     case TYPE_CODE_ARRAY:
       /* Arrays are coerced to pointers to their first element, unless
-         they are vectors, in which case we want to leave them alone,
-         because they are passed by value.  */
+        they are vectors, in which case we want to leave them alone,
+        because they are passed by value.  */
       if (current_language->c_style_arrays_p ())
        if (!type->is_vector ())
          type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
@@ -251,7 +251,7 @@ find_function_addr (struct value *function,
                    struct type **function_type)
 {
   struct type *ftype = check_typedef (value_type (function));
-  struct gdbarch *gdbarch = get_type_arch (ftype);
+  struct gdbarch *gdbarch = ftype->arch ();
   struct type *value_type = NULL;
   /* Initialize it just to avoid a GCC false warning.  */
   CORE_ADDR funaddr = 0;
@@ -269,8 +269,8 @@ find_function_addr (struct value *function,
       ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
       if (ftype->code () == TYPE_CODE_FUNC
          || ftype->code () == TYPE_CODE_METHOD)
-       funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr,
-                                                     current_top_target ());
+       funaddr = gdbarch_convert_from_func_ptr_addr
+         (gdbarch, funaddr, current_inferior ()->top_target());
     }
   if (ftype->code () == TYPE_CODE_FUNC
       || ftype->code () == TYPE_CODE_METHOD)
@@ -306,7 +306,7 @@ find_function_addr (struct value *function,
   else if (ftype->code () == TYPE_CODE_INT)
     {
       /* Handle the case of functions lacking debugging info.
-         Their values are characters since their addresses are char.  */
+        Their values are characters since their addresses are char.  */
       if (TYPE_LENGTH (ftype) == 1)
        funaddr = value_as_address (value_addr (function));
       else
@@ -321,9 +321,8 @@ find_function_addr (struct value *function,
 
              funaddr = value_as_address (value_addr (function));
              nfunaddr = funaddr;
-             funaddr
-               = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr,
-                                                     current_top_target ());
+             funaddr = gdbarch_convert_from_func_ptr_addr
+               (gdbarch, funaddr, current_inferior ()->top_target ());
              if (funaddr != nfunaddr)
                found_descriptor = 1;
            }
@@ -452,7 +451,7 @@ get_call_return_value (struct call_return_meta_info *ri)
        {
          retval = allocate_value (ri->value_type);
          read_value_memory (retval, 0, 1, ri->struct_addr,
-                            value_contents_raw (retval),
+                            value_contents_raw (retval).data (),
                             TYPE_LENGTH (ri->value_type));
        }
     }
@@ -461,7 +460,7 @@ get_call_return_value (struct call_return_meta_info *ri)
       retval = allocate_value (ri->value_type);
       gdbarch_return_value (ri->gdbarch, ri->function, ri->value_type,
                            get_current_regcache (),
-                           value_contents_raw (retval), NULL);
+                           value_contents_raw (retval).data (), NULL);
       if (stack_temporaries && class_or_union_p (ri->value_type))
        {
          /* Values of class type returned in registers are copied onto
@@ -575,7 +574,7 @@ call_thread_fsm::should_notify_stop ()
    thrown errors.  The caller should rethrow if there's an error.  */
 
 static struct gdb_exception
-run_inferior_call (struct call_thread_fsm *sm,
+run_inferior_call (std::unique_ptr<call_thread_fsm> sm,
                   struct thread_info *call_thread, CORE_ADDR real_pc)
 {
   struct gdb_exception caught_error;
@@ -598,9 +597,8 @@ run_inferior_call (struct call_thread_fsm *sm,
   clear_proceed_status (0);
 
   /* Associate the FSM with the thread after clear_proceed_status
-     (otherwise it'd clear this FSM), and before anything throws, so
-     we don't leak it (and any resources it manages).  */
-  call_thread->thread_fsm = sm;
+     (otherwise it'd clear this FSM).  */
+  call_thread->set_thread_fsm (std::move (sm));
 
   disable_watchpoints_before_interactive_call_start ();
 
@@ -786,7 +784,7 @@ call_function_by_hand_dummy (struct value *function,
     error (_("Cannot call functions in the program: "
             "may-call-functions is off."));
 
-  if (!target_has_execution)
+  if (!target_has_execution ())
     noprocess ();
 
   if (get_traceframe_number () >= 0)
@@ -814,6 +812,11 @@ call_function_by_hand_dummy (struct value *function,
   type *values_type;
   CORE_ADDR funaddr = find_function_addr (function, &values_type, &ftype);
 
+  if (is_nocall_function (ftype))
+    error (_("Cannot call the function '%s' which does not follow the "
+            "target calling convention."),
+          get_function_name (funaddr, name_buf, sizeof (name_buf)));
+
   if (values_type == NULL)
     values_type = default_return_type;
   if (values_type == NULL)
@@ -903,8 +906,8 @@ call_function_by_hand_dummy (struct value *function,
         do is add FRAME_ALIGN() to the architecture vector.  If that
         fails, try dummy_id().
 
-         If the ABI specifies a "Red Zone" (see the doco) the code
-         below will quietly trash it.  */
+        If the ABI specifies a "Red Zone" (see the doco) the code
+        below will quietly trash it.  */
       sp = old_sp;
 
     /* Skip over the stack temporaries that might have been generated during
@@ -914,7 +917,7 @@ call_function_by_hand_dummy (struct value *function,
        struct value *lastval;
 
        lastval = get_last_thread_stack_temporary (call_thread.get ());
-        if (lastval != NULL)
+       if (lastval != NULL)
          {
            CORE_ADDR lastval_addr = value_address (lastval);
 
@@ -1027,8 +1030,8 @@ call_function_by_hand_dummy (struct value *function,
         prototyped.  Can we respect TYPE_VARARGS?  Probably not.  */
       if (ftype->code () == TYPE_CODE_METHOD)
        prototyped = 1;
-      if (TYPE_TARGET_TYPE (ftype) == NULL && ftype->num_fields () == 0
-         && default_return_type != NULL)
+      else if (TYPE_TARGET_TYPE (ftype) == NULL && ftype->num_fields () == 0
+              && default_return_type != NULL)
        {
          /* Calling a no-debug function with the return type
             explicitly cast.  Assume the function is prototyped,
@@ -1084,7 +1087,7 @@ call_function_by_hand_dummy (struct value *function,
       if (info.trivially_copy_constructible)
        {
          int length = TYPE_LENGTH (param_type);
-         write_memory (addr, value_contents (args[i]), length);
+         write_memory (addr, value_contents (args[i]).data (), length);
        }
       else
        {
@@ -1252,12 +1255,9 @@ call_function_by_hand_dummy (struct value *function,
      just below is the place to chop this function in two..  */
 
   {
-    struct thread_fsm *saved_sm;
-    struct call_thread_fsm *sm;
-
     /* Save the current FSM.  We'll override it.  */
-    saved_sm = call_thread->thread_fsm;
-    call_thread->thread_fsm = NULL;
+    std::unique_ptr<thread_fsm> saved_sm = call_thread->release_thread_fsm ();
+    struct call_thread_fsm *sm;
 
     /* Save this thread's ptid, we need it later but the thread
        may have exited.  */
@@ -1274,17 +1274,19 @@ call_function_by_hand_dummy (struct value *function,
                              values_type,
                              return_method != return_method_normal,
                              struct_addr);
-
-    e = run_inferior_call (sm, call_thread.get (), real_pc);
+    {
+      std::unique_ptr<call_thread_fsm> sm_up (sm);
+      e = run_inferior_call (std::move (sm_up), call_thread.get (), real_pc);
+    }
 
     gdb::observers::inferior_call_post.notify (call_thread_ptid, funaddr);
 
     if (call_thread->state != THREAD_EXITED)
       {
        /* The FSM should still be the same.  */
-       gdb_assert (call_thread->thread_fsm == sm);
+       gdb_assert (call_thread->thread_fsm () == sm);
 
-       if (call_thread->thread_fsm->finished_p ())
+       if (call_thread->thread_fsm ()->finished_p ())
          {
            struct value *retval;
 
@@ -1298,11 +1300,16 @@ call_function_by_hand_dummy (struct value *function,
            /* Get the return value.  */
            retval = sm->return_value;
 
-           /* Clean up / destroy the call FSM, and restore the
-              original one.  */
-           call_thread->thread_fsm->clean_up (call_thread.get ());
-           delete call_thread->thread_fsm;
-           call_thread->thread_fsm = saved_sm;
+           /* Restore the original FSM and clean up / destroh the call FSM.
+              Doing it in this order ensures that if the call to clean_up
+              throws, the original FSM is properly restored.  */
+           {
+             std::unique_ptr<thread_fsm> finalizing
+               = call_thread->release_thread_fsm ();
+             call_thread->set_thread_fsm (std::move (saved_sm));
+
+             finalizing->clean_up (call_thread.get ());
+           }
 
            maybe_remove_breakpoints ();
 
@@ -1316,9 +1323,13 @@ call_function_by_hand_dummy (struct value *function,
 
        /* Didn't complete.  Clean up / destroy the call FSM, and restore the
           previous state machine, and handle the error.  */
-       call_thread->thread_fsm->clean_up (call_thread.get ());
-       delete call_thread->thread_fsm;
-       call_thread->thread_fsm = saved_sm;
+       {
+         std::unique_ptr<thread_fsm> finalizing
+           = call_thread->release_thread_fsm ();
+         call_thread->set_thread_fsm (std::move (saved_sm));
+
+         finalizing->clean_up (call_thread.get ());
+       }
       }
   }
 
@@ -1327,13 +1338,13 @@ call_function_by_hand_dummy (struct value *function,
   if (e.reason < 0)
     {
       const char *name = get_function_name (funaddr,
-                                            name_buf, sizeof (name_buf));
+                                           name_buf, sizeof (name_buf));
 
       discard_infcall_control_state (inf_status.release ());
 
       /* We could discard the dummy frame here if the program exited,
-         but it will get garbage collected the next time the program is
-         run anyway.  */
+        but it will get garbage collected the next time the program is
+        run anyway.  */
 
       switch (e.reason)
        {
@@ -1353,7 +1364,7 @@ When the function is done executing, GDB will silently stop."),
   /* If the program has exited, or we stopped at a different thread,
      exit and inform the user.  */
 
-  if (! target_has_execution)
+  if (! target_has_execution ())
     {
       const char *name = get_function_name (funaddr,
                                            name_buf, sizeof (name_buf));
@@ -1363,8 +1374,8 @@ When the function is done executing, GDB will silently stop."),
       discard_infcall_control_state (inf_status.release ());
 
       /* We could discard the dummy frame here given that the program exited,
-         but it will get garbage collected the next time the program is
-         run anyway.  */
+        but it will get garbage collected the next time the program is
+        run anyway.  */
 
       error (_("The program being debugged exited while in a function "
               "called from GDB.\n"