/* 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.
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.
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);
}
}
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;
}
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;
}
{
/* 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;
}
*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;
}
/* 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;
}
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;
}
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;
{
/* 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;
}
{
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));
}
}
}
{
/* 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;
}
{
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));
}
}
*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;
}
}
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));
}
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
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
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);
}
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
{
{
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)
{
{
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));
}
}
}
{
/* 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));
}
}
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;
}
}
}
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
{
/* 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));
}
}
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;
}
}
}
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. */