set_gdbarch_get_syscall_number (gdbarch, aarch64_linux_get_syscall_number);
/* Displaced stepping. */
- set_gdbarch_max_insn_length (gdbarch, 4 * AARCH64_DISPLACED_MODIFIED_INSNS);
+ set_gdbarch_max_insn_length (gdbarch, 4);
+ set_gdbarch_displaced_step_buffer_length
+ (gdbarch, 4 * AARCH64_DISPLACED_MODIFIED_INSNS);
set_gdbarch_displaced_step_copy_insn (gdbarch,
aarch64_displaced_step_copy_insn);
set_gdbarch_displaced_step_fixup (gdbarch, aarch64_displaced_step_fixup);
/* Note: for displaced stepping, this includes the breakpoint, and one word
of additional scratch space. This setting isn't used for anything beside
displaced stepping at present. */
- set_gdbarch_max_insn_length (gdbarch, 4 * ARM_DISPLACED_MODIFIED_INSNS);
+ set_gdbarch_displaced_step_buffer_length
+ (gdbarch, 4 * ARM_DISPLACED_MODIFIED_INSNS);
+ set_gdbarch_max_insn_length (gdbarch, 4);
/* This should be low enough for everything. */
tdep->lowest_pc = 0x20;
regcache *regcache = get_thread_regcache (thread);
const address_space *aspace = regcache->aspace ();
gdbarch *arch = regcache->arch ();
- ULONGEST len = gdbarch_max_insn_length (arch);
+ ULONGEST len = gdbarch_displaced_step_buffer_length (arch);
/* Search for an unused buffer. */
displaced_step_buffer *buffer = nullptr;
below. */
thread->inf->displaced_step_state.unavailable = false;
- ULONGEST len = gdbarch_max_insn_length (arch);
+ ULONGEST len = gdbarch_displaced_step_buffer_length (arch);
/* Restore memory of the buffer. */
write_memory_ptid (thread->ptid, buffer->addr,
regcache *regcache = get_thread_regcache (buffer.current_thread);
gdbarch *arch = regcache->arch ();
- ULONGEST len = gdbarch_max_insn_length (arch);
+ ULONGEST len = gdbarch_displaced_step_buffer_length (arch);
write_memory_ptid (ptid, buffer.addr, buffer.saved_copy.data (), len);
see the comments in infrun.c.
The TO area is only guaranteed to have space for
- gdbarch_max_insn_length (arch) bytes, so this function must not
- write more bytes than that to that area.
+ gdbarch_displaced_step_buffer_length (arch) octets, so this
+ function must not write more octets than that to this area.
If you do not provide this function, GDB assumes that the
architecture does not support displaced stepping.
extern void gdbarch_displaced_step_restore_all_in_ptid (struct gdbarch *gdbarch, inferior *parent_inf, ptid_t child_ptid);
extern void set_gdbarch_displaced_step_restore_all_in_ptid (struct gdbarch *gdbarch, gdbarch_displaced_step_restore_all_in_ptid_ftype *displaced_step_restore_all_in_ptid);
+/* The maximum length in octets required for a displaced-step instruction
+ buffer. By default this will be the same as gdbarch::max_insn_length,
+ but should be overridden for architectures that might expand a
+ displaced-step instruction to multiple replacement instructions. */
+
+extern ULONGEST gdbarch_displaced_step_buffer_length (struct gdbarch *gdbarch);
+extern void set_gdbarch_displaced_step_buffer_length (struct gdbarch *gdbarch, ULONGEST displaced_step_buffer_length);
+
/* Relocate an instruction to execute at a different address. OLDLOC
is the address in the inferior memory where the instruction to
relocate is currently at. On input, TO points to the destination
gdbarch_displaced_step_finish_ftype *displaced_step_finish = NULL;
gdbarch_displaced_step_copy_insn_closure_by_addr_ftype *displaced_step_copy_insn_closure_by_addr = nullptr;
gdbarch_displaced_step_restore_all_in_ptid_ftype *displaced_step_restore_all_in_ptid = nullptr;
+ ULONGEST displaced_step_buffer_length = 0;
gdbarch_relocate_instruction_ftype *relocate_instruction = NULL;
gdbarch_overlay_update_ftype *overlay_update = nullptr;
gdbarch_core_read_description_ftype *core_read_description = nullptr;
log.puts ("\n\tdisplaced_step_finish");
/* Skip verify of displaced_step_copy_insn_closure_by_addr, has predicate. */
/* Skip verify of displaced_step_restore_all_in_ptid, invalid_p == 0 */
+ if (gdbarch->displaced_step_buffer_length == 0)
+ gdbarch->displaced_step_buffer_length = gdbarch->max_insn_length;
+ if (gdbarch->displaced_step_buffer_length < gdbarch->max_insn_length)
+ log.puts ("\n\tdisplaced_step_buffer_length");
/* Skip verify of relocate_instruction, has predicate. */
/* Skip verify of overlay_update, has predicate. */
/* Skip verify of core_read_description, has predicate. */
gdb_printf (file,
"gdbarch_dump: displaced_step_restore_all_in_ptid = <%s>\n",
host_address_to_string (gdbarch->displaced_step_restore_all_in_ptid));
+ gdb_printf (file,
+ "gdbarch_dump: displaced_step_buffer_length = %s\n",
+ plongest (gdbarch->displaced_step_buffer_length));
gdb_printf (file,
"gdbarch_dump: gdbarch_relocate_instruction_p() = %d\n",
gdbarch_relocate_instruction_p (gdbarch));
gdbarch->displaced_step_restore_all_in_ptid = displaced_step_restore_all_in_ptid;
}
+ULONGEST
+gdbarch_displaced_step_buffer_length (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Check variable is valid. */
+ gdb_assert (!(gdbarch->displaced_step_buffer_length < gdbarch->max_insn_length));
+ if (gdbarch_debug >= 2)
+ gdb_printf (gdb_stdlog, "gdbarch_displaced_step_buffer_length called\n");
+ return gdbarch->displaced_step_buffer_length;
+}
+
+void
+set_gdbarch_displaced_step_buffer_length (struct gdbarch *gdbarch,
+ ULONGEST displaced_step_buffer_length)
+{
+ gdbarch->displaced_step_buffer_length = displaced_step_buffer_length;
+}
+
bool
gdbarch_relocate_instruction_p (struct gdbarch *gdbarch)
{
see the comments in infrun.c.
The TO area is only guaranteed to have space for
-gdbarch_max_insn_length (arch) bytes, so this function must not
-write more bytes than that to that area.
+gdbarch_displaced_step_buffer_length (arch) octets, so this
+function must not write more octets than that to this area.
If you do not provide this function, GDB assumes that the
architecture does not support displaced stepping.
invalid=False,
)
+Value(
+ comment="""
+The maximum length in octets required for a displaced-step instruction
+buffer. By default this will be the same as gdbarch::max_insn_length,
+but should be overridden for architectures that might expand a
+displaced-step instruction to multiple replacement instructions.
+""",
+ type="ULONGEST",
+ name="displaced_step_buffer_length",
+ predefault="0",
+ postdefault="gdbarch->max_insn_length",
+ invalid="gdbarch->displaced_step_buffer_length < gdbarch->max_insn_length",
+)
+
Method(
comment="""
Relocate an instruction to execute at a different address. OLDLOC
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);
+ int buf_len = gdbarch_displaced_step_buffer_length (arch);
linux_gdbarch_data *gdbarch_data = get_linux_gdbarch_data (arch);
gdb_assert (gdbarch_data->num_disp_step_buffers > 0);
CORE_ADDR from, CORE_ADDR to,
struct regcache *regs)
{
- size_t len = gdbarch_max_insn_length (gdbarch);
+ size_t len = gdbarch_displaced_step_buffer_length (gdbarch);
+ gdb_assert (len > PPC_INSN_SIZE);
std::unique_ptr<ppc_displaced_step_copy_insn_closure> closure
(new ppc_displaced_step_copy_insn_closure (len));
gdb_byte *buf = closure->buf.data ();
set_gdbarch_displaced_step_finish (gdbarch, ppc_displaced_step_finish);
set_gdbarch_displaced_step_restore_all_in_ptid
(gdbarch, ppc_displaced_step_restore_all_in_ptid);
+ set_gdbarch_displaced_step_buffer_length (gdbarch, 2 * PPC_INSN_SIZE);
- set_gdbarch_max_insn_length (gdbarch, 2 * PPC_INSN_SIZE);
+ set_gdbarch_max_insn_length (gdbarch, PPC_INSN_SIZE);
/* Hook in ABI-specific overrides, if they have been registered. */
info.target_desc = tdesc;