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:
parent
d965505887
commit
480af54cf6
34 changed files with 295 additions and 126 deletions
|
@ -1,3 +1,73 @@
|
||||||
|
2020-12-04 Simon Marchi <simon.marchi@efficios.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2020-12-04 Simon Marchi <simon.marchi@efficios.com>
|
2020-12-04 Simon Marchi <simon.marchi@efficios.com>
|
||||||
|
|
||||||
* linux-tdep.c (init_linux_gdbarch_data): Change parameter to
|
* linux-tdep.c (init_linux_gdbarch_data): Change parameter to
|
||||||
|
|
|
@ -1445,7 +1445,7 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
|
|
||||||
tdep->lowest_pc = 0x8000;
|
tdep->lowest_pc = 0x8000;
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, true);
|
linux_init_abi (info, gdbarch, 1);
|
||||||
|
|
||||||
set_solib_svr4_fetch_link_map_offsets (gdbarch,
|
set_solib_svr4_fetch_link_map_offsets (gdbarch,
|
||||||
svr4_lp64_fetch_link_map_offsets);
|
svr4_lp64_fetch_link_map_offsets);
|
||||||
|
|
|
@ -356,7 +356,7 @@ alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep;
|
struct gdbarch_tdep *tdep;
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Hook into the DWARF CFI frame unwinder. */
|
/* Hook into the DWARF CFI frame unwinder. */
|
||||||
alpha_dwarf2_init_abi (info, gdbarch);
|
alpha_dwarf2_init_abi (info, gdbarch);
|
||||||
|
|
|
@ -1796,11 +1796,11 @@ amd64_dtrace_parse_probe_argument (struct gdbarch *gdbarch,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch,
|
amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch,
|
||||||
bool supports_displaced_step)
|
int num_disp_step_buffers)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, supports_displaced_step);
|
linux_init_abi (info, gdbarch, num_disp_step_buffers);
|
||||||
|
|
||||||
tdep->sigtramp_p = amd64_linux_sigtramp_p;
|
tdep->sigtramp_p = amd64_linux_sigtramp_p;
|
||||||
tdep->sigcontext_addr = amd64_linux_sigcontext_addr;
|
tdep->sigcontext_addr = amd64_linux_sigcontext_addr;
|
||||||
|
@ -1880,7 +1880,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
if (!valid_p)
|
if (!valid_p)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
amd64_linux_init_abi_common (info, gdbarch, true);
|
amd64_linux_init_abi_common (info, gdbarch, 1);
|
||||||
|
|
||||||
/* Initialize the amd64_linux_record_tdep. */
|
/* Initialize the amd64_linux_record_tdep. */
|
||||||
/* These values are the size of the type that will be used in a system
|
/* These values are the size of the type that will be used in a system
|
||||||
|
@ -2095,7 +2095,7 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
if (!valid_p)
|
if (!valid_p)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
amd64_linux_init_abi_common (info, gdbarch, false);
|
amd64_linux_init_abi_common (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Initialize the amd64_x32_linux_record_tdep. */
|
/* Initialize the amd64_x32_linux_record_tdep. */
|
||||||
/* These values are the size of the type that will be used in a system
|
/* These values are the size of the type that will be used in a system
|
||||||
|
|
|
@ -439,7 +439,7 @@ arc_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
*/
|
*/
|
||||||
tdep->jb_pc = 15;
|
tdep->jb_pc = 15;
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Set up target dependent GDB architecture entries. */
|
/* Set up target dependent GDB architecture entries. */
|
||||||
set_gdbarch_cannot_fetch_register (gdbarch, arc_linux_cannot_fetch_register);
|
set_gdbarch_cannot_fetch_register (gdbarch, arc_linux_cannot_fetch_register);
|
||||||
|
|
|
@ -1721,7 +1721,7 @@ arm_linux_init_abi (struct gdbarch_info info,
|
||||||
NULL };
|
NULL };
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, true);
|
linux_init_abi (info, gdbarch, 1);
|
||||||
|
|
||||||
tdep->lowest_pc = 0x8000;
|
tdep->lowest_pc = 0x8000;
|
||||||
if (info.byte_order_for_code == BFD_ENDIAN_BIG)
|
if (info.byte_order_for_code == BFD_ENDIAN_BIG)
|
||||||
|
|
|
@ -150,7 +150,7 @@ bfin_linux_get_syscall_number (struct gdbarch *gdbarch,
|
||||||
static void
|
static void
|
||||||
bfin_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
bfin_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Set the sigtramp frame sniffer. */
|
/* Set the sigtramp frame sniffer. */
|
||||||
tramp_frame_prepend_unwinder (gdbarch, &bfin_linux_sigframe);
|
tramp_frame_prepend_unwinder (gdbarch, &bfin_linux_sigframe);
|
||||||
|
|
|
@ -35,7 +35,7 @@ cris_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
if (tdep->cris_version == 32)
|
if (tdep->cris_version == 32)
|
||||||
/* Threaded debugging is only supported on CRISv32 for now. */
|
/* Threaded debugging is only supported on CRISv32 for now. */
|
||||||
|
|
|
@ -233,7 +233,7 @@ csky_linux_rt_sigreturn_tramp_frame = {
|
||||||
static void
|
static void
|
||||||
csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Shared library handling. */
|
/* Shared library handling. */
|
||||||
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
||||||
|
|
|
@ -44,82 +44,121 @@ show_debug_displaced (struct ui_file *file, int from_tty,
|
||||||
}
|
}
|
||||||
|
|
||||||
displaced_step_prepare_status
|
displaced_step_prepare_status
|
||||||
displaced_step_buffer::prepare (thread_info *thread, CORE_ADDR &displaced_pc)
|
displaced_step_buffers::prepare (thread_info *thread, CORE_ADDR &displaced_pc)
|
||||||
{
|
{
|
||||||
gdb_assert (!thread->displaced_step_state.in_progress ());
|
gdb_assert (!thread->displaced_step_state.in_progress ());
|
||||||
|
|
||||||
/* Is a thread currently using the buffer? */
|
/* Sanity check: the thread should not be using a buffer at this point. */
|
||||||
if (m_current_thread != nullptr)
|
for (displaced_step_buffer &buf : m_buffers)
|
||||||
{
|
gdb_assert (buf.current_thread != thread);
|
||||||
/* If so, it better not be this thread. */
|
|
||||||
gdb_assert (thread != m_current_thread);
|
|
||||||
return DISPLACED_STEP_PREPARE_STATUS_UNAVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
regcache *regcache = get_thread_regcache (thread);
|
regcache *regcache = get_thread_regcache (thread);
|
||||||
const address_space *aspace = regcache->aspace ();
|
const address_space *aspace = regcache->aspace ();
|
||||||
gdbarch *arch = regcache->arch ();
|
gdbarch *arch = regcache->arch ();
|
||||||
ULONGEST len = gdbarch_max_insn_length (arch);
|
ULONGEST len = gdbarch_max_insn_length (arch);
|
||||||
|
|
||||||
if (breakpoint_in_range_p (aspace, m_addr, len))
|
/* Search for an unused buffer. */
|
||||||
{
|
displaced_step_buffer *buffer = nullptr;
|
||||||
/* There's a breakpoint set in the scratch pad location range
|
displaced_step_prepare_status fail_status
|
||||||
(which is usually around the entry point). We'd either
|
= DISPLACED_STEP_PREPARE_STATUS_CANT;
|
||||||
install it before resuming, which would overwrite/corrupt the
|
|
||||||
scratch pad, or if it was already inserted, this displaced
|
|
||||||
step would overwrite it. The latter is OK in the sense that
|
|
||||||
we already assume that no thread is going to execute the code
|
|
||||||
in the scratch pad range (after initial startup) anyway, but
|
|
||||||
the former is unacceptable. Simply punt and fallback to
|
|
||||||
stepping over this breakpoint in-line. */
|
|
||||||
displaced_debug_printf ("breakpoint set in scratch pad. "
|
|
||||||
"Stepping over breakpoint in-line instead.");
|
|
||||||
|
|
||||||
return DISPLACED_STEP_PREPARE_STATUS_CANT;
|
for (displaced_step_buffer &candidate : m_buffers)
|
||||||
|
{
|
||||||
|
bool bp_in_range = breakpoint_in_range_p (aspace, candidate.addr, len);
|
||||||
|
bool is_free = candidate.current_thread == nullptr;
|
||||||
|
|
||||||
|
if (!bp_in_range)
|
||||||
|
{
|
||||||
|
if (is_free)
|
||||||
|
{
|
||||||
|
buffer = &candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This buffer would be suitable, but it's used right now. */
|
||||||
|
fail_status = DISPLACED_STEP_PREPARE_STATUS_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* There's a breakpoint set in the scratch pad location range
|
||||||
|
(which is usually around the entry point). We'd either
|
||||||
|
install it before resuming, which would overwrite/corrupt the
|
||||||
|
scratch pad, or if it was already inserted, this displaced
|
||||||
|
step would overwrite it. The latter is OK in the sense that
|
||||||
|
we already assume that no thread is going to execute the code
|
||||||
|
in the scratch pad range (after initial startup) anyway, but
|
||||||
|
the former is unacceptable. Simply punt and fallback to
|
||||||
|
stepping over this breakpoint in-line. */
|
||||||
|
displaced_debug_printf ("breakpoint set in displaced stepping "
|
||||||
|
"buffer at %s, can't use.",
|
||||||
|
paddress (arch, candidate.addr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_original_pc = regcache_read_pc (regcache);
|
if (buffer == nullptr)
|
||||||
displaced_pc = m_addr;
|
return fail_status;
|
||||||
|
|
||||||
|
displaced_debug_printf ("selected buffer at %s",
|
||||||
|
paddress (arch, buffer->addr));
|
||||||
|
|
||||||
|
/* Save the original PC of the thread. */
|
||||||
|
buffer->original_pc = regcache_read_pc (regcache);
|
||||||
|
|
||||||
|
/* Return displaced step buffer address to caller. */
|
||||||
|
displaced_pc = buffer->addr;
|
||||||
|
|
||||||
/* Save the original contents of the displaced stepping buffer. */
|
/* Save the original contents of the displaced stepping buffer. */
|
||||||
m_saved_copy.resize (len);
|
buffer->saved_copy.resize (len);
|
||||||
|
|
||||||
int status = target_read_memory (m_addr, m_saved_copy.data (), len);
|
int status = target_read_memory (buffer->addr,
|
||||||
|
buffer->saved_copy.data (), len);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
throw_error (MEMORY_ERROR,
|
throw_error (MEMORY_ERROR,
|
||||||
_("Error accessing memory address %s (%s) for "
|
_("Error accessing memory address %s (%s) for "
|
||||||
"displaced-stepping scratch space."),
|
"displaced-stepping scratch space."),
|
||||||
paddress (arch, m_addr), safe_strerror (status));
|
paddress (arch, buffer->addr), safe_strerror (status));
|
||||||
|
|
||||||
displaced_debug_printf ("saved %s: %s",
|
displaced_debug_printf ("saved %s: %s",
|
||||||
paddress (arch, m_addr),
|
paddress (arch, buffer->addr),
|
||||||
displaced_step_dump_bytes
|
displaced_step_dump_bytes
|
||||||
(m_saved_copy.data (), len).c_str ());
|
(buffer->saved_copy.data (), len).c_str ());
|
||||||
|
|
||||||
/* Save this in a local variable first, so it's released if code below
|
/* Save this in a local variable first, so it's released if code below
|
||||||
throws. */
|
throws. */
|
||||||
displaced_step_copy_insn_closure_up copy_insn_closure
|
displaced_step_copy_insn_closure_up copy_insn_closure
|
||||||
= gdbarch_displaced_step_copy_insn (arch, m_original_pc, m_addr, regcache);
|
= gdbarch_displaced_step_copy_insn (arch, buffer->original_pc,
|
||||||
|
buffer->addr, regcache);
|
||||||
|
|
||||||
if (copy_insn_closure == nullptr)
|
if (copy_insn_closure == nullptr)
|
||||||
{
|
{
|
||||||
/* The architecture doesn't know how or want to displaced step
|
/* The architecture doesn't know how or want to displaced step
|
||||||
this instruction or instruction sequence. Fallback to
|
this instruction or instruction sequence. Fallback to
|
||||||
stepping over the breakpoint in-line. */
|
stepping over the breakpoint in-line. */
|
||||||
return DISPLACED_STEP_PREPARE_STATUS_CANT;
|
return DISPLACED_STEP_PREPARE_STATUS_CANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resume execution at the copy. */
|
/* Resume execution at the copy. */
|
||||||
regcache_write_pc (regcache, m_addr);
|
regcache_write_pc (regcache, buffer->addr);
|
||||||
|
|
||||||
/* This marks the buffer as being in use. */
|
/* This marks the buffer as being in use. */
|
||||||
m_current_thread = thread;
|
buffer->current_thread = thread;
|
||||||
|
|
||||||
/* Save this, now that we know everything went fine. */
|
/* Save this, now that we know everything went fine. */
|
||||||
m_copy_insn_closure = std::move (copy_insn_closure);
|
buffer->copy_insn_closure = std::move (copy_insn_closure);
|
||||||
|
|
||||||
/* Tell infrun not to try preparing a displaced step again for this inferior. */
|
/* Tell infrun not to try preparing a displaced step again for this inferior if
|
||||||
|
all buffers are taken. */
|
||||||
thread->inf->displaced_step_state.unavailable = true;
|
thread->inf->displaced_step_state.unavailable = true;
|
||||||
|
for (const displaced_step_buffer &buf : m_buffers)
|
||||||
|
{
|
||||||
|
if (buf.current_thread == nullptr)
|
||||||
|
{
|
||||||
|
thread->inf->displaced_step_state.unavailable = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return DISPLACED_STEP_PREPARE_STATUS_OK;
|
return DISPLACED_STEP_PREPARE_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
@ -152,21 +191,34 @@ displaced_step_instruction_executed_successfully (gdbarch *arch,
|
||||||
}
|
}
|
||||||
|
|
||||||
displaced_step_finish_status
|
displaced_step_finish_status
|
||||||
displaced_step_buffer::finish (gdbarch *arch, thread_info *thread,
|
displaced_step_buffers::finish (gdbarch *arch, thread_info *thread,
|
||||||
gdb_signal sig)
|
gdb_signal sig)
|
||||||
{
|
{
|
||||||
gdb_assert (thread->displaced_step_state.in_progress ());
|
gdb_assert (thread->displaced_step_state.in_progress ());
|
||||||
gdb_assert (thread == m_current_thread);
|
|
||||||
|
/* Find the buffer this thread was using. */
|
||||||
|
displaced_step_buffer *buffer = nullptr;
|
||||||
|
|
||||||
|
for (displaced_step_buffer &candidate : m_buffers)
|
||||||
|
{
|
||||||
|
if (candidate.current_thread == thread)
|
||||||
|
{
|
||||||
|
buffer = &candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_assert (buffer != nullptr);
|
||||||
|
|
||||||
/* Move this to a local variable so it's released in case something goes
|
/* Move this to a local variable so it's released in case something goes
|
||||||
wrong. */
|
wrong. */
|
||||||
displaced_step_copy_insn_closure_up copy_insn_closure
|
displaced_step_copy_insn_closure_up copy_insn_closure
|
||||||
= std::move (m_copy_insn_closure);
|
= std::move (buffer->copy_insn_closure);
|
||||||
gdb_assert (copy_insn_closure != nullptr);
|
gdb_assert (copy_insn_closure != nullptr);
|
||||||
|
|
||||||
/* Reset M_CURRENT_THREAD immediately to mark the buffer as available, in case
|
/* Reset BUFFER->CURRENT_THREAD immediately to mark the buffer as available,
|
||||||
something goes wrong below. */
|
in case something goes wrong below. */
|
||||||
m_current_thread = nullptr;
|
buffer->current_thread = nullptr;
|
||||||
|
|
||||||
/* Now that a buffer gets freed, tell infrun it can ask us to prepare a displaced
|
/* Now that a buffer gets freed, tell infrun it can ask us to prepare a displaced
|
||||||
step again for this inferior. Do that here in case something goes wrong
|
step again for this inferior. Do that here in case something goes wrong
|
||||||
|
@ -175,12 +227,13 @@ displaced_step_buffer::finish (gdbarch *arch, thread_info *thread,
|
||||||
|
|
||||||
ULONGEST len = gdbarch_max_insn_length (arch);
|
ULONGEST len = gdbarch_max_insn_length (arch);
|
||||||
|
|
||||||
write_memory_ptid (thread->ptid, m_addr,
|
/* Restore memory of the buffer. */
|
||||||
m_saved_copy.data (), len);
|
write_memory_ptid (thread->ptid, buffer->addr,
|
||||||
|
buffer->saved_copy.data (), len);
|
||||||
|
|
||||||
displaced_debug_printf ("restored %s %s",
|
displaced_debug_printf ("restored %s %s",
|
||||||
target_pid_to_str (thread->ptid).c_str (),
|
target_pid_to_str (thread->ptid).c_str (),
|
||||||
paddress (arch, m_addr));
|
paddress (arch, buffer->addr));
|
||||||
|
|
||||||
regcache *rc = get_thread_regcache (thread);
|
regcache *rc = get_thread_regcache (thread);
|
||||||
|
|
||||||
|
@ -189,8 +242,9 @@ displaced_step_buffer::finish (gdbarch *arch, thread_info *thread,
|
||||||
|
|
||||||
if (instruction_executed_successfully)
|
if (instruction_executed_successfully)
|
||||||
{
|
{
|
||||||
gdbarch_displaced_step_fixup (arch, copy_insn_closure.get (), m_original_pc,
|
gdbarch_displaced_step_fixup (arch, copy_insn_closure.get (),
|
||||||
m_addr, rc);
|
buffer->original_pc,
|
||||||
|
buffer->addr, rc);
|
||||||
return DISPLACED_STEP_FINISH_STATUS_OK;
|
return DISPLACED_STEP_FINISH_STATUS_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -198,35 +252,41 @@ displaced_step_buffer::finish (gdbarch *arch, thread_info *thread,
|
||||||
/* Since the instruction didn't complete, all we can do is relocate the
|
/* Since the instruction didn't complete, all we can do is relocate the
|
||||||
PC. */
|
PC. */
|
||||||
CORE_ADDR pc = regcache_read_pc (rc);
|
CORE_ADDR pc = regcache_read_pc (rc);
|
||||||
pc = m_original_pc + (pc - m_addr);
|
pc = buffer->original_pc + (pc - buffer->addr);
|
||||||
regcache_write_pc (rc, pc);
|
regcache_write_pc (rc, pc);
|
||||||
return DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED;
|
return DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const displaced_step_copy_insn_closure *
|
const displaced_step_copy_insn_closure *
|
||||||
displaced_step_buffer::copy_insn_closure_by_addr (CORE_ADDR addr)
|
displaced_step_buffers::copy_insn_closure_by_addr (CORE_ADDR addr)
|
||||||
{
|
{
|
||||||
if (addr == m_addr)
|
for (const displaced_step_buffer &buffer : m_buffers)
|
||||||
return m_copy_insn_closure.get ();
|
{
|
||||||
else
|
if (addr == buffer.addr)
|
||||||
return nullptr;
|
return buffer.copy_insn_closure.get ();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
displaced_step_buffer::restore_in_ptid (ptid_t ptid)
|
displaced_step_buffers::restore_in_ptid (ptid_t ptid)
|
||||||
{
|
{
|
||||||
if (m_current_thread != nullptr)
|
for (const displaced_step_buffer &buffer : m_buffers)
|
||||||
{
|
{
|
||||||
regcache *regcache = get_thread_regcache (m_current_thread);
|
if (buffer.current_thread == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
regcache *regcache = get_thread_regcache (buffer.current_thread);
|
||||||
gdbarch *arch = regcache->arch ();
|
gdbarch *arch = regcache->arch ();
|
||||||
ULONGEST len = gdbarch_max_insn_length (arch);
|
ULONGEST len = gdbarch_max_insn_length (arch);
|
||||||
|
|
||||||
write_memory_ptid (ptid, m_addr, m_saved_copy.data (), len);
|
write_memory_ptid (ptid, buffer.addr, buffer.saved_copy.data (), len);
|
||||||
|
|
||||||
displaced_debug_printf ("restored in ptid %s %s",
|
displaced_debug_printf ("restored in ptid %s %s",
|
||||||
target_pid_to_str (ptid).c_str (),
|
target_pid_to_str (ptid).c_str (),
|
||||||
paddress (arch, m_addr));
|
paddress (arch, buffer.addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#ifndef DISPLACED_STEPPING_H
|
#ifndef DISPLACED_STEPPING_H
|
||||||
#define DISPLACED_STEPPING_H
|
#define DISPLACED_STEPPING_H
|
||||||
|
|
||||||
|
#include "gdbsupport/array-view.h"
|
||||||
#include "gdbsupport/byte-vector.h"
|
#include "gdbsupport/byte-vector.h"
|
||||||
|
|
||||||
struct gdbarch;
|
struct gdbarch;
|
||||||
|
@ -154,13 +155,19 @@ private:
|
||||||
gdbarch *m_original_gdbarch = nullptr;
|
gdbarch *m_original_gdbarch = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Manage access to a single displaced stepping buffer. */
|
/* Control access to multiple displaced stepping buffers at fixed addresses. */
|
||||||
|
|
||||||
struct displaced_step_buffer
|
struct displaced_step_buffers
|
||||||
{
|
{
|
||||||
explicit displaced_step_buffer (CORE_ADDR buffer_addr)
|
explicit displaced_step_buffers (gdb::array_view<CORE_ADDR> buffer_addrs)
|
||||||
: m_addr (buffer_addr)
|
{
|
||||||
{}
|
gdb_assert (buffer_addrs.size () > 0);
|
||||||
|
|
||||||
|
m_buffers.reserve (buffer_addrs.size ());
|
||||||
|
|
||||||
|
for (CORE_ADDR buffer_addr : buffer_addrs)
|
||||||
|
m_buffers.emplace_back (buffer_addr);
|
||||||
|
}
|
||||||
|
|
||||||
displaced_step_prepare_status prepare (thread_info *thread,
|
displaced_step_prepare_status prepare (thread_info *thread,
|
||||||
CORE_ADDR &displaced_pc);
|
CORE_ADDR &displaced_pc);
|
||||||
|
@ -174,21 +181,35 @@ struct displaced_step_buffer
|
||||||
void restore_in_ptid (ptid_t ptid);
|
void restore_in_ptid (ptid_t ptid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Original PC of the instruction being displaced-stepped in this buffer. */
|
|
||||||
CORE_ADDR m_original_pc = 0;
|
|
||||||
|
|
||||||
/* Address of the buffer. */
|
/* State of a single buffer. */
|
||||||
const CORE_ADDR m_addr;
|
|
||||||
|
|
||||||
/* If set, the thread currently using the buffer. */
|
struct displaced_step_buffer
|
||||||
thread_info *m_current_thread = nullptr;
|
{
|
||||||
|
explicit displaced_step_buffer (CORE_ADDR addr)
|
||||||
|
: addr (addr)
|
||||||
|
{}
|
||||||
|
|
||||||
/* Saved contents of copy area. */
|
/* Address of the buffer. */
|
||||||
gdb::byte_vector m_saved_copy;
|
const CORE_ADDR addr;
|
||||||
|
|
||||||
/* The closure provided gdbarch_displaced_step_copy_insn, to be used
|
/* The original PC of the instruction currently being stepped. */
|
||||||
for post-step cleanup. */
|
CORE_ADDR original_pc = 0;
|
||||||
displaced_step_copy_insn_closure_up m_copy_insn_closure;
|
|
||||||
|
/* If set, the thread currently using the buffer. If unset, the buffer is not
|
||||||
|
used. */
|
||||||
|
thread_info *current_thread = nullptr;
|
||||||
|
|
||||||
|
/* Saved copy of the bytes in the displaced buffer, to be restored once the
|
||||||
|
buffer is no longer used. */
|
||||||
|
gdb::byte_vector saved_copy;
|
||||||
|
|
||||||
|
/* Closure obtained from gdbarch_displaced_step_copy_insn, to be passed to
|
||||||
|
gdbarch_displaced_step_fixup_insn. */
|
||||||
|
displaced_step_copy_insn_closure_up copy_insn_closure;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<displaced_step_buffer> m_buffers;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DISPLACED_STEPPING_H */
|
#endif /* DISPLACED_STEPPING_H */
|
||||||
|
|
|
@ -456,7 +456,7 @@ frv_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
|
||||||
static void
|
static void
|
||||||
frv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
frv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Set the sigtramp frame sniffer. */
|
/* Set the sigtramp frame sniffer. */
|
||||||
frame_unwind_append_unwinder (gdbarch, &frv_linux_sigtramp_frame_unwind);
|
frame_unwind_append_unwinder (gdbarch, &frv_linux_sigtramp_frame_unwind);
|
||||||
|
|
|
@ -489,7 +489,7 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* GNU/Linux is always ELF. */
|
/* GNU/Linux is always ELF. */
|
||||||
tdep->is_elf = 1;
|
tdep->is_elf = 1;
|
||||||
|
|
|
@ -832,7 +832,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
|
|
||||||
gdb_assert (tdesc_data);
|
gdb_assert (tdesc_data);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, true);
|
linux_init_abi (info, gdbarch, 1);
|
||||||
|
|
||||||
/* GNU/Linux uses ELF. */
|
/* GNU/Linux uses ELF. */
|
||||||
i386_elf_init_abi (info, gdbarch);
|
i386_elf_init_abi (info, gdbarch);
|
||||||
|
|
|
@ -223,7 +223,7 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
static const char *const stap_register_indirection_suffixes[] = { "]",
|
static const char *const stap_register_indirection_suffixes[] = { "]",
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Set the method of obtaining the sigcontext addresses at which
|
/* Set the method of obtaining the sigcontext addresses at which
|
||||||
registers are saved. */
|
registers are saved. */
|
||||||
|
|
|
@ -166,9 +166,10 @@ enum
|
||||||
static struct gdbarch_data *linux_gdbarch_data_handle;
|
static struct gdbarch_data *linux_gdbarch_data_handle;
|
||||||
|
|
||||||
struct linux_gdbarch_data
|
struct linux_gdbarch_data
|
||||||
{
|
{
|
||||||
struct type *siginfo_type;
|
struct type *siginfo_type;
|
||||||
};
|
int num_disp_step_buffers;
|
||||||
|
};
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
init_linux_gdbarch_data (struct obstack *obstack)
|
init_linux_gdbarch_data (struct obstack *obstack)
|
||||||
|
@ -200,8 +201,8 @@ struct linux_info
|
||||||
if we tried looking it up but failed. */
|
if we tried looking it up but failed. */
|
||||||
int vsyscall_range_p = 0;
|
int vsyscall_range_p = 0;
|
||||||
|
|
||||||
/* Inferior's displaced step buffer. */
|
/* Inferior's displaced step buffers. */
|
||||||
gdb::optional<displaced_step_buffer> disp_step_buf;
|
gdb::optional<displaced_step_buffers> disp_step_bufs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Per-inferior data key. */
|
/* 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);
|
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
|
CORE_ADDR disp_step_buf_addr
|
||||||
= linux_displaced_step_location (thread->inf->gdbarch);
|
= 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. */
|
/* 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);
|
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. */
|
/* 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);
|
linux_info *per_inferior = linux_inferior_data.get (inf);
|
||||||
|
|
||||||
if (per_inferior == nullptr
|
if (per_inferior == nullptr
|
||||||
|| !per_inferior->disp_step_buf.has_value ())
|
|| !per_inferior->disp_step_bufs.has_value ())
|
||||||
return nullptr;
|
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. */
|
/* 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);
|
linux_info *per_inferior = linux_inferior_data.get (parent_inf);
|
||||||
|
|
||||||
if (per_inferior == nullptr
|
if (per_inferior == nullptr
|
||||||
|| !per_inferior->disp_step_buf.has_value ())
|
|| !per_inferior->disp_step_bufs.has_value ())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
per_inferior->disp_step_buf->restore_in_ptid (ptid);
|
per_inferior->disp_step_bufs->restore_in_ptid (ptid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See linux-tdep.h. */
|
/* 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
|
/* 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
|
void
|
||||||
linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
|
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_finish (gdbarch, linux_displaced_step_finish);
|
||||||
set_gdbarch_displaced_step_copy_insn_closure_by_addr
|
set_gdbarch_displaced_step_copy_insn_closure_by_addr
|
||||||
(gdbarch, linux_displaced_step_copy_insn_closure_by_addr);
|
(gdbarch, linux_displaced_step_copy_insn_closure_by_addr);
|
||||||
|
|
|
@ -82,7 +82,7 @@ extern void linux_displaced_step_restore_all_in_ptid (inferior *parent_inf,
|
||||||
ptid_t ptid);
|
ptid_t ptid);
|
||||||
|
|
||||||
extern void linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
|
extern void linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
|
||||||
bool supports_displaced_step);
|
int num_disp_step_buffers);
|
||||||
|
|
||||||
extern int linux_is_uclinux (void);
|
extern int linux_is_uclinux (void);
|
||||||
|
|
||||||
|
|
|
@ -449,7 +449,7 @@ static void
|
||||||
m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Since EVB register is not available for native debug, we reduce
|
/* Since EVB register is not available for native debug, we reduce
|
||||||
the number of registers. */
|
the number of registers. */
|
||||||
|
|
|
@ -385,7 +385,7 @@ m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
tdep->jb_pc = M68K_LINUX_JB_PC;
|
tdep->jb_pc = M68K_LINUX_JB_PC;
|
||||||
tdep->jb_elt_size = M68K_LINUX_JB_ELEMENT_SIZE;
|
tdep->jb_elt_size = M68K_LINUX_JB_ELEMENT_SIZE;
|
||||||
|
|
|
@ -117,7 +117,7 @@ static void
|
||||||
microblaze_linux_init_abi (struct gdbarch_info info,
|
microblaze_linux_init_abi (struct gdbarch_info info,
|
||||||
struct gdbarch *gdbarch)
|
struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
set_gdbarch_memory_remove_breakpoint (gdbarch,
|
set_gdbarch_memory_remove_breakpoint (gdbarch,
|
||||||
microblaze_linux_memory_remove_breakpoint);
|
microblaze_linux_memory_remove_breakpoint);
|
||||||
|
|
|
@ -1531,7 +1531,7 @@ mips_linux_init_abi (struct gdbarch_info info,
|
||||||
enum mips_abi abi = mips_abi (gdbarch);
|
enum mips_abi abi = mips_abi (gdbarch);
|
||||||
struct tdesc_arch_data *tdesc_data = info.tdesc_data;
|
struct tdesc_arch_data *tdesc_data = info.tdesc_data;
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Get the syscall number from the arch's register. */
|
/* Get the syscall number from the arch's register. */
|
||||||
set_gdbarch_get_syscall_number (gdbarch, mips_linux_get_syscall_number);
|
set_gdbarch_get_syscall_number (gdbarch, mips_linux_get_syscall_number);
|
||||||
|
|
|
@ -704,7 +704,7 @@ am33_linux_sigframe_cache_init (const struct tramp_frame *self,
|
||||||
static void
|
static void
|
||||||
am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
set_gdbarch_iterate_over_regset_sections
|
set_gdbarch_iterate_over_regset_sections
|
||||||
(gdbarch, am33_iterate_over_regset_sections);
|
(gdbarch, am33_iterate_over_regset_sections);
|
||||||
|
|
|
@ -219,7 +219,7 @@ nios2_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Shared library handling. */
|
/* Shared library handling. */
|
||||||
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
||||||
|
|
|
@ -140,7 +140,7 @@ or1k_linux_sigframe_init (const struct tramp_frame *self,
|
||||||
static void
|
static void
|
||||||
or1k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
or1k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
set_solib_svr4_fetch_link_map_offsets (gdbarch,
|
set_solib_svr4_fetch_link_map_offsets (gdbarch,
|
||||||
svr4_ilp32_fetch_link_map_offsets);
|
svr4_ilp32_fetch_link_map_offsets);
|
||||||
|
|
|
@ -1993,7 +1993,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
|
||||||
static const char *const stap_register_indirection_suffixes[] = { ")",
|
static const char *const stap_register_indirection_suffixes[] = { ")",
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* PPC GNU/Linux uses either 64-bit or 128-bit long doubles; where
|
/* PPC GNU/Linux uses either 64-bit or 128-bit long doubles; where
|
||||||
128-bit, they can be either IBM long double or IEEE quad long double.
|
128-bit, they can be either IBM long double or IEEE quad long double.
|
||||||
|
|
|
@ -159,7 +159,7 @@ riscv_linux_sigframe_init (const struct tramp_frame *self,
|
||||||
static void
|
static void
|
||||||
riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);
|
set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ struct ppc_inferior_data
|
||||||
/* This is an optional in case we add more fields to ppc_inferior_data, we
|
/* This is an optional in case we add more fields to ppc_inferior_data, we
|
||||||
don't want it instantiated as soon as we get the ppc_inferior_data for an
|
don't want it instantiated as soon as we get the ppc_inferior_data for an
|
||||||
inferior. */
|
inferior. */
|
||||||
gdb::optional<displaced_step_buffer> disp_step_buf;
|
gdb::optional<displaced_step_buffers> disp_step_buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inferior_key<ppc_inferior_data> ppc_inferior_data_key;
|
static inferior_key<ppc_inferior_data> ppc_inferior_data_key;
|
||||||
|
|
|
@ -1119,7 +1119,7 @@ s390_linux_init_abi_any (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
|
|
||||||
tdep->s390_syscall_record = s390_linux_syscall_record;
|
tdep->s390_syscall_record = s390_linux_syscall_record;
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Register handling. */
|
/* Register handling. */
|
||||||
set_gdbarch_core_read_description (gdbarch, s390_core_read_description);
|
set_gdbarch_core_read_description (gdbarch, s390_core_read_description);
|
||||||
|
|
|
@ -184,7 +184,7 @@ static struct tramp_frame sh_linux_rt_sigreturn_tramp_frame = {
|
||||||
static void
|
static void
|
||||||
sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* GNU/Linux uses SVR4-style shared libraries. */
|
/* GNU/Linux uses SVR4-style shared libraries. */
|
||||||
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
||||||
|
|
|
@ -422,7 +422,7 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
tdep->gregset = &sparc32_linux_gregset;
|
tdep->gregset = &sparc32_linux_gregset;
|
||||||
tdep->sizeof_gregset = 152;
|
tdep->sizeof_gregset = 152;
|
||||||
|
|
|
@ -365,7 +365,7 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
tdep->gregset = &sparc64_linux_gregset;
|
tdep->gregset = &sparc64_linux_gregset;
|
||||||
tdep->sizeof_gregset = 288;
|
tdep->sizeof_gregset = 288;
|
||||||
|
|
|
@ -167,7 +167,7 @@ tic6x_uclinux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
/* Shared library handling. */
|
/* Shared library handling. */
|
||||||
set_solib_ops (gdbarch, &dsbt_so_ops);
|
set_solib_ops (gdbarch, &dsbt_so_ops);
|
||||||
|
|
|
@ -111,7 +111,7 @@ tilegx_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
int arch_size = gdbarch_addr_bit (gdbarch);
|
int arch_size = gdbarch_addr_bit (gdbarch);
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
tramp_frame_prepend_unwinder (gdbarch, &tilegx_linux_rt_sigframe);
|
tramp_frame_prepend_unwinder (gdbarch, &tilegx_linux_rt_sigframe);
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
set_gdbarch_num_pseudo_regs (gdbarch, tdep->num_pseudo_regs);
|
set_gdbarch_num_pseudo_regs (gdbarch, tdep->num_pseudo_regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
linux_init_abi (info, gdbarch, false);
|
linux_init_abi (info, gdbarch, 0);
|
||||||
|
|
||||||
set_solib_svr4_fetch_link_map_offsets
|
set_solib_svr4_fetch_link_map_offsets
|
||||||
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
|
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue