]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
displaced step: pass down target_waitstatus instead of gdb_signal
authorPedro Alves <pedro@palves.net>
Tue, 22 Jun 2021 14:42:51 +0000 (15:42 +0100)
committerPedro Alves <pedro@palves.net>
Thu, 9 Mar 2023 15:31:07 +0000 (15:31 +0000)
This commit tweaks displaced_step_finish & friends to pass down a
target_waitstatus instead of a gdb_signal.  This is needed because a
patch later in the series will want to make
displaced_step_buffers::finish handle TARGET_WAITKIND_THREAD_EXITED.
It also helps with the TARGET_WAITKIND_THREAD_CLONED patch later in
the series.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27338
Change-Id: I4c5d338647b028071bc498c4e47063795a2db4c0

gdb/displaced-stepping.c
gdb/displaced-stepping.h
gdb/gdbarch-gen.h
gdb/gdbarch.c
gdb/gdbarch_components.py
gdb/infrun.c
gdb/linux-tdep.c
gdb/linux-tdep.h
gdb/rs6000-tdep.c

index 06b32a80f6a0ec54284aff2ddd456ea1e2625ecf..08ae1ce4397580c1f021d3b981af5174c3fed564 100644 (file)
@@ -192,12 +192,18 @@ write_memory_ptid (ptid_t ptid, CORE_ADDR memaddr,
 }
 
 static bool
-displaced_step_instruction_executed_successfully (gdbarch *arch,
-                                                 gdb_signal signal)
+displaced_step_instruction_executed_successfully
+  (gdbarch *arch, const target_waitstatus &status)
 {
-  if (signal != GDB_SIGNAL_TRAP)
+  if (status.kind () == TARGET_WAITKIND_STOPPED
+      && status.sig () != GDB_SIGNAL_TRAP)
     return false;
 
+  /* All other (thread event) waitkinds can only happen if the
+     instruction fully executed.  For example, a fork, or a syscall
+     entry can only happen if the syscall instruction actually
+     executed.  */
+
   if (target_stopped_by_watchpoint ())
     {
       if (gdbarch_have_nonsteppable_watchpoint (arch)
@@ -210,7 +216,7 @@ displaced_step_instruction_executed_successfully (gdbarch *arch,
 
 displaced_step_finish_status
 displaced_step_buffers::finish (gdbarch *arch, thread_info *thread,
-                               gdb_signal sig)
+                               const target_waitstatus &status)
 {
   gdb_assert (thread->displaced_step_state.in_progress ());
 
@@ -256,7 +262,7 @@ displaced_step_buffers::finish (gdbarch *arch, thread_info *thread,
   regcache *rc = get_thread_regcache (thread);
 
   bool instruction_executed_successfully
-    = displaced_step_instruction_executed_successfully (arch, sig);
+    = displaced_step_instruction_executed_successfully (arch, status);
 
   if (instruction_executed_successfully)
     {
index e154927ad92978dd2302dee0ec828a0826c3d60b..d2c3fc1b2b451666fbcd689bb106f2709bb50957 100644 (file)
@@ -168,7 +168,7 @@ struct displaced_step_buffers
                                         CORE_ADDR &displaced_pc);
 
   displaced_step_finish_status finish (gdbarch *arch, thread_info *thread,
-                                      gdb_signal sig);
+                                      const target_waitstatus &status);
 
   const displaced_step_copy_insn_closure *
     copy_insn_closure_by_addr (CORE_ADDR addr);
index ddb97f60315f515487dea21fc4c58087a4f395b5..5805dcb75ef79a8c99eed5b002b5904e6fac0c83 100644 (file)
@@ -1103,8 +1103,8 @@ extern void set_gdbarch_displaced_step_prepare (struct gdbarch *gdbarch, gdbarch
 
 /* Clean up after a displaced step of THREAD. */
 
-typedef displaced_step_finish_status (gdbarch_displaced_step_finish_ftype) (struct gdbarch *gdbarch, thread_info *thread, gdb_signal sig);
-extern displaced_step_finish_status gdbarch_displaced_step_finish (struct gdbarch *gdbarch, thread_info *thread, gdb_signal sig);
+typedef displaced_step_finish_status (gdbarch_displaced_step_finish_ftype) (struct gdbarch *gdbarch, thread_info *thread, const target_waitstatus &ws);
+extern displaced_step_finish_status gdbarch_displaced_step_finish (struct gdbarch *gdbarch, thread_info *thread, const target_waitstatus &ws);
 extern void set_gdbarch_displaced_step_finish (struct gdbarch *gdbarch, gdbarch_displaced_step_finish_ftype *displaced_step_finish);
 
 /* Return the closure associated to the displaced step buffer that is at ADDR. */
index 7e4e34d5aca08a8472f3d7271e56275971eabbbf..0b122a860557f82c8ec8bcccc9b2a04b88878314 100644 (file)
@@ -4096,13 +4096,13 @@ set_gdbarch_displaced_step_prepare (struct gdbarch *gdbarch,
 }
 
 displaced_step_finish_status
-gdbarch_displaced_step_finish (struct gdbarch *gdbarch, thread_info *thread, gdb_signal sig)
+gdbarch_displaced_step_finish (struct gdbarch *gdbarch, thread_info *thread, const target_waitstatus &ws)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->displaced_step_finish != NULL);
   if (gdbarch_debug >= 2)
     gdb_printf (gdb_stdlog, "gdbarch_displaced_step_finish called\n");
-  return gdbarch->displaced_step_finish (gdbarch, thread, sig);
+  return gdbarch->displaced_step_finish (gdbarch, thread, ws);
 }
 
 void
index caa65c334ecab49e37217acb0f65dee4c647c3af..8d72bff347e8181b97e9ed229a0d38d714616d49 100644 (file)
@@ -1878,7 +1878,7 @@ Clean up after a displaced step of THREAD.
 """,
     type="displaced_step_finish_status",
     name="displaced_step_finish",
-    params=[("thread_info *", "thread"), ("gdb_signal", "sig")],
+    params=[("thread_info *", "thread"), ("const target_waitstatus &", "ws")],
     predefault="NULL",
     invalid="(! gdbarch->displaced_step_finish) != (! gdbarch->displaced_step_prepare)",
 )
index ab77300f1ff05f1f3e9864ebd4dd75a7253a0ff2..99f2a8e039d628a126efb4179233c62976b869d4 100644 (file)
@@ -1895,7 +1895,8 @@ displaced_step_prepare (thread_info *thread)
    DISPLACED_STEP_FINISH_STATUS_OK as well.  */
 
 static displaced_step_finish_status
-displaced_step_finish (thread_info *event_thread, enum gdb_signal signal)
+displaced_step_finish (thread_info *event_thread,
+                      const target_waitstatus &event_status)
 {
   displaced_step_thread_state *displaced = &event_thread->displaced_step_state;
 
@@ -1917,7 +1918,7 @@ displaced_step_finish (thread_info *event_thread, enum gdb_signal signal)
   /* Do the fixup, and release the resources acquired to do the displaced
      step. */
   return gdbarch_displaced_step_finish (displaced->get_original_gdbarch (),
-                                       event_thread, signal);
+                                       event_thread, event_status);
 }
 
 /* Data to be passed around while handling an event.  This data is
@@ -5122,7 +5123,7 @@ handle_one (const wait_one_event &event)
          /* We caught the event that we intended to catch, so
             there's no event to save as pending.  */
 
-         if (displaced_step_finish (t, GDB_SIGNAL_0)
+         if (displaced_step_finish (t, event.ws)
              == DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
            {
              /* Add it back to the step-over queue.  */
@@ -5137,7 +5138,6 @@ handle_one (const wait_one_event &event)
        }
       else
        {
-         enum gdb_signal sig;
          struct regcache *regcache;
 
          infrun_debug_printf
@@ -5148,10 +5148,7 @@ handle_one (const wait_one_event &event)
          /* Record for later.  */
          save_waitstatus (t, event.ws);
 
-         sig = (event.ws.kind () == TARGET_WAITKIND_STOPPED
-                ? event.ws.sig () : GDB_SIGNAL_0);
-
-         if (displaced_step_finish (t, sig)
+         if (displaced_step_finish (t, event.ws)
              == DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
            {
              /* Add it back to the step-over queue.  */
@@ -5753,7 +5750,7 @@ handle_inferior_event (struct execution_control_state *ecs)
               has been done.  Perform cleanup for parent process here.  Note
               that this operation also cleans up the child process for vfork,
               because their pages are shared.  */
-           displaced_step_finish (ecs->event_thread, GDB_SIGNAL_TRAP);
+           displaced_step_finish (ecs->event_thread, ecs->ws);
            /* Start a new step-over in another thread if there's one
               that needs it.  */
            start_step_over ();
@@ -6118,7 +6115,7 @@ resumed_thread_with_pending_status (struct thread_info *tp,
 static int
 finish_step_over (struct execution_control_state *ecs)
 {
-  displaced_step_finish (ecs->event_thread, ecs->event_thread->stop_signal ());
+  displaced_step_finish (ecs->event_thread, ecs->ws);
 
   bool had_step_over_info = step_over_info_valid_p ();
 
index e6ce13a1c672d4f326a6d5df9609d03d38f61ff2..036ea9f931d8c0e91d2fb1017db25ec616e7f425 100644 (file)
@@ -2621,13 +2621,14 @@ linux_displaced_step_prepare (gdbarch *arch, thread_info *thread,
 /* See linux-tdep.h.  */
 
 displaced_step_finish_status
-linux_displaced_step_finish (gdbarch *arch, thread_info *thread, gdb_signal sig)
+linux_displaced_step_finish (gdbarch *arch, thread_info *thread,
+                            const target_waitstatus &status)
 {
   linux_info *per_inferior = get_linux_inferior_data (thread->inf);
 
   gdb_assert (per_inferior->disp_step_bufs.has_value ());
 
-  return per_inferior->disp_step_bufs->finish (arch, thread, sig);
+  return per_inferior->disp_step_bufs->finish (arch, thread, status);
 }
 
 /* See linux-tdep.h.  */
index 16e1b806b26ee131d277426154266db7af526e53..e09a6ef32b1cf71efb8786ede4c6f28ae059ca05 100644 (file)
@@ -72,7 +72,7 @@ extern displaced_step_prepare_status linux_displaced_step_prepare
 /* Implementation of gdbarch_displaced_step_finish.  */
 
 extern displaced_step_finish_status linux_displaced_step_finish
-  (gdbarch *arch, thread_info *thread, gdb_signal sig);
+  (gdbarch *arch, thread_info *thread, const target_waitstatus &status);
 
 /* Implementation of gdbarch_displaced_step_copy_insn_closure_by_addr.  */
 
index 104515de030127c8dfa25b471f4743b4d34628b9..f9bbc435184ffac8997814689561fae329a132e7 100644 (file)
@@ -1088,13 +1088,13 @@ ppc_displaced_step_prepare  (gdbarch *arch, thread_info *thread,
 
 static displaced_step_finish_status
 ppc_displaced_step_finish (gdbarch *arch, thread_info *thread,
-                          gdb_signal sig)
+                          const target_waitstatus &status)
 {
   ppc_inferior_data *per_inferior = get_ppc_per_inferior (thread->inf);
 
   gdb_assert (per_inferior->disp_step_buf.has_value ());
 
-  return per_inferior->disp_step_buf->finish (arch, thread, sig);
+  return per_inferior->disp_step_buf->finish (arch, thread, status);
 }
 
 /* Implementation of gdbarch_displaced_step_restore_all_in_ptid.  */