gdb: make displaced stepping implementation capable of managing multiple buffers

The displaced_step_buffer class, introduced in the previous patch,
manages access to a single displaced step buffer.  Change it into
displaced_step_buffers (note the plural), which manages access to
multiple displaced step buffers.

When preparing a displaced step for a thread, it looks for an unused
buffer.

For now, all users still pass a single displaced step buffer, so no real
behavior change is expected here.  The following patch makes a user pass
more than one buffer, so the functionality introduced by this patch is
going to be useful in the next one.

gdb/ChangeLog:

	* displaced-stepping.h (struct displaced_step_buffer): Rename
	to...
	(struct displaced_step_buffers): ... this.
	<m_addr, m_current_thread, m_copy_insn_closure>: Remove.
	<struct displaced_step_buffer>: New inner class.
	<m_buffers>: New.
	* displaced-stepping.c (displaced_step_buffer::prepare): Rename
	to...
	(displaced_step_buffers::prepare): ... this, adjust for multiple
	buffers.
	(displaced_step_buffer::finish):  Rename to...
	(displaced_step_buffers::finish): ... this, adjust for multiple
	buffers.
	(displaced_step_buffer::copy_insn_closure_by_addr): Rename to...
	(displaced_step_buffers::copy_insn_closure_by_addr): ... this,
	adjust for multiple buffers.
	(displaced_step_buffer::restore_in_ptid): Rename to...
	(displaced_step_buffers::restore_in_ptid): ... this, adjust for
	multiple buffers.
	* linux-tdep.h (linux_init_abi): Change supports_displaced_step
	for num_disp_step_buffers.
	* linux-tdep.c (struct linux_gdbarch_data)
	<num_disp_step_buffers>: New field.
	(struct linux_info) <disp_step_buf>: Rename to...
	<disp_step_bufs>: ... this, change type to
	displaced_step_buffers.
	(linux_displaced_step_prepare): Use
	linux_gdbarch_data::num_disp_step_buffers to create that number
	of buffers.
	(linux_displaced_step_finish): Adjust.
	(linux_displaced_step_copy_insn_closure_by_addr): Adjust.
	(linux_displaced_step_restore_all_in_ptid): Adjust.
	(linux_init_abi): Change supports_displaced_step parameter for
	num_disp_step_buffers, save it in linux_gdbarch_data.
	* aarch64-linux-tdep.c (aarch64_linux_init_abi): Adjust.
	* alpha-linux-tdep.c (alpha_linux_init_abi): Adjust.
	* amd64-linux-tdep.c (amd64_linux_init_abi_common): Change
	supports_displaced_step parameter for num_disp_step_buffers.
	(amd64_linux_init_abi): Adjust.
	(amd64_x32_linux_init_abi): Adjust.
	* arc-linux-tdep.c (arc_linux_init_osabi): Adjust.
	* arm-linux-tdep.c (arm_linux_init_abi): Adjust.
	* bfin-linux-tdep.c (bfin_linux_init_abi): Adjust.
	* cris-linux-tdep.c (cris_linux_init_abi): Adjust.
	* csky-linux-tdep.c (csky_linux_init_abi): Adjust.
	* frv-linux-tdep.c (frv_linux_init_abi): Adjust.
	* hppa-linux-tdep.c (hppa_linux_init_abi): Adjust.
	* i386-linux-tdep.c (i386_linux_init_abi): Adjust.
	* ia64-linux-tdep.c (ia64_linux_init_abi): Adjust.
	* m32r-linux-tdep.c (m32r_linux_init_abi): Adjust.
	* m68k-linux-tdep.c (m68k_linux_init_abi):
	* microblaze-linux-tdep.c (microblaze_linux_init_abi):
	* mips-linux-tdep.c (mips_linux_init_abi): Adjust.
	* mn10300-linux-tdep.c (am33_linux_init_osabi): Adjust.
	* nios2-linux-tdep.c (nios2_linux_init_abi): Adjust.
	* or1k-linux-tdep.c (or1k_linux_init_abi): Adjust.
	* ppc-linux-tdep.c (ppc_linux_init_abi): Adjust.
	* riscv-linux-tdep.c (riscv_linux_init_abi): Adjust.
	* rs6000-tdep.c (struct ppc_inferior_data) <disp_step_buf>:
	Change type to displaced_step_buffers.
	* s390-linux-tdep.c (s390_linux_init_abi_any): Adjust.
	* sh-linux-tdep.c (sh_linux_init_abi): Adjust.
	* sparc-linux-tdep.c (sparc32_linux_init_abi): Adjust.
	* sparc64-linux-tdep.c (sparc64_linux_init_abi): Adjust.
	* tic6x-linux-tdep.c (tic6x_uclinux_init_abi): Adjust.
	* tilegx-linux-tdep.c (tilegx_linux_init_abi): Adjust.
	* xtensa-linux-tdep.c (xtensa_linux_init_abi): Adjust.

Change-Id: Ia9c02f207da2c9e1d9188020139619122392bb70
This commit is contained in:
Simon Marchi 2020-12-04 16:43:56 -05:00
parent d965505887
commit 480af54cf6
34 changed files with 295 additions and 126 deletions

View file

@ -166,9 +166,10 @@ enum
static struct gdbarch_data *linux_gdbarch_data_handle;
struct linux_gdbarch_data
{
struct type *siginfo_type;
};
{
struct type *siginfo_type;
int num_disp_step_buffers;
};
static void *
init_linux_gdbarch_data (struct obstack *obstack)
@ -200,8 +201,8 @@ struct linux_info
if we tried looking it up but failed. */
int vsyscall_range_p = 0;
/* Inferior's displaced step buffer. */
gdb::optional<displaced_step_buffer> disp_step_buf;
/* Inferior's displaced step buffers. */
gdb::optional<displaced_step_buffers> disp_step_bufs;
};
/* Per-inferior data key. */
@ -2540,15 +2541,25 @@ linux_displaced_step_prepare (gdbarch *arch, thread_info *thread,
{
linux_info *per_inferior = get_linux_inferior_data (thread->inf);
if (!per_inferior->disp_step_buf.has_value ())
if (!per_inferior->disp_step_bufs.has_value ())
{
/* Figure out the location of the buffers. They are contiguous, starting
at DISP_STEP_BUF_ADDR. They are all of size BUF_LEN. */
CORE_ADDR disp_step_buf_addr
= linux_displaced_step_location (thread->inf->gdbarch);
int buf_len = gdbarch_max_insn_length (arch);
per_inferior->disp_step_buf.emplace (disp_step_buf_addr);
linux_gdbarch_data *gdbarch_data = get_linux_gdbarch_data (arch);
gdb_assert (gdbarch_data->num_disp_step_buffers > 0);
std::vector<CORE_ADDR> buffers;
for (int i = 0; i < gdbarch_data->num_disp_step_buffers; i++)
buffers.push_back (disp_step_buf_addr + i * buf_len);
per_inferior->disp_step_bufs.emplace (buffers);
}
return per_inferior->disp_step_buf->prepare (thread, displaced_pc);
return per_inferior->disp_step_bufs->prepare (thread, displaced_pc);
}
/* See linux-tdep.h. */
@ -2558,9 +2569,9 @@ linux_displaced_step_finish (gdbarch *arch, thread_info *thread, gdb_signal sig)
{
linux_info *per_inferior = get_linux_inferior_data (thread->inf);
gdb_assert (per_inferior->disp_step_buf.has_value ());
gdb_assert (per_inferior->disp_step_bufs.has_value ());
return per_inferior->disp_step_buf->finish (arch, thread, sig);
return per_inferior->disp_step_bufs->finish (arch, thread, sig);
}
/* See linux-tdep.h. */
@ -2571,10 +2582,10 @@ linux_displaced_step_copy_insn_closure_by_addr (inferior *inf, CORE_ADDR addr)
linux_info *per_inferior = linux_inferior_data.get (inf);
if (per_inferior == nullptr
|| !per_inferior->disp_step_buf.has_value ())
|| !per_inferior->disp_step_bufs.has_value ())
return nullptr;
return per_inferior->disp_step_buf->copy_insn_closure_by_addr (addr);
return per_inferior->disp_step_bufs->copy_insn_closure_by_addr (addr);
}
/* See linux-tdep.h. */
@ -2585,10 +2596,10 @@ linux_displaced_step_restore_all_in_ptid (inferior *parent_inf, ptid_t ptid)
linux_info *per_inferior = linux_inferior_data.get (parent_inf);
if (per_inferior == nullptr
|| !per_inferior->disp_step_buf.has_value ())
|| !per_inferior->disp_step_bufs.has_value ())
return;
per_inferior->disp_step_buf->restore_in_ptid (ptid);
per_inferior->disp_step_bufs->restore_in_ptid (ptid);
}
/* See linux-tdep.h. */
@ -2636,15 +2647,22 @@ show_dump_excluded_mappings (struct ui_file *file, int from_tty,
}
/* To be called from the various GDB_OSABI_LINUX handlers for the
various GNU/Linux architectures and machine types. */
various GNU/Linux architectures and machine types.
NUM_DISP_STEP_BUFFERS is the number of displaced step buffers to use. If 0,
displaced stepping is not supported. */
void
linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
bool supports_displaced_step)
int num_disp_step_buffers)
{
if (supports_displaced_step)
if (num_disp_step_buffers > 0)
{
set_gdbarch_displaced_step_prepare (gdbarch, linux_displaced_step_prepare);
linux_gdbarch_data *gdbarch_data = get_linux_gdbarch_data (gdbarch);
gdbarch_data->num_disp_step_buffers = num_disp_step_buffers;
set_gdbarch_displaced_step_prepare (gdbarch,
linux_displaced_step_prepare);
set_gdbarch_displaced_step_finish (gdbarch, linux_displaced_step_finish);
set_gdbarch_displaced_step_copy_insn_closure_by_addr
(gdbarch, linux_displaced_step_copy_insn_closure_by_addr);