Handle array- and string-like values in no-op pretty printers
[binutils-gdb.git] / gdbserver / mem-break.cc
index 1b6f236581465f7d4907f03724b15ce556a49f62..897b9a2273c721b849a2f9f176aa0b7ac971988c 100644 (file)
@@ -1,5 +1,5 @@
 /* Memory breakpoint operations for the remote server for GDB.
-   Copyright (C) 2002-2020 Free Software Foundation, Inc.
+   Copyright (C) 2002-2023 Free Software Foundation, Inc.
 
    Contributed by MontaVista Software.
 
@@ -70,7 +70,7 @@
    software breakpoints, a buffer holding a copy of the instructions
    that would be in memory had not been a breakpoint there (we call
    that the shadow memory of the breakpoint).  We occasionally need to
-   temporarilly uninsert a breakpoint without the client knowing about
+   temporarily uninsert a breakpoint without the client knowing about
    it (e.g., to step over an internal breakpoint), so we keep an
    `inserted' state associated with this low level breakpoint
    structure.  There can only be one such object for a given address.
@@ -253,8 +253,7 @@ raw_bkpt_type_to_target_hw_bp_type (enum raw_bkpt_type raw_type)
     case raw_bkpt_type_access_wp:
       return hw_access;
     default:
-      internal_error (__FILE__, __LINE__,
-                     "bad raw breakpoint type %d", (int) raw_type);
+      internal_error ("bad raw breakpoint type %d", (int) raw_type);
     }
 }
 
@@ -371,23 +370,19 @@ insert_memory_breakpoint (struct raw_breakpoint *bp)
   err = read_inferior_memory (bp->pc, buf, bp_size (bp));
   if (err != 0)
     {
-      if (debug_threads)
-       debug_printf ("Failed to read shadow memory of"
-                     " breakpoint at 0x%s (%s).\n",
-                     paddress (bp->pc), safe_strerror (err));
+      threads_debug_printf ("Failed to read shadow memory of"
+                           " breakpoint at 0x%s (%s).",
+                           paddress (bp->pc), safe_strerror (err));
     }
   else
     {
       memcpy (bp->old_data, buf, bp_size (bp));
 
-      err = (*the_target->write_memory) (bp->pc, bp_opcode (bp),
-                                        bp_size (bp));
+      err = the_target->write_memory (bp->pc, bp_opcode (bp),
+                                     bp_size (bp));
       if (err != 0)
-       {
-         if (debug_threads)
-           debug_printf ("Failed to insert breakpoint at 0x%s (%s).\n",
-                         paddress (bp->pc), safe_strerror (err));
-       }
+       threads_debug_printf ("Failed to insert breakpoint at 0x%s (%s).",
+                             paddress (bp->pc), safe_strerror (err));
     }
   return err != 0 ? -1 : 0;
 }
@@ -411,12 +406,10 @@ remove_memory_breakpoint (struct raw_breakpoint *bp)
   memcpy (buf, bp->old_data, bp_size (bp));
   err = target_write_memory (bp->pc, buf, bp_size (bp));
   if (err != 0)
-    {
-      if (debug_threads)
-       debug_printf ("Failed to uninsert raw breakpoint "
-                     "at 0x%s (%s) while deleting it.\n",
-                     paddress (bp->pc), safe_strerror (err));
-    }
+      threads_debug_printf ("Failed to uninsert raw breakpoint "
+                           "at 0x%s (%s) while deleting it.",
+                           paddress (bp->pc), safe_strerror (err));
+
   return err != 0 ? -1 : 0;
 }
 
@@ -438,9 +431,9 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int kind,
        {
          /* A different kind than previously seen.  The previous
             breakpoint must be gone then.  */
-         if (debug_threads)
-           debug_printf ("Inconsistent breakpoint kind?  Was %d, now %d.\n",
-                         bp->kind, kind);
+         threads_debug_printf
+           ("Inconsistent breakpoint kind?  Was %d, now %d.",
+            bp->kind, kind);
          bp->inserted = -1;
          bp = NULL;
        }
@@ -463,9 +456,8 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int kind,
       *err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
       if (*err != 0)
        {
-         if (debug_threads)
-           debug_printf ("Failed to insert breakpoint at 0x%s (%d).\n",
-                         paddress (where), *err);
+         threads_debug_printf ("Failed to insert breakpoint at 0x%s (%d).",
+                               paddress (where), *err);
 
          return NULL;
        }
@@ -594,10 +586,10 @@ delete_fast_tracepoint_jump (struct fast_tracepoint_jump *todel)
                  /* Something went wrong, relink the jump.  */
                  *bp_link = prev_bp_link;
 
-                 if (debug_threads)
-                   debug_printf ("Failed to uninsert fast tracepoint jump "
-                                 "at 0x%s (%s) while deleting it.\n",
-                                 paddress (bp->pc), safe_strerror (ret));
+                 threads_debug_printf
+                   ("Failed to uninsert fast tracepoint jump "
+                    "at 0x%s (%s) while deleting it.",
+                    paddress (bp->pc), safe_strerror (ret));
                  return ret;
                }
 
@@ -657,10 +649,9 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   err = read_inferior_memory (where, buf, length);
   if (err != 0)
     {
-      if (debug_threads)
-       debug_printf ("Failed to read shadow memory of"
-                     " fast tracepoint at 0x%s (%s).\n",
-                     paddress (where), safe_strerror (err));
+      threads_debug_printf ("Failed to read shadow memory of"
+                           " fast tracepoint at 0x%s (%s).",
+                           paddress (where), safe_strerror (err));
       free (jp);
       return NULL;
     }
@@ -682,9 +673,9 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   err = target_write_memory (where, buf, length);
   if (err != 0)
     {
-      if (debug_threads)
-       debug_printf ("Failed to insert fast tracepoint jump at 0x%s (%s).\n",
-                     paddress (where), safe_strerror (err));
+      threads_debug_printf
+       ("Failed to insert fast tracepoint jump at 0x%s (%s).",
+        paddress (where), safe_strerror (err));
 
       /* Unlink it.  */
       proc->fast_tracepoint_jumps = jp->next;
@@ -707,10 +698,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
     {
       /* This can happen when we remove all breakpoints while handling
         a step-over.  */
-      if (debug_threads)
-       debug_printf ("Could not find fast tracepoint jump at 0x%s "
-                     "in list (uninserting).\n",
-                     paddress (pc));
+      threads_debug_printf ("Could not find fast tracepoint jump at 0x%s "
+                           "in list (uninserting).",
+                           paddress (pc));
       return;
     }
 
@@ -736,10 +726,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
        {
          jp->inserted = 1;
 
-         if (debug_threads)
-           debug_printf ("Failed to uninsert fast tracepoint jump at"
-                         " 0x%s (%s).\n",
-                         paddress (pc), safe_strerror (err));
+         threads_debug_printf ("Failed to uninsert fast tracepoint jump at"
+                               " 0x%s (%s).",
+                               paddress (pc), safe_strerror (err));
        }
     }
 }
@@ -756,10 +745,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
     {
       /* This can happen when we remove breakpoints when a tracepoint
         hit causes a tracing stop, while handling a step-over.  */
-      if (debug_threads)
-       debug_printf ("Could not find fast tracepoint jump at 0x%s "
-                     "in list (reinserting).\n",
-                     paddress (where));
+      threads_debug_printf ("Could not find fast tracepoint jump at 0x%s "
+                           "in list (reinserting).",
+                           paddress (where));
       return;
     }
 
@@ -783,10 +771,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
     {
       jp->inserted = 0;
 
-      if (debug_threads)
-       debug_printf ("Failed to reinsert fast tracepoint jump at"
-                     " 0x%s (%s).\n",
-                     paddress (where), safe_strerror (err));
+      threads_debug_printf ("Failed to reinsert fast tracepoint jump at"
+                           " 0x%s (%s).",
+                           paddress (where), safe_strerror (err));
     }
 }
 
@@ -890,17 +877,16 @@ delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
 
              *bp_link = bp->next;
 
-             ret = the_target->remove_point (bp->raw_type, bp->pc, bp->kind,
-                                             bp);
+             ret = the_target->remove_point (bp->raw_type, bp->pc,
+                                             bp->kind, bp);
              if (ret != 0)
                {
                  /* Something went wrong, relink the breakpoint.  */
                  *bp_link = prev_bp_link;
 
-                 if (debug_threads)
-                   debug_printf ("Failed to uninsert raw breakpoint "
-                                 "at 0x%s while deleting it.\n",
-                                 paddress (bp->pc));
+                 threads_debug_printf ("Failed to uninsert raw breakpoint "
+                                       "at 0x%s while deleting it.",
+                                       paddress (bp->pc));
                  return ret;
                }
            }
@@ -1005,7 +991,6 @@ static int
 z_type_supported (char z_type)
 {
   return (z_type >= '0' && z_type <= '4'
-         && the_target->supports_z_point_type != NULL
          && the_target->supports_z_point_type (z_type));
 }
 
@@ -1014,13 +999,19 @@ z_type_supported (char z_type)
    failure returns NULL and sets *ERR to either -1 for error, or 1 if
    Z_TYPE breakpoints are not supported on this target.  */
 
-static struct gdb_breakpoint *
-set_gdb_breakpoint_1 (char z_type, CORE_ADDR addr, int kind, int *err)
+struct gdb_breakpoint *
+set_gdb_breakpoint (char z_type, CORE_ADDR addr, int kind, int *err)
 {
   struct gdb_breakpoint *bp;
   enum bkpt_type type;
   enum raw_bkpt_type raw_type;
 
+  if (!z_type_supported (z_type))
+    {
+      *err = 1;
+      return nullptr;
+    }
+
   /* If we see GDB inserting a second code breakpoint at the same
      address, then either: GDB is updating the breakpoint's conditions
      or commands; or, the first breakpoint must have disappeared due
@@ -1088,110 +1079,31 @@ set_gdb_breakpoint_1 (char z_type, CORE_ADDR addr, int kind, int *err)
                                                   kind, NULL, err);
 }
 
-static int
-check_gdb_bp_preconditions (char z_type, int *err)
-{
-  /* As software/memory breakpoints work by poking at memory, we need
-     to prepare to access memory.  If that operation fails, we need to
-     return error.  Seeing an error, if this is the first breakpoint
-     of that type that GDB tries to insert, GDB would then assume the
-     breakpoint type is supported, but it may actually not be.  So we
-     need to check whether the type is supported at all before
-     preparing to access memory.  */
-  if (!z_type_supported (z_type))
-    {
-      *err = 1;
-      return 0;
-    }
-
-  return 1;
-}
-
-/* See mem-break.h.  This is a wrapper for set_gdb_breakpoint_1 that
-   knows to prepare to access memory for Z0 breakpoints.  */
-
-struct gdb_breakpoint *
-set_gdb_breakpoint (char z_type, CORE_ADDR addr, int kind, int *err)
-{
-  struct gdb_breakpoint *bp;
-
-  if (!check_gdb_bp_preconditions (z_type, err))
-    return NULL;
-
-  /* If inserting a software/memory breakpoint, need to prepare to
-     access memory.  */
-  if (z_type == Z_PACKET_SW_BP)
-    {
-      if (prepare_to_access_memory () != 0)
-       {
-         *err = -1;
-         return NULL;
-       }
-    }
-
-  bp = set_gdb_breakpoint_1 (z_type, addr, kind, err);
-
-  if (z_type == Z_PACKET_SW_BP)
-    done_accessing_memory ();
-
-  return bp;
-}
-
 /* Delete a GDB breakpoint of type Z_TYPE and kind KIND previously
    inserted at ADDR with set_gdb_breakpoint_at.  Returns 0 on success,
    -1 on error, and 1 if Z_TYPE breakpoints are not supported on this
    target.  */
 
-static int
-delete_gdb_breakpoint_1 (char z_type, CORE_ADDR addr, int kind)
+int
+delete_gdb_breakpoint (char z_type, CORE_ADDR addr, int kind)
 {
-  struct gdb_breakpoint *bp;
-  int err;
+  if (!z_type_supported (z_type))
+    return 1;
 
-  bp = find_gdb_breakpoint (z_type, addr, kind);
+  gdb_breakpoint *bp = find_gdb_breakpoint (z_type, addr, kind);
   if (bp == NULL)
     return -1;
 
   /* Before deleting the breakpoint, make sure to free its condition
      and command lists.  */
   clear_breakpoint_conditions_and_commands (bp);
-  err = delete_breakpoint ((struct breakpoint *) bp);
+  int err = delete_breakpoint ((struct breakpoint *) bp);
   if (err != 0)
     return -1;
 
   return 0;
 }
 
-/* See mem-break.h.  This is a wrapper for delete_gdb_breakpoint that
-   knows to prepare to access memory for Z0 breakpoints.  */
-
-int
-delete_gdb_breakpoint (char z_type, CORE_ADDR addr, int kind)
-{
-  int ret;
-
-  if (!check_gdb_bp_preconditions (z_type, &ret))
-    return ret;
-
-  /* If inserting a software/memory breakpoint, need to prepare to
-     access memory.  */
-  if (z_type == Z_PACKET_SW_BP)
-    {
-      int err;
-
-      err = prepare_to_access_memory ();
-      if (err != 0)
-       return -1;
-    }
-
-  ret = delete_gdb_breakpoint_1 (z_type, addr, kind);
-
-  if (z_type == Z_PACKET_SW_BP)
-    done_accessing_memory ();
-
-  return ret;
-}
-
 /* Clear all conditions associated with a breakpoint.  */
 
 static void
@@ -1405,10 +1317,9 @@ gdb_no_commands_at_breakpoint_z_type (char z_type, CORE_ADDR addr)
   if (bp == NULL)
     return 1;
 
-  if (debug_threads)
-    debug_printf ("at 0x%s, type Z%c, bp command_list is 0x%s\n",
-                 paddress (addr), z_type,
-                 phex_nz ((uintptr_t) bp->command_list, 0));
+  threads_debug_printf ("at 0x%s, type Z%c, bp command_list is 0x%s",
+                       paddress (addr), z_type,
+                       phex_nz ((uintptr_t) bp->command_list, 0));
   return (bp->command_list == NULL);
 }
 
@@ -1502,13 +1413,12 @@ delete_single_step_breakpoints (struct thread_info *thread)
       if (bp->type == single_step_breakpoint
          && ((struct single_step_breakpoint *) bp)->ptid == ptid_of (thread))
        {
-         struct thread_info *saved_thread = current_thread;
+         scoped_restore_current_thread restore_thread;
 
-         current_thread = thread;
+         switch_to_thread (thread);
          *bp_link = bp->next;
          release_breakpoint (proc, bp);
          bp = *bp_link;
-         current_thread = saved_thread;
        }
       else
        {
@@ -1523,9 +1433,8 @@ uninsert_raw_breakpoint (struct raw_breakpoint *bp)
 {
   if (bp->inserted < 0)
     {
-      if (debug_threads)
-       debug_printf ("Breakpoint at %s is marked insert-disabled.\n",
-                     paddress (bp->pc));
+      threads_debug_printf ("Breakpoint at %s is marked insert-disabled.",
+                           paddress (bp->pc));
     }
   else if (bp->inserted > 0)
     {
@@ -1538,9 +1447,8 @@ uninsert_raw_breakpoint (struct raw_breakpoint *bp)
        {
          bp->inserted = 1;
 
-         if (debug_threads)
-           debug_printf ("Failed to uninsert raw breakpoint at 0x%s.\n",
-                         paddress (bp->pc));
+         threads_debug_printf ("Failed to uninsert raw breakpoint at 0x%s.",
+                               paddress (bp->pc));
        }
     }
 }
@@ -1567,10 +1475,9 @@ uninsert_breakpoints_at (CORE_ADDR pc)
     {
       /* This can happen when we remove all breakpoints while handling
         a step-over.  */
-      if (debug_threads)
-       debug_printf ("Could not find breakpoint at 0x%s "
-                     "in list (uninserting).\n",
-                     paddress (pc));
+      threads_debug_printf ("Could not find breakpoint at 0x%s "
+                           "in list (uninserting).",
+                           paddress (pc));
     }
 }
 
@@ -1604,11 +1511,10 @@ uninsert_single_step_breakpoints (struct thread_info *thread)
           reinsert breakpoint.  */
        if (bp->raw->refcount == 1)
          {
-           struct thread_info *saved_thread = current_thread;
+           scoped_restore_current_thread restore_thread;
 
-           current_thread = thread;
+           switch_to_thread (thread);
            uninsert_raw_breakpoint (bp->raw);
-           current_thread = saved_thread;
          }
       }
     }
@@ -1625,9 +1531,9 @@ reinsert_raw_breakpoint (struct raw_breakpoint *bp)
   err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
   if (err == 0)
     bp->inserted = 1;
-  else if (debug_threads)
-    debug_printf ("Failed to reinsert breakpoint at 0x%s (%d).\n",
-                 paddress (bp->pc), err);
+  else
+    threads_debug_printf ("Failed to reinsert breakpoint at 0x%s (%d).",
+                         paddress (bp->pc), err);
 }
 
 void
@@ -1651,10 +1557,9 @@ reinsert_breakpoints_at (CORE_ADDR pc)
     {
       /* This can happen when we remove all breakpoints while handling
         a step-over.  */
-      if (debug_threads)
-       debug_printf ("Could not find raw breakpoint at 0x%s "
-                     "in list (reinserting).\n",
-                     paddress (pc));
+      threads_debug_printf ("Could not find raw breakpoint at 0x%s "
+                           "in list (reinserting).",
+                           paddress (pc));
     }
 }
 
@@ -1710,11 +1615,10 @@ reinsert_single_step_breakpoints (struct thread_info *thread)
 
          if (bp->raw->refcount == 1)
            {
-             struct thread_info *saved_thread = current_thread;
+             scoped_restore_current_thread restore_thread;
 
-             current_thread = thread;
+             switch_to_thread (thread);
              reinsert_raw_breakpoint (bp->raw);
-             current_thread = saved_thread;
            }
        }
     }
@@ -1857,7 +1761,7 @@ validate_inserted_breakpoint (struct raw_breakpoint *bp)
   gdb_assert (bp->raw_type == raw_bkpt_type_sw);
 
   buf = (unsigned char *) alloca (bp_size (bp));
-  err = (*the_target->read_memory) (bp->pc, buf, bp_size (bp));
+  err = the_target->read_memory (bp->pc, buf, bp_size (bp));
   if (err || memcmp (buf, bp_opcode (bp), bp_size (bp)) != 0)
     {
       /* Tag it as gone.  */