gdbserver: Eliminate prepare_to_access_memory

Given:

 - The prepare_to_access_memory machinery was added for non-stop mode.

 - Only Linux supports non-stop.

 - Linux no longer needs the prepare_to_access_memory machinery.  In
   fact, after the previous patch,
   linux_process_target::prepare_to_access_memory became a nop.

Thus, prepare_to_access_memory can go away, simplifying core GDBserver
code.

Change-Id: I93ac8bfe66bd61c3d1c4a0e7d419335163120ecf
This commit is contained in:
Pedro Alves 2022-03-29 13:32:48 +01:00
parent 421490af33
commit 8e347faf8f
5 changed files with 24 additions and 235 deletions

View File

@ -1000,13 +1000,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
@ -1074,110 +1080,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

View File

@ -1067,19 +1067,12 @@ gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
/* (assume no half-trace half-real blocks for now) */
}
res = prepare_to_access_memory ();
if (res == 0)
{
if (set_desired_thread ())
res = read_inferior_memory (memaddr, myaddr, len);
else
res = 1;
done_accessing_memory ();
return res == 0 ? len : -1;
}
if (set_desired_thread ())
res = read_inferior_memory (memaddr, myaddr, len);
else
return -1;
res = 1;
return res == 0 ? len : -1;
}
/* Write trace frame or inferior memory. Actually, writing to trace
@ -1095,15 +1088,10 @@ gdb_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
{
int ret;
ret = prepare_to_access_memory ();
if (ret == 0)
{
if (set_desired_thread ())
ret = target_write_memory (memaddr, myaddr, len);
else
ret = EIO;
done_accessing_memory ();
}
if (set_desired_thread ())
ret = target_write_memory (memaddr, myaddr, len);
else
ret = EIO;
return ret;
}
}

View File

@ -39,88 +39,6 @@ set_desired_thread ()
return (current_thread != NULL);
}
/* The thread that was current before prepare_to_access_memory was
called. done_accessing_memory uses this to restore the previous
selected thread. */
static ptid_t prev_general_thread;
/* See target.h. */
int
prepare_to_access_memory (void)
{
client_state &cs = get_client_state ();
/* The first thread found. */
struct thread_info *first = NULL;
/* The first stopped thread found. */
struct thread_info *stopped = NULL;
/* The current general thread, if found. */
struct thread_info *current = NULL;
/* Save the general thread value, since prepare_to_access_memory could change
it. */
prev_general_thread = cs.general_thread;
int res = the_target->prepare_to_access_memory ();
if (res != 0)
return res;
for_each_thread (prev_general_thread.pid (), [&] (thread_info *thread)
{
if (mythread_alive (thread->id))
{
if (stopped == NULL && the_target->supports_thread_stopped ()
&& target_thread_stopped (thread))
stopped = thread;
if (first == NULL)
first = thread;
if (current == NULL && prev_general_thread == thread->id)
current = thread;
}
});
/* The thread we end up choosing. */
struct thread_info *thread;
/* Prefer a stopped thread. If none is found, try the current
thread. Otherwise, take the first thread in the process. If
none is found, undo the effects of
target->prepare_to_access_memory() and return error. */
if (stopped != NULL)
thread = stopped;
else if (current != NULL)
thread = current;
else if (first != NULL)
thread = first;
else
{
done_accessing_memory ();
return 1;
}
switch_to_thread (thread);
cs.general_thread = ptid_of (thread);
return 0;
}
/* See target.h. */
void
done_accessing_memory (void)
{
client_state &cs = get_client_state ();
the_target->done_accessing_memory ();
/* Restore the previous selected thread. */
cs.general_thread = prev_general_thread;
switch_to_thread (the_target, cs.general_thread);
}
int
read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
@ -373,18 +291,6 @@ process_stratum_target::post_create_inferior ()
/* Nop. */
}
int
process_stratum_target::prepare_to_access_memory ()
{
return 0;
}
void
process_stratum_target::done_accessing_memory ()
{
/* Nop. */
}
void
process_stratum_target::look_up_symbols ()
{

View File

@ -141,21 +141,6 @@ public:
If REGNO is -1, store all registers; otherwise, store at least REGNO. */
virtual void store_registers (regcache *regcache, int regno) = 0;
/* Prepare to read or write memory from the inferior process.
Targets use this to do what is necessary to get the state of the
inferior such that it is possible to access memory.
This should generally only be called from client facing routines,
such as gdb_read_memory/gdb_write_memory, or the GDB breakpoint
insertion routine.
Like `read_memory' and `write_memory' below, returns 0 on success
and errno on failure. */
virtual int prepare_to_access_memory ();
/* Undo the effects of prepare_to_access_memory. */
virtual void done_accessing_memory ();
/* Read memory from the inferior process. This should generally be
called through read_inferior_memory, which handles breakpoint shadowing.
@ -691,12 +676,6 @@ target_read_btrace_conf (struct btrace_target_info *tinfo,
ptid_t mywait (ptid_t ptid, struct target_waitstatus *ourstatus,
target_wait_flags options, int connected_wait);
/* Prepare to read or write memory from the inferior process. See the
corresponding process_stratum_target methods for more details. */
int prepare_to_access_memory (void);
void done_accessing_memory (void);
#define target_core_of_thread(ptid) \
the_target->core_of_thread (ptid)

View File

@ -2784,21 +2784,10 @@ cmd_qtenable_disable (char *own_buf, int enable)
if (tp->type == fast_tracepoint || tp->type == static_tracepoint)
{
int ret;
int offset = offsetof (struct tracepoint, enabled);
CORE_ADDR obj_addr = tp->obj_addr_on_target + offset;
ret = prepare_to_access_memory ();
if (ret)
{
trace_debug ("Failed to temporarily stop inferior threads");
write_enn (own_buf);
return;
}
ret = write_inferior_int8 (obj_addr, enable);
done_accessing_memory ();
int ret = write_inferior_int8 (obj_addr, enable);
if (ret)
{
trace_debug ("Cannot write enabled flag into "